From 9d2184eb2d29846b087857168c248610cf6d2c12 Mon Sep 17 00:00:00 2001 From: SulaimanAminuBarkindo Date: Thu, 7 Mar 2024 08:45:10 +0100 Subject: [PATCH] Add check for maximum signature length in ecdsa.ParseDERSignature * Updated the `ecdsa.ParseDERSignature` to include the MaxSigLen constant, which defines the maximum length of a DER encoded signature. * The MaxSigLen constant is set to 72 bytes, as per the explanation in the comment. * A new test case has been added to test the functionality with a long signature. * The test case checks if signatures longer than the specified maximum length are properly handled. * The test ensures that signatures exceeding the maximum length are correctly identified as invalid. --- btcec/ecdsa/signature.go | 26 +++++++++++++++++++++----- btcec/ecdsa/signature_test.go | 15 +++++++++++++++ 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/btcec/ecdsa/signature.go b/btcec/ecdsa/signature.go index 092e4ceb1c..44b84a78c9 100644 --- a/btcec/ecdsa/signature.go +++ b/btcec/ecdsa/signature.go @@ -37,10 +37,20 @@ var ( oneInitializer = []byte{0x01} ) -// MinSigLen is the minimum length of a DER encoded signature and is when both R -// and S are 1 byte each. -// 0x30 + <1-byte> + 0x02 + 0x01 + + 0x2 + 0x01 + -const MinSigLen = 8 +const ( + // MinSigLen is the minimum length of a DER encoded signature and is when both R + // and S are 1 byte each. + // 0x30 + <1-byte> + 0x02 + 0x01 + + 0x2 + 0x01 + + MinSigLen = 8 + + // MaxSigLen is the maximum length of a DER encoded signature and is + // when both R and S are 33 bytes each. It is 33 bytes because a + // 256-bit integer requires 32 bytes and an additional leading null byte + // might be required if the high bit is set in the value. + // + // 0x30 + <1-byte> + 0x02 + 0x21 + <33 bytes> + 0x2 + 0x21 + <33 bytes> + MaxSigLen = 72 +) // canonicalPadding checks whether a big-endian encoded integer could // possibly be misinterpreted as a negative number (even though OpenSSL @@ -68,9 +78,15 @@ func parseSig(sigStr []byte, der bool) (*Signature, error) { // 0x30 <0x02> 0x2 // . - if len(sigStr) < MinSigLen { + // The signature must adhere to the minimum and maximum allowed length. + totalSigLen := len(sigStr) + if totalSigLen < MinSigLen { return nil, errors.New("malformed signature: too short") } + if der && totalSigLen > MaxSigLen { + return nil, errors.New("malformed signature: too long") + } + // 0x30 index := 0 if sigStr[index] != 0x30 { diff --git a/btcec/ecdsa/signature_test.go b/btcec/ecdsa/signature_test.go index d2eebdc788..f36e15db89 100644 --- a/btcec/ecdsa/signature_test.go +++ b/btcec/ecdsa/signature_test.go @@ -333,6 +333,21 @@ var signatureTests = []signatureTest{ der: false, isValid: false, }, + { + name: "Long signature.", + sig: []byte{0x30, 0x44, 0x02, 0x20, 0x4e, 0x45, 0xe1, 0x69, + 0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1, + 0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6, + 0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd, + 0x41, 0x02, 0x20, 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca, + 0x07, 0xde, 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90, + 0x9d, 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22, + 0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09, 0x91, + 0x17, 0x90, 0xda, 0x42, 0xca, 0xaf, 0x19, 0x7d, 0xb4, + }, + der: true, + isValid: false, + }, } func TestSignatures(t *testing.T) {