edited the wrong file...

This commit is contained in:
Magnus von Wachenfeldt 2021-09-01 11:19:47 +02:00
parent e3c35c525f
commit b70f21a233
Signed by: magnus
GPG Key ID: A469F7D71D09F795

View File

@ -1,183 +1,148 @@
/** var ber = require('asn1').Ber;
* PKCS1 padding and signature scheme var _ = require('../utils')._;
*/ var utils = require('../utils');
var BigInteger = require('../libs/jsbn'); const PRIVATE_OPENING_BOUNDARY = '-----BEGIN RSA PRIVATE KEY-----';
var crypt = require('crypto'); const PRIVATE_CLOSING_BOUNDARY = '-----END RSA PRIVATE KEY-----';
var SIGN_INFO_HEAD = {
md2: Buffer.from('3020300c06082a864886f70d020205000410', 'hex'), const PUBLIC_OPENING_BOUNDARY = '-----BEGIN RSA PUBLIC KEY-----';
md5: Buffer.from('3020300c06082a864886f70d020505000410', 'hex'), const PUBLIC_CLOSING_BOUNDARY = '-----END RSA PUBLIC KEY-----';
sha1: Buffer.from('3021300906052b0e03021a05000414', 'hex'),
sha224: Buffer.from('302d300d06096086480165030402040500041c', 'hex'), module.exports = {
sha256: Buffer.from('3031300d060960864801650304020105000420', 'hex'), privateExport: function (key, options) {
sha384: Buffer.from('3041300d060960864801650304020205000430', 'hex'), options = options || {};
sha512: Buffer.from('3051300d060960864801650304020305000440', 'hex'),
ripemd160: Buffer.from('3021300906052b2403020105000414', 'hex'), var n = key.n.toBuffer();
rmd160: Buffer.from('3021300906052b2403020105000414', 'hex') var d = key.d.toBuffer();
}; var p = key.p.toBuffer();
var q = key.q.toBuffer();
var SIGN_ALG_TO_HASH_ALIASES = { var dmp1 = key.dmp1.toBuffer();
'ripemd160': 'rmd160' var dmq1 = key.dmq1.toBuffer();
}; var coeff = key.coeff.toBuffer();
var DEFAULT_HASH_FUNCTION = 'sha256'; var length = n.length + d.length + p.length + q.length + dmp1.length + dmq1.length + coeff.length + 512; // magic
var writer = new ber.Writer({size: length});
module.exports = {
isEncryption: true, writer.startSequence();
isSignature: true writer.writeInt(0);
}; writer.writeBuffer(n, 2);
writer.writeInt(key.e);
module.exports.makeScheme = function (key, options) { writer.writeBuffer(d, 2);
function Scheme(key, options) { writer.writeBuffer(p, 2);
this.key = key; writer.writeBuffer(q, 2);
this.options = options; writer.writeBuffer(dmp1, 2);
} writer.writeBuffer(dmq1, 2);
writer.writeBuffer(coeff, 2);
Scheme.prototype.maxMessageLength = function () { writer.endSequence();
if (this.options.encryptionSchemeOptions && this.options.encryptionSchemeOptions.padding == 3) {
return this.key.encryptedDataLength; if (options.type === 'der') {
} return writer.buffer;
return this.key.encryptedDataLength - 11; } else {
}; return PRIVATE_OPENING_BOUNDARY + '\n' + utils.linebrk(writer.buffer.toString('base64'), 64) + '\n' + PRIVATE_CLOSING_BOUNDARY;
}
/** },
* Pad input Buffer to encryptedDataLength bytes, and return Buffer.from
* alg: PKCS#1 privateImport: function (key, data, options) {
* @param buffer options = options || {};
* @returns {Buffer} var buffer;
*/
Scheme.prototype.encPad = function (buffer, options) { if (options.type !== 'der') {
options = options || {}; if (Buffer.isBuffer(data)) {
var filled; data = data.toString('utf8');
if (buffer.length > this.key.maxMessageLength) { }
throw new Error("Message too long for RSA (n=" + this.key.encryptedDataLength + ", l=" + buffer.length + ")");
} if (_.isString(data)) {
var pem = utils.trimSurroundingText(data, PRIVATE_OPENING_BOUNDARY, PRIVATE_CLOSING_BOUNDARY)
if (this.options.encryptionSchemeOptions && this.options.encryptionSchemeOptions.padding == 3) { .replace(/\s+|\n\r|\n|\r$/gm, '');
//RSA_NO_PADDING treated like JAVA left pad with zero character buffer = Buffer.from(pem, 'base64');
filled = Buffer.alloc(this.key.maxMessageLength - buffer.length); } else {
filled.fill(0); throw Error('Unsupported key format');
return Buffer.concat([filled, buffer]); }
} } else if (Buffer.isBuffer(data)) {
buffer = data;
/* Type 1: zeros padding for private key encrypt */ } else {
if (options.type === 1) { throw Error('Unsupported key format');
filled = Buffer.alloc(this.key.encryptedDataLength - buffer.length - 1); }
filled.fill(0xff, 0, filled.length - 1);
filled[0] = 1; var reader = new ber.Reader(buffer);
filled[filled.length - 1] = 0; reader.readSequence();
reader.readString(2, true); // just zero
return Buffer.concat([filled, buffer]); key.setPrivate(
} else { reader.readString(2, true), // modulus
/* random padding for public key encrypt */ reader.readString(2, true), // publicExponent
filled = Buffer.alloc(this.key.encryptedDataLength - buffer.length); reader.readString(2, true), // privateExponent
filled[0] = 0; reader.readString(2, true), // prime1
filled[1] = 2; reader.readString(2, true), // prime2
var rand = crypt.randomBytes(filled.length - 3); reader.readString(2, true), // exponent1 -- d mod (p1)
for (var i = 0; i < rand.length; i++) { reader.readString(2, true), // exponent2 -- d mod (q-1)
var r = rand[i]; reader.readString(2, true) // coefficient -- (inverse of q) mod p
while (r === 0) { // non-zero only );
r = crypt.randomBytes(1)[0]; },
}
filled[i + 2] = r; publicExport: function (key, options) {
} options = options || {};
filled[filled.length - 1] = 0;
return Buffer.concat([filled, buffer]); var n = key.n.toBuffer();
} var length = n.length + 512; // magic
};
var bodyWriter = new ber.Writer({size: length});
/** bodyWriter.startSequence();
* Unpad input Buffer and, if valid, return the Buffer object bodyWriter.writeBuffer(n, 2);
* alg: PKCS#1 (type 2, random) bodyWriter.writeInt(key.e);
* @param buffer bodyWriter.endSequence();
* @returns {Buffer}
*/ if (options.type === 'der') {
Scheme.prototype.encUnPad = function (buffer, options) { return bodyWriter.buffer;
return buffer; } else {
}; return PUBLIC_OPENING_BOUNDARY + '\n' + utils.linebrk(bodyWriter.buffer.toString('base64'), 64) + '\n' + PUBLIC_CLOSING_BOUNDARY;
}
Scheme.prototype.sign = function (buffer) { },
var hashAlgorithm = this.options.signingSchemeOptions.hash || DEFAULT_HASH_FUNCTION;
hashAlgorithm = SIGN_ALG_TO_HASH_ALIASES[hashAlgorithm] || hashAlgorithm; publicImport: function (key, data, options) {
options = options || {};
var hasher = crypt.createHash(hashAlgorithm); var buffer;
hasher.update(buffer);
var hash = this.pkcs1pad(hasher.digest(), hashAlgorithm); if (options.type !== 'der') {
var res = this.key.$doPrivate(new BigInteger(hash)).toBuffer(this.key.encryptedDataLength); if (Buffer.isBuffer(data)) {
data = data.toString('utf8');
return res; }
};
if (_.isString(data)) {
Scheme.prototype.verify = function (buffer, signature, signature_encoding) { var pem = utils.trimSurroundingText(data, PUBLIC_OPENING_BOUNDARY, PUBLIC_CLOSING_BOUNDARY)
if (this.options.encryptionSchemeOptions && this.options.encryptionSchemeOptions.padding == 3) { .replace(/\s+|\n\r|\n|\r$/gm, '');
//RSA_NO_PADDING has no verify data buffer = Buffer.from(pem, 'base64');
return false; }
} } else if (Buffer.isBuffer(data)) {
var hashAlgorithm = this.options.signingSchemeOptions.hash || DEFAULT_HASH_FUNCTION; buffer = data;
hashAlgorithm = SIGN_ALG_TO_HASH_ALIASES[hashAlgorithm] || hashAlgorithm; } else {
throw Error('Unsupported key format');
if (signature_encoding) { }
signature = Buffer.from(signature, signature_encoding);
} var body = new ber.Reader(buffer);
body.readSequence();
var hasher = crypt.createHash(hashAlgorithm); key.setPublic(
hasher.update(buffer); body.readString(0x02, true), // modulus
var hash = this.pkcs1pad(hasher.digest(), hashAlgorithm); body.readString(0x02, true) // publicExponent
var m = this.key.$doPublic(new BigInteger(signature)); );
},
return m.toBuffer().toString('hex') == hash.toString('hex');
}; /**
* Trying autodetect and import key
/** * @param key
* PKCS#1 zero pad input buffer to max data length * @param data
* @param hashBuf */
* @param hashAlgorithm autoImport: function (key, data) {
* @returns {*} // [\S\s]* matches zero or more of any character
*/ if (/^[\S\s]*-----BEGIN RSA PRIVATE KEY-----\s*(?=(([A-Za-z0-9+/=]+\s*)+))\1-----END RSA PRIVATE KEY-----[\S\s]*$/g.test(data)) {
Scheme.prototype.pkcs0pad = function (buffer) { module.exports.privateImport(key, data);
var filled = Buffer.alloc(this.key.maxMessageLength - buffer.length); return true;
filled.fill(0); }
return Buffer.concat([filled, buffer]);
}; if (/^[\S\s]*-----BEGIN RSA PUBLIC KEY-----\s*(?=(([A-Za-z0-9+/=]+\s*)+))\1-----END RSA PUBLIC KEY-----[\S\s]*$/g.test(data)) {
module.exports.publicImport(key, data);
Scheme.prototype.pkcs0unpad = function (buffer) { return true;
var unPad; }
if (typeof buffer.lastIndexOf == "function") { //patch for old node version
unPad = buffer.slice(buffer.lastIndexOf('\0') + 1, buffer.length); return false;
} else { }
unPad = buffer.slice(String.prototype.lastIndexOf.call(buffer, '\0') + 1, buffer.length); };
}
return unPad;
};
/**
* PKCS#1 pad input buffer to max data length
* @param hashBuf
* @param hashAlgorithm
* @returns {*}
*/
Scheme.prototype.pkcs1pad = function (hashBuf, hashAlgorithm) {
var digest = SIGN_INFO_HEAD[hashAlgorithm];
if (!digest) {
throw Error('Unsupported hash algorithm');
}
var data = Buffer.concat([digest, hashBuf]);
if (data.length + 10 > this.key.encryptedDataLength) {
throw Error('Key is too short for signing algorithm (' + hashAlgorithm + ')');
}
var filled = Buffer.alloc(this.key.encryptedDataLength - data.length - 1);
filled.fill(0xff, 0, filled.length - 1);
filled[0] = 1;
filled[filled.length - 1] = 0;
var res = Buffer.concat([filled, data]);
return res;
};
return new Scheme(key, options);
};