105 lines
2.6 KiB
JavaScript
105 lines
2.6 KiB
JavaScript
|
'use strict';
|
||
|
|
||
|
/*global Promise*/
|
||
|
var keypairs = module.exports;
|
||
|
|
||
|
var PEM = require('./pem-parser.js');
|
||
|
PEM.packBlock = require('./pem-packer.js').packBlock;
|
||
|
|
||
|
var ASN1 = require('./asn1-parser.js');
|
||
|
ASN1.pack = require('./asn1-packer.js').pack;
|
||
|
|
||
|
var x509 = require('./x509-parser.js');
|
||
|
|
||
|
var SSH = require('./ssh-parser.js');
|
||
|
SSH.pack = require('./ssh-packer.js').pack;
|
||
|
|
||
|
// sign, signJws, signJwt
|
||
|
var JWS = require('./jws.js');
|
||
|
var JWT = require('./jwt.js');
|
||
|
|
||
|
var RSA = require('./rsa.js');
|
||
|
var EC = require('./ec.js');
|
||
|
|
||
|
keypairs.import = function (opts) {
|
||
|
return Promise.resolve().then(function () {
|
||
|
var jwk = opts.jwk;
|
||
|
var pem;
|
||
|
var der;
|
||
|
var typ;
|
||
|
|
||
|
if (opts.pem) {
|
||
|
pem = PEM.parseBlock(opts.pem);
|
||
|
if (/OPENSSH/.test(pem.type)) {
|
||
|
jwk = SSH.parse(pem);
|
||
|
} else {
|
||
|
der = pem.bytes;
|
||
|
jwk = x509.parse(der);
|
||
|
}
|
||
|
}
|
||
|
if (opts.ssh) {
|
||
|
jwk = SSH.parse(opts.ssh);
|
||
|
}
|
||
|
if (jwk) {
|
||
|
// Both RSA and EC use 'd' as part of the private key
|
||
|
if (jwk.d) {
|
||
|
typ = 'PRIVATE KEY';
|
||
|
der = x509.pack({ jwk: jwk, format: 'pkcs8', encoding: 'pem' });
|
||
|
} else {
|
||
|
typ = 'PUBLIC KEY';
|
||
|
der = x509.pack({ jwk: jwk, format: 'spki', encoding: 'pem' });
|
||
|
}
|
||
|
pem = PEM.packBlock({ type: typ, bytes: der });
|
||
|
}
|
||
|
|
||
|
return { pem: pem, jwk: jwk };
|
||
|
});
|
||
|
};
|
||
|
|
||
|
keypairs.export = function (opts) {
|
||
|
// { pem, jwk, format, encoding }
|
||
|
var format = opts.format;
|
||
|
var encoding = opts.encoding;
|
||
|
var jwk = opts.jwk;
|
||
|
var pem = opts.pem;
|
||
|
var der = opts.der;
|
||
|
var pub = opts.public;
|
||
|
|
||
|
if (opts.key) {
|
||
|
if ('string' === typeof opts.key) {
|
||
|
pem = opts.key;
|
||
|
} else if (opts.key.d) {
|
||
|
jwk = opts.key;
|
||
|
} else if (opts.key.length) {
|
||
|
der = opts.der;
|
||
|
} else {
|
||
|
throw new Error("'key' must be of type 'string' (PEM), 'object' (JWK), Buffer, or Array (DER)");
|
||
|
}
|
||
|
}
|
||
|
if (!format) { format = 'jwk'; }
|
||
|
|
||
|
if (!jwk) {
|
||
|
jwk = keypairs.import({ pem: pem }).jwk;
|
||
|
}
|
||
|
if (pub) {
|
||
|
if ('RSA' === jwk.kty) {
|
||
|
jwk = { kty: jwk.kty, n: jwk.n, e: jwk.e };
|
||
|
} else {
|
||
|
jwk = { kty: jwk.kty, x: jwk.x, y: jwk.y };
|
||
|
}
|
||
|
}
|
||
|
if ('jwk' === format) {
|
||
|
if (encoding && 'json' !== encoding) {
|
||
|
throw new Error("'encoding' must be 'json' for 'jwk'");
|
||
|
}
|
||
|
return jwk;
|
||
|
}
|
||
|
|
||
|
if ('openssh' === format || 'ssh' === format) {
|
||
|
// TODO if ('ssh' === format) { format = 'pkcs8'; }
|
||
|
// TODO 'ssh2' public key is a special variant of pkcs8
|
||
|
return SSH.pack({ jwk: jwk, public: opts.public });
|
||
|
}
|
||
|
return x509.pack({ jwk: jwk, format: opts.format, encoding: opts.encoding, public: opts.public });
|
||
|
};
|