aboutsummaryrefslogtreecommitdiff
path: root/deps/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib
diff options
context:
space:
mode:
Diffstat (limited to 'deps/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib')
-rw-r--r--deps/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/dhe.js103
-rw-r--r--deps/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/formats/openssh-cert.js35
-rw-r--r--deps/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/formats/x509.js29
-rw-r--r--deps/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/identity.js2
-rw-r--r--deps/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/index.js1
-rw-r--r--deps/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/key.js8
-rw-r--r--deps/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/private-key.js26
-rw-r--r--deps/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/signature.js84
8 files changed, 272 insertions, 16 deletions
diff --git a/deps/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/dhe.js b/deps/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/dhe.js
index 8f9548ce57..74f5e04702 100644
--- a/deps/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/dhe.js
+++ b/deps/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/dhe.js
@@ -1,12 +1,17 @@
-// Copyright 2015 Joyent, Inc.
+// Copyright 2017 Joyent, Inc.
-module.exports = DiffieHellman;
+module.exports = {
+ DiffieHellman: DiffieHellman,
+ generateECDSA: generateECDSA,
+ generateED25519: generateED25519
+};
var assert = require('assert-plus');
var crypto = require('crypto');
var algs = require('./algs');
var utils = require('./utils');
var ed;
+var nacl;
var Key = require('./key');
var PrivateKey = require('./private-key');
@@ -309,3 +314,97 @@ ECPrivate.prototype.deriveSharedSecret = function (pubKey) {
var S = pubKey._pub.multiply(this._priv);
return (new Buffer(S.getX().toBigInteger().toByteArray()));
};
+
+function generateED25519() {
+ if (nacl === undefined)
+ nacl = require('tweetnacl');
+
+ var pair = nacl.sign.keyPair();
+ var priv = new Buffer(pair.secretKey);
+ var pub = new Buffer(pair.publicKey);
+ assert.strictEqual(priv.length, 64);
+ assert.strictEqual(pub.length, 32);
+
+ var parts = [];
+ parts.push({name: 'R', data: pub});
+ parts.push({name: 'r', data: priv});
+ var key = new PrivateKey({
+ type: 'ed25519',
+ parts: parts
+ });
+ return (key);
+}
+
+/* Generates a new ECDSA private key on a given curve. */
+function generateECDSA(curve) {
+ var parts = [];
+ var key;
+
+ if (CRYPTO_HAVE_ECDH) {
+ /*
+ * Node crypto doesn't expose key generation directly, but the
+ * ECDH instances can generate keys. It turns out this just
+ * calls into the OpenSSL generic key generator, and we can
+ * read its output happily without doing an actual DH. So we
+ * use that here.
+ */
+ var osCurve = {
+ 'nistp256': 'prime256v1',
+ 'nistp384': 'secp384r1',
+ 'nistp521': 'secp521r1'
+ }[curve];
+
+ var dh = crypto.createECDH(osCurve);
+ dh.generateKeys();
+
+ parts.push({name: 'curve',
+ data: new Buffer(curve)});
+ parts.push({name: 'Q', data: dh.getPublicKey()});
+ parts.push({name: 'd', data: dh.getPrivateKey()});
+
+ key = new PrivateKey({
+ type: 'ecdsa',
+ curve: curve,
+ parts: parts
+ });
+ return (key);
+
+ } else {
+ if (ecdh === undefined)
+ ecdh = require('ecc-jsbn');
+ if (ec === undefined)
+ ec = require('ecc-jsbn/lib/ec');
+ if (jsbn === undefined)
+ jsbn = require('jsbn').BigInteger;
+
+ var ecParams = new X9ECParameters(curve);
+
+ /* This algorithm taken from FIPS PUB 186-4 (section B.4.1) */
+ var n = ecParams.getN();
+ /*
+ * The crypto.randomBytes() function can only give us whole
+ * bytes, so taking a nod from X9.62, we round up.
+ */
+ var cByteLen = Math.ceil((n.bitLength() + 64) / 8);
+ var c = new jsbn(crypto.randomBytes(cByteLen));
+
+ var n1 = n.subtract(jsbn.ONE);
+ var priv = c.mod(n1).add(jsbn.ONE);
+ var pub = ecParams.getG().multiply(priv);
+
+ priv = new Buffer(priv.toByteArray());
+ pub = new Buffer(ecParams.getCurve().
+ encodePointHex(pub), 'hex');
+
+ parts.push({name: 'curve', data: new Buffer(curve)});
+ parts.push({name: 'Q', data: pub});
+ parts.push({name: 'd', data: priv});
+
+ key = new PrivateKey({
+ type: 'ecdsa',
+ curve: curve,
+ parts: parts
+ });
+ return (key);
+ }
+}
diff --git a/deps/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/formats/openssh-cert.js b/deps/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/formats/openssh-cert.js
index 8ce7350fee..b68155e887 100644
--- a/deps/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/formats/openssh-cert.js
+++ b/deps/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/formats/openssh-cert.js
@@ -1,9 +1,10 @@
-// Copyright 2016 Joyent, Inc.
+// Copyright 2017 Joyent, Inc.
module.exports = {
read: read,
verify: verify,
sign: sign,
+ signAsync: signAsync,
write: write,
/* Internal private API */
@@ -188,6 +189,38 @@ function sign(cert, key) {
return (true);
}
+function signAsync(cert, signer, done) {
+ if (cert.signatures.openssh === undefined)
+ cert.signatures.openssh = {};
+ try {
+ var blob = toBuffer(cert, true);
+ } catch (e) {
+ delete (cert.signatures.openssh);
+ done(e);
+ return;
+ }
+ var sig = cert.signatures.openssh;
+
+ signer(blob, function (err, signature) {
+ if (err) {
+ done(err);
+ return;
+ }
+ try {
+ /*
+ * This will throw if the signature isn't of a
+ * type/algo that can be used for SSH.
+ */
+ signature.toBuffer('ssh');
+ } catch (e) {
+ done(e);
+ return;
+ }
+ sig.signature = signature;
+ done();
+ });
+}
+
function write(cert, options) {
if (options === undefined)
options = {};
diff --git a/deps/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/formats/x509.js b/deps/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/formats/x509.js
index c630ce1059..23acd245fb 100644
--- a/deps/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/formats/x509.js
+++ b/deps/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/formats/x509.js
@@ -1,9 +1,10 @@
-// Copyright 2016 Joyent, Inc.
+// Copyright 2017 Joyent, Inc.
module.exports = {
read: read,
verify: verify,
sign: sign,
+ signAsync: signAsync,
write: write
};
@@ -451,6 +452,32 @@ function sign(cert, key) {
return (true);
}
+function signAsync(cert, signer, done) {
+ if (cert.signatures.x509 === undefined)
+ cert.signatures.x509 = {};
+ var sig = cert.signatures.x509;
+
+ var der = new asn1.BerWriter();
+ writeTBSCert(cert, der);
+ var blob = der.buffer;
+ sig.cache = blob;
+
+ signer(blob, function (err, signature) {
+ if (err) {
+ done(err);
+ return;
+ }
+ sig.algo = signature.type + '-' + signature.hashAlgorithm;
+ if (SIGN_ALGS[sig.algo] === undefined) {
+ done(new Error('Invalid signing algorithm "' +
+ sig.algo + '"'));
+ return;
+ }
+ sig.signature = signature;
+ done();
+ });
+}
+
function write(cert, options) {
var sig = cert.signatures.x509;
assert.object(sig, 'x509 signature');
diff --git a/deps/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/identity.js b/deps/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/identity.js
index eeda3a3219..5e9021f8ee 100644
--- a/deps/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/identity.js
+++ b/deps/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/identity.js
@@ -1,4 +1,4 @@
-// Copyright 2016 Joyent, Inc.
+// Copyright 2017 Joyent, Inc.
module.exports = Identity;
diff --git a/deps/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/index.js b/deps/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/index.js
index 96a1384286..cb8cd1a1b8 100644
--- a/deps/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/index.js
+++ b/deps/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/index.js
@@ -18,6 +18,7 @@ module.exports = {
parseSignature: Signature.parse,
PrivateKey: PrivateKey,
parsePrivateKey: PrivateKey.parse,
+ generatePrivateKey: PrivateKey.generate,
Certificate: Certificate,
parseCertificate: Certificate.parse,
createSelfSignedCertificate: Certificate.createSelfSigned,
diff --git a/deps/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/key.js b/deps/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/key.js
index ff5c363733..56b8cb4f05 100644
--- a/deps/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/key.js
+++ b/deps/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/key.js
@@ -1,4 +1,4 @@
-// Copyright 2015 Joyent, Inc.
+// Copyright 2017 Joyent, Inc.
module.exports = Key;
@@ -7,7 +7,7 @@ var algs = require('./algs');
var crypto = require('crypto');
var Fingerprint = require('./fingerprint');
var Signature = require('./signature');
-var DiffieHellman = require('./dhe');
+var DiffieHellman = require('./dhe').DiffieHellman;
var errs = require('./errors');
var utils = require('./utils');
var PrivateKey = require('./private-key');
@@ -171,6 +171,7 @@ Key.prototype.createVerify = function (hashAlgo) {
assert.ok(v, 'failed to create verifier');
var oldVerify = v.verify.bind(v);
var key = this.toBuffer('pkcs8');
+ var curve = this.curve;
var self = this;
v.verify = function (signature, fmt) {
if (Signature.isSignature(signature, [2, 0])) {
@@ -179,6 +180,9 @@ Key.prototype.createVerify = function (hashAlgo) {
if (signature.hashAlgorithm &&
signature.hashAlgorithm !== hashAlgo)
return (false);
+ if (signature.curve && self.type === 'ecdsa' &&
+ signature.curve !== curve)
+ return (false);
return (oldVerify(key, signature.toBuffer('asn1')));
} else if (typeof (signature) === 'string' ||
diff --git a/deps/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/private-key.js b/deps/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/private-key.js
index f80d939662..b56201a189 100644
--- a/deps/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/private-key.js
+++ b/deps/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/private-key.js
@@ -1,4 +1,4 @@
-// Copyright 2015 Joyent, Inc.
+// Copyright 2017 Joyent, Inc.
module.exports = PrivateKey;
@@ -10,6 +10,9 @@ var Signature = require('./signature');
var errs = require('./errors');
var util = require('util');
var utils = require('./utils');
+var dhe = require('./dhe');
+var generateECDSA = dhe.generateECDSA;
+var generateED25519 = dhe.generateED25519;
var edCompat;
var ed;
@@ -163,12 +166,14 @@ PrivateKey.prototype.createSign = function (hashAlgo) {
var oldSign = v.sign.bind(v);
var key = this.toBuffer('pkcs1');
var type = this.type;
+ var curve = this.curve;
v.sign = function () {
var sig = oldSign(key);
if (typeof (sig) === 'string')
sig = new Buffer(sig, 'binary');
sig = Signature.parse(sig, type, 'asn1');
sig.hashAlgorithm = hashAlgo;
+ sig.curve = curve;
return (sig);
};
return (v);
@@ -208,6 +213,25 @@ PrivateKey.isPrivateKey = function (obj, ver) {
return (utils.isCompatible(obj, PrivateKey, ver));
};
+PrivateKey.generate = function (type, options) {
+ if (options === undefined)
+ options = {};
+ assert.object(options, 'options');
+
+ switch (type) {
+ case 'ecdsa':
+ if (options.curve === undefined)
+ options.curve = 'nistp256';
+ assert.string(options.curve, 'options.curve');
+ return (generateECDSA(options.curve));
+ case 'ed25519':
+ return (generateED25519());
+ default:
+ throw (new Error('Key generation not supported with key ' +
+ 'type "' + type + '"'));
+ }
+};
+
/*
* API versions for PrivateKey:
* [1,0] -- initial ver
diff --git a/deps/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/signature.js b/deps/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/signature.js
index 964f55cb56..333bb5d39e 100644
--- a/deps/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/signature.js
+++ b/deps/npm/node_modules/request/node_modules/http-signature/node_modules/sshpk/lib/signature.js
@@ -26,6 +26,7 @@ function Signature(opts) {
this.type = opts.type;
this.hashAlgorithm = opts.hashAlgo;
+ this.curve = opts.curve;
this.parts = opts.parts;
this.part = partLookup;
}
@@ -36,18 +37,45 @@ Signature.prototype.toBuffer = function (format) {
assert.string(format, 'format');
var buf;
+ var stype = 'ssh-' + this.type;
switch (this.type) {
case 'rsa':
+ switch (this.hashAlgorithm) {
+ case 'sha256':
+ stype = 'rsa-sha2-256';
+ break;
+ case 'sha512':
+ stype = 'rsa-sha2-512';
+ break;
+ case 'sha1':
+ case undefined:
+ break;
+ default:
+ throw (new Error('SSH signature ' +
+ 'format does not support hash ' +
+ 'algorithm ' + this.hashAlgorithm));
+ }
+ if (format === 'ssh') {
+ buf = new SSHBuffer({});
+ buf.writeString(stype);
+ buf.writePart(this.part.sig);
+ return (buf.toBuffer());
+ } else {
+ return (this.part.sig.data);
+ }
+ break;
+
case 'ed25519':
if (format === 'ssh') {
buf = new SSHBuffer({});
- buf.writeString('ssh-' + this.type);
+ buf.writeString(stype);
buf.writePart(this.part.sig);
return (buf.toBuffer());
} else {
return (this.part.sig.data);
}
+ break;
case 'dsa':
case 'ecdsa':
@@ -126,11 +154,9 @@ Signature.parse = function (data, type, format) {
assert.ok(data.length > 0, 'signature must not be empty');
switch (opts.type) {
case 'rsa':
- return (parseOneNum(data, type, format, opts,
- 'ssh-rsa'));
+ return (parseOneNum(data, type, format, opts));
case 'ed25519':
- return (parseOneNum(data, type, format, opts,
- 'ssh-ed25519'));
+ return (parseOneNum(data, type, format, opts));
case 'dsa':
case 'ecdsa':
@@ -152,7 +178,7 @@ Signature.parse = function (data, type, format) {
}
};
-function parseOneNum(data, type, format, opts, headType) {
+function parseOneNum(data, type, format, opts) {
if (format === 'ssh') {
try {
var buf = new SSHBuffer({buffer: data});
@@ -160,7 +186,30 @@ function parseOneNum(data, type, format, opts, headType) {
} catch (e) {
/* fall through */
}
- if (head === headType) {
+ if (buf !== undefined) {
+ var msg = 'SSH signature does not match expected ' +
+ 'type (expected ' + type + ', got ' + head + ')';
+ switch (head) {
+ case 'ssh-rsa':
+ assert.strictEqual(type, 'rsa', msg);
+ opts.hashAlgo = 'sha1';
+ break;
+ case 'rsa-sha2-256':
+ assert.strictEqual(type, 'rsa', msg);
+ opts.hashAlgo = 'sha256';
+ break;
+ case 'rsa-sha2-512':
+ assert.strictEqual(type, 'rsa', msg);
+ opts.hashAlgo = 'sha512';
+ break;
+ case 'ssh-ed25519':
+ assert.strictEqual(type, 'ed25519', msg);
+ opts.hashAlgo = 'sha512';
+ break;
+ default:
+ throw (new Error('Unknown SSH signature ' +
+ 'type: ' + head));
+ }
var sig = buf.readPart();
assert.ok(buf.atEnd(), 'extra trailing bytes');
sig.name = 'sig';
@@ -204,7 +253,26 @@ function parseECDSA(data, type, format, opts) {
var r, s;
var inner = buf.readBuffer();
- if (inner.toString('ascii').match(/^ecdsa-/)) {
+ var stype = inner.toString('ascii');
+ if (stype.slice(0, 6) === 'ecdsa-') {
+ var parts = stype.split('-');
+ assert.strictEqual(parts[0], 'ecdsa');
+ assert.strictEqual(parts[1], 'sha2');
+ opts.curve = parts[2];
+ switch (opts.curve) {
+ case 'nistp256':
+ opts.hashAlgo = 'sha256';
+ break;
+ case 'nistp384':
+ opts.hashAlgo = 'sha384';
+ break;
+ case 'nistp521':
+ opts.hashAlgo = 'sha512';
+ break;
+ default:
+ throw (new Error('Unsupported ECDSA curve: ' +
+ opts.curve));
+ }
inner = buf.readBuffer();
assert.ok(buf.atEnd(), 'extra trailing bytes on outer');
buf = new SSHBuffer({buffer: inner});