v1.2.5: fix multiple bugs with conversion
This commit is contained in:
parent
a5236f6c2f
commit
ad312edfa6
110
bin/keypairs.js
110
bin/keypairs.js
|
@ -13,7 +13,7 @@ var Keypairs = require('../');
|
|||
var pkg = require('../package.json');
|
||||
|
||||
var args = process.argv.slice(2);
|
||||
var opts = { jwks: [], jwts: [], jwss: [], payloads: [], names: [], filenames: [], files: [], pems: [] };
|
||||
var opts = { keys: [], jwts: [], jwss: [], payloads: [], names: [], filenames: [], files: [] };
|
||||
var conflicts = {
|
||||
'namedCurve': 'modulusLength'
|
||||
, 'public': 'private'
|
||||
|
@ -187,13 +187,7 @@ args.forEach(function (arg) {
|
|||
}
|
||||
|
||||
// Possibly the output file
|
||||
if (!opts.extra1) {
|
||||
opts.extra1 = arg;
|
||||
opts.names.push({ taken: false, name: arg });
|
||||
return;
|
||||
}
|
||||
if (!opts.extra2) {
|
||||
opts.extra2 = arg;
|
||||
if (opts.names.length < 3) {
|
||||
opts.names.push({ taken: false, name: arg });
|
||||
return;
|
||||
}
|
||||
|
@ -220,7 +214,7 @@ function guess(txt, filename) {
|
|||
try {
|
||||
var json = JSON.parse(txt);
|
||||
if (-1 !== [ 'RSA', 'EC' ].indexOf(json.kty)) {
|
||||
opts.jwks.push({ jwk: json, filename: filename });
|
||||
opts.keys.push({ raw: txt, jwk: json, filename: filename });
|
||||
return true;
|
||||
} else if (json.signature && json.payload && (json.header || json.protected)) {
|
||||
opts.jwss.push(json);
|
||||
|
@ -231,15 +225,15 @@ function guess(txt, filename) {
|
|||
}
|
||||
} catch(e) {
|
||||
try {
|
||||
var pem = Eckles.importSync({ pem: txt });
|
||||
var jwk = Eckles.importSync({ pem: txt });
|
||||
// pem._string = txt;
|
||||
opts.pems.push(pem);
|
||||
opts.keys.push({ jwk: jwk, pem: true, raw: txt });
|
||||
return true;
|
||||
} catch(e) {
|
||||
try {
|
||||
var pem = Rasha.importSync({ pem: txt });
|
||||
var jwk = Rasha.importSync({ pem: txt });
|
||||
// pem._string = txt;
|
||||
opts.pems.push(pem);
|
||||
opts.keys.push({ jwk: jwk, pem: true, raw: txt });
|
||||
return true;
|
||||
} catch(e) {
|
||||
// ignore
|
||||
|
@ -348,8 +342,8 @@ if ('sign' === opts.action) {
|
|||
|
||||
function readKeypair() {
|
||||
// note that the jwk may be a string
|
||||
var jwkopts = opts.jwks.shift();
|
||||
var jwk = jwkopts && jwkopts.jwk;
|
||||
var keyopts = opts.keys.shift();
|
||||
var jwk = keyopts && keyopts.jwk;
|
||||
if (!jwk) {
|
||||
console.error("no keys could be parsed from the given arguments");
|
||||
console.error(opts.names.map(function (t) { return t.name; }));
|
||||
|
@ -358,13 +352,13 @@ function readKeypair() {
|
|||
}
|
||||
|
||||
// omit the primary private key from the list of actual (or soon-to-be) files
|
||||
if (jwkopts.filename) {
|
||||
if (keyopts.filename) {
|
||||
opts.names = opts.names.filter(function (name) {
|
||||
return name.name !== jwkopts.filename;
|
||||
return name.name !== keyopts.filename;
|
||||
});
|
||||
}
|
||||
|
||||
var pair = { private: null, public: null };
|
||||
var pair = { private: null, public: null, pem: keyopts.pem, raw: keyopts.raw };
|
||||
if (jwk.d) {
|
||||
pair.private = jwk;
|
||||
}
|
||||
|
@ -372,69 +366,91 @@ function readKeypair() {
|
|||
return pair;
|
||||
}
|
||||
|
||||
// Note: some of the conditions can be factored out
|
||||
// this was all built in high-speed iterative during the 3ams+
|
||||
function convertKeypair(pair) {
|
||||
//var pair = readKeypair();
|
||||
|
||||
var ps = [];
|
||||
if (pair.private && !opts.public) {
|
||||
if ((!opts.privEncoding || 'json' === opts.privEncoding) && (!opts.privFormat || 'jwk' === opts.privFormat)) {
|
||||
// if it's private only, or if it's not public-only, produce the private key
|
||||
if (pair.private || !opts.public) {
|
||||
// if it came from pem (or is explicitly json), it should go to jwk
|
||||
// otherwise, if it came from jwk, it should go to pem
|
||||
if (((!opts.privEncoding && pair.pem) || 'json' === opts.privEncoding)
|
||||
&& ((!opts.privFormat && pair.pem) || 'jwk' === opts.privFormat)) {
|
||||
ps.push(Promise.resolve(pair.private));
|
||||
} else {
|
||||
ps.push(Keypairs.export({ jwk: pair.private, format: opts.privFormat, encoding: opts.privEncoding }));
|
||||
}
|
||||
}
|
||||
|
||||
// if it's not private key only, we want to produce the public key
|
||||
if (!opts.private) {
|
||||
if (opts.public) {
|
||||
// if it's public-only the ambigious options will fall to the private key
|
||||
// so we need to fix that
|
||||
if (!opts.pubFormat) { opts.pubFormat = opts.privFormat; }
|
||||
if (!opts.pubEncoding) { opts.pubEncoding = opts.privEncoding; }
|
||||
}
|
||||
|
||||
if ((!opts.pubEncoding || 'json' === opts.pubEncoding) && (!opts.pubFormat || 'jwk' === opts.pubFormat)) {
|
||||
// same as above - swap formats by default
|
||||
if (((!opts.pubEncoding && pair.pem) || 'json' === opts.pubEncoding)
|
||||
&& ((!opts.pubFormat && pair.pem) || 'jwk' === opts.pubFormat)) {
|
||||
ps.push(Promise.resolve(pair.public));
|
||||
} else {
|
||||
ps.push(Keypairs.export({ jwk: pair.public, format: opts.pubFormat, encoding: opts.pubEncoding, public: true }));
|
||||
}
|
||||
}
|
||||
return Promise.all(ps).then(function (arr) {
|
||||
// only use the first key
|
||||
var key = convert(0, opts.public);
|
||||
|
||||
return Promise.all(ps).then(function (exported) {
|
||||
// start with the first key, annotating if it should be public
|
||||
var index = 0;
|
||||
var key = stringifyIfJson(index, opts.public);
|
||||
|
||||
// re: opts.names
|
||||
// if we're only doing the public key we can end early
|
||||
// (if the source key was from a file and was in opts.names,
|
||||
// we're safe here because we already removed it earlier)
|
||||
|
||||
if (opts.public) {
|
||||
// end early
|
||||
if (opts.names.length) {
|
||||
writeFile(opts.names[0].name, key, !opts.public); // todo make pub/priv param consistent, not flip-flop
|
||||
writeFile(opts.names[index].name, key, !opts.public);
|
||||
} else {
|
||||
console.warn(key + "\n");
|
||||
// output public keys to stderr
|
||||
printPublic(key);
|
||||
}
|
||||
// end <-- we're not outputting other keys
|
||||
return;
|
||||
}
|
||||
|
||||
// private key stuff
|
||||
if (opts.names.length) {
|
||||
writeFile(opts.names[0].name, key, true);
|
||||
if (opts.names.length >= 1) {
|
||||
writeFile(opts.names[index].name, key, true);
|
||||
} else {
|
||||
console.info(key + "\n");
|
||||
printPrivate(key);
|
||||
}
|
||||
|
||||
// pub key stuff
|
||||
if (!opts.private) {
|
||||
if (opts.names.length >= 2) {
|
||||
writeFile(opts.names[1].name, key, false);
|
||||
} else {
|
||||
console.warn(key + "\n");
|
||||
}
|
||||
// we have to output the private key,
|
||||
// but the public key can be derived at any time
|
||||
// so we don't need to put the same noise to the screen
|
||||
if (!opts.private && opts.names.length >= 2) {
|
||||
index = 1;
|
||||
key = stringifyIfJson(index, false);
|
||||
writeFile(opts.names[index].name, key, false);
|
||||
}
|
||||
|
||||
return pair;
|
||||
|
||||
function convert(i, pub) {
|
||||
if (arr[i].kty) {
|
||||
function stringifyIfJson(i, pub) {
|
||||
if (exported[i].kty) {
|
||||
if (pub) {
|
||||
if (opts.expiresAt) { arr[i].exp = opts.expiresAt; }
|
||||
arr[i].use = "sig";
|
||||
if (opts.expiresAt) { exported[i].exp = opts.expiresAt; }
|
||||
exported[i].use = "sig";
|
||||
}
|
||||
arr[i] = JSON.stringify(arr[i]);
|
||||
exported[i] = JSON.stringify(exported[i]);
|
||||
}
|
||||
return arr[i];
|
||||
return exported[i];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -445,6 +461,7 @@ function genKeypair() {
|
|||
, modulusLength: opts.modulusLength
|
||||
, namedCurve: opts.namedCurve
|
||||
}).then(function (pair) {
|
||||
// always generate as jwk by default
|
||||
var ps = [];
|
||||
if ((!opts.privEncoding || 'json' === opts.privEncoding) && (!opts.privFormat || 'jwk' === opts.privFormat)) {
|
||||
ps.push(Promise.resolve(pair.private));
|
||||
|
@ -488,8 +505,10 @@ function writeFile(name, key, priv) {
|
|||
overwrite = opts.overwrite;
|
||||
if (!opts.overwrite) {
|
||||
if (priv) {
|
||||
// output private keys to stdout
|
||||
console.info(key + "\n");
|
||||
} else {
|
||||
// output public keys to stderr
|
||||
console.warn(key + "\n");
|
||||
}
|
||||
console.error("'" + name + "' exists! force overwrite with 'overwrite'");
|
||||
|
@ -583,3 +602,10 @@ function decodeJwt(jwt) {
|
|||
, signature: parts[2] //Buffer.from(parts[2], 'base64')
|
||||
};
|
||||
}
|
||||
|
||||
function printPrivate(key) {
|
||||
console.info(key + "\n");
|
||||
}
|
||||
function printPublic(key) {
|
||||
console.warn(key + "\n");
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "keypairs",
|
||||
"version": "1.2.2",
|
||||
"version": "1.2.5",
|
||||
"description": "Lightweight RSA/ECDSA keypair generation and JWK <-> PEM",
|
||||
"main": "keypairs.js",
|
||||
"files": [
|
||||
|
|
Loading…
Reference in New Issue