Class: Moxml::Signature::Algorithms::EcdsaSha

Inherits:
SignatureMethodBase show all
Defined in:
lib/moxml/signature/algorithms/ecdsa_sha.rb

Overview

ECDSA signature methods per FIPS 186-3, bound to a digest.

Spec §6.4.3 requires support for ECDSAwithSHA256 over the P-256 curve. Recommended: P-384, P-521.

The wire format is base64(I2OSP(r, n_bytes) || I2OSP(s, n_bytes)) where n_bytes is the byte length of the base point order (32 for P-256, 48 for P-384, 66 for P-521).

OpenSSL returns a DER-encoded ASN.1 sequence of (r, s). We convert to the raw r||s form on sign, and back from raw to DER on verify.

Constant Summary collapse

PAIRINGS =
{
  "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1" => "SHA1",
  "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha224" => "SHA224",
  "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256" => "SHA256",
  "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384" => "SHA384",
  "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512" => "SHA512",
}.freeze
CURVE_ORDER_BYTES =

Map OpenSSL curve name → byte length of base point order.

{
  "prime256v1" => 32,   # P-256
  "secp384r1" => 48,    # P-384
  "secp521r1" => 66,    # P-521 (ceil(521/8) = 66)
}.freeze

Instance Method Summary collapse

Methods inherited from SignatureMethodBase

identifier, #sign, #verify

Constructor Details

#initialize(identifier_uri:, parameters: nil) ⇒ EcdsaSha

Returns a new instance of EcdsaSha.



37
38
39
40
41
# File 'lib/moxml/signature/algorithms/ecdsa_sha.rb', line 37

def initialize(identifier_uri:, parameters: nil)
  super(nil)
  @identifier_uri = identifier_uri
  @parameters = parameters
end

Instance Method Details

#compute_signature(data, key) ⇒ Object



43
44
45
46
47
48
# File 'lib/moxml/signature/algorithms/ecdsa_sha.rb', line 43

def compute_signature(data, key)
  ec_key = coerce_key(key)
  digest_name = self.class::PAIRINGS.fetch(@identifier_uri)
  der_signature = ec_key.sign(digest_name, data)
  der_to_raw(der_signature, coordinate_bytes_for(ec_key))
end

#verify_signature(data, key, signature) ⇒ Object



50
51
52
53
54
55
56
57
58
# File 'lib/moxml/signature/algorithms/ecdsa_sha.rb', line 50

def verify_signature(data, key, signature)
  ec_key = coerce_key(key)
  digest_name = self.class::PAIRINGS.fetch(@identifier_uri)
  n_bytes = coordinate_bytes_for(ec_key)
  der_signature = raw_to_der(signature, n_bytes)
  ec_key.verify(digest_name, der_signature, data)
rescue ArgumentError
  false
end