aboutsummaryrefslogtreecommitdiffstats
path: root/vnfmarket/src/main/webapp/vnfmarket/node_modules/sshpk/lib/formats/ssh-private.js
diff options
context:
space:
mode:
Diffstat (limited to 'vnfmarket/src/main/webapp/vnfmarket/node_modules/sshpk/lib/formats/ssh-private.js')
-rw-r--r--vnfmarket/src/main/webapp/vnfmarket/node_modules/sshpk/lib/formats/ssh-private.js261
1 files changed, 261 insertions, 0 deletions
diff --git a/vnfmarket/src/main/webapp/vnfmarket/node_modules/sshpk/lib/formats/ssh-private.js b/vnfmarket/src/main/webapp/vnfmarket/node_modules/sshpk/lib/formats/ssh-private.js
new file mode 100644
index 00000000..2fcf7199
--- /dev/null
+++ b/vnfmarket/src/main/webapp/vnfmarket/node_modules/sshpk/lib/formats/ssh-private.js
@@ -0,0 +1,261 @@
+// Copyright 2015 Joyent, Inc.
+
+module.exports = {
+ read: read,
+ readSSHPrivate: readSSHPrivate,
+ write: write
+};
+
+var assert = require('assert-plus');
+var asn1 = require('asn1');
+var algs = require('../algs');
+var utils = require('../utils');
+var crypto = require('crypto');
+
+var Key = require('../key');
+var PrivateKey = require('../private-key');
+var pem = require('./pem');
+var rfc4253 = require('./rfc4253');
+var SSHBuffer = require('../ssh-buffer');
+var errors = require('../errors');
+
+var bcrypt;
+
+function read(buf, options) {
+ return (pem.read(buf, options));
+}
+
+var MAGIC = 'openssh-key-v1';
+
+function readSSHPrivate(type, buf, options) {
+ buf = new SSHBuffer({buffer: buf});
+
+ var magic = buf.readCString();
+ assert.strictEqual(magic, MAGIC, 'bad magic string');
+
+ var cipher = buf.readString();
+ var kdf = buf.readString();
+ var kdfOpts = buf.readBuffer();
+
+ var nkeys = buf.readInt();
+ if (nkeys !== 1) {
+ throw (new Error('OpenSSH-format key file contains ' +
+ 'multiple keys: this is unsupported.'));
+ }
+
+ var pubKey = buf.readBuffer();
+
+ if (type === 'public') {
+ assert.ok(buf.atEnd(), 'excess bytes left after key');
+ return (rfc4253.read(pubKey));
+ }
+
+ var privKeyBlob = buf.readBuffer();
+ assert.ok(buf.atEnd(), 'excess bytes left after key');
+
+ var kdfOptsBuf = new SSHBuffer({ buffer: kdfOpts });
+ switch (kdf) {
+ case 'none':
+ if (cipher !== 'none') {
+ throw (new Error('OpenSSH-format key uses KDF "none" ' +
+ 'but specifies a cipher other than "none"'));
+ }
+ break;
+ case 'bcrypt':
+ var salt = kdfOptsBuf.readBuffer();
+ var rounds = kdfOptsBuf.readInt();
+ var cinf = utils.opensshCipherInfo(cipher);
+ if (bcrypt === undefined) {
+ bcrypt = require('bcrypt-pbkdf');
+ }
+
+ if (typeof (options.passphrase) === 'string') {
+ options.passphrase = new Buffer(options.passphrase,
+ 'utf-8');
+ }
+ if (!Buffer.isBuffer(options.passphrase)) {
+ throw (new errors.KeyEncryptedError(
+ options.filename, 'OpenSSH'));
+ }
+
+ var pass = new Uint8Array(options.passphrase);
+ var salti = new Uint8Array(salt);
+ /* Use the pbkdf to derive both the key and the IV. */
+ var out = new Uint8Array(cinf.keySize + cinf.blockSize);
+ var res = bcrypt.pbkdf(pass, pass.length, salti, salti.length,
+ out, out.length, rounds);
+ if (res !== 0) {
+ throw (new Error('bcrypt_pbkdf function returned ' +
+ 'failure, parameters invalid'));
+ }
+ out = new Buffer(out);
+ var ckey = out.slice(0, cinf.keySize);
+ var iv = out.slice(cinf.keySize, cinf.keySize + cinf.blockSize);
+ var cipherStream = crypto.createDecipheriv(cinf.opensslName,
+ ckey, iv);
+ cipherStream.setAutoPadding(false);
+ var chunk, chunks = [];
+ cipherStream.once('error', function (e) {
+ if (e.toString().indexOf('bad decrypt') !== -1) {
+ throw (new Error('Incorrect passphrase ' +
+ 'supplied, could not decrypt key'));
+ }
+ throw (e);
+ });
+ cipherStream.write(privKeyBlob);
+ cipherStream.end();
+ while ((chunk = cipherStream.read()) !== null)
+ chunks.push(chunk);
+ privKeyBlob = Buffer.concat(chunks);
+ break;
+ default:
+ throw (new Error(
+ 'OpenSSH-format key uses unknown KDF "' + kdf + '"'));
+ }
+
+ buf = new SSHBuffer({buffer: privKeyBlob});
+
+ var checkInt1 = buf.readInt();
+ var checkInt2 = buf.readInt();
+ if (checkInt1 !== checkInt2) {
+ throw (new Error('Incorrect passphrase supplied, could not ' +
+ 'decrypt key'));
+ }
+
+ var ret = {};
+ var key = rfc4253.readInternal(ret, 'private', buf.remainder());
+
+ buf.skip(ret.consumed);
+
+ var comment = buf.readString();
+ key.comment = comment;
+
+ return (key);
+}
+
+function write(key, options) {
+ var pubKey;
+ if (PrivateKey.isPrivateKey(key))
+ pubKey = key.toPublic();
+ else
+ pubKey = key;
+
+ var cipher = 'none';
+ var kdf = 'none';
+ var kdfopts = new Buffer(0);
+ var cinf = { blockSize: 8 };
+ var passphrase;
+ if (options !== undefined) {
+ passphrase = options.passphrase;
+ if (typeof (passphrase) === 'string')
+ passphrase = new Buffer(passphrase, 'utf-8');
+ if (passphrase !== undefined) {
+ assert.buffer(passphrase, 'options.passphrase');
+ assert.optionalString(options.cipher, 'options.cipher');
+ cipher = options.cipher;
+ if (cipher === undefined)
+ cipher = 'aes128-ctr';
+ cinf = utils.opensshCipherInfo(cipher);
+ kdf = 'bcrypt';
+ }
+ }
+
+ var privBuf;
+ if (PrivateKey.isPrivateKey(key)) {
+ privBuf = new SSHBuffer({});
+ var checkInt = crypto.randomBytes(4).readUInt32BE(0);
+ privBuf.writeInt(checkInt);
+ privBuf.writeInt(checkInt);
+ privBuf.write(key.toBuffer('rfc4253'));
+ privBuf.writeString(key.comment || '');
+
+ var n = 1;
+ while (privBuf._offset % cinf.blockSize !== 0)
+ privBuf.writeChar(n++);
+ privBuf = privBuf.toBuffer();
+ }
+
+ switch (kdf) {
+ case 'none':
+ break;
+ case 'bcrypt':
+ var salt = crypto.randomBytes(16);
+ var rounds = 16;
+ var kdfssh = new SSHBuffer({});
+ kdfssh.writeBuffer(salt);
+ kdfssh.writeInt(rounds);
+ kdfopts = kdfssh.toBuffer();
+
+ if (bcrypt === undefined) {
+ bcrypt = require('bcrypt-pbkdf');
+ }
+ var pass = new Uint8Array(passphrase);
+ var salti = new Uint8Array(salt);
+ /* Use the pbkdf to derive both the key and the IV. */
+ var out = new Uint8Array(cinf.keySize + cinf.blockSize);
+ var res = bcrypt.pbkdf(pass, pass.length, salti, salti.length,
+ out, out.length, rounds);
+ if (res !== 0) {
+ throw (new Error('bcrypt_pbkdf function returned ' +
+ 'failure, parameters invalid'));
+ }
+ out = new Buffer(out);
+ var ckey = out.slice(0, cinf.keySize);
+ var iv = out.slice(cinf.keySize, cinf.keySize + cinf.blockSize);
+
+ var cipherStream = crypto.createCipheriv(cinf.opensslName,
+ ckey, iv);
+ cipherStream.setAutoPadding(false);
+ var chunk, chunks = [];
+ cipherStream.once('error', function (e) {
+ throw (e);
+ });
+ cipherStream.write(privBuf);
+ cipherStream.end();
+ while ((chunk = cipherStream.read()) !== null)
+ chunks.push(chunk);
+ privBuf = Buffer.concat(chunks);
+ break;
+ default:
+ throw (new Error('Unsupported kdf ' + kdf));
+ }
+
+ var buf = new SSHBuffer({});
+
+ buf.writeCString(MAGIC);
+ buf.writeString(cipher); /* cipher */
+ buf.writeString(kdf); /* kdf */
+ buf.writeBuffer(kdfopts); /* kdfoptions */
+
+ buf.writeInt(1); /* nkeys */
+ buf.writeBuffer(pubKey.toBuffer('rfc4253'));
+
+ if (privBuf)
+ buf.writeBuffer(privBuf);
+
+ buf = buf.toBuffer();
+
+ var header;
+ if (PrivateKey.isPrivateKey(key))
+ header = 'OPENSSH PRIVATE KEY';
+ else
+ header = 'OPENSSH PUBLIC KEY';
+
+ var tmp = buf.toString('base64');
+ var len = tmp.length + (tmp.length / 70) +
+ 18 + 16 + header.length*2 + 10;
+ buf = new Buffer(len);
+ var o = 0;
+ o += buf.write('-----BEGIN ' + header + '-----\n', o);
+ for (var i = 0; i < tmp.length; ) {
+ var limit = i + 70;
+ if (limit > tmp.length)
+ limit = tmp.length;
+ o += buf.write(tmp.slice(i, limit), o);
+ buf[o++] = 10;
+ i = limit;
+ }
+ o += buf.write('-----END ' + header + '-----\n', o);
+
+ return (buf.slice(0, o));
+}