partial implementations
This commit is contained in:
parent
2aced3a54d
commit
0ebedd4e74
|
@ -0,0 +1,76 @@
|
|||
// Copyright 2014 ISRG. All rights reserved
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
'use strict';
|
||||
|
||||
var utils = {
|
||||
|
||||
fromStandardB64: function(x) {
|
||||
return x.replace(/[+]/g, "-").replace(/\//g, "_").replace(/=/g,"");
|
||||
},
|
||||
|
||||
toStandardB64: function(x) {
|
||||
var b64 = x.replace(/-/g, "+").replace(/_/g, "/").replace(/=/g, "");
|
||||
|
||||
switch (b64.length % 4) {
|
||||
case 2: b64 += "=="; break;
|
||||
case 3: b64 += "="; break;
|
||||
}
|
||||
|
||||
return b64;
|
||||
},
|
||||
|
||||
b64enc: function(buffer) {
|
||||
return utils.fromStandardB64(buffer.toString("base64"));
|
||||
},
|
||||
|
||||
b64dec: function(str) {
|
||||
return new Buffer(utils.toStandardB64(str), "base64");
|
||||
},
|
||||
|
||||
isB64String: function(x) {
|
||||
return ("string" === typeof x) && !x.match(/[^a-zA-Z0-9_-]/);
|
||||
},
|
||||
|
||||
fieldsPresent: function(fields, object) {
|
||||
for (var i in fields) {
|
||||
if (!(fields[i] in object)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
validSignature: function(sig) {
|
||||
return (("object" === typeof sig) &&
|
||||
("alg" in sig) && ("string" === typeof sig.alg) &&
|
||||
("nonce" in sig) && utils.isB64String(sig.nonce) &&
|
||||
("sig" in sig) && utils.isB64String(sig.sig) &&
|
||||
("jwk" in sig) && utils.validJWK(sig.jwk));
|
||||
},
|
||||
|
||||
validJWK: function(jwk) {
|
||||
return (("object" === typeof jwk) && ("kty" in jwk) && (
|
||||
((jwk.kty === "RSA")
|
||||
&& ("n" in jwk) && utils.isB64String(jwk.n)
|
||||
&& ("e" in jwk) && utils.isB64String(jwk.e)) ||
|
||||
((jwk.kty === "EC")
|
||||
&& ("crv" in jwk)
|
||||
&& ("x" in jwk) && utils.isB64String(jwk.x)
|
||||
&& ("y" in jwk) && utils.isB64String(jwk.y))
|
||||
) && !("d" in jwk));
|
||||
},
|
||||
|
||||
// A simple, non-standard fingerprint for a JWK,
|
||||
// just so that we don't have to store objects
|
||||
keyFingerprint: function(jwk) {
|
||||
switch (jwk.kty) {
|
||||
case "RSA": return jwk.n;
|
||||
case "EC": return jwk.crv + jwk.x + jwk.y;
|
||||
}
|
||||
throw "Unrecognized key type";
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = utils;
|
|
@ -0,0 +1,44 @@
|
|||
/*!
|
||||
* rsa-compat
|
||||
* Copyright(c) 2016 AJ ONeal <aj@daplie.com> https://daplie.com
|
||||
* Apache-2.0 OR MIT (and hence also MPL 2.0)
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var cryptoc = {};
|
||||
var rsaExtra = require('./rsa-extra');
|
||||
var rsaForge = require('./rsa-forge');
|
||||
var ursac;
|
||||
|
||||
try {
|
||||
ursac = require('./rsa-ursa');
|
||||
} catch(e) {
|
||||
ursac = {};
|
||||
// things will run a little slower on keygen, but it'll work on windows
|
||||
// (but don't try this on raspberry pi - 20+ MINUTES key generation)
|
||||
}
|
||||
|
||||
// order of crypto precdence is
|
||||
// * native
|
||||
// * ursa
|
||||
// * forge extra (the new one aimed to be less-forgey)
|
||||
// * forge (fallback)
|
||||
Object.keys(ursac).forEach(function (key) {
|
||||
if (!cryptoc[key]) {
|
||||
cryptoc[key] = ursac[key];
|
||||
}
|
||||
});
|
||||
|
||||
Object.keys(rsaExtra).forEach(function (key) {
|
||||
if (!cryptoc[key]) {
|
||||
cryptoc[key] = rsaExtra[key];
|
||||
}
|
||||
});
|
||||
|
||||
Object.keys(rsaForge).forEach(function (key) {
|
||||
if (!cryptoc[key]) {
|
||||
cryptoc[key] = rsaForge[key];
|
||||
}
|
||||
});
|
||||
|
||||
module.exports.cryptoc = cryptoc;
|
|
@ -0,0 +1,120 @@
|
|||
'use strict';
|
||||
|
||||
var ursa = require('ursa');
|
||||
|
||||
function notToJson() {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
var ursac = {
|
||||
|
||||
|
||||
|
||||
//
|
||||
// to components
|
||||
//
|
||||
_privateJwkToComponents: function (jwk) {
|
||||
var components = [];
|
||||
|
||||
[ 'n', 'e', 'p', 'q', 'dp', 'dq', 'qi', 'd' ].forEach(function (key) {
|
||||
components.push(new Buffer(jwk[key], 'base64'));
|
||||
});
|
||||
|
||||
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) {
|
||||
var keypair = ursa.generatePrivateKey(bitlen || 2048, exp || 6553);
|
||||
|
||||
keypair.toJSON = notToJson;
|
||||
|
||||
cb(null, {
|
||||
_ursa: keypair
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Export Public / Private PEMs
|
||||
//
|
||||
, exportPrivateKeyPem: function (keypair) {
|
||||
if (keypair.privateKeyPem) {
|
||||
return keypair.privateKeyPem;
|
||||
}
|
||||
|
||||
if (keypair._ursa) {
|
||||
return keypair._ursa.toPrivatePem().toString('ascii');
|
||||
}
|
||||
|
||||
if (keypair.privateKeyJwk) {
|
||||
keypair._ursa = ursa.createPrivateKeyFromComponents.apply(
|
||||
ursa
|
||||
, ursac._privateJwkToComponents(keypair.privateKeyJwk)
|
||||
);
|
||||
keypair._ursa.toJSON = notToJson;
|
||||
|
||||
return keypair._ursa.toPrivatePem().toString('ascii');
|
||||
}
|
||||
|
||||
throw new Error("None of privateKeyPem, _ursa, or privateKeyJwk found. No way to export private key PEM");
|
||||
}
|
||||
, exportPublicKeyPem: function (keypair) {
|
||||
if (keypair.publicKeyPem) {
|
||||
return keypair.publicKeyPem;
|
||||
}
|
||||
|
||||
if (keypair._ursa || keypair._ursaPublic) {
|
||||
return (keypair._ursa || keypair._ursaPublic).toPublicPem().toString('ascii');
|
||||
}
|
||||
|
||||
if (keypair.publicKeyJwk) {
|
||||
keypair._ursaPublic = ursa.createPublicKeyFromComponents.apply(
|
||||
ursa
|
||||
, ursac._publicJwkToComponents(keypair.publicKeyJwk)
|
||||
);
|
||||
keypair._ursaPublic.toJSON = notToJson;
|
||||
|
||||
return keypair._ursa.toPublicPem().toString('ascii');
|
||||
}
|
||||
|
||||
if (keypair.privateKeyJwk) {
|
||||
keypair._ursa = ursa.createPrivateKeyFromComponents.apply(
|
||||
ursa
|
||||
, ursac._privateJwkToComponents(keypair.privateKeyJwk)
|
||||
);
|
||||
keypair._ursa.toJSON = notToJson;
|
||||
|
||||
return keypair._ursa.toPublicPem().toString('ascii');
|
||||
}
|
||||
|
||||
if (keypair.privateKeyPem) {
|
||||
keypair._ursa = ursa.createPrivateKey(keypair.privateKeyPem);
|
||||
keypair._ursa.toJSON = notToJson;
|
||||
|
||||
return keypair._ursa.toPublicPem().toString('ascii');
|
||||
}
|
||||
|
||||
throw new Error("None of publicKeyPem, _ursa, publicKeyJwk, privateKeyPem, or privateKeyJwk found. No way to export public key PEM");
|
||||
}
|
||||
//, exportPrivateKeyJwk: NOT IMPLEMENTED HERE
|
||||
//, exportPublicKeyJwk: NOT IMPLEMENTED HERE
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
return ursac;
|
|
@ -0,0 +1,88 @@
|
|||
/*!
|
||||
* rsa-compat
|
||||
* Copyright(c) 2016 AJ ONeal <aj@daplie.com> https://daplie.com
|
||||
* Apache-2.0 OR MIT (and hence also MPL 2.0)
|
||||
*/
|
||||
'use strict';
|
||||
var RSA = {};
|
||||
var NOBJ = {};
|
||||
|
||||
function create(deps) {
|
||||
var crypto = require('crypto');
|
||||
|
||||
deps = deps || {};
|
||||
deps.NOBJ = {};
|
||||
deps.RSA = RSA;
|
||||
|
||||
RSA.utils = require('./lib/key-utils.js');
|
||||
|
||||
RSA.utils._bytesToBuffer = function (bytes) {
|
||||
var forge = require("node-forge");
|
||||
return new Buffer(forge.util.bytesToHex(bytes), "hex");
|
||||
};
|
||||
RSA._internal = require('./lib/node').create(deps);
|
||||
|
||||
RSA.thumbprint = function (jwk) {
|
||||
jwk = jwk.privateKeyJwk || jwk.publicKeyJwk || jwk;
|
||||
if (!jwk.e || !jwk.n) {
|
||||
throw new Error("You must provide an RSA jwk with 'e' and 'n' (the public components)");
|
||||
}
|
||||
var input = RSA.utils._bytesToBuffer('{"e":"'+ jwk.e + '","kty":"RSA","n":"'+ jwk.n +'"}');
|
||||
return RSA.util.b64enc(crypto.createHash('sha256').update(input).digest());
|
||||
};
|
||||
|
||||
RSA.generateKeypair = function (length, exponent, options, cb) {
|
||||
var keypair = {
|
||||
privateKeyPem: undefined
|
||||
, publicKeyPem: undefined
|
||||
, privateKeyJwk: undefined
|
||||
, publicKeyJwk: undefined
|
||||
, _ursa: undefined
|
||||
, _forge: undefined
|
||||
};
|
||||
|
||||
options = options || NOBJ;
|
||||
|
||||
RSA._internal.generateKeypair(length, exponent, options, function (keys) {
|
||||
if (false !== options.jwk || options.thumbprint) {
|
||||
keypair.privateKeyJwk = RSA._internal.exportPrivateJwk(keys);
|
||||
if (options.public) {
|
||||
keypair.publicKeyJwk = RSA._internal.exportPublicJwk(keys);
|
||||
/*
|
||||
return {
|
||||
kty: keypair.privateKeyJwk.kty
|
||||
, n: keypair.privateKeyJwk.n
|
||||
, e: keypair.privateKeyJwk.e
|
||||
};
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
if (options.pem) {
|
||||
keypair.privateKeyPem = RSA._internal.exportPrivatePem(keys);
|
||||
if (options.public) {
|
||||
keypair.publicKeyPem = RSA._internal.exportPublicPem(keys);
|
||||
}
|
||||
}
|
||||
|
||||
if (options.thumprint) {
|
||||
keypair.thumbprint = RSA.thumbprint(keypair.privateKeyJwk /*|| keypair.publicKeyJwk*/);
|
||||
}
|
||||
|
||||
if (options.internal) {
|
||||
//keypair._ursa = undefined;
|
||||
//keypair._forge = undefined;
|
||||
keypair._ursa = keys._ursa;
|
||||
keypair._forge = keys._forge;
|
||||
}
|
||||
|
||||
cb(null, keypair);
|
||||
return;
|
||||
});
|
||||
};
|
||||
|
||||
return RSA;
|
||||
}
|
||||
|
||||
module.exports.RSA = create(/*require('./lib/node')*/);
|
||||
//module.exports.RSA.create = create;
|
Loading…
Reference in New Issue