diff --git a/signature/subtle/ecdsa_signer.go b/signature/subtle/ecdsa_signer.go index ecc20a6..64b9e13 100644 --- a/signature/subtle/ecdsa_signer.go +++ b/signature/subtle/ecdsa_signer.go @@ -69,15 +69,25 @@ func (e *ECDSASigner) Sign(data []byte) ([]byte, error) { if err != nil { return nil, err } - r, s, err := ecdsa.Sign(rand.Reader, e.privateKey, hashed) - if err != nil { - return nil, fmt.Errorf("ecdsa_signer: signing failed: %s", err) - } - // format the signature - sig := NewECDSASignature(r, s) - ret, err := sig.EncodeECDSASignature(e.encoding, e.privateKey.PublicKey.Curve.Params().Name) - if err != nil { - return nil, fmt.Errorf("ecdsa_signer: signing failed: %s", err) + var signatureBytes []byte + switch e.encoding { + case "IEEE_P1363": + r, s, err := ecdsa.Sign(rand.Reader, e.privateKey, hashed) + if err != nil { + return nil, err + } + sig := NewECDSASignature(r, s) + signatureBytes, err = sig.EncodeECDSASignature(e.encoding, e.privateKey.PublicKey.Curve.Params().Name) + if err != nil { + return nil, fmt.Errorf("ecdsa_signer: signing failed: %s", err) + } + case "DER": + signatureBytes, err = ecdsa.SignASN1(rand.Reader, e.privateKey, hashed) + if err != nil { + return nil, fmt.Errorf("ecdsa_signer: signing failed: %s", err) + } + default: + return nil, fmt.Errorf("ecdsa_signer: unsupported encoding: %s", e.encoding) } - return ret, nil + return signatureBytes, nil } diff --git a/signature/subtle/ecdsa_verifier.go b/signature/subtle/ecdsa_verifier.go index 70784bc..87a90bb 100644 --- a/signature/subtle/ecdsa_verifier.go +++ b/signature/subtle/ecdsa_verifier.go @@ -21,11 +21,10 @@ import ( "hash" "math/big" + internalecdsa "github.com/tink-crypto/tink-go/v2/internal/signature/ecdsa" "github.com/tink-crypto/tink-go/v2/subtle" ) -var errInvalidECDSASignature = errors.New("ecdsa_verifier: invalid signature") - // ECDSAVerifier is an implementation of Verifier for ECDSA. // At the moment, the implementation only accepts signatures with strict DER encoding. type ECDSAVerifier struct { @@ -67,17 +66,28 @@ func NewECDSAVerifierFromPublicKey(hashAlg string, encoding string, publicKey *e // Verify verifies whether the given signature is valid for the given data. // It returns an error if the signature is not valid; nil otherwise. func (e *ECDSAVerifier) Verify(signatureBytes, data []byte) error { - signature, err := DecodeECDSASignature(signatureBytes, e.encoding) - if err != nil { - return fmt.Errorf("ecdsa_verifier: %s", err) - } hashed, err := subtle.ComputeHash(e.hashFunc, data) if err != nil { return err } - valid := ecdsa.Verify(e.publicKey, hashed, signature.R, signature.S) - if !valid { - return errInvalidECDSASignature + var asn1Signature []byte + switch e.encoding { + case "DER": + asn1Signature = signatureBytes + case "IEEE_P1363": + decodedSig, err := internalecdsa.IEEEP1363Decode(signatureBytes) + if err != nil { + return err + } + asn1Signature, err = internalecdsa.ASN1Encode(decodedSig) + if err != nil { + return err + } + default: + return fmt.Errorf("ecdsa: unsupported encoding: %s", e.encoding) + } + if ok := ecdsa.VerifyASN1(e.publicKey, hashed, asn1Signature); !ok { + return fmt.Errorf("ecdsa_verifier: invalid signature") } return nil }