mirror of
https://github.com/nodejs/node.git
synced 2024-11-30 07:27:22 +01:00
6ebdb69472
PR #11705 switched Node away from using using OpenSSL's legacy EVP_Sign* and EVP_Verify* APIs. Instead, it computes a hash normally via EVP_Digest* and then uses EVP_PKEY_sign and EVP_PKEY_verify to verify the hash directly. This change corrects two problems: 1. The documentation still recommends the signature algorithm EVP_MD names of OpenSSL's legacy APIs. OpenSSL has since moved away from thosee, which is why ECDSA was strangely inconsistent. (This is why "ecdsa-with-SHA256" was missing.) 2. Node_SignFinal copied some code from EVP_SignFinal's internals. This is problematic for OpenSSL 1.1.0 and is missing a critical check that prevents pkey->pkey.ptr from being cast to the wrong type. To resolve this, remove the non-EVP_PKEY_sign codepath. This codepath is no longer necessary. PR #11705's verify half was already assuming all EVP_PKEYs supported EVP_PKEY_sign and EVP_PKEY_verify. Also, in the documentation, point users towards using hash function names which are more consisent. This avoids an ECDSA special-case and some strangeness around RSA-PSS ("RSA-SHA256" is the OpenSSL name of the sha256WithRSAEncryption OID which is not used for RSA-PSS). PR-URL: https://github.com/nodejs/node/pull/15024 Reviewed-By: Shigeki Ohtsu <ohtsu@ohtsu.org> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
76 lines
2.5 KiB
JavaScript
76 lines
2.5 KiB
JavaScript
'use strict';
|
|
const asn1 = require('asn1.js');
|
|
const crypto = require('crypto');
|
|
const fs = require('fs');
|
|
const rfc5280 = require('asn1.js-rfc5280');
|
|
const BN = asn1.bignum;
|
|
|
|
const id_at_commonName = [ 2, 5, 4, 3 ];
|
|
const rsaEncryption = [1, 2, 840, 113549, 1, 1, 1];
|
|
const sha256WithRSAEncryption = [1, 2, 840, 113549, 1, 1, 11];
|
|
const digest = 'SHA256';
|
|
|
|
const private_key = fs.readFileSync('./0-dns-key.pem');
|
|
// public key file can be generated from the private key with
|
|
// openssl rsa -in 0-dns-key.pem -RSAPublicKey_out -outform der
|
|
// -out 0-dns-rsapub.der
|
|
const public_key = fs.readFileSync('./0-dns-rsapub.der');
|
|
|
|
const now = Date.now();
|
|
const days = 3650;
|
|
|
|
const Null_ = asn1.define('Null_', function() {
|
|
this.null_();
|
|
});
|
|
const null_ = Null_.encode('der');
|
|
|
|
const PrintStr = asn1.define('PrintStr', function() {
|
|
this.printstr();
|
|
});
|
|
const issuer = PrintStr.encode('ca.example.com', 'der');
|
|
const subject = PrintStr.encode('evil.example.com', 'der');
|
|
|
|
const tbs = {
|
|
version: 'v3',
|
|
serialNumber: new BN('01', 16),
|
|
signature: { algorithm: sha256WithRSAEncryption, parameters: null_},
|
|
issuer: { type: 'rdnSequence',
|
|
value: [ [{type: id_at_commonName, value: issuer}] ] },
|
|
validity:
|
|
{ notBefore: { type: 'utcTime', value: now },
|
|
notAfter: { type: 'utcTime', value: now + days * 86400000} },
|
|
subject: { type: 'rdnSequence',
|
|
value: [ [{type: id_at_commonName, value: subject}] ] },
|
|
subjectPublicKeyInfo:
|
|
{ algorithm: { algorithm: rsaEncryption, parameters: null_},
|
|
subjectPublicKey: { unused: 0, data: public_key} },
|
|
extensions:
|
|
[ { extnID: 'subjectAlternativeName',
|
|
critical: false,
|
|
// subjectAltName which contains '\0' character to check CVE-2009-2408
|
|
extnValue: [
|
|
{ type: 'dNSName', value: 'good.example.org\u0000.evil.example.com' },
|
|
{ type: 'dNSName', value: 'just-another.example.com' },
|
|
{ type: 'iPAddress', value: Buffer.from('08080808', 'hex') },
|
|
{ type: 'iPAddress', value: Buffer.from('08080404', 'hex') },
|
|
{ type: 'dNSName', value: 'last.example.com' } ] }
|
|
]
|
|
};
|
|
|
|
const tbs_der = rfc5280.TBSCertificate.encode(tbs, 'der');
|
|
|
|
const sign = crypto.createSign(digest);
|
|
sign.update(tbs_der);
|
|
const signature = sign.sign(private_key);
|
|
|
|
const cert = {
|
|
tbsCertificate: tbs,
|
|
signatureAlgorithm: { algorithm: sha256WithRSAEncryption, parameters: null_ },
|
|
signature:
|
|
{ unused: 0,
|
|
data: signature }
|
|
};
|
|
const pem = rfc5280.Certificate.encode(cert, 'pem', {label: 'CERTIFICATE'});
|
|
|
|
fs.writeFileSync('./0-dns-cert.pem', pem + '\n');
|