class JWT::JWA::Ecdsa

Constants

NAMED_CURVES

Attributes

digest[R]

Public Class Methods

curve_by_name(name) click to toggle source
# File lib/jwt/jwa/ecdsa.rb, line 66
def self.curve_by_name(name)
  NAMED_CURVES.fetch(name) do
    raise UnsupportedEcdsaCurve, "The ECDSA curve '#{name}' is not supported"
  end
end
from_algorithm(algorithm) click to toggle source
# File lib/jwt/jwa/ecdsa.rb, line 62
def self.from_algorithm(algorithm)
  new(algorithm, algorithm.downcase.gsub('es', 'sha'))
end
new(alg, digest) click to toggle source
# File lib/jwt/jwa/ecdsa.rb, line 8
def initialize(alg, digest)
  @alg = alg
  @digest = OpenSSL::Digest.new(digest)
end

Public Instance Methods

sign(data:, signing_key:) click to toggle source
# File lib/jwt/jwa/ecdsa.rb, line 13
def sign(data:, signing_key:)
  curve_definition = curve_by_name(signing_key.group.curve_name)
  key_algorithm = curve_definition[:algorithm]
  if alg != key_algorithm
    raise IncorrectAlgorithm, "payload algorithm is #{alg} but #{key_algorithm} signing key was provided"
  end

  asn1_to_raw(signing_key.dsa_sign_asn1(digest.digest(data)), signing_key)
end
verify(data:, signature:, verification_key:) click to toggle source
# File lib/jwt/jwa/ecdsa.rb, line 23
def verify(data:, signature:, verification_key:)
  curve_definition = curve_by_name(verification_key.group.curve_name)
  key_algorithm = curve_definition[:algorithm]
  if alg != key_algorithm
    raise IncorrectAlgorithm, "payload algorithm is #{alg} but #{key_algorithm} verification key was provided"
  end

  verification_key.dsa_verify_asn1(digest.digest(data), raw_to_asn1(signature, verification_key))
rescue OpenSSL::PKey::PKeyError
  raise JWT::VerificationError, 'Signature verification raised'
end

Private Instance Methods

asn1_to_raw(signature, public_key) click to toggle source
# File lib/jwt/jwa/ecdsa.rb, line 87
def asn1_to_raw(signature, public_key)
  byte_size = (public_key.group.degree + 7) / 8
  OpenSSL::ASN1.decode(signature).value.map { |value| value.value.to_s(2).rjust(byte_size, "\x00") }.join
end
curve_by_name(name) click to toggle source
# File lib/jwt/jwa/ecdsa.rb, line 76
def curve_by_name(name)
  self.class.curve_by_name(name)
end
raw_to_asn1(signature, private_key) click to toggle source
# File lib/jwt/jwa/ecdsa.rb, line 80
def raw_to_asn1(signature, private_key)
  byte_size = (private_key.group.degree + 7) / 8
  sig_bytes = signature[0..(byte_size - 1)]
  sig_char = signature[byte_size..-1] || ''
  OpenSSL::ASN1::Sequence.new([sig_bytes, sig_char].map { |int| OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(int, 2)) }).to_der
end