Module: CaveatEmptor::Protocol::V1

Defined in:
lib/caveat_emptor/protocol/v1.rb

Constant Summary collapse

VERSION =
1
HMAC_ALGORITHM =
"SHA256"

Class Method Summary collapse

Class Method Details

.attenuate(macaroon, caveat) ⇒ Object



29
30
31
32
33
34
35
36
37
# File 'lib/caveat_emptor/protocol/v1.rb', line 29

def attenuate(macaroon, caveat)
  Macaroon.new(
    location: macaroon.location.clone,
    id: macaroon.id.clone,
    caveats: macaroon.caveats.clone.push(caveat),
    signature: compute_attenuated_signature(macaroon.signature, caveat),
    protocol_version: 1
  )
end

.compute_attenuated_signature(signature, caveat) ⇒ Object



47
48
49
# File 'lib/caveat_emptor/protocol/v1.rb', line 47

def compute_attenuated_signature(signature, caveat)
  OpenSSL::HMAC.digest(HMAC_ALGORITHM, signature, caveat)
end

.compute_expected_signature(root_key, macaroon) ⇒ Object



39
40
41
42
43
44
45
# File 'lib/caveat_emptor/protocol/v1.rb', line 39

def compute_expected_signature(root_key, macaroon)
  computed_signature = initial_signature(root_key, macaroon.id)
  macaroon.caveats.each do |caveat|
    computed_signature = OpenSSL::HMAC.digest(HMAC_ALGORITHM, computed_signature, caveat)
  end
  computed_signature
end

.initial_signature(root_key, id) ⇒ Object



51
52
53
# File 'lib/caveat_emptor/protocol/v1.rb', line 51

def initial_signature(root_key, id)
  OpenSSL::HMAC.digest(HMAC_ALGORITHM, root_key, version_prefixed_id(id))
end

.mint(root_key:, location:, id:) ⇒ Object



12
13
14
15
16
17
18
19
20
# File 'lib/caveat_emptor/protocol/v1.rb', line 12

def mint(root_key:, location:, id:)
  Macaroon.new(
    location: location,
    id: id,
    caveats: [],
    signature: initial_signature(root_key, id),
    protocol_version: 1
  )
end

.secure_compare(a, b) ⇒ Object



55
56
57
# File 'lib/caveat_emptor/protocol/v1.rb', line 55

def secure_compare(a, b)
  OpenSSL.fixed_length_secure_compare(a, b)
end

.verify!(root_key, macaroon) ⇒ Object



22
23
24
25
26
27
# File 'lib/caveat_emptor/protocol/v1.rb', line 22

def verify!(root_key, macaroon)
  challenge_signature = macaroon.signature
  computed_signature = compute_expected_signature(root_key, macaroon)
  raise "Verification failed" unless secure_compare(challenge_signature, computed_signature)
  macaroon
end

.version_prefixed_id(id) ⇒ Object



59
60
61
# File 'lib/caveat_emptor/protocol/v1.rb', line 59

def version_prefixed_id(id)
  [VERSION].pack("C") + [id.bytesize].pack("N") + id.b
end