2019-10-15 10:12:46 +00:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
var native = module.exports;
|
|
|
|
// XXX provided by caller: import, export
|
|
|
|
var EC = native;
|
|
|
|
// TODO SSH
|
|
|
|
|
2020-07-28 21:42:32 +00:00
|
|
|
native.generate = function (opts) {
|
|
|
|
return Promise.resolve().then(function () {
|
2019-10-15 10:12:46 +00:00
|
|
|
var typ = 'ec';
|
|
|
|
var format = opts.format;
|
|
|
|
var encoding = opts.encoding;
|
|
|
|
var priv;
|
|
|
|
var pub = 'spki';
|
|
|
|
|
|
|
|
if (!format) {
|
|
|
|
format = 'jwk';
|
|
|
|
}
|
|
|
|
if (-1 !== ['spki', 'pkcs8', 'ssh'].indexOf(format)) {
|
|
|
|
format = 'pkcs8';
|
|
|
|
}
|
|
|
|
|
|
|
|
if ('pem' === format) {
|
|
|
|
format = 'sec1';
|
|
|
|
encoding = 'pem';
|
|
|
|
} else if ('der' === format) {
|
|
|
|
format = 'sec1';
|
|
|
|
encoding = 'der';
|
|
|
|
}
|
|
|
|
|
|
|
|
if ('jwk' === format || 'json' === format) {
|
|
|
|
format = 'jwk';
|
|
|
|
encoding = 'json';
|
|
|
|
} else {
|
|
|
|
priv = format;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!encoding) {
|
|
|
|
encoding = 'pem';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (priv) {
|
|
|
|
priv = { type: priv, format: encoding };
|
|
|
|
pub = { type: pub, format: encoding };
|
|
|
|
} else {
|
|
|
|
// jwk
|
|
|
|
priv = { type: 'sec1', format: 'pem' };
|
|
|
|
pub = { type: 'spki', format: 'pem' };
|
|
|
|
}
|
|
|
|
|
2020-07-28 21:42:32 +00:00
|
|
|
return new Promise(function (resolve, reject) {
|
2019-10-15 10:12:46 +00:00
|
|
|
return require('crypto').generateKeyPair(
|
|
|
|
typ,
|
|
|
|
{
|
|
|
|
namedCurve: opts.crv || opts.namedCurve || 'P-256',
|
|
|
|
privateKeyEncoding: priv,
|
|
|
|
publicKeyEncoding: pub
|
|
|
|
},
|
2020-07-28 21:42:32 +00:00
|
|
|
function (err, pubkey, privkey) {
|
2019-10-15 10:12:46 +00:00
|
|
|
if (err) {
|
|
|
|
reject(err);
|
|
|
|
}
|
|
|
|
resolve({
|
|
|
|
private: privkey,
|
|
|
|
public: pubkey
|
|
|
|
});
|
|
|
|
}
|
|
|
|
);
|
2020-07-28 21:42:32 +00:00
|
|
|
}).then(function (keypair) {
|
2019-10-15 10:12:46 +00:00
|
|
|
if ('jwk' === format) {
|
|
|
|
return Promise.all([
|
|
|
|
native.import({
|
|
|
|
pem: keypair.private,
|
|
|
|
format: priv.type
|
|
|
|
}),
|
|
|
|
native.import({
|
|
|
|
pem: keypair.public,
|
|
|
|
format: pub.type,
|
|
|
|
public: true
|
|
|
|
})
|
2020-07-28 21:42:32 +00:00
|
|
|
]).then(function (pair) {
|
2019-10-15 10:12:46 +00:00
|
|
|
return {
|
|
|
|
private: pair[0],
|
|
|
|
public: pair[1]
|
|
|
|
};
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
if ('ssh' !== opts.format) {
|
|
|
|
return keypair;
|
|
|
|
}
|
|
|
|
|
|
|
|
return native
|
|
|
|
.import({
|
|
|
|
pem: keypair.public,
|
|
|
|
format: format,
|
|
|
|
public: true
|
|
|
|
})
|
2020-07-28 21:42:32 +00:00
|
|
|
.then(function (jwk) {
|
2019-10-15 10:12:46 +00:00
|
|
|
return EC.export({
|
|
|
|
jwk: jwk,
|
|
|
|
format: opts.format,
|
|
|
|
public: true
|
2020-07-28 21:42:32 +00:00
|
|
|
}).then(function (pub) {
|
2019-10-15 10:12:46 +00:00
|
|
|
return {
|
|
|
|
private: keypair.private,
|
|
|
|
public: pub
|
|
|
|
};
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|