Skip to content

Commit

Permalink
fix(crypto): reject long form signature lengths
Browse files Browse the repository at this point in the history
Co-authored-by: Air1 <erwann@ark.io>
  • Loading branch information
alessiodf and air1one committed Dec 3, 2020
1 parent 72f99b9 commit 8f8976d
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 2 deletions.
42 changes: 42 additions & 0 deletions __tests__/unit/crypto/blocks/block.test.ts
Expand Up @@ -488,6 +488,48 @@ describe("Block", () => {
expect(blockInvalidR.verification.errors).toEqual(["Failed to verify block signature"]);
});

it("should fail to verify a block with long form signature", () => {
const block = BlockFactory.fromData({
id: "62b348a7aba2c60506929eec1311eaecb48ef232d4b154db2ede3f5e53700be9",
version: 0,
timestamp: 102041016,
height: 5470549,
reward: Utils.BigNumber.make("200000000"),
previousBlock: "2d270cae7e2bd9da27f6160b521859820f2c90315672e1774733bdd6415abb86",
numberOfTransactions: 0,
totalAmount: Utils.BigNumber.ZERO,
totalFee: Utils.BigNumber.ZERO,
payloadLength: 0,
payloadHash: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
generatorPublicKey: "026a423b3323de175dd82788c7eab57850c6a37ea6a470308ebadd7007baf8ceb3",
blockSignature:
"3045022100c92d7d0c3ea2ba72576f6494a81fc498d0420286896f806a7ead443d0b5d89720220501610f0d5498d028fd27676ea2597a5cb80cf5896e77fe2fa61623d31ff290c",
});

expect(block.verification.verified).toBeTrue();
expect(block.verification.errors).toEqual([]);

const blockLongFormSig = BlockFactory.fromData({
id: "62b348a7aba2c60506929eec1311eaecb48ef232d4b154db2ede3f5e53700be9",
version: 0,
timestamp: 102041016,
height: 5470549,
reward: Utils.BigNumber.make("200000000"),
previousBlock: "2d270cae7e2bd9da27f6160b521859820f2c90315672e1774733bdd6415abb86",
numberOfTransactions: 0,
totalAmount: Utils.BigNumber.ZERO,
totalFee: Utils.BigNumber.ZERO,
payloadLength: 0,
payloadHash: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
generatorPublicKey: "026a423b3323de175dd82788c7eab57850c6a37ea6a470308ebadd7007baf8ceb3",
blockSignature:
"30820045022100c92d7d0c3ea2ba72576f6494a81fc498d0420286896f806a7ead443d0b5d89720220501610f0d5498d028fd27676ea2597a5cb80cf5896e77fe2fa61623d31ff290c0239111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111",
});

expect(blockLongFormSig.verification.verified).toBeFalse();
expect(blockLongFormSig.verification.errors).toEqual(["Failed to verify block signature"]);
});

it("should construct the block (header only)", () => {
const block = BlockFactory.fromHex(dummyBlock2.serialized);
const actual = block.toJson();
Expand Down
8 changes: 6 additions & 2 deletions packages/crypto/src/crypto/hash.ts
Expand Up @@ -19,14 +19,18 @@ export class Hash {
const signatureLength = bufferSignature.readUInt8(1);
const rLength = bufferSignature.readUInt8(3);
const sLength = bufferSignature.readUInt8(4 + rLength + 1);
if (bufferSignature.length !== 4 + rLength + 2 + sLength || signatureLength !== 2 + rLength + 2 + sLength) {
if (
bufferSignature.length !== 4 + rLength + 2 + sLength ||
signatureLength !== 2 + rLength + 2 + sLength ||
signatureLength > 127
) {
return false;
}

// check that first byte is positive, if it is then the whole R / S will be positive as required
const rFirstByte = bufferSignature.readInt8(4);
const sFirstByte = bufferSignature.readInt8(4 + rLength + 2);
if (rFirstByte < 0 || sFirstByte < 0) {
if (rFirstByte < 0 || sFirstByte < 0 || rFirstByte > 127 || sFirstByte > 127) {
return false;
}

Expand Down

0 comments on commit 8f8976d

Please sign in to comment.