Class: JWT::JWK::EC

Inherits:
KeyBase show all
Defined in:
lib/jwt/jwk/ec.rb

Overview

JWK representation for Elliptic Curve (EC) keys

Constant Summary collapse

KTY =

rubocop:disable Metrics/ClassLength

'EC'
KTYS =
[KTY, OpenSSL::PKey::EC, JWT::JWK::EC].freeze
BINARY =
2
EC_PUBLIC_KEY_ELEMENTS =
%i[kty crv x y].freeze
EC_PRIVATE_KEY_ELEMENTS =
%i[d].freeze
EC_KEY_ELEMENTS =
(EC_PRIVATE_KEY_ELEMENTS + EC_PUBLIC_KEY_ELEMENTS).freeze
ZERO_BYTE =
"\0".b.freeze

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from KeyBase

#<=>, #==, #[], #hash, #kid

Constructor Details

#initialize(key, params = nil, options = {}) ⇒ EC

Returns a new instance of EC.



17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/jwt/jwk/ec.rb', line 17

def initialize(key, params = nil, options = {})
  params ||= {}

  # For backwards compatibility when kid was a String
  params = { kid: params } if params.is_a?(String)

  key_params = extract_key_params(key)

  params = params.transform_keys(&:to_sym)
  check_jwk_params!(key_params, params)

  super(options, key_params.merge(params))
end

Class Method Details

.import(jwk_data) ⇒ Object



227
228
229
# File 'lib/jwt/jwk/ec.rb', line 227

def import(jwk_data)
  new(jwk_data)
end

.to_openssl_curve(crv) ⇒ Object



231
232
233
234
235
236
237
238
239
240
241
242
# File 'lib/jwt/jwk/ec.rb', line 231

def to_openssl_curve(crv)
  # The JWK specs and OpenSSL use different names for the same curves.
  # See https://tools.ietf.org/html/rfc5480#section-2.1.1.1 for some
  # pointers on different names for common curves.
  case crv
  when 'P-256' then 'prime256v1'
  when 'P-384' then 'secp384r1'
  when 'P-521' then 'secp521r1'
  when 'P-256K' then 'secp256k1'
  else raise JWT::JWKError, 'Invalid curve provided'
  end
end

Instance Method Details

#[]=(key, value) ⇒ Object

Raises:

  • (ArgumentError)


68
69
70
71
72
# File 'lib/jwt/jwk/ec.rb', line 68

def []=(key, value)
  raise ArgumentError, 'cannot overwrite cryptographic key attributes' if EC_KEY_ELEMENTS.include?(key.to_sym)

  super(key, value)
end

#export(options = {}) ⇒ Object



55
56
57
58
59
# File 'lib/jwt/jwk/ec.rb', line 55

def export(options = {})
  exported = parameters.clone
  exported.reject! { |k, _| EC_PRIVATE_KEY_ELEMENTS.include? k } unless private? && options[:include_private] == true
  exported
end

#key_digestObject



61
62
63
64
65
66
# File 'lib/jwt/jwk/ec.rb', line 61

def key_digest
  _crv, x_octets, y_octets = keypair_components(ec_key)
  sequence = OpenSSL::ASN1::Sequence([OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(x_octets, BINARY)),
                                      OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(y_octets, BINARY))])
  OpenSSL::Digest::SHA256.hexdigest(sequence.to_der)
end

#keypairObject



31
32
33
# File 'lib/jwt/jwk/ec.rb', line 31

def keypair
  ec_key
end

#membersObject



51
52
53
# File 'lib/jwt/jwk/ec.rb', line 51

def members
  EC_PUBLIC_KEY_ELEMENTS.each_with_object({}) { |i, h| h[i] = self[i] }
end

#private?Boolean

Returns:

  • (Boolean)


35
36
37
# File 'lib/jwt/jwk/ec.rb', line 35

def private?
  ec_key.private_key?
end

#public_keyObject



47
48
49
# File 'lib/jwt/jwk/ec.rb', line 47

def public_key
  ec_key
end

#signing_keyObject



39
40
41
# File 'lib/jwt/jwk/ec.rb', line 39

def signing_key
  ec_key
end

#verify_keyObject



43
44
45
# File 'lib/jwt/jwk/ec.rb', line 43

def verify_key
  ec_key
end