Module: JWT::JWA::Ecdsa
- Defined in:
- lib/jwt/jwa/ecdsa.rb
Constant Summary collapse
- NAMED_CURVES =
{ 'prime256v1' => { algorithm: 'ES256', digest: 'sha256' }, 'secp256r1' => { # alias for prime256v1 algorithm: 'ES256', digest: 'sha256' }, 'secp384r1' => { algorithm: 'ES384', digest: 'sha384' }, 'secp521r1' => { algorithm: 'ES512', digest: 'sha512' }, 'secp256k1' => { algorithm: 'ES256K', digest: 'sha256' } }.freeze
- SUPPORTED =
NAMED_CURVES.map { |_, c| c[:algorithm] }.uniq.freeze
Class Method Summary collapse
- .asn1_to_raw(signature, public_key) ⇒ Object
- .curve_by_name(name) ⇒ Object
- .raw_to_asn1(signature, private_key) ⇒ Object
- .sign(algorithm, msg, key) ⇒ Object
- .verify(algorithm, public_key, signing_input, signature) ⇒ Object
Class Method Details
.asn1_to_raw(signature, public_key) ⇒ Object
70 71 72 73 |
# File 'lib/jwt/jwa/ecdsa.rb', line 70 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) ⇒ Object
57 58 59 60 61 |
# File 'lib/jwt/jwa/ecdsa.rb', line 57 def curve_by_name(name) NAMED_CURVES.fetch(name) do raise UnsupportedEcdsaCurve, "The ECDSA curve '#{name}' is not supported" end end |
.raw_to_asn1(signature, private_key) ⇒ Object
63 64 65 66 67 68 |
# File 'lib/jwt/jwa/ecdsa.rb', line 63 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 |
.sign(algorithm, msg, key) ⇒ Object
33 34 35 36 37 38 39 40 41 42 |
# File 'lib/jwt/jwa/ecdsa.rb', line 33 def sign(algorithm, msg, key) curve_definition = curve_by_name(key.group.curve_name) key_algorithm = curve_definition[:algorithm] if algorithm != key_algorithm raise IncorrectAlgorithm, "payload algorithm is #{algorithm} but #{key_algorithm} signing key was provided" end digest = OpenSSL::Digest.new(curve_definition[:digest]) asn1_to_raw(key.dsa_sign_asn1(digest.digest(msg)), key) end |
.verify(algorithm, public_key, signing_input, signature) ⇒ Object
44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/jwt/jwa/ecdsa.rb', line 44 def verify(algorithm, public_key, signing_input, signature) curve_definition = curve_by_name(public_key.group.curve_name) key_algorithm = curve_definition[:algorithm] if algorithm != key_algorithm raise IncorrectAlgorithm, "payload algorithm is #{algorithm} but #{key_algorithm} verification key was provided" end digest = OpenSSL::Digest.new(curve_definition[:digest]) public_key.dsa_verify_asn1(digest.digest(signing_input), raw_to_asn1(signature, public_key)) rescue OpenSSL::PKey::PKeyError raise JWT::VerificationError, 'Signature verification raised' end |