Class: JOSE::JWE::ALG_ECDH_ES

Inherits:
Struct
  • Object
show all
Defined in:
lib/jose/jwe/alg_ecdh_es.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#apuObject

Returns the value of attribute apu

Returns:

  • (Object)

    the current value of apu


1
2
3
# File 'lib/jose/jwe/alg_ecdh_es.rb', line 1

def apu
  @apu
end

#apvObject

Returns the value of attribute apv

Returns:

  • (Object)

    the current value of apv


1
2
3
# File 'lib/jose/jwe/alg_ecdh_es.rb', line 1

def apv
  @apv
end

#bitsObject

Returns the value of attribute bits

Returns:

  • (Object)

    the current value of bits


1
2
3
# File 'lib/jose/jwe/alg_ecdh_es.rb', line 1

def bits
  @bits
end

#epkObject

Returns the value of attribute epk

Returns:

  • (Object)

    the current value of epk


1
2
3
# File 'lib/jose/jwe/alg_ecdh_es.rb', line 1

def epk
  @epk
end

Class Method Details

.from_map(fields) ⇒ Object

JOSE::JWE callbacks


5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/jose/jwe/alg_ecdh_es.rb', line 5

def self.from_map(fields)
  bits = nil
  case fields['alg']
  when 'ECDH-ES'
    bits = nil
  when 'ECDH-ES+A128KW'
    bits = 128
  when 'ECDH-ES+A192KW'
    bits = 192
  when 'ECDH-ES+A256KW'
    bits = 256
  else
    raise ArgumentError, "invalid 'alg' for JWE: #{fields['alg'].inspect}"
  end
  epk = nil
  if fields.has_key?('epk')
    epk = JOSE::JWK.from_map(fields['epk'])
  end
  apu = nil
  if fields.has_key?('apu')
    apu = JOSE.urlsafe_decode64(fields['apu'])
  end
  apv = nil
  if fields.has_key?('apv')
    apv = JOSE.urlsafe_decode64(fields['apv'])
  end
  return new(bits, epk, apu, apv), fields.except('alg', 'apu', 'apv', 'epk')
end

Instance Method Details

#algorithmObject

API functions


116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/jose/jwe/alg_ecdh_es.rb', line 116

def algorithm
  case bits
  when nil
    return 'ECDH-ES'
  when 128
    return 'ECDH-ES+A128KW'
  when 192
    return 'ECDH-ES+A192KW'
  when 256
    return 'ECDH-ES+A256KW'
  else
    raise ArgumentError, "unhandled JOSE::JWE::ALG_ECDH_ES bits: #{bits.inspect}"
  end
end

#generate_key(fields, enc) ⇒ Object

JOSE::JWE::ALG callbacks


50
51
52
53
54
55
56
# File 'lib/jose/jwe/alg_ecdh_es.rb', line 50

def generate_key(fields, enc)
  if not epk.nil?
    return JOSE::JWE::ALG.generate_key(epk, algorithm, enc.algorithm)
  else
    return JOSE::JWE::ALG.generate_key([:ec, 'P-521'], algorithm, enc.algorithm)
  end
end

#key_decrypt(box_keys, enc, encrypted_key) ⇒ Object


58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/jose/jwe/alg_ecdh_es.rb', line 58

def key_decrypt(box_keys, enc, encrypted_key)
  other_public_key, my_private_key = box_keys
  if my_private_key and epk and epk.to_key != other_public_key.to_key
    raise ArgumentError, "other and ephemeral public key mismatch"
  elsif epk and my_private_key.nil?
    my_private_key = other_public_key
    other_public_key = epk
  else
    raise ArgumentError, "missing 'epk' or my_private_key"
  end
  z = other_public_key.derive_key(my_private_key)
  if bits.nil?
    algorithm_id = enc.algorithm
    key_data_len = enc.bits
    supp_pub_info = [key_data_len].pack('N')
    derived_key = JOSE::JWA::ConcatKDF.kdf(OpenSSL::Digest::SHA256, z, [algorithm_id, apu, apv, supp_pub_info], key_data_len)
    return derived_key
  else
    algorithm_id = algorithm
    key_data_len = bits
    supp_pub_info = [key_data_len].pack('N')
    derived_key = JOSE::JWA::ConcatKDF.kdf(OpenSSL::Digest::SHA256, z, [algorithm_id, apu, apv, supp_pub_info], key_data_len)
    decrypted_key = JOSE::JWA::AES_KW.unwrap(encrypted_key, derived_key)
    return decrypted_key
  end
end

#key_encrypt(box_keys, enc, decrypted_key) ⇒ Object


85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/jose/jwe/alg_ecdh_es.rb', line 85

def key_encrypt(box_keys, enc, decrypted_key)
  if bits.nil?
    return '', self
  else
    other_public_key, my_private_key = box_keys
    z = other_public_key.derive_key(my_private_key)
    algorithm_id = algorithm
    key_data_len = bits
    supp_pub_info = [key_data_len].pack('N')
    derived_key = JOSE::JWA::ConcatKDF.kdf(OpenSSL::Digest::SHA256, z, [algorithm_id, apu, apv, supp_pub_info], key_data_len)
    encrypted_key = JOSE::JWA::AES_KW.wrap(decrypted_key, derived_key)
    return encrypted_key, self
  end
end

#next_cek(box_keys, enc) ⇒ Object


100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/jose/jwe/alg_ecdh_es.rb', line 100

def next_cek(box_keys, enc)
  if bits.nil?
    other_public_key, my_private_key = box_keys
    z = other_public_key.derive_key(my_private_key)
    algorithm_id = enc.algorithm
    key_data_len = enc.bits
    supp_pub_info = [key_data_len].pack('N')
    derived_key = JOSE::JWA::ConcatKDF.kdf(OpenSSL::Digest::SHA256, z, [algorithm_id, apu, apv, supp_pub_info], key_data_len)
    return derived_key
  else
    return enc.next_cek
  end
end

#to_map(fields) ⇒ Object


34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/jose/jwe/alg_ecdh_es.rb', line 34

def to_map(fields)
  fields = fields.put('alg', algorithm)
  if epk
    fields = fields.put('epk', epk.to_map)
  end
  if apu
    fields = fields.put('apu', JOSE.urlsafe_encode64(apu))
  end
  if apv
    fields = fields.put('apv', JOSE.urlsafe_encode64(apv))
  end
  return fields
end