Skip to content

Commit 6ef1fdf

Browse files
committed
fix: Correct the signature length check for ECDSA keys supplied via PKCS#11
An ASN.1 DER encoded signature is specified by RFC 3279 as: Ecdsa-Sig-Value ::= SEQUENCE { r INTEGER, s INTEGER } ASN.1 gives an overhead of 6 bytes (SEQUENCE and INTEGER tags + length) and for P-256 "r" and "s" are 32 bytes each. This gives a minimum length of 70 bytes. "r" and "s" should be positive numbers so if the numbers are negative (msb is 1), the numbers need to be padded, i.e. they will use 33 bytes instead of 32. This means the encoded signature can be 71 or 72 bytes depending on padding. Ticket: MEN-7941 Changelog: Title Signed-off-by: John Olav Lund <[email protected]>
1 parent 1e86686 commit 6ef1fdf

File tree

1 file changed

+6
-6
lines changed

1 file changed

+6
-6
lines changed

artifact/signer.go

+6-6
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ func (r *RSA) Verify(message, sig []byte, key interface{}) error {
7878
// ECDSA Crypto interface implementation
7979
const ecdsa256curveBits = 256
8080
const ecdsa256keySize = 32
81-
const ecdsa256Asn1SizeBytes = 72
81+
const ecdsa256Asn1SizeBytes = 70
82+
const ecdsa256Asn1Padding = 2
8283

8384
type ECDSA256 struct{}
8485

@@ -171,15 +172,14 @@ func UnmarshalECDSASignature(sig []byte) (r, s *big.Int, e error) {
171172
// in case of a key supplied via PKCS#11 URI, we have no control over what the signature is
172173
// since it is designed to be actually verified via the same mechanism (PKCS#11 URI).
173174
// We know here that it is ECDSA key, and judging form the size we can assume
174-
// that it is ASN.1 encoded. If so, then it should be 72 bytes, the less or equal is here
175-
// to support keys of size 71 bytes (strangely seen in the wild). In other words:
175+
// that it is ASN.1 encoded. If so, then it should be between 70 and 72 bytes.
176+
// In other words:
176177
// if the signature has not been created with MarshalECDSASignature, then we assume
177178
// it is to be decoded via ASN.1, with the protection on the signature length.
178-
if len(sig) == ecdsa256Asn1SizeBytes ||
179-
len(sig) == ecdsa256Asn1SizeBytes-1 {
179+
if len(sig) >= ecdsa256Asn1SizeBytes &&
180+
len(sig) <= ecdsa256Asn1SizeBytes+ecdsa256Asn1Padding {
180181
return UnmarshalECDSASignatureASN1(sig)
181182
}
182-
183183
return nil, nil, errors.Errorf("signer: invalid signature length: %d. "+
184184
"For ECDSA only P-256 is supported.", len(sig))
185185
}

0 commit comments

Comments
 (0)