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



143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/jose/jwe/alg_ecdh_es.rb', line 143

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
84
85
86
87
88
# 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.nil?
    my_private_key = other_public_key
    other_public_key = nil
  end
  if epk.nil? and other_public_key.nil?
    raise ArgumentError, "missing 'epk' and 'other_public_key'"
  elsif epk and other_public_key and epk.thumbprint != other_public_key.thumbprint
    raise ArgumentError, "other and ephemeral public key mismatch"
  end
  new_alg = self
  if epk.nil?
    new_alg = JOSE::JWE::ALG_ECDH_ES.new(bits, other_public_key.to_public, apu, apv)
  end
  z = new_alg.epk.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, new_alg.apu, new_alg.apv, supp_pub_info], key_data_len)
    return derived_key
  else
    algorithm_id = new_alg.algorithm
    key_data_len = new_alg.bits
    supp_pub_info = [key_data_len].pack('N')
    derived_key = JOSE::JWA::ConcatKDF.kdf(OpenSSL::Digest::SHA256, z, [algorithm_id, new_alg.apu, new_alg.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



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/jose/jwe/alg_ecdh_es.rb', line 90

def key_encrypt(box_keys, enc, decrypted_key)
  if bits.nil?
    return '', self
  else
    other_public_key, my_private_key = box_keys
    if my_private_key.nil?
      raise ArgumentError, "missing 'my_private_key'"
    elsif other_public_key.nil?
      raise ArgumentError, "missing 'other_public_key'"
    elsif epk and my_private_key and epk.thumbprint != my_private_key.thumbprint
      raise ArgumentError, "private and ephemeral public key mismatch"
    end
    new_alg = self
    if epk.nil?
      new_alg = JOSE::JWE::ALG_ECDH_ES.new(bits, my_private_key.to_public, apu, apv)
    end
    z = other_public_key.derive_key(my_private_key)
    algorithm_id = new_alg.algorithm
    key_data_len = new_alg.bits
    supp_pub_info = [key_data_len].pack('N')
    derived_key = JOSE::JWA::ConcatKDF.kdf(OpenSSL::Digest::SHA256, z, [algorithm_id, new_alg.apu, new_alg.apv, supp_pub_info], key_data_len)
    encrypted_key = JOSE::JWA::AES_KW.wrap(decrypted_key, derived_key)
    return encrypted_key, new_alg
  end
end

#next_cek(box_keys, enc) ⇒ Object



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/jose/jwe/alg_ecdh_es.rb', line 116

def next_cek(box_keys, enc)
  if bits.nil?
    other_public_key, my_private_key = box_keys
    if my_private_key.nil?
      raise ArgumentError, "missing 'my_private_key'"
    elsif other_public_key.nil?
      raise ArgumentError, "missing 'other_public_key'"
    elsif epk and my_private_key and epk.thumbprint != my_private_key.thumbprint
      raise ArgumentError, "private and ephemeral public key mismatch"
    end
    new_alg = self
    if epk.nil?
      new_alg = JOSE::JWE::ALG_ECDH_ES.new(bits, my_private_key.to_public, apu, apv)
    end
    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, new_alg.apu, new_alg.apv, supp_pub_info], key_data_len)
    return derived_key, new_alg
  else
    return enc.next_cek, self
  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