class HealthCards::Key

Methods to generate signing keys and jwk

Constants

BASE
DIGEST

Public Class Methods

enforce_valid_key_type!(obj, allow_nil: false) click to toggle source

Checks if obj is the the correct key type or nil @param obj Object that should be of same type as caller or nil @param allow_nil Allow/Disallow key to be nil

# 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) click to toggle source

Create a key from a JWK

@param jwk_key [Hash] The JWK represented by a Hash @return [HealthCards::Key] The key represented by the JWK

# 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
new(ec_key) click to toggle source
# File lib/health_cards/key.rb, line 33
def initialize(ec_key)
  @key = ec_key
end

Public Instance Methods

coordinates() click to toggle source
# 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() click to toggle source
# File lib/health_cards/key.rb, line 37
def group
  @key.group
end
kid() click to toggle source
# File lib/health_cards/key.rb, line 49
def kid
  Base64.urlsafe_encode64(DIGEST.digest(public_coordinates.to_json), padding: false)
end
public_coordinates() click to toggle source
# File lib/health_cards/key.rb, line 53
def public_coordinates
  coordinates.slice(:crv, :kty, :x, :y)
end
to_json(*_args) click to toggle source
# File lib/health_cards/key.rb, line 41
def to_json(*_args)
  to_jwk.to_json
end
to_jwk() click to toggle source
# File lib/health_cards/key.rb, line 45
def to_jwk
  coordinates.merge(kid: kid, use: 'sig', alg: 'ES256')
end