Current Folder
This commit is contained in:
1 parent
8b3382289b
commit
cfcada880d
4379 files changed
No files matched your search
-223
@@ -1,223 +0,0 @@
|
||||
/*!
|
||||
* RSA library for Node.js
|
||||
*
|
||||
* Author: rzcoder
|
||||
* License MIT
|
||||
*/
|
||||
|
||||
var rsa = require('./libs/rsa.js');
|
||||
var _ = require('./utils')._;
|
||||
var schemes = require('./schemes/schemes.js');
|
||||
var formats = require('./formats/formats.js');
|
||||
|
||||
module.exports = (function () {
|
||||
var SUPPORTED_HASH_ALGORITHMS = {
|
||||
browser: ['md5', 'ripemd160', 'sha1', 'sha256', 'sha512']
|
||||
};
|
||||
|
||||
var DEFAULT_ENCRYPTION_SCHEME = 'pkcs1';
|
||||
var DEFAULT_SIGNING_SCHEME = 'pkcs1';
|
||||
|
||||
var EXPORT_FORMAT_ALIASES = {
|
||||
'private': 'pkcs1-private-pem',
|
||||
'private-der': 'pkcs1-private-der',
|
||||
'public': 'pkcs8-public-pem',
|
||||
'public-der': 'pkcs8-public-der',
|
||||
};
|
||||
|
||||
/**
|
||||
* @param key {string|buffer|object} Key in PEM format, or data for generate key {b: bits, e: exponent}
|
||||
* @constructor
|
||||
*/
|
||||
function NodeRSA(key, format, options) {
|
||||
if (!(this instanceof NodeRSA)) {
|
||||
return new NodeRSA(key, format, options);
|
||||
}
|
||||
|
||||
if (_.isObject(format)) {
|
||||
options = format;
|
||||
format = undefined;
|
||||
}
|
||||
|
||||
this.$options = {
|
||||
signingScheme: DEFAULT_SIGNING_SCHEME,
|
||||
signingSchemeOptions: {
|
||||
hash: 'sha256',
|
||||
saltLength: null
|
||||
},
|
||||
encryptionScheme: DEFAULT_ENCRYPTION_SCHEME,
|
||||
encryptionSchemeOptions: {
|
||||
hash: 'sha1',
|
||||
label: null
|
||||
},
|
||||
environment: 'browser',
|
||||
rsaUtils: this
|
||||
};
|
||||
this.keyPair = new rsa.Key();
|
||||
this.$cache = {};
|
||||
|
||||
if (Buffer.isBuffer(key) || _.isString(key)) {
|
||||
this.importKey(key, format);
|
||||
} else if (_.isObject(key)) {
|
||||
this.generateKeyPair(key.b, key.e);
|
||||
}
|
||||
|
||||
this.setOptions(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set and validate options for key instance
|
||||
* @param options
|
||||
*/
|
||||
NodeRSA.prototype.setOptions = function (options) {
|
||||
options = options || {};
|
||||
if (options.environment) {
|
||||
this.$options.environment = options.environment;
|
||||
}
|
||||
|
||||
if (options.signingScheme) {
|
||||
if (_.isString(options.signingScheme)) {
|
||||
var signingScheme = options.signingScheme.toLowerCase().split('-');
|
||||
if (signingScheme.length == 1) {
|
||||
if (SUPPORTED_HASH_ALGORITHMS.node.indexOf(signingScheme[0]) > -1) {
|
||||
this.$options.signingSchemeOptions = {
|
||||
hash: signingScheme[0]
|
||||
};
|
||||
this.$options.signingScheme = DEFAULT_SIGNING_SCHEME;
|
||||
} else {
|
||||
this.$options.signingScheme = signingScheme[0];
|
||||
this.$options.signingSchemeOptions = {
|
||||
hash: null
|
||||
};
|
||||
}
|
||||
} else {
|
||||
this.$options.signingSchemeOptions = {
|
||||
hash: signingScheme[1]
|
||||
};
|
||||
this.$options.signingScheme = signingScheme[0];
|
||||
}
|
||||
} else if (_.isObject(options.signingScheme)) {
|
||||
this.$options.signingScheme = options.signingScheme.scheme || DEFAULT_SIGNING_SCHEME;
|
||||
this.$options.signingSchemeOptions = _.omit(options.signingScheme, 'scheme');
|
||||
}
|
||||
|
||||
if (!schemes.isSignature(this.$options.signingScheme)) {
|
||||
throw Error('Unsupported signing scheme');
|
||||
}
|
||||
|
||||
if (this.$options.signingSchemeOptions.hash &&
|
||||
SUPPORTED_HASH_ALGORITHMS[this.$options.environment].indexOf(this.$options.signingSchemeOptions.hash) === -1) {
|
||||
throw Error('Unsupported hashing algorithm for ' + this.$options.environment + ' environment');
|
||||
}
|
||||
}
|
||||
|
||||
if (options.encryptionScheme) {
|
||||
if (_.isString(options.encryptionScheme)) {
|
||||
this.$options.encryptionScheme = options.encryptionScheme.toLowerCase();
|
||||
this.$options.encryptionSchemeOptions = {};
|
||||
} else if (_.isObject(options.encryptionScheme)) {
|
||||
this.$options.encryptionScheme = options.encryptionScheme.scheme || DEFAULT_ENCRYPTION_SCHEME;
|
||||
this.$options.encryptionSchemeOptions = _.omit(options.encryptionScheme, 'scheme');
|
||||
}
|
||||
|
||||
if (!schemes.isEncryption(this.$options.encryptionScheme)) {
|
||||
throw Error('Unsupported encryption scheme');
|
||||
}
|
||||
|
||||
if (this.$options.encryptionSchemeOptions.hash &&
|
||||
SUPPORTED_HASH_ALGORITHMS[this.$options.environment].indexOf(this.$options.encryptionSchemeOptions.hash) === -1) {
|
||||
throw Error('Unsupported hashing algorithm for ' + this.$options.environment + ' environment');
|
||||
}
|
||||
}
|
||||
|
||||
this.keyPair.setOptions(this.$options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Importing key
|
||||
* @param keyData {string|buffer|Object}
|
||||
* @param format {string}
|
||||
*/
|
||||
NodeRSA.prototype.importKey = function (keyData, format) {
|
||||
if (!keyData) {
|
||||
throw Error("Empty key given");
|
||||
}
|
||||
|
||||
if (format) {
|
||||
format = EXPORT_FORMAT_ALIASES[format] || format;
|
||||
}
|
||||
|
||||
if (!formats.detectAndImport(this.keyPair, keyData, format) && format === undefined) {
|
||||
throw Error("Key format must be specified");
|
||||
}
|
||||
|
||||
this.$cache = {};
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if key pair contains private key
|
||||
*/
|
||||
NodeRSA.prototype.isPrivate = function () {
|
||||
return this.keyPair.isPrivate();
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if key pair contains public key
|
||||
* @param [strict] {boolean} - public key only, return false if have private exponent
|
||||
*/
|
||||
NodeRSA.prototype.isPublic = function (strict) {
|
||||
return this.keyPair.isPublic(strict);
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if key pair doesn't contains any data
|
||||
*/
|
||||
NodeRSA.prototype.isEmpty = function (strict) {
|
||||
return !(this.keyPair.n || this.keyPair.e || this.keyPair.d);
|
||||
};
|
||||
|
||||
/**
|
||||
* Signing data
|
||||
*
|
||||
* @param buffer {string|number|object|array|Buffer} - data for signing. Object and array will convert to JSON string.
|
||||
* @param encoding {string} - optional. Encoding for output result, may be 'buffer', 'binary', 'hex' or 'base64'. Default 'buffer'.
|
||||
* @param source_encoding {string} - optional. Encoding for given string. Default utf8.
|
||||
* @returns {string|Buffer}
|
||||
*/
|
||||
NodeRSA.prototype.sign = function (buffer, encoding, source_encoding) {
|
||||
if (!this.isPrivate()) {
|
||||
throw Error("This is not private key");
|
||||
}
|
||||
|
||||
var res = this.keyPair.sign(this.$getDataForEncrypt(buffer, source_encoding));
|
||||
|
||||
if (encoding && encoding != 'buffer') {
|
||||
res = res.toString(encoding);
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
/**
|
||||
* Preparing given data for encrypting/signing. Just make new/return Buffer object.
|
||||
*
|
||||
* @param buffer {string|number|object|array|Buffer} - data for encrypting. Object and array will convert to JSON string.
|
||||
* @param encoding {string} - optional. Encoding for given string. Default utf8.
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
NodeRSA.prototype.$getDataForEncrypt = function (buffer, encoding) {
|
||||
if (_.isString(buffer) || _.isNumber(buffer)) {
|
||||
return Buffer.from('' + buffer, encoding || 'utf8');
|
||||
} else if (Buffer.isBuffer(buffer)) {
|
||||
return buffer;
|
||||
} else if (_.isObject(buffer)) {
|
||||
return Buffer.from(JSON.stringify(buffer));
|
||||
} else {
|
||||
throw Error("Unexpected data type");
|
||||
}
|
||||
};
|
||||
|
||||
return NodeRSA;
|
||||
})();
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
// Copyright 2011 Mark Cavage <mcavage@gmail.com> All rights reserved.
|
||||
|
||||
|
||||
module.exports = {
|
||||
|
||||
newInvalidAsn1Error: function (msg) {
|
||||
var e = new Error();
|
||||
e.name = 'InvalidAsn1Error';
|
||||
e.message = msg || '';
|
||||
return e;
|
||||
}
|
||||
|
||||
};
|
||||
-21
@@ -1,21 +0,0 @@
|
||||
// Copyright 2011 Mark Cavage <mcavage@gmail.com> All rights reserved.
|
||||
|
||||
var errors = require('./errors');
|
||||
var types = require('./types');
|
||||
|
||||
var Reader = require('./reader');
|
||||
|
||||
// --- Exports
|
||||
|
||||
module.exports = {
|
||||
Reader: Reader,
|
||||
};
|
||||
|
||||
for (var t in types) {
|
||||
if (types.hasOwnProperty(t))
|
||||
module.exports[t] = types[t];
|
||||
}
|
||||
for (var e in errors) {
|
||||
if (errors.hasOwnProperty(e))
|
||||
module.exports[e] = errors[e];
|
||||
}
|
||||
-262
@@ -1,262 +0,0 @@
|
||||
// Copyright 2011 Mark Cavage <mcavage@gmail.com> All rights reserved.
|
||||
|
||||
var assert = require('assert');
|
||||
// var Buffer = require('safer-buffer').Buffer;
|
||||
|
||||
var ASN1 = require('./types');
|
||||
var errors = require('./errors');
|
||||
|
||||
|
||||
// --- Globals
|
||||
|
||||
var newInvalidAsn1Error = errors.newInvalidAsn1Error;
|
||||
|
||||
|
||||
|
||||
// --- API
|
||||
|
||||
function Reader(data) {
|
||||
if (!data || !Buffer.isBuffer(data))
|
||||
throw new TypeError('data must be a node Buffer');
|
||||
|
||||
this._buf = data;
|
||||
this._size = data.length;
|
||||
|
||||
// These hold the "current" state
|
||||
this._len = 0;
|
||||
this._offset = 0;
|
||||
}
|
||||
|
||||
Object.defineProperty(Reader.prototype, 'length', {
|
||||
enumerable: true,
|
||||
get: function () { return (this._len); }
|
||||
});
|
||||
|
||||
Object.defineProperty(Reader.prototype, 'offset', {
|
||||
enumerable: true,
|
||||
get: function () { return (this._offset); }
|
||||
});
|
||||
|
||||
Object.defineProperty(Reader.prototype, 'remain', {
|
||||
get: function () { return (this._size - this._offset); }
|
||||
});
|
||||
|
||||
Object.defineProperty(Reader.prototype, 'buffer', {
|
||||
get: function () { return (this._buf.slice(this._offset)); }
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Reads a single byte and advances offset; you can pass in `true` to make this
|
||||
* a "peek" operation (i.e., get the byte, but don't advance the offset).
|
||||
*
|
||||
* @param {Boolean} peek true means don't move offset.
|
||||
* @return {Number} the next byte, null if not enough data.
|
||||
*/
|
||||
Reader.prototype.readByte = function (peek) {
|
||||
if (this._size - this._offset < 1)
|
||||
return null;
|
||||
|
||||
var b = this._buf[this._offset] & 0xff;
|
||||
|
||||
if (!peek)
|
||||
this._offset += 1;
|
||||
|
||||
return b;
|
||||
};
|
||||
|
||||
|
||||
Reader.prototype.peek = function () {
|
||||
return this.readByte(true);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a (potentially) variable length off the BER buffer. This call is
|
||||
* not really meant to be called directly, as callers have to manipulate
|
||||
* the internal buffer afterwards.
|
||||
*
|
||||
* As a result of this call, you can call `Reader.length`, until the
|
||||
* next thing called that does a readLength.
|
||||
*
|
||||
* @return {Number} the amount of offset to advance the buffer.
|
||||
* @throws {InvalidAsn1Error} on bad ASN.1
|
||||
*/
|
||||
Reader.prototype.readLength = function (offset) {
|
||||
if (offset === undefined)
|
||||
offset = this._offset;
|
||||
|
||||
if (offset >= this._size)
|
||||
return null;
|
||||
|
||||
var lenB = this._buf[offset++] & 0xff;
|
||||
if (lenB === null)
|
||||
return null;
|
||||
|
||||
if ((lenB & 0x80) === 0x80) {
|
||||
lenB &= 0x7f;
|
||||
|
||||
if (lenB === 0)
|
||||
throw newInvalidAsn1Error('Indefinite length not supported');
|
||||
|
||||
if (lenB > 4)
|
||||
throw newInvalidAsn1Error('encoding too long');
|
||||
|
||||
if (this._size - offset < lenB)
|
||||
return null;
|
||||
|
||||
this._len = 0;
|
||||
for (var i = 0; i < lenB; i++)
|
||||
this._len = (this._len << 8) + (this._buf[offset++] & 0xff);
|
||||
|
||||
} else {
|
||||
// Wasn't a variable length
|
||||
this._len = lenB;
|
||||
}
|
||||
|
||||
return offset;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Parses the next sequence in this BER buffer.
|
||||
*
|
||||
* To get the length of the sequence, call `Reader.length`.
|
||||
*
|
||||
* @return {Number} the sequence's tag.
|
||||
*/
|
||||
Reader.prototype.readSequence = function (tag) {
|
||||
var seq = this.peek();
|
||||
if (seq === null)
|
||||
return null;
|
||||
if (tag !== undefined && tag !== seq)
|
||||
throw newInvalidAsn1Error('Expected 0x' + tag.toString(16) +
|
||||
': got 0x' + seq.toString(16));
|
||||
|
||||
var o = this.readLength(this._offset + 1); // stored in `length`
|
||||
if (o === null)
|
||||
return null;
|
||||
|
||||
this._offset = o;
|
||||
return seq;
|
||||
};
|
||||
|
||||
|
||||
Reader.prototype.readInt = function () {
|
||||
return this._readTag(ASN1.Integer);
|
||||
};
|
||||
|
||||
|
||||
Reader.prototype.readBoolean = function () {
|
||||
return (this._readTag(ASN1.Boolean) === 0 ? false : true);
|
||||
};
|
||||
|
||||
|
||||
Reader.prototype.readEnumeration = function () {
|
||||
return this._readTag(ASN1.Enumeration);
|
||||
};
|
||||
|
||||
|
||||
Reader.prototype.readString = function (tag, retbuf) {
|
||||
if (!tag)
|
||||
tag = ASN1.OctetString;
|
||||
|
||||
var b = this.peek();
|
||||
if (b === null)
|
||||
return null;
|
||||
|
||||
if (b !== tag)
|
||||
throw newInvalidAsn1Error('Expected 0x' + tag.toString(16) +
|
||||
': got 0x' + b.toString(16));
|
||||
|
||||
var o = this.readLength(this._offset + 1); // stored in `length`
|
||||
|
||||
if (o === null)
|
||||
return null;
|
||||
|
||||
if (this.length > this._size - o)
|
||||
return null;
|
||||
|
||||
this._offset = o;
|
||||
|
||||
if (this.length === 0)
|
||||
return retbuf ? Buffer.alloc(0) : '';
|
||||
|
||||
var str = this._buf.slice(this._offset, this._offset + this.length);
|
||||
this._offset += this.length;
|
||||
|
||||
return retbuf ? str : str.toString('utf8');
|
||||
};
|
||||
|
||||
Reader.prototype.readOID = function (tag) {
|
||||
if (!tag)
|
||||
tag = ASN1.OID;
|
||||
|
||||
var b = this.readString(tag, true);
|
||||
if (b === null)
|
||||
return null;
|
||||
|
||||
var values = [];
|
||||
var value = 0;
|
||||
|
||||
for (var i = 0; i < b.length; i++) {
|
||||
var byte = b[i] & 0xff;
|
||||
|
||||
value <<= 7;
|
||||
value += byte & 0x7f;
|
||||
if ((byte & 0x80) === 0) {
|
||||
values.push(value);
|
||||
value = 0;
|
||||
}
|
||||
}
|
||||
|
||||
value = values.shift();
|
||||
values.unshift(value % 40);
|
||||
values.unshift((value / 40) >> 0);
|
||||
|
||||
return values.join('.');
|
||||
};
|
||||
|
||||
|
||||
Reader.prototype._readTag = function (tag) {
|
||||
assert.ok(tag !== undefined);
|
||||
|
||||
var b = this.peek();
|
||||
|
||||
if (b === null)
|
||||
return null;
|
||||
|
||||
if (b !== tag)
|
||||
throw newInvalidAsn1Error('Expected 0x' + tag.toString(16) +
|
||||
': got 0x' + b.toString(16));
|
||||
|
||||
var o = this.readLength(this._offset + 1); // stored in `length`
|
||||
if (o === null)
|
||||
return null;
|
||||
|
||||
if (this.length > 4)
|
||||
throw newInvalidAsn1Error('Integer too long: ' + this.length);
|
||||
|
||||
if (this.length > this._size - o)
|
||||
return null;
|
||||
this._offset = o;
|
||||
|
||||
var fb = this._buf[this._offset];
|
||||
var value = 0;
|
||||
|
||||
for (var i = 0; i < this.length; i++) {
|
||||
value <<= 8;
|
||||
value |= (this._buf[this._offset++] & 0xff);
|
||||
}
|
||||
|
||||
if ((fb & 0x80) === 0x80 && i !== 4)
|
||||
value -= (1 << (i * 8));
|
||||
|
||||
return value >> 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// --- Exported API
|
||||
|
||||
module.exports = Reader;
|
||||
-36
@@ -1,36 +0,0 @@
|
||||
// Copyright 2011 Mark Cavage <mcavage@gmail.com> All rights reserved.
|
||||
|
||||
|
||||
module.exports = {
|
||||
EOC: 0,
|
||||
Boolean: 1,
|
||||
Integer: 2,
|
||||
BitString: 3,
|
||||
OctetString: 4,
|
||||
Null: 5,
|
||||
OID: 6,
|
||||
ObjectDescriptor: 7,
|
||||
External: 8,
|
||||
Real: 9, // float
|
||||
Enumeration: 10,
|
||||
PDV: 11,
|
||||
Utf8String: 12,
|
||||
RelativeOID: 13,
|
||||
Sequence: 16,
|
||||
Set: 17,
|
||||
NumericString: 18,
|
||||
PrintableString: 19,
|
||||
T61String: 20,
|
||||
VideotexString: 21,
|
||||
IA5String: 22,
|
||||
UTCTime: 23,
|
||||
GeneralizedTime: 24,
|
||||
GraphicString: 25,
|
||||
VisibleString: 26,
|
||||
GeneralString: 28,
|
||||
UniversalString: 29,
|
||||
CharacterString: 30,
|
||||
BMPString: 31,
|
||||
Constructor: 32,
|
||||
Context: 128
|
||||
};
|
||||
-17
@@ -1,17 +0,0 @@
|
||||
// Copyright 2011 Mark Cavage <mcavage@gmail.com> All rights reserved.
|
||||
|
||||
// If you have no idea what ASN.1 or BER is, see this:
|
||||
// ftp://ftp.rsa.com/pub/pkcs/ascii/layman.asc
|
||||
|
||||
var Ber = require('./ber/index');
|
||||
|
||||
|
||||
|
||||
// --- Exported API
|
||||
|
||||
module.exports = {
|
||||
|
||||
Ber: Ber,
|
||||
|
||||
BerReader: Ber.Reader,
|
||||
};
|
||||
Generated
Vendored
-34
@@ -1,34 +0,0 @@
|
||||
var BigInteger = require('../libs/jsbn.js');
|
||||
var schemes = require('../schemes/schemes.js');
|
||||
|
||||
module.exports = function (keyPair, options) {
|
||||
var pkcs1Scheme = schemes.pkcs1.makeScheme(keyPair, options);
|
||||
|
||||
return {
|
||||
encrypt: function (buffer, usePrivate) {
|
||||
var m, c;
|
||||
if (usePrivate) {
|
||||
/* Type 1: zeros padding for private key encrypt */
|
||||
m = new BigInteger(pkcs1Scheme.encPad(buffer, {type: 1}));
|
||||
c = keyPair.$doPrivate(m);
|
||||
} else {
|
||||
m = new BigInteger(keyPair.encryptionScheme.encPad(buffer));
|
||||
c = keyPair.$doPublic(m);
|
||||
}
|
||||
return c.toBuffer(keyPair.encryptedDataLength);
|
||||
},
|
||||
|
||||
decrypt: function (buffer, usePublic) {
|
||||
var m, c = new BigInteger(buffer);
|
||||
|
||||
if (usePublic) {
|
||||
m = keyPair.$doPublic(c);
|
||||
/* Type 1: zeros padding for private key decrypt */
|
||||
return pkcs1Scheme.encUnPad(m.toBuffer(keyPair.encryptedDataLength), {type: 1});
|
||||
} else {
|
||||
m = keyPair.$doPrivate(c);
|
||||
return keyPair.encryptionScheme.encUnPad(m.toBuffer(keyPair.encryptedDataLength));
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
Generated
Vendored
-71
@@ -1,71 +0,0 @@
|
||||
var _ = require('../utils')._;
|
||||
var utils = require('../utils');
|
||||
|
||||
module.exports = {
|
||||
privateExport: function (key, options) {
|
||||
return {
|
||||
n: key.n.toBuffer(),
|
||||
e: key.e,
|
||||
d: key.d.toBuffer(),
|
||||
p: key.p.toBuffer(),
|
||||
q: key.q.toBuffer(),
|
||||
dmp1: key.dmp1.toBuffer(),
|
||||
dmq1: key.dmq1.toBuffer(),
|
||||
coeff: key.coeff.toBuffer()
|
||||
};
|
||||
},
|
||||
|
||||
privateImport: function (key, data, options) {
|
||||
if (data.n && data.e && data.d && data.p && data.q && data.dmp1 && data.dmq1 && data.coeff) {
|
||||
key.setPrivate(
|
||||
data.n,
|
||||
data.e,
|
||||
data.d,
|
||||
data.p,
|
||||
data.q,
|
||||
data.dmp1,
|
||||
data.dmq1,
|
||||
data.coeff
|
||||
);
|
||||
} else {
|
||||
throw Error("Invalid key data");
|
||||
}
|
||||
},
|
||||
|
||||
publicExport: function (key, options) {
|
||||
return {
|
||||
n: key.n.toBuffer(),
|
||||
e: key.e
|
||||
};
|
||||
},
|
||||
|
||||
publicImport: function (key, data, options) {
|
||||
if (data.n && data.e) {
|
||||
key.setPublic(
|
||||
data.n,
|
||||
data.e
|
||||
);
|
||||
} else {
|
||||
throw Error("Invalid key data");
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Trying autodetect and import key
|
||||
* @param key
|
||||
* @param data
|
||||
*/
|
||||
autoImport: function (key, data) {
|
||||
if (data.n && data.e) {
|
||||
if (data.d && data.p && data.q && data.dmp1 && data.dmq1 && data.coeff) {
|
||||
module.exports.privateImport(key, data);
|
||||
return true;
|
||||
} else {
|
||||
module.exports.publicImport(key, data);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
var _ = require('../utils')._;
|
||||
|
||||
module.exports = {
|
||||
pkcs1: require('./pkcs1'),
|
||||
pkcs8: require('./pkcs8'),
|
||||
components: require('./components'),
|
||||
|
||||
detectAndImport: function (key, data, format) {
|
||||
if (format === undefined) {
|
||||
for (var scheme in module.exports) {
|
||||
if (typeof module.exports[scheme].autoImport === 'function' && module.exports[scheme].autoImport(key, data)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (format) {
|
||||
var fmt = formatParse(format);
|
||||
|
||||
if (module.exports[fmt.scheme]) {
|
||||
if (fmt.keyType === 'private') {
|
||||
module.exports[fmt.scheme].privateImport(key, data, fmt.keyOpt);
|
||||
} else {
|
||||
module.exports[fmt.scheme].publicImport(key, data, fmt.keyOpt);
|
||||
}
|
||||
} else {
|
||||
throw Error('Unsupported key format');
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
};
|
||||
-148
@@ -1,148 +0,0 @@
|
||||
var ber = require('../asn1/index').Ber;
|
||||
var _ = require('../utils')._;
|
||||
var utils = require('../utils');
|
||||
|
||||
const PRIVATE_OPENING_BOUNDARY = '-----BEGIN RSA PRIVATE KEY-----';
|
||||
const PRIVATE_CLOSING_BOUNDARY = '-----END RSA PRIVATE KEY-----';
|
||||
|
||||
const PUBLIC_OPENING_BOUNDARY = '-----BEGIN RSA PUBLIC KEY-----';
|
||||
const PUBLIC_CLOSING_BOUNDARY = '-----END RSA PUBLIC KEY-----';
|
||||
|
||||
module.exports = {
|
||||
privateExport: function (key, options) {
|
||||
options = options || {};
|
||||
|
||||
var n = key.n.toBuffer();
|
||||
var d = key.d.toBuffer();
|
||||
var p = key.p.toBuffer();
|
||||
var q = key.q.toBuffer();
|
||||
var dmp1 = key.dmp1.toBuffer();
|
||||
var dmq1 = key.dmq1.toBuffer();
|
||||
var coeff = key.coeff.toBuffer();
|
||||
|
||||
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});
|
||||
|
||||
writer.startSequence();
|
||||
writer.writeInt(0);
|
||||
writer.writeBuffer(n, 2);
|
||||
writer.writeInt(key.e);
|
||||
writer.writeBuffer(d, 2);
|
||||
writer.writeBuffer(p, 2);
|
||||
writer.writeBuffer(q, 2);
|
||||
writer.writeBuffer(dmp1, 2);
|
||||
writer.writeBuffer(dmq1, 2);
|
||||
writer.writeBuffer(coeff, 2);
|
||||
writer.endSequence();
|
||||
|
||||
if (options.type === 'der') {
|
||||
return writer.buffer;
|
||||
} else {
|
||||
return PRIVATE_OPENING_BOUNDARY + '\n' + utils.linebrk(writer.buffer.toString('base64'), 64) + '\n' + PRIVATE_CLOSING_BOUNDARY;
|
||||
}
|
||||
},
|
||||
|
||||
privateImport: function (key, data, options) {
|
||||
options = options || {};
|
||||
var buffer;
|
||||
|
||||
if (options.type !== 'der') {
|
||||
if (Buffer.isBuffer(data)) {
|
||||
data = data.toString('utf8');
|
||||
}
|
||||
|
||||
if (_.isString(data)) {
|
||||
var pem = utils.trimSurroundingText(data, PRIVATE_OPENING_BOUNDARY, PRIVATE_CLOSING_BOUNDARY)
|
||||
.replace(/\s+|\n\r|\n|\r$/gm, '');
|
||||
buffer = Buffer.from(pem, 'base64');
|
||||
} else {
|
||||
throw Error('Unsupported key format');
|
||||
}
|
||||
} else if (Buffer.isBuffer(data)) {
|
||||
buffer = data;
|
||||
} else {
|
||||
throw Error('Unsupported key format');
|
||||
}
|
||||
|
||||
var reader = new ber.Reader(buffer);
|
||||
reader.readSequence();
|
||||
reader.readString(2, true); // just zero
|
||||
key.setPrivate(
|
||||
reader.readString(2, true), // modulus
|
||||
reader.readString(2, true), // publicExponent
|
||||
reader.readString(2, true), // privateExponent
|
||||
reader.readString(2, true), // prime1
|
||||
reader.readString(2, true), // prime2
|
||||
reader.readString(2, true), // exponent1 -- d mod (p1)
|
||||
reader.readString(2, true), // exponent2 -- d mod (q-1)
|
||||
reader.readString(2, true) // coefficient -- (inverse of q) mod p
|
||||
);
|
||||
},
|
||||
|
||||
publicExport: function (key, options) {
|
||||
options = options || {};
|
||||
|
||||
var n = key.n.toBuffer();
|
||||
var length = n.length + 512; // magic
|
||||
|
||||
var bodyWriter = new ber.Writer({size: length});
|
||||
bodyWriter.startSequence();
|
||||
bodyWriter.writeBuffer(n, 2);
|
||||
bodyWriter.writeInt(key.e);
|
||||
bodyWriter.endSequence();
|
||||
|
||||
if (options.type === 'der') {
|
||||
return bodyWriter.buffer;
|
||||
} else {
|
||||
return PUBLIC_OPENING_BOUNDARY + '\n' + utils.linebrk(bodyWriter.buffer.toString('base64'), 64) + '\n' + PUBLIC_CLOSING_BOUNDARY;
|
||||
}
|
||||
},
|
||||
|
||||
publicImport: function (key, data, options) {
|
||||
options = options || {};
|
||||
var buffer;
|
||||
|
||||
if (options.type !== 'der') {
|
||||
if (Buffer.isBuffer(data)) {
|
||||
data = data.toString('utf8');
|
||||
}
|
||||
|
||||
if (_.isString(data)) {
|
||||
var pem = utils.trimSurroundingText(data, PUBLIC_OPENING_BOUNDARY, PUBLIC_CLOSING_BOUNDARY)
|
||||
.replace(/\s+|\n\r|\n|\r$/gm, '');
|
||||
buffer = Buffer.from(pem, 'base64');
|
||||
}
|
||||
} else if (Buffer.isBuffer(data)) {
|
||||
buffer = data;
|
||||
} else {
|
||||
throw Error('Unsupported key format');
|
||||
}
|
||||
|
||||
var body = new ber.Reader(buffer);
|
||||
body.readSequence();
|
||||
key.setPublic(
|
||||
body.readString(0x02, true), // modulus
|
||||
body.readString(0x02, true) // publicExponent
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Trying autodetect and import key
|
||||
* @param key
|
||||
* @param data
|
||||
*/
|
||||
autoImport: function (key, data) {
|
||||
// [\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)) {
|
||||
module.exports.privateImport(key, data);
|
||||
return true;
|
||||
}
|
||||
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
-187
@@ -1,187 +0,0 @@
|
||||
var ber = require('../asn1/index').Ber;
|
||||
var _ = require('../utils')._;
|
||||
var PUBLIC_RSA_OID = '1.2.840.113549.1.1.1';
|
||||
var utils = require('../utils');
|
||||
|
||||
const PRIVATE_OPENING_BOUNDARY = '-----BEGIN PRIVATE KEY-----';
|
||||
const PRIVATE_CLOSING_BOUNDARY = '-----END PRIVATE KEY-----';
|
||||
|
||||
const PUBLIC_OPENING_BOUNDARY = '-----BEGIN PUBLIC KEY-----';
|
||||
const PUBLIC_CLOSING_BOUNDARY = '-----END PUBLIC KEY-----';
|
||||
|
||||
module.exports = {
|
||||
privateExport: function (key, options) {
|
||||
options = options || {};
|
||||
|
||||
var n = key.n.toBuffer();
|
||||
var d = key.d.toBuffer();
|
||||
var p = key.p.toBuffer();
|
||||
var q = key.q.toBuffer();
|
||||
var dmp1 = key.dmp1.toBuffer();
|
||||
var dmq1 = key.dmq1.toBuffer();
|
||||
var coeff = key.coeff.toBuffer();
|
||||
|
||||
var length = n.length + d.length + p.length + q.length + dmp1.length + dmq1.length + coeff.length + 512; // magic
|
||||
var bodyWriter = new ber.Writer({size: length});
|
||||
|
||||
bodyWriter.startSequence();
|
||||
bodyWriter.writeInt(0);
|
||||
bodyWriter.writeBuffer(n, 2);
|
||||
bodyWriter.writeInt(key.e);
|
||||
bodyWriter.writeBuffer(d, 2);
|
||||
bodyWriter.writeBuffer(p, 2);
|
||||
bodyWriter.writeBuffer(q, 2);
|
||||
bodyWriter.writeBuffer(dmp1, 2);
|
||||
bodyWriter.writeBuffer(dmq1, 2);
|
||||
bodyWriter.writeBuffer(coeff, 2);
|
||||
bodyWriter.endSequence();
|
||||
|
||||
var writer = new ber.Writer({size: length});
|
||||
writer.startSequence();
|
||||
writer.writeInt(0);
|
||||
writer.startSequence();
|
||||
writer.writeOID(PUBLIC_RSA_OID);
|
||||
writer.writeNull();
|
||||
writer.endSequence();
|
||||
writer.writeBuffer(bodyWriter.buffer, 4);
|
||||
writer.endSequence();
|
||||
|
||||
if (options.type === 'der') {
|
||||
return writer.buffer;
|
||||
} else {
|
||||
return PRIVATE_OPENING_BOUNDARY + '\n' + utils.linebrk(writer.buffer.toString('base64'), 64) + '\n' + PRIVATE_CLOSING_BOUNDARY;
|
||||
}
|
||||
},
|
||||
|
||||
privateImport: function (key, data, options) {
|
||||
options = options || {};
|
||||
var buffer;
|
||||
|
||||
if (options.type !== 'der') {
|
||||
if (Buffer.isBuffer(data)) {
|
||||
data = data.toString('utf8');
|
||||
}
|
||||
|
||||
if (_.isString(data)) {
|
||||
var pem = utils.trimSurroundingText(data, PRIVATE_OPENING_BOUNDARY, PRIVATE_CLOSING_BOUNDARY)
|
||||
.replace('-----END PRIVATE KEY-----', '')
|
||||
.replace(/\s+|\n\r|\n|\r$/gm, '');
|
||||
buffer = Buffer.from(pem, 'base64');
|
||||
} else {
|
||||
throw Error('Unsupported key format');
|
||||
}
|
||||
} else if (Buffer.isBuffer(data)) {
|
||||
buffer = data;
|
||||
} else {
|
||||
throw Error('Unsupported key format');
|
||||
}
|
||||
|
||||
var reader = new ber.Reader(buffer);
|
||||
reader.readSequence();
|
||||
reader.readInt(0);
|
||||
var header = new ber.Reader(reader.readString(0x30, true));
|
||||
|
||||
if (header.readOID(0x06, true) !== PUBLIC_RSA_OID) {
|
||||
throw Error('Invalid Public key format');
|
||||
}
|
||||
|
||||
var body = new ber.Reader(reader.readString(0x04, true));
|
||||
body.readSequence();
|
||||
body.readString(2, true); // just zero
|
||||
key.setPrivate(
|
||||
body.readString(2, true), // modulus
|
||||
body.readString(2, true), // publicExponent
|
||||
body.readString(2, true), // privateExponent
|
||||
body.readString(2, true), // prime1
|
||||
body.readString(2, true), // prime2
|
||||
body.readString(2, true), // exponent1 -- d mod (p1)
|
||||
body.readString(2, true), // exponent2 -- d mod (q-1)
|
||||
body.readString(2, true) // coefficient -- (inverse of q) mod p
|
||||
);
|
||||
},
|
||||
|
||||
publicExport: function (key, options) {
|
||||
options = options || {};
|
||||
|
||||
var n = key.n.toBuffer();
|
||||
var length = n.length + 512; // magic
|
||||
|
||||
var bodyWriter = new ber.Writer({size: length});
|
||||
bodyWriter.writeByte(0);
|
||||
bodyWriter.startSequence();
|
||||
bodyWriter.writeBuffer(n, 2);
|
||||
bodyWriter.writeInt(key.e);
|
||||
bodyWriter.endSequence();
|
||||
|
||||
var writer = new ber.Writer({size: length});
|
||||
writer.startSequence();
|
||||
writer.startSequence();
|
||||
writer.writeOID(PUBLIC_RSA_OID);
|
||||
writer.writeNull();
|
||||
writer.endSequence();
|
||||
writer.writeBuffer(bodyWriter.buffer, 3);
|
||||
writer.endSequence();
|
||||
|
||||
if (options.type === 'der') {
|
||||
return writer.buffer;
|
||||
} else {
|
||||
return PUBLIC_OPENING_BOUNDARY + '\n' + utils.linebrk(writer.buffer.toString('base64'), 64) + '\n' + PUBLIC_CLOSING_BOUNDARY;
|
||||
}
|
||||
},
|
||||
|
||||
publicImport: function (key, data, options) {
|
||||
options = options || {};
|
||||
var buffer;
|
||||
|
||||
if (options.type !== 'der') {
|
||||
if (Buffer.isBuffer(data)) {
|
||||
data = data.toString('utf8');
|
||||
}
|
||||
|
||||
if (_.isString(data)) {
|
||||
var pem = utils.trimSurroundingText(data, PUBLIC_OPENING_BOUNDARY, PUBLIC_CLOSING_BOUNDARY)
|
||||
.replace(/\s+|\n\r|\n|\r$/gm, '');
|
||||
buffer = Buffer.from(pem, 'base64');
|
||||
}
|
||||
} else if (Buffer.isBuffer(data)) {
|
||||
buffer = data;
|
||||
} else {
|
||||
throw Error('Unsupported key format');
|
||||
}
|
||||
|
||||
var reader = new ber.Reader(buffer);
|
||||
reader.readSequence();
|
||||
var header = new ber.Reader(reader.readString(0x30, true));
|
||||
|
||||
if (header.readOID(0x06, true) !== PUBLIC_RSA_OID) {
|
||||
throw Error('Invalid Public key format');
|
||||
}
|
||||
|
||||
var body = new ber.Reader(reader.readString(0x03, true));
|
||||
body.readByte();
|
||||
body.readSequence();
|
||||
key.setPublic(
|
||||
body.readString(0x02, true), // modulus
|
||||
body.readString(0x02, true) // publicExponent
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Trying autodetect and import key
|
||||
* @param key
|
||||
* @param data
|
||||
*/
|
||||
autoImport: function (key, data) {
|
||||
if (/^[\S\s]*-----BEGIN PRIVATE KEY-----\s*(?=(([A-Za-z0-9+/=]+\s*)+))\1-----END PRIVATE KEY-----[\S\s]*$/g.test(data)) {
|
||||
module.exports.privateImport(key, data);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (/^[\S\s]*-----BEGIN PUBLIC KEY-----\s*(?=(([A-Za-z0-9+/=]+\s*)+))\1-----END PUBLIC KEY-----[\S\s]*$/g.test(data)) {
|
||||
module.exports.publicImport(key, data);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
-1252
File diff suppressed because it is too large.
Load diff
-147
@@ -1,147 +0,0 @@
|
||||
/*
|
||||
* RSA Encryption / Decryption with PKCS1 v2 Padding.
|
||||
*
|
||||
* ~MIT License~
|
||||
* Contributors:
|
||||
* Tom Wu, rzcoder, frosty00
|
||||
*/
|
||||
|
||||
var _ = require('../utils')._;
|
||||
var BigInteger = require('./jsbn.js');
|
||||
var utils = require('../utils.js');
|
||||
var schemes = require('../schemes/schemes.js');
|
||||
|
||||
//exports.BigInteger = BigInteger;
|
||||
module.exports.Key = (function () {
|
||||
/**
|
||||
* RSA key constructor
|
||||
*
|
||||
* n - modulus
|
||||
* e - publicExponent
|
||||
* d - privateExponent
|
||||
* p - prime1
|
||||
* q - prime2
|
||||
* dmp1 - exponent1 -- d mod (p1)
|
||||
* dmq1 - exponent2 -- d mod (q-1)
|
||||
* coeff - coefficient -- (inverse of q) mod p
|
||||
*/
|
||||
function RSAKey() {
|
||||
this.n = null;
|
||||
this.e = 0;
|
||||
this.d = null;
|
||||
this.p = null;
|
||||
this.q = null;
|
||||
this.dmp1 = null;
|
||||
this.dmq1 = null;
|
||||
this.coeff = null;
|
||||
}
|
||||
|
||||
RSAKey.prototype.setOptions = function (options) {
|
||||
var signingSchemeProvider = schemes[options.signingScheme];
|
||||
var encryptionSchemeProvider = schemes[options.encryptionScheme];
|
||||
|
||||
if (signingSchemeProvider === encryptionSchemeProvider) {
|
||||
this.signingScheme = this.encryptionScheme = encryptionSchemeProvider.makeScheme(this, options);
|
||||
} else {
|
||||
this.encryptionScheme = encryptionSchemeProvider.makeScheme(this, options);
|
||||
this.signingScheme = signingSchemeProvider.makeScheme(this, options);
|
||||
}
|
||||
|
||||
};
|
||||
/**
|
||||
* Set the private key fields N, e, d and CRT params from buffers
|
||||
*
|
||||
* @param N
|
||||
* @param E
|
||||
* @param D
|
||||
* @param P
|
||||
* @param Q
|
||||
* @param DP
|
||||
* @param DQ
|
||||
* @param C
|
||||
*/
|
||||
RSAKey.prototype.setPrivate = function (N, E, D, P, Q, DP, DQ, C) {
|
||||
if (N && E && D && N.length > 0 && (_.isNumber(E) || E.length > 0) && D.length > 0) {
|
||||
this.n = new BigInteger(N);
|
||||
this.e = _.isNumber(E) ? E : utils.get32IntFromBuffer(E, 0);
|
||||
this.d = new BigInteger(D);
|
||||
|
||||
if (P && Q && DP && DQ && C) {
|
||||
this.p = new BigInteger(P);
|
||||
this.q = new BigInteger(Q);
|
||||
this.dmp1 = new BigInteger(DP);
|
||||
this.dmq1 = new BigInteger(DQ);
|
||||
this.coeff = new BigInteger(C);
|
||||
} else {
|
||||
// TODO: re-calculate any missing CRT params
|
||||
}
|
||||
this.$$recalculateCache();
|
||||
} else {
|
||||
throw Error("Invalid RSA private key");
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* private
|
||||
* Perform raw private operation on "x": return x^d (mod n)
|
||||
*
|
||||
* @param x
|
||||
* @returns {*}
|
||||
*/
|
||||
RSAKey.prototype.$doPrivate = function (x) {
|
||||
if (this.p || this.q) {
|
||||
return x.modPow(this.d, this.n);
|
||||
}
|
||||
|
||||
// TODO: re-calculate any missing CRT params
|
||||
var xp = x.mod(this.p).modPow(this.dmp1, this.p);
|
||||
var xq = x.mod(this.q).modPow(this.dmq1, this.q);
|
||||
|
||||
while (xp.compareTo(xq) < 0) {
|
||||
xp = xp.add(this.p);
|
||||
}
|
||||
return xp.subtract(xq).multiply(this.coeff).mod(this.p).multiply(this.q).add(xq);
|
||||
};
|
||||
|
||||
RSAKey.prototype.sign = function (buffer) {
|
||||
return this.signingScheme.sign.apply(this.signingScheme, arguments);
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if key pair contains private key
|
||||
*/
|
||||
RSAKey.prototype.isPrivate = function () {
|
||||
return this.n && this.e && this.d || false;
|
||||
};
|
||||
|
||||
Object.defineProperty(RSAKey.prototype, 'keySize', {
|
||||
get: function () {
|
||||
return this.cache.keyBitLength;
|
||||
}
|
||||
});
|
||||
|
||||
Object.defineProperty(RSAKey.prototype, 'encryptedDataLength', {
|
||||
get: function () {
|
||||
return this.cache.keyByteLength;
|
||||
}
|
||||
});
|
||||
|
||||
Object.defineProperty(RSAKey.prototype, 'maxMessageLength', {
|
||||
get: function () {
|
||||
return this.encryptionScheme.maxMessageLength();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Caching key data
|
||||
*/
|
||||
RSAKey.prototype.$$recalculateCache = function () {
|
||||
this.cache = this.cache || {};
|
||||
// Bit & byte length
|
||||
this.cache.keyBitLength = this.n.bitLength();
|
||||
this.cache.keyByteLength = (this.cache.keyBitLength + 6) >> 3;
|
||||
};
|
||||
|
||||
return RSAKey;
|
||||
})();
|
||||
|
||||
-176
@@ -1,176 +0,0 @@
|
||||
/**
|
||||
* PKCS1 padding and signature scheme
|
||||
*/
|
||||
|
||||
var BigInteger = require('../libs/jsbn');
|
||||
var CryptoJS = require('../../crypto-js/crypto-js');
|
||||
var constants = { RSA_NO_PADDING: 3 }
|
||||
require('constants');
|
||||
var SIGN_INFO_HEAD = {
|
||||
md2: Buffer.from('3020300c06082a864886f70d020205000410', 'hex'),
|
||||
md5: Buffer.from('3020300c06082a864886f70d020505000410', 'hex'),
|
||||
sha1: Buffer.from('3021300906052b0e03021a05000414', 'hex'),
|
||||
sha224: Buffer.from('302d300d06096086480165030402040500041c', 'hex'),
|
||||
sha256: Buffer.from('3031300d060960864801650304020105000420', 'hex'),
|
||||
sha384: Buffer.from('3041300d060960864801650304020205000430', 'hex'),
|
||||
sha512: Buffer.from('3051300d060960864801650304020305000440', 'hex'),
|
||||
ripemd160: Buffer.from('3021300906052b2403020105000414', 'hex'),
|
||||
rmd160: Buffer.from('3021300906052b2403020105000414', 'hex')
|
||||
};
|
||||
|
||||
var SIGN_ALG_TO_HASH_ALIASES = {
|
||||
'ripemd160': 'rmd160'
|
||||
};
|
||||
|
||||
var DEFAULT_HASH_FUNCTION = 'sha256';
|
||||
|
||||
module.exports = {
|
||||
isEncryption: true,
|
||||
isSignature: true
|
||||
};
|
||||
|
||||
module.exports.makeScheme = function (key, options) {
|
||||
function Scheme(key, options) {
|
||||
this.key = key;
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
Scheme.prototype.maxMessageLength = function () {
|
||||
if (this.options.encryptionSchemeOptions && this.options.encryptionSchemeOptions.padding == constants.RSA_NO_PADDING) {
|
||||
return this.key.encryptedDataLength;
|
||||
}
|
||||
return this.key.encryptedDataLength - 11;
|
||||
};
|
||||
|
||||
/**
|
||||
* Unpad input Buffer and, if valid, return the Buffer object
|
||||
* alg: PKCS#1 (type 2, random)
|
||||
* @param buffer
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
Scheme.prototype.encUnPad = function (buffer, options) {
|
||||
options = options || {};
|
||||
var i = 0;
|
||||
|
||||
if (this.options.encryptionSchemeOptions && this.options.encryptionSchemeOptions.padding == constants.RSA_NO_PADDING) {
|
||||
//RSA_NO_PADDING treated like JAVA left pad with zero character
|
||||
var unPad;
|
||||
if (typeof buffer.lastIndexOf == "function") { //patch for old node version
|
||||
unPad = buffer.slice(buffer.lastIndexOf('\0') + 1, buffer.length);
|
||||
} else {
|
||||
unPad = buffer.slice(String.prototype.lastIndexOf.call(buffer, '\0') + 1, buffer.length);
|
||||
}
|
||||
return unPad;
|
||||
}
|
||||
|
||||
if (buffer.length < 4) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/* Type 1: zeros padding for private key decrypt */
|
||||
if (options.type === 1) {
|
||||
if (buffer[0] !== 0 && buffer[1] !== 1) {
|
||||
return null;
|
||||
}
|
||||
i = 3;
|
||||
while (buffer[i] !== 0) {
|
||||
if (buffer[i] != 0xFF || ++i >= buffer.length) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* random padding for public key decrypt */
|
||||
if (buffer[0] !== 0 && buffer[1] !== 2) {
|
||||
return null;
|
||||
}
|
||||
i = 3;
|
||||
while (buffer[i] !== 0) {
|
||||
if (++i >= buffer.length) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return buffer.slice(i + 1, buffer.length);
|
||||
};
|
||||
|
||||
Scheme.prototype.sign = function (buffer) {
|
||||
var hashAlgorithm = this.options.signingSchemeOptions.hash || DEFAULT_HASH_FUNCTION;
|
||||
if (this.options.environment === 'browser') {
|
||||
hashAlgorithm = SIGN_ALG_TO_HASH_ALIASES[hashAlgorithm] || hashAlgorithm;
|
||||
var hasher = CryptoJS[hashAlgorithm.toUpperCase()] (buffer.toString());
|
||||
var asBuffer = wordArrayToBuffer(hasher)
|
||||
var paddedHash = this.pkcs1pad(asBuffer, hashAlgorithm);
|
||||
var res = this.key.$doPrivate(new BigInteger(paddedHash)).toBuffer(this.key.encryptedDataLength);
|
||||
return res;
|
||||
} else {
|
||||
throw new Error ('CCXT only supports browser mode :P');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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);
|
||||
};
|
||||
|
||||
// used to convert `CryptoJS` wordArrays into `crypto` hex buffers
|
||||
function wordToByteArray(word, length) {
|
||||
var ba = [],
|
||||
xFF = 0xFF;
|
||||
if (length > 0)
|
||||
ba.push(word >>> 24);
|
||||
if (length > 1)
|
||||
ba.push((word >>> 16) & xFF);
|
||||
if (length > 2)
|
||||
ba.push((word >>> 8) & xFF);
|
||||
if (length > 3)
|
||||
ba.push(word & xFF);
|
||||
|
||||
return ba;
|
||||
}
|
||||
|
||||
function wordArrayToBuffer(wordArray) {
|
||||
let length = undefined;
|
||||
if (wordArray.hasOwnProperty("sigBytes") && wordArray.hasOwnProperty("words")) {
|
||||
length = wordArray.sigBytes;
|
||||
wordArray = wordArray.words;
|
||||
} else {
|
||||
throw Error('Argument not a wordArray')
|
||||
}
|
||||
|
||||
const result = []
|
||||
let bytes = []
|
||||
let i = 0;
|
||||
while (length > 0) {
|
||||
bytes = wordToByteArray(wordArray[i], Math.min(4, length));
|
||||
length -= bytes.length;
|
||||
result.push(bytes);
|
||||
i++;
|
||||
}
|
||||
return new Buffer.from([].concat.apply([], result), 'hex');
|
||||
}
|
||||
-21
@@ -1,21 +0,0 @@
|
||||
module.exports = {
|
||||
pkcs1: require('./pkcs1'),
|
||||
|
||||
/**
|
||||
* Check if scheme has padding methods
|
||||
* @param scheme {string}
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
isEncryption: function (scheme) {
|
||||
return module.exports[scheme] && module.exports[scheme].isEncryption;
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if scheme has sign/verify methods
|
||||
* @param scheme {string}
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
isSignature: function (scheme) {
|
||||
return module.exports[scheme] && module.exports[scheme].isSignature;
|
||||
}
|
||||
};
|
||||
-98
@@ -1,98 +0,0 @@
|
||||
/*
|
||||
* Utils functions
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Break string str each maxLen symbols
|
||||
* @param str
|
||||
* @param maxLen
|
||||
* @returns {string}
|
||||
*/
|
||||
module.exports.linebrk = function (str, maxLen) {
|
||||
var res = '';
|
||||
var i = 0;
|
||||
while (i + maxLen < str.length) {
|
||||
res += str.substring(i, i + maxLen) + "\n";
|
||||
i += maxLen;
|
||||
}
|
||||
return res + str.substring(i, str.length);
|
||||
};
|
||||
|
||||
/**
|
||||
* Trying get a 32-bit unsigned integer from the partial buffer
|
||||
* @param buffer
|
||||
* @param offset
|
||||
* @returns {Number}
|
||||
*/
|
||||
module.exports.get32IntFromBuffer = function (buffer, offset) {
|
||||
offset = offset || 0;
|
||||
var size = 0;
|
||||
if ((size = buffer.length - offset) > 0) {
|
||||
if (size >= 4) {
|
||||
return buffer.readUInt32BE(offset);
|
||||
} else {
|
||||
var res = 0;
|
||||
for (var i = offset + size, d = 0; i > offset; i--, d += 2) {
|
||||
res += buffer[i - 1] * Math.pow(16, d);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
} else {
|
||||
return NaN;
|
||||
}
|
||||
};
|
||||
|
||||
module.exports._ = {
|
||||
isObject: function (value) {
|
||||
var type = typeof value;
|
||||
return !!value && (type == 'object' || type == 'function');
|
||||
},
|
||||
|
||||
isString: function (value) {
|
||||
return typeof value == 'string' || value instanceof String;
|
||||
},
|
||||
|
||||
isNumber: function (value) {
|
||||
return typeof value == 'number' || !isNaN(parseFloat(value)) && isFinite(value);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns copy of `obj` without `removeProp` field.
|
||||
* @param obj
|
||||
* @param removeProp
|
||||
* @returns Object
|
||||
*/
|
||||
omit: function (obj, removeProp) {
|
||||
var newObj = {};
|
||||
for (var prop in obj) {
|
||||
if (!obj.hasOwnProperty(prop) || prop === removeProp) {
|
||||
continue;
|
||||
}
|
||||
newObj[prop] = obj[prop];
|
||||
}
|
||||
|
||||
return newObj;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Strips everything around the opening and closing lines, including the lines
|
||||
* themselves.
|
||||
*/
|
||||
module.exports.trimSurroundingText = function (data, opening, closing) {
|
||||
var trimStartIndex = 0;
|
||||
var trimEndIndex = data.length;
|
||||
|
||||
var openingBoundaryIndex = data.indexOf(opening);
|
||||
if (openingBoundaryIndex >= 0) {
|
||||
trimStartIndex = openingBoundaryIndex + opening.length;
|
||||
}
|
||||
|
||||
var closingBoundaryIndex = data.indexOf(closing, openingBoundaryIndex);
|
||||
if (closingBoundaryIndex >= 0) {
|
||||
trimEndIndex = closingBoundaryIndex;
|
||||
}
|
||||
|
||||
return data.substring(trimStartIndex, trimEndIndex);
|
||||
}
|
||||
Reference in new issue
Block a user