2016-07-30 20:35:25 +00:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
var forge = require('node-forge');
|
|
|
|
|
|
|
|
function notToJson() {
|
|
|
|
return undefined;
|
|
|
|
}
|
|
|
|
|
2016-07-30 23:09:37 +00:00
|
|
|
var forgec = module.exports = {
|
2016-07-30 20:35:25 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// to components
|
|
|
|
//
|
2016-08-01 08:03:50 +00:00
|
|
|
_toStandardBase64: function (str) {
|
|
|
|
var b64 = str.replace(/-/g, "+").replace(/_/g, "/").replace(/=/g, "");
|
|
|
|
|
|
|
|
switch (b64.length % 4) {
|
|
|
|
case 2: b64 += "=="; break;
|
|
|
|
case 3: b64 += "="; break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return b64;
|
|
|
|
}
|
|
|
|
, _base64ToBin: function (base64) {
|
|
|
|
var std64 = forgec._toStandardBase64(base64);
|
|
|
|
var hex = new Buffer(std64, 'base64').toString("hex");
|
|
|
|
|
|
|
|
return new forge.jsbn.BigInteger(hex, 16);
|
2016-07-30 20:35:25 +00:00
|
|
|
}
|
|
|
|
, _privateJwkToComponents: function (jwk) {
|
|
|
|
var components = [];
|
|
|
|
|
2016-07-31 03:47:52 +00:00
|
|
|
// [ 'n', 'e', 'd', 'p', 'q', 'dP', 'dQ', 'qInv' ]
|
2016-07-30 20:35:25 +00:00
|
|
|
[ 'n', 'e', 'd', 'p', 'q', 'dp', 'dq', 'qi' ].forEach(function (key) {
|
2016-08-01 08:03:50 +00:00
|
|
|
components.push(forgec._base64ToBin(jwk[key]));
|
2016-07-30 20:35:25 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
return components;
|
|
|
|
}
|
|
|
|
, _publicJwkToComponents: function (jwk) {
|
|
|
|
var components = [];
|
|
|
|
[ 'n', 'e' ].forEach(function (key) {
|
|
|
|
components.push(new Buffer(jwk[key], 'base64'));
|
|
|
|
});
|
|
|
|
|
|
|
|
return components;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// Generate New Keypair
|
|
|
|
//
|
|
|
|
, generateKeypair: function (bitlen, exp, options, cb) {
|
2016-08-01 08:03:50 +00:00
|
|
|
var fkeypair = forge.pki.rsa.generateKeyPair({ bits: bitlen || 1024, e: exp || 0x10001 });
|
2016-07-30 20:35:25 +00:00
|
|
|
|
2016-08-01 08:03:50 +00:00
|
|
|
fkeypair.toJSON = notToJson;
|
2016-07-30 20:35:25 +00:00
|
|
|
|
|
|
|
cb(null, {
|
2016-08-01 08:03:50 +00:00
|
|
|
_forge: fkeypair.privateKey
|
|
|
|
, _forgePublic: fkeypair.publicKey
|
2016-07-30 20:35:25 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-08-01 08:03:50 +00:00
|
|
|
//
|
|
|
|
// Import (no-op)
|
|
|
|
//
|
|
|
|
, _forgeImportJwk: function (keypair) {
|
2016-08-01 09:36:39 +00:00
|
|
|
if (!keypair._forge && keypair.privateKeyJwk) {
|
|
|
|
keypair._forge = forge.pki.rsa.setPrivateKey.apply(
|
|
|
|
forge.pki.rsa
|
|
|
|
, forgec._privateJwkToComponents(keypair.privateKeyJwk)
|
|
|
|
);
|
|
|
|
}
|
2016-08-01 08:03:50 +00:00
|
|
|
keypair._forge.toJSON = notToJson;
|
2016-08-01 09:36:39 +00:00
|
|
|
|
|
|
|
forgec._forgeImportPublicJwk(keypair);
|
2016-08-01 08:03:50 +00:00
|
|
|
}
|
|
|
|
, _forgeImportPublicJwk: function (keypair) {
|
2016-08-01 09:36:39 +00:00
|
|
|
if (keypair._forgePublic) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (keypair._forge) {
|
|
|
|
keypair._forgePublic = forge.pki.rsa.setPublicKey(keypair._forge.n, keypair._forge.e);
|
|
|
|
}
|
|
|
|
else if (keypair.publicKeyJwk) {
|
|
|
|
keypair._forgePublic = forge.pki.rsa.setPublicKey.apply(
|
|
|
|
forge.pki.rsa
|
|
|
|
, forgec._publicJwkToComponents(keypair.publicKeyJwk || keypair.privateKeyJwk)
|
|
|
|
);
|
|
|
|
}
|
2016-08-01 08:03:50 +00:00
|
|
|
keypair._forgePublic.toJSON = notToJson;
|
|
|
|
}
|
2016-08-01 14:01:52 +00:00
|
|
|
, _forgeImportPem: function (keypair) {
|
|
|
|
if (!keypair._forge && keypair.privateKeyPem) {
|
|
|
|
keypair._forge = forge.pki.privateKeyFromPem(keypair.privateKeyPem);
|
|
|
|
}
|
|
|
|
keypair._forge.toJSON = notToJson;
|
|
|
|
|
|
|
|
forgec._forgeImportPublicPem(keypair);
|
|
|
|
}
|
|
|
|
, _forgeImportPublicPem: function (keypair) {
|
|
|
|
if (keypair._forgePublic) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (keypair._forge) {
|
|
|
|
keypair._forgePublic = forge.pki.rsa.setPublicKey(keypair._forge.n, keypair._forge.e);
|
|
|
|
}
|
|
|
|
else if (keypair.publicKeyPem) {
|
|
|
|
keypair._forgePublic = keypair._forgePublic || forge.pki.publicKeyFromPem(keypair.publicKeyPem);
|
|
|
|
}
|
|
|
|
keypair._forgePublic.toJSON = notToJson;
|
|
|
|
}
|
2016-08-01 08:03:50 +00:00
|
|
|
, import: function (keypair) {
|
|
|
|
// no-op since this must be done anyway in extra
|
|
|
|
return keypair;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-07-30 20:35:25 +00:00
|
|
|
//
|
|
|
|
// Export Public / Private PEMs
|
|
|
|
//
|
2016-07-31 03:47:52 +00:00
|
|
|
, exportPrivatePem: function (keypair) {
|
2016-07-30 20:35:25 +00:00
|
|
|
if (keypair.privateKeyPem) {
|
|
|
|
return keypair.privateKeyPem;
|
|
|
|
}
|
|
|
|
|
2016-08-01 13:50:46 +00:00
|
|
|
if (keypair.privateKeyJwk && !keypair._forge) {
|
2016-08-01 08:03:50 +00:00
|
|
|
forgec._forgeImportJwk(keypair);
|
2016-07-30 20:35:25 +00:00
|
|
|
}
|
|
|
|
|
2016-08-01 13:50:46 +00:00
|
|
|
if (keypair._forge) {
|
2016-08-01 08:03:50 +00:00
|
|
|
return forge.pki.privateKeyToPem(keypair._forge);
|
2016-07-30 20:35:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
throw new Error("None of privateKeyPem, _forge, or privateKeyJwk found. No way to export private key PEM");
|
|
|
|
}
|
2016-07-31 03:47:52 +00:00
|
|
|
, exportPublicPem: function (keypair) {
|
2016-07-30 20:35:25 +00:00
|
|
|
if (keypair.publicKeyPem) {
|
|
|
|
return keypair.publicKeyPem;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((keypair.privateKeyJwk || keypair.publicKeyJwk)
|
2016-08-01 13:50:46 +00:00
|
|
|
&& !(keypair._forge || keypair._forgePublic)
|
2016-07-30 20:35:25 +00:00
|
|
|
) {
|
2016-08-01 08:03:50 +00:00
|
|
|
forgec._forgeImportPublicJwk(keypair);
|
2016-07-30 20:35:25 +00:00
|
|
|
}
|
|
|
|
|
2016-08-01 14:01:52 +00:00
|
|
|
if (!keypair._forge) {
|
|
|
|
if (keypair.privateKeyPem) {
|
|
|
|
forgec._forgeImportPem(keypair);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (keypair.publicKeyPem) {
|
|
|
|
return keypair.publicKeyPem;
|
|
|
|
}
|
|
|
|
if (keypair._forge || keypair._forgePublic) {
|
2016-08-01 08:03:50 +00:00
|
|
|
return forge.pki.publicKeyToPem(keypair._forgePublic || keypair._forge);
|
2016-07-30 20:35:25 +00:00
|
|
|
}
|
|
|
|
|
2016-08-01 14:01:52 +00:00
|
|
|
throw new Error("None of publicKeyPem, _forge, _forgePublic, publicKeyJwk, privateKeyPem, or privateKeyJwk found. No way to export public key PEM");
|
2016-07-30 20:35:25 +00:00
|
|
|
}
|
|
|
|
//, exportPrivateKeyJwk: NOT IMPLEMENTED HERE
|
|
|
|
//, exportPublicKeyJwk: NOT IMPLEMENTED HERE
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
};
|