crypto: support Ed448 and ML-DSA context parameter in node:crypto · nodejs/node@7a8e2c2

@@ -9,7 +9,7 @@ const exec = require('child_process').exec;

99

const crypto = require('crypto');

1010

const fixtures = require('../common/fixtures');

1111

const {

12-

hasOpenSSL3,

12+

hasOpenSSL,

1313

opensslCli,

1414

} = require('../common/crypto');

1515

@@ -66,7 +66,7 @@ const keySize = 2048;

6666

key: keyPem,

6767

padding: crypto.constants.RSA_PKCS1_OAEP_PADDING

6868

});

69-

}, { message: hasOpenSSL3 ?

69+

}, { message: hasOpenSSL(3) ?

7070

'error:1C8000A5:Provider routines::illegal or unsupported padding mode' :

7171

'bye, bye, error stack' });

7272

@@ -344,7 +344,7 @@ assert.throws(

344344

key: keyPem,

345345

padding: crypto.constants.RSA_PKCS1_OAEP_PADDING

346346

});

347-

}, hasOpenSSL3 ? {

347+

}, hasOpenSSL(3) ? {

348348

code: 'ERR_OSSL_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE',

349349

message: /illegal or unsupported padding mode/,

350350

} : {

@@ -426,6 +426,7 @@ assert.throws(

426426

{ private: fixtures.readKey('ed448_private.pem', 'ascii'),

427427

public: fixtures.readKey('ed448_public.pem', 'ascii'),

428428

algo: null,

429+

supportsContext: true,

429430

sigLen: 114 },

430431

{ private: fixtures.readKey('rsa_private_2048.pem', 'ascii'),

431432

public: fixtures.readKey('rsa_public_2048.pem', 'ascii'),

@@ -473,6 +474,55 @@ assert.throws(

473474

assert.strictEqual(crypto.verify(algo, data, pair.private, sig),

474475

true);

475476

});

477+478+

if (pair.supportsContext && hasOpenSSL(3, 2)) {

479+

const data = Buffer.from('Hello world');

480+

{

481+

const context = new Uint8Array();

482+

const sig = crypto.sign(algo, data, { key: pair.private, context });

483+

assert.strictEqual(crypto.verify(algo, data, { key: pair.public }, sig), true);

484+

assert.strictEqual(crypto.verify(algo, data, { key: pair.public, context }, sig), true);

485+

assert.strictEqual(crypto.verify(algo, data, { key: pair.public, context: crypto.randomBytes(30) }, sig), false);

486+

}

487+488+

{

489+

const context = new Uint8Array(32);

490+

const sig = crypto.sign(algo, data, { key: pair.private, context });

491+

assert.strictEqual(crypto.verify(algo, data, { key: pair.public }, sig), false);

492+

assert.strictEqual(crypto.verify(algo, data, { key: pair.public, context }, sig), true);

493+

assert.strictEqual(crypto.verify(algo, data, { key: pair.public, context: crypto.randomBytes(30) }, sig), false);

494+

}

495+496+

assert.throws(() => crypto.sign(algo, data, { key: pair.private, context: new Uint8Array(256) }), {

497+

code: 'ERR_OUT_OF_RANGE',

498+

message: 'context string must be at most 255 bytes',

499+

});

500+501+

assert.throws(() => {

502+

crypto.verify(algo, data, { key: pair.public, context: new Uint8Array(256) }, new Uint8Array());

503+

}, {

504+

code: 'ERR_OUT_OF_RANGE',

505+

message: 'context string must be at most 255 bytes',

506+

});

507+

} else if (pair.supportsContext) {

508+

const data = Buffer.from('Hello world');

509+

{

510+

const context = new Uint8Array();

511+

const sig = crypto.sign(algo, data, { key: pair.private, context });

512+

assert.strictEqual(crypto.verify(algo, data, { key: pair.public }, sig), true);

513+

assert.strictEqual(crypto.verify(algo, data, { key: pair.public, context }, sig), true);

514+

}

515+516+

{

517+

const context = new Uint8Array(32);

518+

assert.throws(() => {

519+

crypto.sign(algo, data, { key: pair.private, context });

520+

}, { message: 'Context parameter is unsupported' });

521+

assert.throws(() => {

522+

crypto.verify(algo, data, { key: pair.public, context: crypto.randomBytes(30) }, crypto.randomBytes(32));

523+

}, { message: 'Context parameter is unsupported' });

524+

}

525+

}

476526

});

477527478528

[1, {}, [], true, Infinity].forEach((input) => {