rsa-compat.js/lib/rsa-forge.js

182 lines
4.5 KiB
JavaScript

'use strict';
var forge = require('node-forge');
function notToJson() {
return undefined;
}
var forgec = module.exports = {
//
// to components
//
_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;
}
, _base64UrlToBin: function (base64) {
var std64 = forgec._toStandardBase64(base64);
var hex = Buffer.from(std64, 'base64').toString("hex");
return new forge.jsbn.BigInteger(hex, 16);
}
, _privateJwkToComponents: function (jwk) {
var components = [];
// [ 'n', 'e', 'd', 'p', 'q', 'dP', 'dQ', 'qInv' ]
[ 'n', 'e', 'd', 'p', 'q', 'dp', 'dq', 'qi' ].forEach(function (key) {
components.push(forgec._base64UrlToBin(jwk[key]));
});
return components;
}
, _publicJwkToComponents: function (jwk) {
var components = [];
[ 'n', 'e' ].forEach(function (key) {
components.push(forgec._base64UrlToBin(jwk[key]));
});
return components;
}
//
// Generate New Keypair
//
, generateKeypair: function (bitlen, exp, options, cb) {
var fkeypair = forge.pki.rsa.generateKeyPair({ bits: bitlen || 2048, e: exp || 0x10001 });
var result = {
_forge: fkeypair.privateKey
, _forgePublic: fkeypair.publicKey
};
result._forge.toJSON = notToJson;
result._forgePublic.toJSON = notToJson;
cb(null, result);
}
//
// Import (no-op)
//
, _forgeImportJwk: function (keypair) {
if (!keypair._forge && keypair.privateKeyJwk) {
keypair._forge = forge.pki.rsa.setPrivateKey.apply(
forge.pki.rsa
, forgec._privateJwkToComponents(keypair.privateKeyJwk)
);
keypair._forge.toJSON = notToJson;
}
forgec._forgeImportPublicJwk(keypair);
}
, _forgeImportPublicJwk: function (keypair) {
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)
);
}
if (keypair._forgePublic) {
keypair._forgePublic.toJSON = notToJson;
}
}
, _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);
}
if (keypair._forgePublic) {
keypair._forgePublic.toJSON = notToJson;
}
}
, import: function (keypair) {
// no-op since this must be done anyway in extra
return keypair;
}
//
// Export Public / Private PEMs
//
, exportPrivatePem: function (keypair) {
if (keypair.privateKeyPem) {
return keypair.privateKeyPem;
}
if (keypair.privateKeyJwk && !keypair._forge) {
forgec._forgeImportJwk(keypair);
}
if (keypair._forge) {
return forge.pki.privateKeyToPem(keypair._forge);
}
throw new Error("None of privateKeyPem, _forge, or privateKeyJwk found. No way to export private key PEM");
}
, exportPublicPem: function (keypair) {
if (keypair.publicKeyPem) {
return keypair.publicKeyPem;
}
if ((keypair.privateKeyJwk || keypair.publicKeyJwk)
&& !(keypair._forge || keypair._forgePublic)
) {
forgec._forgeImportPublicJwk(keypair);
}
if (!keypair._forge) {
if (keypair.privateKeyPem) {
forgec._forgeImportPem(keypair);
}
}
if (keypair.publicKeyPem) {
return keypair.publicKeyPem;
}
if (keypair._forge || keypair._forgePublic) {
return forge.pki.publicKeyToPem(keypair._forgePublic || keypair._forge);
}
throw new Error("None of publicKeyPem, _forge, _forgePublic, publicKeyJwk, privateKeyPem, or privateKeyJwk found. No way to export public key PEM");
}
//, exportPrivateKeyJwk: NOT IMPLEMENTED HERE
//, exportPublicKeyJwk: NOT IMPLEMENTED HERE
};