mirror of
https://github.com/mgerb/mywebsite
synced 2026-01-12 02:42:48 +00:00
updated bunch of file paths and changed the way posts are loaded
This commit is contained in:
73
node_modules/sshpk/lib/formats/auto.js
generated
vendored
Normal file
73
node_modules/sshpk/lib/formats/auto.js
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
// Copyright 2015 Joyent, Inc.
|
||||
|
||||
module.exports = {
|
||||
read: read,
|
||||
write: write
|
||||
};
|
||||
|
||||
var assert = require('assert-plus');
|
||||
var utils = require('../utils');
|
||||
var Key = require('../key');
|
||||
var PrivateKey = require('../private-key');
|
||||
|
||||
var pem = require('./pem');
|
||||
var ssh = require('./ssh');
|
||||
var rfc4253 = require('./rfc4253');
|
||||
|
||||
function read(buf) {
|
||||
if (typeof (buf) === 'string') {
|
||||
if (buf.trim().match(/^[-]+[ ]*BEGIN/))
|
||||
return (pem.read(buf));
|
||||
if (buf.match(/^\s*ssh-[a-z]/))
|
||||
return (ssh.read(buf));
|
||||
if (buf.match(/^\s*ecdsa-/))
|
||||
return (ssh.read(buf));
|
||||
buf = new Buffer(buf, 'binary');
|
||||
} else {
|
||||
assert.buffer(buf);
|
||||
if (findPEMHeader(buf))
|
||||
return (pem.read(buf));
|
||||
if (findSSHHeader(buf))
|
||||
return (ssh.read(buf));
|
||||
}
|
||||
if (buf.readUInt32BE(0) < buf.length)
|
||||
return (rfc4253.read(buf));
|
||||
throw (new Error('Failed to auto-detect format of key'));
|
||||
}
|
||||
|
||||
function findSSHHeader(buf) {
|
||||
var offset = 0;
|
||||
while (offset < buf.length &&
|
||||
(buf[offset] === 32 || buf[offset] === 10 || buf[offset] === 9))
|
||||
++offset;
|
||||
if (offset + 4 <= buf.length &&
|
||||
buf.slice(offset, offset + 4).toString('ascii') === 'ssh-')
|
||||
return (true);
|
||||
if (offset + 6 <= buf.length &&
|
||||
buf.slice(offset, offset + 6).toString('ascii') === 'ecdsa-')
|
||||
return (true);
|
||||
return (false);
|
||||
}
|
||||
|
||||
function findPEMHeader(buf) {
|
||||
var offset = 0;
|
||||
while (offset < buf.length &&
|
||||
(buf[offset] === 32 || buf[offset] === 10))
|
||||
++offset;
|
||||
if (buf[offset] !== 45)
|
||||
return (false);
|
||||
while (offset < buf.length &&
|
||||
(buf[offset] === 45))
|
||||
++offset;
|
||||
while (offset < buf.length &&
|
||||
(buf[offset] === 32))
|
||||
++offset;
|
||||
if (offset + 5 > buf.length ||
|
||||
buf.slice(offset, offset + 5).toString('ascii') !== 'BEGIN')
|
||||
return (false);
|
||||
return (true);
|
||||
}
|
||||
|
||||
function write(key) {
|
||||
throw (new Error('"auto" format cannot be used for writing'));
|
||||
}
|
||||
152
node_modules/sshpk/lib/formats/pem.js
generated
vendored
Normal file
152
node_modules/sshpk/lib/formats/pem.js
generated
vendored
Normal file
@@ -0,0 +1,152 @@
|
||||
// Copyright 2015 Joyent, Inc.
|
||||
|
||||
module.exports = {
|
||||
read: read,
|
||||
write: write
|
||||
};
|
||||
|
||||
var assert = require('assert-plus');
|
||||
var asn1 = require('asn1');
|
||||
var algs = require('../algs');
|
||||
var utils = require('../utils');
|
||||
var Key = require('../key');
|
||||
var PrivateKey = require('../private-key');
|
||||
|
||||
var pkcs1 = require('./pkcs1');
|
||||
var pkcs8 = require('./pkcs8');
|
||||
var sshpriv = require('./ssh-private');
|
||||
var rfc4253 = require('./rfc4253');
|
||||
|
||||
/*
|
||||
* For reading we support both PKCS#1 and PKCS#8. If we find a private key,
|
||||
* we just take the public component of it and use that.
|
||||
*/
|
||||
function read(buf, forceType) {
|
||||
var input = buf;
|
||||
if (typeof (buf) !== 'string') {
|
||||
assert.buffer(buf, 'buf');
|
||||
buf = buf.toString('ascii');
|
||||
}
|
||||
|
||||
var lines = buf.trim().split('\n');
|
||||
|
||||
var m = lines[0].match(/*JSSTYLED*/
|
||||
/[-]+[ ]*BEGIN ([A-Z0-9]+ )?(PUBLIC|PRIVATE) KEY[ ]*[-]+/);
|
||||
assert.ok(m, 'invalid PEM header');
|
||||
|
||||
var m2 = lines[lines.length - 1].match(/*JSSTYLED*/
|
||||
/[-]+[ ]*END ([A-Z0-9]+ )?(PUBLIC|PRIVATE) KEY[ ]*[-]+/);
|
||||
assert.ok(m2, 'invalid PEM footer');
|
||||
|
||||
/* Begin and end banners must match key type */
|
||||
assert.equal(m[2], m2[2]);
|
||||
var type = m[2].toLowerCase();
|
||||
|
||||
var alg;
|
||||
if (m[1]) {
|
||||
/* They also must match algorithms, if given */
|
||||
assert.equal(m[1], m2[1], 'PEM header and footer mismatch');
|
||||
alg = m[1].trim();
|
||||
}
|
||||
|
||||
var headers = {};
|
||||
while (true) {
|
||||
lines = lines.slice(1);
|
||||
m = lines[0].match(/*JSSTYLED*/
|
||||
/^([A-Za-z0-9-]+): (.+)$/);
|
||||
if (!m)
|
||||
break;
|
||||
headers[m[1].toLowerCase()] = m[2];
|
||||
}
|
||||
if (headers['proc-type']) {
|
||||
var parts = headers['proc-type'].split(',');
|
||||
if (parts[0] === '4' && parts[1] === 'ENCRYPTED') {
|
||||
throw (new Error('PEM key is encrypted ' +
|
||||
'(password-protected). Please use the ' +
|
||||
'SSH agent or decrypt the key.'));
|
||||
}
|
||||
}
|
||||
|
||||
/* Chop off the first and last lines */
|
||||
lines = lines.slice(0, -1).join('');
|
||||
buf = new Buffer(lines, 'base64');
|
||||
|
||||
/* The new OpenSSH internal format abuses PEM headers */
|
||||
if (alg && alg.toLowerCase() === 'openssh')
|
||||
return (sshpriv.readSSHPrivate(type, buf));
|
||||
if (alg && alg.toLowerCase() === 'ssh2')
|
||||
return (rfc4253.readType(type, buf));
|
||||
|
||||
var der = new asn1.BerReader(buf);
|
||||
der.originalInput = input;
|
||||
|
||||
/*
|
||||
* All of the PEM file types start with a sequence tag, so chop it
|
||||
* off here
|
||||
*/
|
||||
der.readSequence();
|
||||
|
||||
/* PKCS#1 type keys name an algorithm in the banner explicitly */
|
||||
if (alg) {
|
||||
if (forceType)
|
||||
assert.strictEqual(forceType, 'pkcs1');
|
||||
return (pkcs1.readPkcs1(alg, type, der));
|
||||
} else {
|
||||
if (forceType)
|
||||
assert.strictEqual(forceType, 'pkcs8');
|
||||
return (pkcs8.readPkcs8(alg, type, der));
|
||||
}
|
||||
}
|
||||
|
||||
function write(key, type) {
|
||||
assert.object(key);
|
||||
|
||||
var alg = {'ecdsa': 'EC', 'rsa': 'RSA', 'dsa': 'DSA'}[key.type];
|
||||
var header;
|
||||
|
||||
var der = new asn1.BerWriter();
|
||||
|
||||
if (PrivateKey.isPrivateKey(key)) {
|
||||
if (type && type === 'pkcs8') {
|
||||
header = 'PRIVATE KEY';
|
||||
pkcs8.writePkcs8(der, key);
|
||||
} else {
|
||||
if (type)
|
||||
assert.strictEqual(type, 'pkcs1');
|
||||
header = alg + ' PRIVATE KEY';
|
||||
pkcs1.writePkcs1(der, key);
|
||||
}
|
||||
|
||||
} else if (Key.isKey(key)) {
|
||||
if (type && type === 'pkcs1') {
|
||||
header = alg + ' PUBLIC KEY';
|
||||
pkcs1.writePkcs1(der, key);
|
||||
} else {
|
||||
if (type)
|
||||
assert.strictEqual(type, 'pkcs8');
|
||||
header = 'PUBLIC KEY';
|
||||
pkcs8.writePkcs8(der, key);
|
||||
}
|
||||
|
||||
} else {
|
||||
throw (new Error('key is not a Key or PrivateKey'));
|
||||
}
|
||||
|
||||
var tmp = der.buffer.toString('base64');
|
||||
var len = tmp.length + (tmp.length / 64) +
|
||||
18 + 16 + header.length*2 + 10;
|
||||
var buf = new Buffer(len);
|
||||
var o = 0;
|
||||
o += buf.write('-----BEGIN ' + header + '-----\n', o);
|
||||
for (var i = 0; i < tmp.length; ) {
|
||||
var limit = i + 64;
|
||||
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));
|
||||
}
|
||||
320
node_modules/sshpk/lib/formats/pkcs1.js
generated
vendored
Normal file
320
node_modules/sshpk/lib/formats/pkcs1.js
generated
vendored
Normal file
@@ -0,0 +1,320 @@
|
||||
// Copyright 2015 Joyent, Inc.
|
||||
|
||||
module.exports = {
|
||||
read: read,
|
||||
readPkcs1: readPkcs1,
|
||||
write: write,
|
||||
writePkcs1: writePkcs1
|
||||
};
|
||||
|
||||
var assert = require('assert-plus');
|
||||
var asn1 = require('asn1');
|
||||
var algs = require('../algs');
|
||||
var utils = require('../utils');
|
||||
|
||||
var Key = require('../key');
|
||||
var PrivateKey = require('../private-key');
|
||||
var pem = require('./pem');
|
||||
|
||||
var pkcs8 = require('./pkcs8');
|
||||
var readECDSACurve = pkcs8.readECDSACurve;
|
||||
|
||||
function read(buf) {
|
||||
return (pem.read(buf, 'pkcs1'));
|
||||
}
|
||||
|
||||
function write(key) {
|
||||
return (pem.write(key, 'pkcs1'));
|
||||
}
|
||||
|
||||
/* Helper to read in a single mpint */
|
||||
function readMPInt(der, nm) {
|
||||
assert.strictEqual(der.peek(), asn1.Ber.Integer,
|
||||
nm + ' is not an Integer');
|
||||
return (utils.mpNormalize(der.readString(asn1.Ber.Integer, true)));
|
||||
}
|
||||
|
||||
function readPkcs1(alg, type, der) {
|
||||
switch (alg) {
|
||||
case 'RSA':
|
||||
if (type === 'public')
|
||||
return (readPkcs1RSAPublic(der));
|
||||
else if (type === 'private')
|
||||
return (readPkcs1RSAPrivate(der));
|
||||
throw (new Error('Unknown key type: ' + type));
|
||||
case 'DSA':
|
||||
if (type === 'public')
|
||||
return (readPkcs1DSAPublic(der));
|
||||
else if (type === 'private')
|
||||
return (readPkcs1DSAPrivate(der));
|
||||
throw (new Error('Unknown key type: ' + type));
|
||||
case 'EC':
|
||||
case 'ECDSA':
|
||||
if (type === 'private')
|
||||
return (readPkcs1ECDSAPrivate(der));
|
||||
else if (type === 'public')
|
||||
return (readPkcs1ECDSAPublic(der));
|
||||
throw (new Error('Unknown key type: ' + type));
|
||||
default:
|
||||
throw (new Error('Unknown key algo: ' + alg));
|
||||
}
|
||||
}
|
||||
|
||||
function readPkcs1RSAPublic(der) {
|
||||
// modulus and exponent
|
||||
var n = readMPInt(der, 'modulus');
|
||||
var e = readMPInt(der, 'exponent');
|
||||
|
||||
// now, make the key
|
||||
var key = {
|
||||
type: 'rsa',
|
||||
parts: [
|
||||
{ name: 'e', data: e },
|
||||
{ name: 'n', data: n }
|
||||
]
|
||||
};
|
||||
|
||||
return (new Key(key));
|
||||
}
|
||||
|
||||
function readPkcs1RSAPrivate(der) {
|
||||
var version = readMPInt(der, 'version');
|
||||
assert.strictEqual(version[0], 0);
|
||||
|
||||
// modulus then public exponent
|
||||
var n = readMPInt(der, 'modulus');
|
||||
var e = readMPInt(der, 'public exponent');
|
||||
var d = readMPInt(der, 'private exponent');
|
||||
var p = readMPInt(der, 'prime1');
|
||||
var q = readMPInt(der, 'prime2');
|
||||
var dmodp = readMPInt(der, 'exponent1');
|
||||
var dmodq = readMPInt(der, 'exponent2');
|
||||
var iqmp = readMPInt(der, 'iqmp');
|
||||
|
||||
// now, make the key
|
||||
var key = {
|
||||
type: 'rsa',
|
||||
parts: [
|
||||
{ name: 'n', data: n },
|
||||
{ name: 'e', data: e },
|
||||
{ name: 'd', data: d },
|
||||
{ name: 'iqmp', data: iqmp },
|
||||
{ name: 'p', data: p },
|
||||
{ name: 'q', data: q },
|
||||
{ name: 'dmodp', data: dmodp },
|
||||
{ name: 'dmodq', data: dmodq }
|
||||
]
|
||||
};
|
||||
|
||||
return (new PrivateKey(key));
|
||||
}
|
||||
|
||||
function readPkcs1DSAPrivate(der) {
|
||||
var version = readMPInt(der, 'version');
|
||||
assert.strictEqual(version.readUInt8(0), 0);
|
||||
|
||||
var p = readMPInt(der, 'p');
|
||||
var q = readMPInt(der, 'q');
|
||||
var g = readMPInt(der, 'g');
|
||||
var y = readMPInt(der, 'y');
|
||||
var x = readMPInt(der, 'x');
|
||||
|
||||
// now, make the key
|
||||
var key = {
|
||||
type: 'dsa',
|
||||
parts: [
|
||||
{ name: 'p', data: p },
|
||||
{ name: 'q', data: q },
|
||||
{ name: 'g', data: g },
|
||||
{ name: 'y', data: y },
|
||||
{ name: 'x', data: x }
|
||||
]
|
||||
};
|
||||
|
||||
return (new PrivateKey(key));
|
||||
}
|
||||
|
||||
function readPkcs1DSAPublic(der) {
|
||||
var y = readMPInt(der, 'y');
|
||||
var p = readMPInt(der, 'p');
|
||||
var q = readMPInt(der, 'q');
|
||||
var g = readMPInt(der, 'g');
|
||||
|
||||
var key = {
|
||||
type: 'dsa',
|
||||
parts: [
|
||||
{ name: 'y', data: y },
|
||||
{ name: 'p', data: p },
|
||||
{ name: 'q', data: q },
|
||||
{ name: 'g', data: g }
|
||||
]
|
||||
};
|
||||
|
||||
return (new Key(key));
|
||||
}
|
||||
|
||||
function readPkcs1ECDSAPublic(der) {
|
||||
der.readSequence();
|
||||
|
||||
var oid = der.readOID();
|
||||
assert.strictEqual(oid, '1.2.840.10045.2.1', 'must be ecPublicKey');
|
||||
|
||||
var curveOid = der.readOID();
|
||||
|
||||
var curve;
|
||||
var curves = Object.keys(algs.curves);
|
||||
for (var j = 0; j < curves.length; ++j) {
|
||||
var c = curves[j];
|
||||
var cd = algs.curves[c];
|
||||
if (cd.pkcs8oid === curveOid) {
|
||||
curve = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert.string(curve, 'a known ECDSA named curve');
|
||||
|
||||
var Q = der.readString(asn1.Ber.BitString, true);
|
||||
Q = utils.ecNormalize(Q);
|
||||
|
||||
var key = {
|
||||
type: 'ecdsa',
|
||||
parts: [
|
||||
{ name: 'curve', data: new Buffer(curve) },
|
||||
{ name: 'Q', data: Q }
|
||||
]
|
||||
};
|
||||
|
||||
return (new Key(key));
|
||||
}
|
||||
|
||||
function readPkcs1ECDSAPrivate(der) {
|
||||
var version = readMPInt(der, 'version');
|
||||
assert.strictEqual(version.readUInt8(0), 1);
|
||||
|
||||
// private key
|
||||
var d = der.readString(asn1.Ber.OctetString, true);
|
||||
|
||||
der.readSequence(0xa0);
|
||||
var curve = readECDSACurve(der);
|
||||
assert.string(curve, 'a known elliptic curve');
|
||||
|
||||
der.readSequence(0xa1);
|
||||
var Q = der.readString(asn1.Ber.BitString, true);
|
||||
Q = utils.ecNormalize(Q);
|
||||
|
||||
var key = {
|
||||
type: 'ecdsa',
|
||||
parts: [
|
||||
{ name: 'curve', data: new Buffer(curve) },
|
||||
{ name: 'Q', data: Q },
|
||||
{ name: 'd', data: d }
|
||||
]
|
||||
};
|
||||
|
||||
return (new PrivateKey(key));
|
||||
}
|
||||
|
||||
function writePkcs1(der, key) {
|
||||
der.startSequence();
|
||||
|
||||
switch (key.type) {
|
||||
case 'rsa':
|
||||
if (PrivateKey.isPrivateKey(key))
|
||||
writePkcs1RSAPrivate(der, key);
|
||||
else
|
||||
writePkcs1RSAPublic(der, key);
|
||||
break;
|
||||
case 'dsa':
|
||||
if (PrivateKey.isPrivateKey(key))
|
||||
writePkcs1DSAPrivate(der, key);
|
||||
else
|
||||
writePkcs1DSAPublic(der, key);
|
||||
break;
|
||||
case 'ecdsa':
|
||||
if (PrivateKey.isPrivateKey(key))
|
||||
writePkcs1ECDSAPrivate(der, key);
|
||||
else
|
||||
writePkcs1ECDSAPublic(der, key);
|
||||
break;
|
||||
default:
|
||||
throw (new Error('Unknown key algo: ' + key.type));
|
||||
}
|
||||
|
||||
der.endSequence();
|
||||
}
|
||||
|
||||
function writePkcs1RSAPublic(der, key) {
|
||||
der.writeBuffer(key.part.n.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.e.data, asn1.Ber.Integer);
|
||||
}
|
||||
|
||||
function writePkcs1RSAPrivate(der, key) {
|
||||
var ver = new Buffer(1);
|
||||
ver[0] = 0;
|
||||
der.writeBuffer(ver, asn1.Ber.Integer);
|
||||
|
||||
der.writeBuffer(key.part.n.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.e.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.d.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.p.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.q.data, asn1.Ber.Integer);
|
||||
if (!key.part.dmodp || !key.part.dmodq)
|
||||
utils.addRSAMissing(key);
|
||||
der.writeBuffer(key.part.dmodp.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.dmodq.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.iqmp.data, asn1.Ber.Integer);
|
||||
}
|
||||
|
||||
function writePkcs1DSAPrivate(der, key) {
|
||||
var ver = new Buffer(1);
|
||||
ver[0] = 0;
|
||||
der.writeBuffer(ver, asn1.Ber.Integer);
|
||||
|
||||
der.writeBuffer(key.part.p.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.q.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.g.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.y.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.x.data, asn1.Ber.Integer);
|
||||
}
|
||||
|
||||
function writePkcs1DSAPublic(der, key) {
|
||||
der.writeBuffer(key.part.y.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.p.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.q.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.g.data, asn1.Ber.Integer);
|
||||
}
|
||||
|
||||
function writePkcs1ECDSAPublic(der, key) {
|
||||
der.startSequence();
|
||||
|
||||
der.writeOID('1.2.840.10045.2.1'); /* ecPublicKey */
|
||||
var curve = key.part.curve.data.toString();
|
||||
var curveOid = algs.curves[curve].pkcs8oid;
|
||||
assert.string(curveOid, 'a known ECDSA named curve');
|
||||
der.writeOID(curveOid);
|
||||
|
||||
der.endSequence();
|
||||
|
||||
var Q = utils.ecNormalize(key.part.Q.data, true);
|
||||
der.writeBuffer(Q, asn1.Ber.BitString);
|
||||
}
|
||||
|
||||
function writePkcs1ECDSAPrivate(der, key) {
|
||||
var ver = new Buffer(1);
|
||||
ver[0] = 1;
|
||||
der.writeBuffer(ver, asn1.Ber.Integer);
|
||||
|
||||
der.writeBuffer(key.part.d.data, asn1.Ber.OctetString);
|
||||
|
||||
der.startSequence(0xa0);
|
||||
var curve = key.part.curve.data.toString();
|
||||
var curveOid = algs.curves[curve].pkcs8oid;
|
||||
assert.string(curveOid, 'a known ECDSA named curve');
|
||||
der.writeOID(curveOid);
|
||||
der.endSequence();
|
||||
|
||||
der.startSequence(0xa1);
|
||||
var Q = utils.ecNormalize(key.part.Q.data, true);
|
||||
der.writeBuffer(Q, asn1.Ber.BitString);
|
||||
der.endSequence();
|
||||
}
|
||||
510
node_modules/sshpk/lib/formats/pkcs8.js
generated
vendored
Normal file
510
node_modules/sshpk/lib/formats/pkcs8.js
generated
vendored
Normal file
@@ -0,0 +1,510 @@
|
||||
// Copyright 2015 Joyent, Inc.
|
||||
|
||||
module.exports = {
|
||||
read: read,
|
||||
readPkcs8: readPkcs8,
|
||||
write: write,
|
||||
writePkcs8: writePkcs8,
|
||||
|
||||
readECDSACurve: readECDSACurve,
|
||||
writeECDSACurve: writeECDSACurve
|
||||
};
|
||||
|
||||
var assert = require('assert-plus');
|
||||
var asn1 = require('asn1');
|
||||
var algs = require('../algs');
|
||||
var utils = require('../utils');
|
||||
var Key = require('../key');
|
||||
var PrivateKey = require('../private-key');
|
||||
var pem = require('./pem');
|
||||
|
||||
function read(buf) {
|
||||
return (pem.read(buf, 'pkcs8'));
|
||||
}
|
||||
|
||||
function write(key) {
|
||||
return (pem.write(key, 'pkcs8'));
|
||||
}
|
||||
|
||||
/* Helper to read in a single mpint */
|
||||
function readMPInt(der, nm) {
|
||||
assert.strictEqual(der.peek(), asn1.Ber.Integer,
|
||||
nm + ' is not an Integer');
|
||||
return (utils.mpNormalize(der.readString(asn1.Ber.Integer, true)));
|
||||
}
|
||||
|
||||
function readPkcs8(alg, type, der) {
|
||||
/* Private keys in pkcs#8 format have a weird extra int */
|
||||
if (der.peek() === asn1.Ber.Integer) {
|
||||
assert.strictEqual(type, 'private',
|
||||
'unexpected Integer at start of public key');
|
||||
der.readString(asn1.Ber.Integer, true);
|
||||
}
|
||||
|
||||
der.readSequence();
|
||||
|
||||
var oid = der.readOID();
|
||||
switch (oid) {
|
||||
case '1.2.840.113549.1.1.1':
|
||||
if (type === 'public')
|
||||
return (readPkcs8RSAPublic(der));
|
||||
else
|
||||
return (readPkcs8RSAPrivate(der));
|
||||
case '1.2.840.10040.4.1':
|
||||
if (type === 'public')
|
||||
return (readPkcs8DSAPublic(der));
|
||||
else
|
||||
return (readPkcs8DSAPrivate(der));
|
||||
case '1.2.840.10045.2.1':
|
||||
if (type === 'public')
|
||||
return (readPkcs8ECDSAPublic(der));
|
||||
else
|
||||
return (readPkcs8ECDSAPrivate(der));
|
||||
default:
|
||||
throw (new Error('Unknown key type OID ' + oid));
|
||||
}
|
||||
}
|
||||
|
||||
function readPkcs8RSAPublic(der) {
|
||||
// Null -- XXX this probably isn't good practice
|
||||
der.readByte();
|
||||
der.readByte();
|
||||
|
||||
// bit string sequence
|
||||
der.readSequence(asn1.Ber.BitString);
|
||||
der.readByte();
|
||||
der.readSequence();
|
||||
|
||||
// modulus
|
||||
var n = readMPInt(der, 'modulus');
|
||||
var e = readMPInt(der, 'exponent');
|
||||
|
||||
// now, make the key
|
||||
var key = {
|
||||
type: 'rsa',
|
||||
source: der.originalInput,
|
||||
parts: [
|
||||
{ name: 'e', data: e },
|
||||
{ name: 'n', data: n }
|
||||
]
|
||||
};
|
||||
|
||||
return (new Key(key));
|
||||
}
|
||||
|
||||
function readPkcs8RSAPrivate(der) {
|
||||
der.readByte();
|
||||
der.readByte();
|
||||
|
||||
der.readSequence(asn1.Ber.OctetString);
|
||||
der.readSequence();
|
||||
|
||||
var ver = readMPInt(der, 'version');
|
||||
assert.equal(ver[0], 0x0, 'unknown RSA private key version');
|
||||
|
||||
// modulus then public exponent
|
||||
var n = readMPInt(der, 'modulus');
|
||||
var e = readMPInt(der, 'public exponent');
|
||||
var d = readMPInt(der, 'private exponent');
|
||||
var p = readMPInt(der, 'prime1');
|
||||
var q = readMPInt(der, 'prime2');
|
||||
var dmodp = readMPInt(der, 'exponent1');
|
||||
var dmodq = readMPInt(der, 'exponent2');
|
||||
var iqmp = readMPInt(der, 'iqmp');
|
||||
|
||||
// now, make the key
|
||||
var key = {
|
||||
type: 'rsa',
|
||||
parts: [
|
||||
{ name: 'n', data: n },
|
||||
{ name: 'e', data: e },
|
||||
{ name: 'd', data: d },
|
||||
{ name: 'iqmp', data: iqmp },
|
||||
{ name: 'p', data: p },
|
||||
{ name: 'q', data: q },
|
||||
{ name: 'dmodp', data: dmodp },
|
||||
{ name: 'dmodq', data: dmodq }
|
||||
]
|
||||
};
|
||||
|
||||
return (new PrivateKey(key));
|
||||
}
|
||||
|
||||
function readPkcs8DSAPublic(der) {
|
||||
der.readSequence();
|
||||
|
||||
var p = readMPInt(der, 'p');
|
||||
var q = readMPInt(der, 'q');
|
||||
var g = readMPInt(der, 'g');
|
||||
|
||||
// bit string sequence
|
||||
der.readSequence(asn1.Ber.BitString);
|
||||
der.readByte();
|
||||
|
||||
var y = readMPInt(der, 'y');
|
||||
|
||||
// now, make the key
|
||||
var key = {
|
||||
type: 'dsa',
|
||||
parts: [
|
||||
{ name: 'p', data: p },
|
||||
{ name: 'q', data: q },
|
||||
{ name: 'g', data: g },
|
||||
{ name: 'y', data: y }
|
||||
]
|
||||
};
|
||||
|
||||
return (new Key(key));
|
||||
}
|
||||
|
||||
function readPkcs8DSAPrivate(der) {
|
||||
der.readSequence();
|
||||
|
||||
var p = readMPInt(der, 'p');
|
||||
var q = readMPInt(der, 'q');
|
||||
var g = readMPInt(der, 'g');
|
||||
|
||||
der.readSequence(asn1.Ber.OctetString);
|
||||
var x = readMPInt(der, 'x');
|
||||
|
||||
/* The pkcs#8 format does not include the public key */
|
||||
var y = utils.calculateDSAPublic(g, p, x);
|
||||
|
||||
var key = {
|
||||
type: 'dsa',
|
||||
parts: [
|
||||
{ name: 'p', data: p },
|
||||
{ name: 'q', data: q },
|
||||
{ name: 'g', data: g },
|
||||
{ name: 'y', data: y },
|
||||
{ name: 'x', data: x }
|
||||
]
|
||||
};
|
||||
|
||||
return (new PrivateKey(key));
|
||||
}
|
||||
|
||||
function readECDSACurve(der) {
|
||||
var curveName, curveNames;
|
||||
var j, c, cd;
|
||||
|
||||
if (der.peek() === asn1.Ber.OID) {
|
||||
var oid = der.readOID();
|
||||
|
||||
curveNames = Object.keys(algs.curves);
|
||||
for (j = 0; j < curveNames.length; ++j) {
|
||||
c = curveNames[j];
|
||||
cd = algs.curves[c];
|
||||
if (cd.pkcs8oid === oid) {
|
||||
curveName = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// ECParameters sequence
|
||||
der.readSequence();
|
||||
var version = der.readString(asn1.Ber.Integer, true);
|
||||
assert.strictEqual(version[0], 1, 'ECDSA key not version 1');
|
||||
|
||||
var curve = {};
|
||||
|
||||
// FieldID sequence
|
||||
der.readSequence();
|
||||
var fieldTypeOid = der.readOID();
|
||||
assert.strictEqual(fieldTypeOid, '1.2.840.10045.1.1',
|
||||
'ECDSA key is not from a prime-field');
|
||||
var p = curve.p = utils.mpNormalize(
|
||||
der.readString(asn1.Ber.Integer, true));
|
||||
/*
|
||||
* p always starts with a 1 bit, so count the zeros to get its
|
||||
* real size.
|
||||
*/
|
||||
curve.size = p.length * 8 - utils.countZeros(p);
|
||||
|
||||
// Curve sequence
|
||||
der.readSequence();
|
||||
curve.a = utils.mpNormalize(
|
||||
der.readString(asn1.Ber.OctetString, true));
|
||||
curve.b = utils.mpNormalize(
|
||||
der.readString(asn1.Ber.OctetString, true));
|
||||
if (der.peek() === asn1.Ber.BitString)
|
||||
curve.s = der.readString(asn1.Ber.BitString, true);
|
||||
|
||||
// Combined Gx and Gy
|
||||
curve.G = der.readString(asn1.Ber.OctetString, true);
|
||||
assert.strictEqual(curve.G[0], 0x4,
|
||||
'uncompressed G is required');
|
||||
|
||||
curve.n = utils.mpNormalize(
|
||||
der.readString(asn1.Ber.Integer, true));
|
||||
curve.h = utils.mpNormalize(
|
||||
der.readString(asn1.Ber.Integer, true));
|
||||
assert.strictEqual(curve.h[0], 0x1, 'a cofactor=1 curve is ' +
|
||||
'required');
|
||||
|
||||
curveNames = Object.keys(algs.curves);
|
||||
var ks = Object.keys(curve);
|
||||
for (j = 0; j < curveNames.length; ++j) {
|
||||
c = curveNames[j];
|
||||
cd = algs.curves[c];
|
||||
var equal = true;
|
||||
for (var i = 0; i < ks.length; ++i) {
|
||||
var k = ks[i];
|
||||
if (cd[k] === undefined)
|
||||
continue;
|
||||
if (typeof (cd[k]) === 'object' &&
|
||||
cd[k].equals !== undefined) {
|
||||
if (!cd[k].equals(curve[k])) {
|
||||
equal = false;
|
||||
break;
|
||||
}
|
||||
} else if (Buffer.isBuffer(cd[k])) {
|
||||
if (cd[k].toString('binary')
|
||||
!== curve[k].toString('binary')) {
|
||||
equal = false;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (cd[k] !== curve[k]) {
|
||||
equal = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (equal) {
|
||||
curveName = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (curveName);
|
||||
}
|
||||
|
||||
function readPkcs8ECDSAPrivate(der) {
|
||||
var curveName = readECDSACurve(der);
|
||||
assert.string(curveName, 'a known elliptic curve');
|
||||
|
||||
der.readSequence(asn1.Ber.OctetString);
|
||||
der.readSequence();
|
||||
|
||||
var version = readMPInt(der, 'version');
|
||||
assert.equal(version[0], 1, 'unknown version of ECDSA key');
|
||||
|
||||
var d = der.readString(asn1.Ber.OctetString, true);
|
||||
der.readSequence(0xa1);
|
||||
|
||||
var Q = der.readString(asn1.Ber.BitString, true);
|
||||
Q = utils.ecNormalize(Q);
|
||||
|
||||
var key = {
|
||||
type: 'ecdsa',
|
||||
parts: [
|
||||
{ name: 'curve', data: new Buffer(curveName) },
|
||||
{ name: 'Q', data: Q },
|
||||
{ name: 'd', data: d }
|
||||
]
|
||||
};
|
||||
|
||||
return (new PrivateKey(key));
|
||||
}
|
||||
|
||||
function readPkcs8ECDSAPublic(der) {
|
||||
var curveName = readECDSACurve(der);
|
||||
assert.string(curveName, 'a known elliptic curve');
|
||||
|
||||
var Q = der.readString(asn1.Ber.BitString, true);
|
||||
Q = utils.ecNormalize(Q);
|
||||
|
||||
var key = {
|
||||
type: 'ecdsa',
|
||||
parts: [
|
||||
{ name: 'curve', data: new Buffer(curveName) },
|
||||
{ name: 'Q', data: Q }
|
||||
]
|
||||
};
|
||||
|
||||
return (new Key(key));
|
||||
}
|
||||
|
||||
function writePkcs8(der, key) {
|
||||
der.startSequence();
|
||||
|
||||
if (PrivateKey.isPrivateKey(key)) {
|
||||
var sillyInt = new Buffer(1);
|
||||
sillyInt[0] = 0x0;
|
||||
der.writeBuffer(sillyInt, asn1.Ber.Integer);
|
||||
}
|
||||
|
||||
der.startSequence();
|
||||
switch (key.type) {
|
||||
case 'rsa':
|
||||
der.writeOID('1.2.840.113549.1.1.1');
|
||||
if (PrivateKey.isPrivateKey(key))
|
||||
writePkcs8RSAPrivate(key, der);
|
||||
else
|
||||
writePkcs8RSAPublic(key, der);
|
||||
break;
|
||||
case 'dsa':
|
||||
der.writeOID('1.2.840.10040.4.1');
|
||||
if (PrivateKey.isPrivateKey(key))
|
||||
writePkcs8DSAPrivate(key, der);
|
||||
else
|
||||
writePkcs8DSAPublic(key, der);
|
||||
break;
|
||||
case 'ecdsa':
|
||||
der.writeOID('1.2.840.10045.2.1');
|
||||
if (PrivateKey.isPrivateKey(key))
|
||||
writePkcs8ECDSAPrivate(key, der);
|
||||
else
|
||||
writePkcs8ECDSAPublic(key, der);
|
||||
break;
|
||||
default:
|
||||
throw (new Error('Unsupported key type: ' + key.type));
|
||||
}
|
||||
|
||||
der.endSequence();
|
||||
}
|
||||
|
||||
function writePkcs8RSAPrivate(key, der) {
|
||||
der.writeNull();
|
||||
der.endSequence();
|
||||
|
||||
der.startSequence(asn1.Ber.OctetString);
|
||||
der.startSequence();
|
||||
|
||||
var version = new Buffer(1);
|
||||
version[0] = 0;
|
||||
der.writeBuffer(version, asn1.Ber.Integer);
|
||||
|
||||
der.writeBuffer(key.part.n.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.e.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.d.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.p.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.q.data, asn1.Ber.Integer);
|
||||
if (!key.part.dmodp || !key.part.dmodq)
|
||||
utils.addRSAMissing(key);
|
||||
der.writeBuffer(key.part.dmodp.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.dmodq.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.iqmp.data, asn1.Ber.Integer);
|
||||
|
||||
der.endSequence();
|
||||
der.endSequence();
|
||||
}
|
||||
|
||||
function writePkcs8RSAPublic(key, der) {
|
||||
der.writeNull();
|
||||
der.endSequence();
|
||||
|
||||
der.startSequence(asn1.Ber.BitString);
|
||||
der.writeByte(0x00);
|
||||
|
||||
der.startSequence();
|
||||
der.writeBuffer(key.part.n.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.e.data, asn1.Ber.Integer);
|
||||
der.endSequence();
|
||||
|
||||
der.endSequence();
|
||||
}
|
||||
|
||||
function writePkcs8DSAPrivate(key, der) {
|
||||
der.startSequence();
|
||||
der.writeBuffer(key.part.p.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.q.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.g.data, asn1.Ber.Integer);
|
||||
der.endSequence();
|
||||
|
||||
der.endSequence();
|
||||
|
||||
der.startSequence(asn1.Ber.OctetString);
|
||||
der.writeBuffer(key.part.x.data, asn1.Ber.Integer);
|
||||
der.endSequence();
|
||||
}
|
||||
|
||||
function writePkcs8DSAPublic(key, der) {
|
||||
der.startSequence();
|
||||
der.writeBuffer(key.part.p.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.q.data, asn1.Ber.Integer);
|
||||
der.writeBuffer(key.part.g.data, asn1.Ber.Integer);
|
||||
der.endSequence();
|
||||
der.endSequence();
|
||||
|
||||
der.startSequence(asn1.Ber.BitString);
|
||||
der.writeByte(0x00);
|
||||
der.writeBuffer(key.part.y.data, asn1.Ber.Integer);
|
||||
der.endSequence();
|
||||
}
|
||||
|
||||
function writeECDSACurve(key, der) {
|
||||
var curve = algs.curves[key.curve];
|
||||
if (curve.pkcs8oid) {
|
||||
/* This one has a name in pkcs#8, so just write the oid */
|
||||
der.writeOID(curve.pkcs8oid);
|
||||
|
||||
} else {
|
||||
// ECParameters sequence
|
||||
der.startSequence();
|
||||
|
||||
var version = new Buffer(1);
|
||||
version.writeUInt8(1, 0);
|
||||
der.writeBuffer(version, asn1.Ber.Integer);
|
||||
|
||||
// FieldID sequence
|
||||
der.startSequence();
|
||||
der.writeOID('1.2.840.10045.1.1'); // prime-field
|
||||
der.writeBuffer(curve.p, asn1.Ber.Integer);
|
||||
der.endSequence();
|
||||
|
||||
// Curve sequence
|
||||
der.startSequence();
|
||||
var a = curve.p;
|
||||
if (a[0] === 0x0)
|
||||
a = a.slice(1);
|
||||
der.writeBuffer(a, asn1.Ber.OctetString);
|
||||
der.writeBuffer(curve.b, asn1.Ber.OctetString);
|
||||
der.writeBuffer(curve.s, asn1.Ber.BitString);
|
||||
der.endSequence();
|
||||
|
||||
der.writeBuffer(curve.G, asn1.Ber.OctetString);
|
||||
der.writeBuffer(curve.n, asn1.Ber.Integer);
|
||||
var h = curve.h;
|
||||
if (!h) {
|
||||
h = new Buffer(1);
|
||||
h[0] = 1;
|
||||
}
|
||||
der.writeBuffer(h, asn1.Ber.Integer);
|
||||
|
||||
// ECParameters
|
||||
der.endSequence();
|
||||
}
|
||||
}
|
||||
|
||||
function writePkcs8ECDSAPublic(key, der) {
|
||||
writeECDSACurve(key, der);
|
||||
der.endSequence();
|
||||
|
||||
var Q = utils.ecNormalize(key.part.Q.data, true);
|
||||
der.writeBuffer(Q, asn1.Ber.BitString);
|
||||
}
|
||||
|
||||
function writePkcs8ECDSAPrivate(key, der) {
|
||||
writeECDSACurve(key, der);
|
||||
der.endSequence();
|
||||
|
||||
der.startSequence(asn1.Ber.OctetString);
|
||||
der.startSequence();
|
||||
|
||||
var version = new Buffer(1);
|
||||
version[0] = 1;
|
||||
der.writeBuffer(version, asn1.Ber.Integer);
|
||||
|
||||
der.writeBuffer(key.part.d.data, asn1.Ber.OctetString);
|
||||
|
||||
der.startSequence(0xa1);
|
||||
var Q = utils.ecNormalize(key.part.Q.data, true);
|
||||
der.writeBuffer(Q, asn1.Ber.BitString);
|
||||
der.endSequence();
|
||||
|
||||
der.endSequence();
|
||||
der.endSequence();
|
||||
}
|
||||
145
node_modules/sshpk/lib/formats/rfc4253.js
generated
vendored
Normal file
145
node_modules/sshpk/lib/formats/rfc4253.js
generated
vendored
Normal file
@@ -0,0 +1,145 @@
|
||||
// Copyright 2015 Joyent, Inc.
|
||||
|
||||
module.exports = {
|
||||
read: read.bind(undefined, false, undefined),
|
||||
readType: read.bind(undefined, false),
|
||||
write: write,
|
||||
/* semi-private api, used by sshpk-agent */
|
||||
readPartial: read.bind(undefined, true),
|
||||
|
||||
/* shared with ssh format */
|
||||
readInternal: read,
|
||||
keyTypeToAlg: keyTypeToAlg,
|
||||
algToKeyType: algToKeyType
|
||||
};
|
||||
|
||||
var assert = require('assert-plus');
|
||||
var algs = require('../algs');
|
||||
var utils = require('../utils');
|
||||
var Key = require('../key');
|
||||
var PrivateKey = require('../private-key');
|
||||
var SSHBuffer = require('../ssh-buffer');
|
||||
|
||||
function algToKeyType(alg) {
|
||||
assert.string(alg);
|
||||
if (alg === 'ssh-dss')
|
||||
return ('dsa');
|
||||
else if (alg === 'ssh-rsa')
|
||||
return ('rsa');
|
||||
else if (alg === 'ssh-ed25519')
|
||||
return ('ed25519');
|
||||
else if (alg === 'ssh-curve25519')
|
||||
return ('curve25519');
|
||||
else if (alg.match(/^ecdsa-sha2-/))
|
||||
return ('ecdsa');
|
||||
else
|
||||
throw (new Error('Unknown algorithm ' + alg));
|
||||
}
|
||||
|
||||
function keyTypeToAlg(key) {
|
||||
assert.object(key);
|
||||
if (key.type === 'dsa')
|
||||
return ('ssh-dss');
|
||||
else if (key.type === 'rsa')
|
||||
return ('ssh-rsa');
|
||||
else if (key.type === 'ed25519')
|
||||
return ('ssh-ed25519');
|
||||
else if (key.type === 'curve25519')
|
||||
return ('ssh-curve25519');
|
||||
else if (key.type === 'ecdsa')
|
||||
return ('ecdsa-sha2-' + key.part.curve.data.toString());
|
||||
else
|
||||
throw (new Error('Unknown key type ' + key.type));
|
||||
}
|
||||
|
||||
function read(partial, type, buf) {
|
||||
if (typeof (buf) === 'string')
|
||||
buf = new Buffer(buf);
|
||||
assert.buffer(buf, 'buf');
|
||||
|
||||
var key = {};
|
||||
|
||||
var parts = key.parts = [];
|
||||
var sshbuf = new SSHBuffer({buffer: buf});
|
||||
|
||||
var alg = sshbuf.readString();
|
||||
assert.ok(!sshbuf.atEnd(), 'key must have at least one part');
|
||||
|
||||
key.type = algToKeyType(alg);
|
||||
|
||||
var partCount = algs.info[key.type].parts.length;
|
||||
if (type && type === 'private')
|
||||
partCount = algs.privInfo[key.type].parts.length;
|
||||
|
||||
while (!sshbuf.atEnd() && parts.length < partCount)
|
||||
parts.push(sshbuf.readPart());
|
||||
while (!partial && !sshbuf.atEnd())
|
||||
parts.push(sshbuf.readPart());
|
||||
|
||||
assert.ok(parts.length >= 1,
|
||||
'key must have at least one part');
|
||||
assert.ok(partial || sshbuf.atEnd(),
|
||||
'leftover bytes at end of key');
|
||||
|
||||
var Constructor = Key;
|
||||
var algInfo = algs.info[key.type];
|
||||
if (type === 'private' || algInfo.parts.length !== parts.length) {
|
||||
algInfo = algs.privInfo[key.type];
|
||||
Constructor = PrivateKey;
|
||||
}
|
||||
assert.strictEqual(algInfo.parts.length, parts.length);
|
||||
|
||||
if (key.type === 'ecdsa') {
|
||||
var res = /^ecdsa-sha2-(.+)$/.exec(alg);
|
||||
assert.ok(res !== null);
|
||||
assert.strictEqual(res[1], parts[0].data.toString());
|
||||
}
|
||||
|
||||
var normalized = true;
|
||||
for (var i = 0; i < algInfo.parts.length; ++i) {
|
||||
parts[i].name = algInfo.parts[i];
|
||||
if (parts[i].name !== 'curve' &&
|
||||
algInfo.normalize !== false) {
|
||||
var p = parts[i];
|
||||
var nd = utils.mpNormalize(p.data);
|
||||
if (nd !== p.data) {
|
||||
p.data = nd;
|
||||
normalized = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (normalized)
|
||||
key._rfc4253Cache = sshbuf.toBuffer();
|
||||
|
||||
if (partial && typeof (partial) === 'object') {
|
||||
partial.remainder = sshbuf.remainder();
|
||||
partial.consumed = sshbuf._offset;
|
||||
}
|
||||
|
||||
return (new Constructor(key));
|
||||
}
|
||||
|
||||
function write(key) {
|
||||
assert.object(key);
|
||||
|
||||
var alg = keyTypeToAlg(key);
|
||||
var i;
|
||||
|
||||
var algInfo = algs.info[key.type];
|
||||
if (PrivateKey.isPrivateKey(key))
|
||||
algInfo = algs.privInfo[key.type];
|
||||
var parts = algInfo.parts;
|
||||
|
||||
var buf = new SSHBuffer({});
|
||||
|
||||
buf.writeString(alg);
|
||||
|
||||
for (i = 0; i < parts.length; ++i) {
|
||||
var data = key.part[parts[i]].data;
|
||||
data = utils.mpNormalize(data);
|
||||
buf.writeBuffer(data);
|
||||
}
|
||||
|
||||
return (buf.toBuffer());
|
||||
}
|
||||
138
node_modules/sshpk/lib/formats/ssh-private.js
generated
vendored
Normal file
138
node_modules/sshpk/lib/formats/ssh-private.js
generated
vendored
Normal file
@@ -0,0 +1,138 @@
|
||||
// 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');
|
||||
|
||||
function read(buf) {
|
||||
return (pem.read(buf));
|
||||
}
|
||||
|
||||
var MAGIC = 'openssh-key-v1';
|
||||
|
||||
function readSSHPrivate(type, buf) {
|
||||
buf = new SSHBuffer({buffer: buf});
|
||||
|
||||
var magic = buf.readCString();
|
||||
assert.strictEqual(magic, MAGIC, 'bad magic string');
|
||||
|
||||
var cipher = buf.readString();
|
||||
var kdf = buf.readString();
|
||||
|
||||
/* We only support unencrypted keys. */
|
||||
if (cipher !== 'none' || kdf !== 'none') {
|
||||
throw (new Error('OpenSSH-format key is encrypted ' +
|
||||
'(password-protected). Please use the SSH agent ' +
|
||||
'or decrypt the key.'));
|
||||
}
|
||||
|
||||
/* Skip over kdfoptions. */
|
||||
buf.readString();
|
||||
|
||||
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');
|
||||
|
||||
buf = new SSHBuffer({buffer: privKeyBlob});
|
||||
|
||||
var checkInt1 = buf.readInt();
|
||||
var checkInt2 = buf.readInt();
|
||||
assert.strictEqual(checkInt1, checkInt2, 'checkints do not match');
|
||||
|
||||
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) {
|
||||
var pubKey;
|
||||
if (PrivateKey.isPrivateKey(key))
|
||||
pubKey = key.toPublic();
|
||||
else
|
||||
pubKey = key;
|
||||
|
||||
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 % 8 !== 0)
|
||||
privBuf.writeChar(n++);
|
||||
}
|
||||
|
||||
var buf = new SSHBuffer({});
|
||||
|
||||
buf.writeCString(MAGIC);
|
||||
buf.writeString('none'); /* cipher */
|
||||
buf.writeString('none'); /* kdf */
|
||||
buf.writeBuffer(new Buffer(0)); /* kdfoptions */
|
||||
|
||||
buf.writeInt(1); /* nkeys */
|
||||
buf.writeBuffer(pubKey.toBuffer('rfc4253'));
|
||||
|
||||
if (privBuf)
|
||||
buf.writeBuffer(privBuf.toBuffer());
|
||||
|
||||
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));
|
||||
}
|
||||
114
node_modules/sshpk/lib/formats/ssh.js
generated
vendored
Normal file
114
node_modules/sshpk/lib/formats/ssh.js
generated
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
// Copyright 2015 Joyent, Inc.
|
||||
|
||||
module.exports = {
|
||||
read: read,
|
||||
write: write
|
||||
};
|
||||
|
||||
var assert = require('assert-plus');
|
||||
var rfc4253 = require('./rfc4253');
|
||||
var utils = require('../utils');
|
||||
var Key = require('../key');
|
||||
var PrivateKey = require('../private-key');
|
||||
|
||||
var sshpriv = require('./ssh-private');
|
||||
|
||||
/*JSSTYLED*/
|
||||
var SSHKEY_RE = /^([a-z0-9-]+)[ \t]+([a-zA-Z0-9+\/]+[=]*)([\n \t]+([^\n]+))?$/;
|
||||
/*JSSTYLED*/
|
||||
var SSHKEY_RE2 = /^([a-z0-9-]+)[ \t]+([a-zA-Z0-9+\/ \t\n]+[=]*)(.*)$/;
|
||||
|
||||
function read(buf) {
|
||||
if (typeof (buf) !== 'string') {
|
||||
assert.buffer(buf, 'buf');
|
||||
buf = buf.toString('ascii');
|
||||
}
|
||||
|
||||
var trimmed = buf.trim().replace(/[\\\r]/g, '');
|
||||
var m = trimmed.match(SSHKEY_RE);
|
||||
if (!m)
|
||||
m = trimmed.match(SSHKEY_RE2);
|
||||
assert.ok(m, 'key must match regex');
|
||||
|
||||
var type = rfc4253.algToKeyType(m[1]);
|
||||
var kbuf = new Buffer(m[2], 'base64');
|
||||
|
||||
/*
|
||||
* This is a bit tricky. If we managed to parse the key and locate the
|
||||
* key comment with the regex, then do a non-partial read and assert
|
||||
* that we have consumed all bytes. If we couldn't locate the key
|
||||
* comment, though, there may be whitespace shenanigans going on that
|
||||
* have conjoined the comment to the rest of the key. We do a partial
|
||||
* read in this case to try to make the best out of a sorry situation.
|
||||
*/
|
||||
var key;
|
||||
var ret = {};
|
||||
if (m[4]) {
|
||||
try {
|
||||
key = rfc4253.read(kbuf);
|
||||
|
||||
} catch (e) {
|
||||
m = trimmed.match(SSHKEY_RE2);
|
||||
assert.ok(m, 'key must match regex');
|
||||
kbuf = new Buffer(m[2], 'base64');
|
||||
key = rfc4253.readInternal(ret, 'public', kbuf);
|
||||
}
|
||||
} else {
|
||||
key = rfc4253.readInternal(ret, 'public', kbuf);
|
||||
}
|
||||
|
||||
assert.strictEqual(type, key.type);
|
||||
|
||||
if (m[4] && m[4].length > 0) {
|
||||
key.comment = m[4];
|
||||
|
||||
} else if (ret.consumed) {
|
||||
/*
|
||||
* Now the magic: trying to recover the key comment when it's
|
||||
* gotten conjoined to the key or otherwise shenanigan'd.
|
||||
*
|
||||
* Work out how much base64 we used, then drop all non-base64
|
||||
* chars from the beginning up to this point in the the string.
|
||||
* Then offset in this and try to make up for missing = chars.
|
||||
*/
|
||||
var data = m[2] + m[3];
|
||||
var realOffset = Math.ceil(ret.consumed / 3) * 4;
|
||||
data = data.slice(0, realOffset - 2). /*JSSTYLED*/
|
||||
replace(/[^a-zA-Z0-9+\/=]/g, '') +
|
||||
data.slice(realOffset - 2);
|
||||
|
||||
var padding = ret.consumed % 3;
|
||||
if (padding > 0 &&
|
||||
data.slice(realOffset - 1, realOffset) !== '=')
|
||||
realOffset--;
|
||||
while (data.slice(realOffset, realOffset + 1) === '=')
|
||||
realOffset++;
|
||||
|
||||
/* Finally, grab what we think is the comment & clean it up. */
|
||||
var trailer = data.slice(realOffset);
|
||||
trailer = trailer.replace(/[\r\n]/g, ' ').
|
||||
replace(/^\s+/, '');
|
||||
if (trailer.match(/^[a-zA-Z0-9]/))
|
||||
key.comment = trailer;
|
||||
}
|
||||
|
||||
return (key);
|
||||
}
|
||||
|
||||
function write(key) {
|
||||
assert.object(key);
|
||||
if (!Key.isKey(key))
|
||||
throw (new Error('Must be a public key'));
|
||||
|
||||
var parts = [];
|
||||
var alg = rfc4253.keyTypeToAlg(key);
|
||||
parts.push(alg);
|
||||
|
||||
var buf = rfc4253.write(key);
|
||||
parts.push(buf.toString('base64'));
|
||||
|
||||
if (key.comment)
|
||||
parts.push(key.comment);
|
||||
|
||||
return (new Buffer(parts.join(' ')));
|
||||
}
|
||||
Reference in New Issue
Block a user