diff --git a/.changeset/warm-signatures-smile.md b/.changeset/warm-signatures-smile.md new file mode 100644 index 00000000..b30bcd60 --- /dev/null +++ b/.changeset/warm-signatures-smile.md @@ -0,0 +1,5 @@ +--- +'@bitauth/libauth': patch +--- + +Fix `isValidSignatureEncodingDER` to accept valid 8- and 72-byte DER signatures diff --git a/src/lib/vm/instruction-sets/common/encoding.spec.ts b/src/lib/vm/instruction-sets/common/encoding.spec.ts new file mode 100644 index 00000000..d33f8b4f --- /dev/null +++ b/src/lib/vm/instruction-sets/common/encoding.spec.ts @@ -0,0 +1,36 @@ +import test from 'ava'; + +import { isValidSignatureEncodingDER, range } from '../../../lib.js'; + +const minimumLengthSignature = Uint8Array.from([ + 0x30, 0x06, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01, +]); +const maximumLengthInteger = [0, ...range(32).map(() => 0x80)]; +const maximumLengthSignature = Uint8Array.from([ + 0x30, + 0x46, + 0x02, + 0x21, + ...maximumLengthInteger, + 0x02, + 0x21, + ...maximumLengthInteger, +]); +const oversizedInteger = [0, ...range(33).map(() => 0x80)]; +const oversizedSignature = Uint8Array.from([ + 0x30, + 0x47, + 0x02, + 0x22, + ...oversizedInteger, + 0x02, + 0x21, + ...maximumLengthInteger, +]); + +test('isValidSignatureEncodingDER: length boundaries', (t) => { + t.false(isValidSignatureEncodingDER(minimumLengthSignature.slice(0, -1))); + t.true(isValidSignatureEncodingDER(minimumLengthSignature)); + t.true(isValidSignatureEncodingDER(maximumLengthSignature)); + t.false(isValidSignatureEncodingDER(oversizedSignature)); +}); diff --git a/src/lib/vm/instruction-sets/common/encoding.ts b/src/lib/vm/instruction-sets/common/encoding.ts index cac63230..2c0d344d 100644 --- a/src/lib/vm/instruction-sets/common/encoding.ts +++ b/src/lib/vm/instruction-sets/common/encoding.ts @@ -86,8 +86,8 @@ const isValidInteger = ( // eslint-disable-next-line complexity export const isValidSignatureEncodingDER = (signature: Uint8Array) => { const correctLengthRange = - signature.length > DER.minimumLength && - signature.length < DER.maximumLength; + signature.length >= DER.minimumLength && + signature.length <= DER.maximumLength; const correctSequenceTagType = signature[DER.sequenceTagIndex] === ASN1.sequenceTagType; const correctSequenceLength =