Class: HealthCards::Key
- Inherits:
-
Object
- Object
- HealthCards::Key
- Defined in:
- lib/health_cards/key.rb
Overview
Methods to generate signing keys and jwk
Direct Known Subclasses
Constant Summary collapse
- BASE =
{ kty: 'EC', crv: 'P-256' }.freeze
- DIGEST =
OpenSSL::Digest.new('SHA256')
Class Method Summary collapse
-
.enforce_valid_key_type!(obj, allow_nil: false) ⇒ Object
Checks if obj is the the correct key type or nil.
-
.from_jwk(jwk_key) ⇒ HealthCards::Key
Create a key from a JWK.
Instance Method Summary collapse
- #coordinates ⇒ Object
- #group ⇒ Object
-
#initialize(ec_key) ⇒ Key
constructor
A new instance of Key.
- #kid ⇒ Object
- #public_coordinates ⇒ Object
- #to_json(*_args) ⇒ Object
- #to_jwk ⇒ Object
Constructor Details
#initialize(ec_key) ⇒ Key
Returns a new instance of Key.
33 34 35 |
# File 'lib/health_cards/key.rb', line 33 def initialize(ec_key) @key = ec_key end |
Class Method Details
.enforce_valid_key_type!(obj, allow_nil: false) ⇒ Object
Checks if obj is the the correct key type or nil
15 16 17 |
# File 'lib/health_cards/key.rb', line 15 def self.enforce_valid_key_type!(obj, allow_nil: false) raise InvalidKeyError.new(self, obj) unless obj.is_a?(self) || (allow_nil && obj.nil?) end |
.from_jwk(jwk_key) ⇒ HealthCards::Key
Create a key from a JWK
23 24 25 26 27 28 29 30 31 |
# File 'lib/health_cards/key.rb', line 23 def self.from_jwk(jwk_key) jwk_key = jwk_key.transform_keys(&:to_sym) group = OpenSSL::PKey::EC::Group.new('prime256v1') key = OpenSSL::PKey::EC.new(group) key.private_key = OpenSSL::BN.new(Base64.urlsafe_decode64(jwk_key[:d]), 2) if jwk_key[:d] public_key_bn = ['04'].pack('H*') + Base64.urlsafe_decode64(jwk_key[:x]) + Base64.urlsafe_decode64(jwk_key[:y]) key.public_key = OpenSSL::PKey::EC::Point.new(group, OpenSSL::BN.new(public_key_bn, 2)) key.private_key? ? HealthCards::PrivateKey.new(key) : HealthCards::PublicKey.new(key) end |
Instance Method Details
#coordinates ⇒ Object
57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/health_cards/key.rb', line 57 def coordinates return @coordinates if @coordinates key_binary = @key.public_key.to_bn.to_s(2) coords = { x: key_binary[1, key_binary.length / 2], y: key_binary[key_binary.length / 2 + 1, key_binary.length] } coords[:d] = @key.private_key.to_s(2) if @key.private_key? @coordinates = coords.transform_values do |val| Base64.urlsafe_encode64(val, padding: false) end.merge(BASE) end |
#group ⇒ Object
37 38 39 |
# File 'lib/health_cards/key.rb', line 37 def group @key.group end |
#kid ⇒ Object
49 50 51 |
# File 'lib/health_cards/key.rb', line 49 def kid Base64.urlsafe_encode64(DIGEST.digest(public_coordinates.to_json), padding: false) end |
#public_coordinates ⇒ Object
53 54 55 |
# File 'lib/health_cards/key.rb', line 53 def public_coordinates coordinates.slice(:crv, :kty, :x, :y) end |
#to_json(*_args) ⇒ Object
41 42 43 |
# File 'lib/health_cards/key.rb', line 41 def to_json(*_args) to_jwk.to_json end |
#to_jwk ⇒ Object
45 46 47 |
# File 'lib/health_cards/key.rb', line 45 def to_jwk coordinates.merge(kid: kid, use: 'sig', alg: 'ES256') end |