提交物业报修模块
This commit is contained in:
1 parent
60cb1b09f8
commit
2371080245
597 files changed
+100361
-4145
No files matched your search
+71
@@ -0,0 +1,71 @@
|
||||
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;
|
||||
}
|
||||
};
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
var _ = require('../utils')._;
|
||||
|
||||
function formatParse(format) {
|
||||
format = format.split('-');
|
||||
var keyType = 'private';
|
||||
var keyOpt = {type: 'default'};
|
||||
|
||||
for (var i = 1; i < format.length; i++) {
|
||||
if (format[i]) {
|
||||
switch (format[i]) {
|
||||
case 'public':
|
||||
keyType = format[i];
|
||||
break;
|
||||
case 'private':
|
||||
keyType = format[i];
|
||||
break;
|
||||
case 'pem':
|
||||
keyOpt.type = format[i];
|
||||
break;
|
||||
case 'der':
|
||||
keyOpt.type = format[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {scheme: format[0], keyType: keyType, keyOpt: keyOpt};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
pkcs1: require('./pkcs1'),
|
||||
pkcs8: require('./pkcs8'),
|
||||
components: require('./components'),
|
||||
openssh: require('./openssh'),
|
||||
|
||||
isPrivateExport: function (format) {
|
||||
return module.exports[format] && typeof module.exports[format].privateExport === 'function';
|
||||
},
|
||||
|
||||
isPrivateImport: function (format) {
|
||||
return module.exports[format] && typeof module.exports[format].privateImport === 'function';
|
||||
},
|
||||
|
||||
isPublicExport: function (format) {
|
||||
return module.exports[format] && typeof module.exports[format].publicExport === 'function';
|
||||
},
|
||||
|
||||
isPublicImport: function (format) {
|
||||
return module.exports[format] && typeof module.exports[format].publicImport === 'function';
|
||||
},
|
||||
|
||||
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;
|
||||
},
|
||||
|
||||
detectAndExport: function (key, format) {
|
||||
if (format) {
|
||||
var fmt = formatParse(format);
|
||||
|
||||
if (module.exports[fmt.scheme]) {
|
||||
if (fmt.keyType === 'private') {
|
||||
if (!key.isPrivate()) {
|
||||
throw Error("This is not private key");
|
||||
}
|
||||
return module.exports[fmt.scheme].privateExport(key, fmt.keyOpt);
|
||||
} else {
|
||||
if (!key.isPublic()) {
|
||||
throw Error("This is not public key");
|
||||
}
|
||||
return module.exports[fmt.scheme].publicExport(key, fmt.keyOpt);
|
||||
}
|
||||
} else {
|
||||
throw Error('Unsupported key format');
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
+292
@@ -0,0 +1,292 @@
|
||||
var _ = require("../utils")._;
|
||||
var utils = require("../utils");
|
||||
var BigInteger = require("../libs/jsbn");
|
||||
|
||||
const PRIVATE_OPENING_BOUNDARY = "-----BEGIN OPENSSH PRIVATE KEY-----";
|
||||
const PRIVATE_CLOSING_BOUNDARY = "-----END OPENSSH PRIVATE KEY-----";
|
||||
|
||||
module.exports = {
|
||||
privateExport: function (key, options) {
|
||||
const nbuf = key.n.toBuffer();
|
||||
|
||||
let ebuf = Buffer.alloc(4)
|
||||
ebuf.writeUInt32BE(key.e, 0);
|
||||
//Slice leading zeroes
|
||||
while (ebuf[0] === 0) ebuf = ebuf.slice(1);
|
||||
|
||||
const dbuf = key.d.toBuffer();
|
||||
const coeffbuf = key.coeff.toBuffer();
|
||||
const pbuf = key.p.toBuffer();
|
||||
const qbuf = key.q.toBuffer();
|
||||
let commentbuf;
|
||||
if (typeof key.sshcomment !== "undefined") {
|
||||
commentbuf = Buffer.from(key.sshcomment);
|
||||
} else {
|
||||
commentbuf = Buffer.from([]);
|
||||
}
|
||||
|
||||
const pubkeyLength =
|
||||
11 + // 32bit length, 'ssh-rsa'
|
||||
4 + ebuf.byteLength +
|
||||
4 + nbuf.byteLength;
|
||||
|
||||
const privateKeyLength =
|
||||
8 + //64bit unused checksum
|
||||
11 + // 32bit length, 'ssh-rsa'
|
||||
4 + nbuf.byteLength +
|
||||
4 + ebuf.byteLength +
|
||||
4 + dbuf.byteLength +
|
||||
4 + coeffbuf.byteLength +
|
||||
4 + pbuf.byteLength +
|
||||
4 + qbuf.byteLength +
|
||||
4 + commentbuf.byteLength;
|
||||
|
||||
let length =
|
||||
15 + //openssh-key-v1,0x00,
|
||||
16 + // 2*(32bit length, 'none')
|
||||
4 + // 32bit length, empty string
|
||||
4 + // 32bit number of keys
|
||||
4 + // 32bit pubkey length
|
||||
pubkeyLength +
|
||||
4 + //32bit private+checksum+comment+padding length
|
||||
privateKeyLength;
|
||||
|
||||
const paddingLength = Math.ceil(privateKeyLength / 8) * 8 - privateKeyLength;
|
||||
length += paddingLength;
|
||||
|
||||
const buf = Buffer.alloc(length);
|
||||
const writer = {buf: buf, off: 0};
|
||||
buf.write("openssh-key-v1", "utf8");
|
||||
buf.writeUInt8(0, 14);
|
||||
writer.off += 15;
|
||||
|
||||
writeOpenSSHKeyString(writer, Buffer.from("none"));
|
||||
writeOpenSSHKeyString(writer, Buffer.from("none"));
|
||||
writeOpenSSHKeyString(writer, Buffer.from(""));
|
||||
|
||||
writer.off = writer.buf.writeUInt32BE(1, writer.off);
|
||||
writer.off = writer.buf.writeUInt32BE(pubkeyLength, writer.off);
|
||||
|
||||
writeOpenSSHKeyString(writer, Buffer.from("ssh-rsa"));
|
||||
writeOpenSSHKeyString(writer, ebuf);
|
||||
writeOpenSSHKeyString(writer, nbuf);
|
||||
|
||||
writer.off = writer.buf.writeUInt32BE(
|
||||
length - 47 - pubkeyLength,
|
||||
writer.off
|
||||
);
|
||||
writer.off += 8;
|
||||
|
||||
writeOpenSSHKeyString(writer, Buffer.from("ssh-rsa"));
|
||||
writeOpenSSHKeyString(writer, nbuf);
|
||||
writeOpenSSHKeyString(writer, ebuf);
|
||||
writeOpenSSHKeyString(writer, dbuf);
|
||||
writeOpenSSHKeyString(writer, coeffbuf);
|
||||
writeOpenSSHKeyString(writer, pbuf);
|
||||
writeOpenSSHKeyString(writer, qbuf);
|
||||
writeOpenSSHKeyString(writer, commentbuf);
|
||||
|
||||
let pad = 0x01;
|
||||
while (writer.off < length) {
|
||||
writer.off = writer.buf.writeUInt8(pad++, writer.off);
|
||||
}
|
||||
|
||||
if (options.type === "der") {
|
||||
return writer.buf
|
||||
} else {
|
||||
return PRIVATE_OPENING_BOUNDARY + "\n" + utils.linebrk(buf.toString("base64"), 70) + "\n" + PRIVATE_CLOSING_BOUNDARY + "\n";
|
||||
}
|
||||
},
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
const reader = {buf: buffer, off: 0};
|
||||
|
||||
if (buffer.slice(0, 14).toString("ascii") !== "openssh-key-v1")
|
||||
throw "Invalid file format.";
|
||||
|
||||
reader.off += 15;
|
||||
|
||||
//ciphername
|
||||
if (readOpenSSHKeyString(reader).toString("ascii") !== "none")
|
||||
throw Error("Unsupported key type");
|
||||
//kdfname
|
||||
if (readOpenSSHKeyString(reader).toString("ascii") !== "none")
|
||||
throw Error("Unsupported key type");
|
||||
//kdf
|
||||
if (readOpenSSHKeyString(reader).toString("ascii") !== "")
|
||||
throw Error("Unsupported key type");
|
||||
//keynum
|
||||
reader.off += 4;
|
||||
|
||||
//sshpublength
|
||||
reader.off += 4;
|
||||
|
||||
//keytype
|
||||
if (readOpenSSHKeyString(reader).toString("ascii") !== "ssh-rsa")
|
||||
throw Error("Unsupported key type");
|
||||
readOpenSSHKeyString(reader);
|
||||
readOpenSSHKeyString(reader);
|
||||
|
||||
reader.off += 12;
|
||||
if (readOpenSSHKeyString(reader).toString("ascii") !== "ssh-rsa")
|
||||
throw Error("Unsupported key type");
|
||||
|
||||
const n = readOpenSSHKeyString(reader);
|
||||
const e = readOpenSSHKeyString(reader);
|
||||
const d = readOpenSSHKeyString(reader);
|
||||
const coeff = readOpenSSHKeyString(reader);
|
||||
const p = readOpenSSHKeyString(reader);
|
||||
const q = readOpenSSHKeyString(reader);
|
||||
|
||||
//Calculate missing values
|
||||
const dint = new BigInteger(d);
|
||||
const qint = new BigInteger(q);
|
||||
const pint = new BigInteger(p);
|
||||
const dp = dint.mod(pint.subtract(BigInteger.ONE));
|
||||
const dq = dint.mod(qint.subtract(BigInteger.ONE));
|
||||
|
||||
key.setPrivate(
|
||||
n, // modulus
|
||||
e, // publicExponent
|
||||
d, // privateExponent
|
||||
p, // prime1
|
||||
q, // prime2
|
||||
dp.toBuffer(), // exponent1 -- d mod (p1)
|
||||
dq.toBuffer(), // exponent2 -- d mod (q-1)
|
||||
coeff // coefficient -- (inverse of q) mod p
|
||||
);
|
||||
|
||||
key.sshcomment = readOpenSSHKeyString(reader).toString("ascii");
|
||||
},
|
||||
|
||||
publicExport: function (key, options) {
|
||||
let ebuf = Buffer.alloc(4)
|
||||
ebuf.writeUInt32BE(key.e, 0);
|
||||
//Slice leading zeroes
|
||||
while (ebuf[0] === 0) ebuf = ebuf.slice(1);
|
||||
const nbuf = key.n.toBuffer();
|
||||
const buf = Buffer.alloc(
|
||||
ebuf.byteLength + 4 +
|
||||
nbuf.byteLength + 4 +
|
||||
"ssh-rsa".length + 4
|
||||
);
|
||||
|
||||
const writer = {buf: buf, off: 0};
|
||||
writeOpenSSHKeyString(writer, Buffer.from("ssh-rsa"));
|
||||
writeOpenSSHKeyString(writer, ebuf);
|
||||
writeOpenSSHKeyString(writer, nbuf);
|
||||
|
||||
let comment = key.sshcomment || "";
|
||||
|
||||
if (options.type === "der") {
|
||||
return writer.buf
|
||||
} else {
|
||||
return "ssh-rsa " + buf.toString("base64") + " " + comment + "\n";
|
||||
}
|
||||
},
|
||||
|
||||
publicImport: function (key, data, options) {
|
||||
options = options || {};
|
||||
var buffer;
|
||||
|
||||
if (options.type !== "der") {
|
||||
if (Buffer.isBuffer(data)) {
|
||||
data = data.toString("utf8");
|
||||
}
|
||||
|
||||
if (_.isString(data)) {
|
||||
if (data.substring(0, 8) !== "ssh-rsa ")
|
||||
throw Error("Unsupported key format");
|
||||
let pemEnd = data.indexOf(" ", 8);
|
||||
|
||||
//Handle keys with no comment
|
||||
if (pemEnd === -1) {
|
||||
pemEnd = data.length;
|
||||
} else {
|
||||
key.sshcomment = data.substring(pemEnd + 1)
|
||||
.replace(/\s+|\n\r|\n|\r$/gm, "");
|
||||
}
|
||||
|
||||
const pem = data.substring(8, pemEnd)
|
||||
.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");
|
||||
}
|
||||
|
||||
const reader = {buf: buffer, off: 0};
|
||||
|
||||
const type = readOpenSSHKeyString(reader).toString("ascii");
|
||||
|
||||
if (type !== "ssh-rsa")
|
||||
throw Error("Invalid key type: " + type);
|
||||
|
||||
const e = readOpenSSHKeyString(reader);
|
||||
const n = readOpenSSHKeyString(reader);
|
||||
|
||||
key.setPublic(
|
||||
n,
|
||||
e
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* 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 OPENSSH PRIVATE KEY-----\s*(?=(([A-Za-z0-9+/=]+\s*)+))\1-----END OPENSSH PRIVATE KEY-----[\S\s]*$/g.test(data)) {
|
||||
module.exports.privateImport(key, data);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (/^[\S\s]*ssh-rsa \s*(?=(([A-Za-z0-9+/=]+\s*)+))\1[\S\s]*$/g.test(data)) {
|
||||
module.exports.publicImport(key, data);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
function readOpenSSHKeyString(reader) {
|
||||
const len = reader.buf.readInt32BE(reader.off);
|
||||
reader.off += 4;
|
||||
const res = reader.buf.slice(reader.off, reader.off + len);
|
||||
reader.off += len;
|
||||
return res;
|
||||
}
|
||||
|
||||
function writeOpenSSHKeyString(writer, data) {
|
||||
writer.buf.writeInt32BE(data.byteLength, writer.off);
|
||||
writer.off += 4;
|
||||
writer.off += data.copy(writer.buf, writer.off);
|
||||
}
|
||||
+148
@@ -0,0 +1,148 @@
|
||||
var ber = require('asn1').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
@@ -0,0 +1,187 @@
|
||||
var ber = require('asn1').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;
|
||||
}
|
||||
};
|
||||
Reference in new issue
Block a user