You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 7-8.RSVP
Socket
Socket
Sign inDemoInstall

sshpk

Package Overview
Dependencies
Maintainers
1
Versions
50
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.13.1 to 1.13.2

lib/formats/dnssec.js

8

lib/algs.js

@@ -17,5 +17,4 @@ // Copyright 2015 Joyent, Inc.

'ed25519': {
parts: ['R'],
normalize: false,
sizePart: 'R'
parts: ['A'],
sizePart: 'A'
}

@@ -36,4 +35,3 @@ };

'ed25519': {
parts: ['R', 'r'],
normalize: false
parts: ['A', 'k']
}

@@ -40,0 +38,0 @@ };

@@ -82,3 +82,4 @@ // Copyright 2017 Joyent, Inc.

if (this._isPriv) {
this._priv = key.part.r.data;
utils.assertCompatible(key, PrivateKey, [1, 5], 'key');
this._priv = key.part.k.data;
}

@@ -147,3 +148,6 @@

} else if (pk.type === 'curve25519') {
this._priv = pk.part.r.data;
var k = pk.part.k;
if (!pk.part.k)
k = pk.part.r;
this._priv = k.data;
if (this._priv[0] === 0x00)

@@ -180,10 +184,9 @@ this._priv = this._priv.slice(1);

} else if (this._algo === 'curve25519') {
pub = otherpk.part.R.data;
pub = otherpk.part.A.data;
while (pub[0] === 0x00 && pub.length > 32)
pub = pub.slice(1);
var priv = this._priv;
assert.strictEqual(pub.length, 32);
assert.strictEqual(this._priv.length, 64);
assert.strictEqual(priv.length, 32);
var priv = this._priv.slice(0, 32);
var secret = nacl.box.before(new Uint8Array(pub),

@@ -267,4 +270,4 @@ new Uint8Array(priv));

parts.push({name: 'R', data: pub});
parts.push({name: 'r', data: priv});
parts.push({name: 'A', data: pub});
parts.push({name: 'k', data: priv});
this._key = new PrivateKey({

@@ -334,4 +337,4 @@ type: 'curve25519',

var parts = [];
parts.push({name: 'R', data: pub});
parts.push({name: 'r', data: priv});
parts.push({name: 'A', data: pub});
parts.push({name: 'k', data: priv.slice(0, 32)});
var key = new PrivateKey({

@@ -377,3 +380,2 @@ type: 'ed25519',

return (key);
} else {

@@ -380,0 +382,0 @@ if (ecdh === undefined)

@@ -59,3 +59,3 @@ // Copyright 2015 Joyent, Inc.

new Uint8Array(sig),
new Uint8Array(this.key.part.R.data)));
new Uint8Array(this.key.part.A.data)));
};

@@ -92,3 +92,4 @@

new Uint8Array(Buffer.concat(this.chunks)),
new Uint8Array(this.key.part.r.data));
new Uint8Array(Buffer.concat([
this.key.part.k.data, this.key.part.A.data])));
var sigBuf = new Buffer(sig);

@@ -95,0 +96,0 @@ var sigObj = Signature.parse(sigBuf, 'ed25519', 'raw');

@@ -16,3 +16,6 @@ // Copyright 2015 Joyent, Inc.

var rfc4253 = require('./rfc4253');
var dnssec = require('./dnssec');
var DNSSEC_PRIVKEY_HEADER_PREFIX = 'Private-key-format: v1';
function read(buf, options) {

@@ -26,2 +29,4 @@ if (typeof (buf) === 'string') {

return (ssh.read(buf, options));
if (findDNSSECHeader(buf))
return (dnssec.read(buf, options));
buf = new Buffer(buf, 'binary');

@@ -34,2 +39,4 @@ } else {

return (ssh.read(buf, options));
if (findDNSSECHeader(buf))
return (dnssec.read(buf, options));
}

@@ -74,4 +81,30 @@ if (buf.readUInt32BE(0) < buf.length)

function findDNSSECHeader(buf) {
// private case first
if (buf.length <= DNSSEC_PRIVKEY_HEADER_PREFIX.length)
return (false);
var headerCheck = buf.slice(0, DNSSEC_PRIVKEY_HEADER_PREFIX.length);
if (headerCheck.toString('ascii') === DNSSEC_PRIVKEY_HEADER_PREFIX)
return (true);
// public-key RFC3110 ?
// 'domain.com. IN KEY ...' or 'domain.com. IN DNSKEY ...'
// skip any comment-lines
if (typeof (buf) !== 'string') {
buf = buf.toString('ascii');
}
var lines = buf.split('\n');
var line = 0;
/* JSSTYLED */
while (lines[line].match(/^\;/))
line++;
if (lines[line].toString('ascii').match(/\. IN KEY /))
return (true);
if (lines[line].toString('ascii').match(/\. IN DNSKEY /))
return (true);
return (false);
}
function write(key, options) {
throw (new Error('"auto" format cannot be used for writing'));
}

@@ -37,7 +37,7 @@ // Copyright 2015 Joyent, Inc.

var m = lines[0].match(/*JSSTYLED*/
/[-]+[ ]*BEGIN ([A-Z0-9]+ )?(PUBLIC|PRIVATE) KEY[ ]*[-]+/);
/[-]+[ ]*BEGIN ([A-Z0-9][A-Za-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[ ]*[-]+/);
/[-]+[ ]*END ([A-Z0-9][A-Za-z0-9]+ )?(PUBLIC|PRIVATE) KEY[ ]*[-]+/);
assert.ok(m2, 'invalid PEM footer');

@@ -139,3 +139,8 @@

var alg = {'ecdsa': 'EC', 'rsa': 'RSA', 'dsa': 'DSA'}[key.type];
var alg = {
'ecdsa': 'EC',
'rsa': 'RSA',
'dsa': 'DSA',
'ed25519': 'EdDSA'
}[key.type];
var header;

@@ -142,0 +147,0 @@

@@ -58,2 +58,7 @@ // Copyright 2015 Joyent, Inc.

throw (new Error('Unknown key type: ' + type));
case 'EDDSA':
case 'EdDSA':
if (type === 'private')
return (readPkcs1EdDSAPrivate(der));
throw (new Error(type + ' keys not supported with EdDSA'));
default:

@@ -138,2 +143,27 @@ throw (new Error('Unknown key algo: ' + alg));

function readPkcs1EdDSAPrivate(der) {
var version = readMPInt(der, 'version');
assert.strictEqual(version.readUInt8(0), 1);
// private key
var k = der.readString(asn1.Ber.OctetString, true);
der.readSequence(0xa0);
var oid = der.readOID();
assert.strictEqual(oid, '1.3.101.112', 'the ed25519 curve identifier');
der.readSequence(0xa1);
var A = utils.readBitString(der);
var key = {
type: 'ed25519',
parts: [
{ name: 'A', data: utils.zeroPadToLength(A, 32) },
{ name: 'k', data: k }
]
};
return (new PrivateKey(key));
}
function readPkcs1DSAPublic(der) {

@@ -241,2 +271,8 @@ var y = readMPInt(der, 'y');

break;
case 'ed25519':
if (PrivateKey.isPrivateKey(key))
writePkcs1EdDSAPrivate(der, key);
else
writePkcs1EdDSAPublic(der, key);
break;
default:

@@ -324,1 +360,21 @@ throw (new Error('Unknown key algo: ' + key.type));

}
function writePkcs1EdDSAPrivate(der, key) {
var ver = new Buffer(1);
ver[0] = 1;
der.writeBuffer(ver, asn1.Ber.Integer);
der.writeBuffer(key.part.k.data, asn1.Ber.OctetString);
der.startSequence(0xa0);
der.writeOID('1.3.101.112');
der.endSequence();
der.startSequence(0xa1);
utils.writeBitString(der, key.part.A.data);
der.endSequence();
}
function writePkcs1EdDSAPublic(der, key) {
throw (new Error('Public keys are not supported for EdDSA PKCS#1'));
}

@@ -65,2 +65,14 @@ // Copyright 2015 Joyent, Inc.

return (readPkcs8ECDSAPrivate(der));
case '1.3.101.112':
if (type === 'public') {
return (readPkcs8EdDSAPublic(der));
} else {
return (readPkcs8EdDSAPrivate(der));
}
case '1.3.101.110':
if (type === 'public') {
return (readPkcs8X25519Public(der));
} else {
return (readPkcs8X25519Private(der));
}
default:

@@ -326,2 +338,79 @@ throw (new Error('Unknown key type OID ' + oid));

function readPkcs8EdDSAPublic(der) {
if (der.peek() === 0x00)
der.readByte();
var A = utils.readBitString(der);
var key = {
type: 'ed25519',
parts: [
{ name: 'A', data: utils.zeroPadToLength(A, 32) }
]
};
return (new Key(key));
}
function readPkcs8X25519Public(der) {
var A = utils.readBitString(der);
var key = {
type: 'curve25519',
parts: [
{ name: 'A', data: utils.zeroPadToLength(A, 32) }
]
};
return (new Key(key));
}
function readPkcs8EdDSAPrivate(der) {
if (der.peek() === 0x00)
der.readByte();
der.readSequence(asn1.Ber.OctetString);
var k = der.readString(asn1.Ber.OctetString, true);
k = utils.zeroPadToLength(k, 32);
var A;
if (der.peek() === asn1.Ber.BitString) {
A = utils.readBitString(der);
A = utils.zeroPadToLength(A, 32);
} else {
A = utils.calculateED25519Public(k);
}
var key = {
type: 'ed25519',
parts: [
{ name: 'A', data: utils.zeroPadToLength(A, 32) },
{ name: 'k', data: utils.zeroPadToLength(k, 32) }
]
};
return (new PrivateKey(key));
}
function readPkcs8X25519Private(der) {
if (der.peek() === 0x00)
der.readByte();
der.readSequence(asn1.Ber.OctetString);
var k = der.readString(asn1.Ber.OctetString, true);
k = utils.zeroPadToLength(k, 32);
var A = utils.calculateX25519Public(k);
var key = {
type: 'curve25519',
parts: [
{ name: 'A', data: utils.zeroPadToLength(A, 32) },
{ name: 'k', data: utils.zeroPadToLength(k, 32) }
]
};
return (new PrivateKey(key));
}
function writePkcs8(der, key) {

@@ -359,2 +448,9 @@ der.startSequence();

break;
case 'ed25519':
der.writeOID('1.3.101.112');
if (PrivateKey.isPrivateKey(key))
throw (new Error('Ed25519 private keys in pkcs8 ' +
'format are not supported'));
writePkcs8EdDSAPublic(key, der);
break;
default:

@@ -509,1 +605,16 @@ throw (new Error('Unsupported key type: ' + key.type));

}
function writePkcs8EdDSAPublic(key, der) {
der.endSequence();
utils.writeBitString(der, key.part.A.data);
}
function writePkcs8EdDSAPrivate(key, der) {
der.endSequence();
var k = utils.mpNormalize(key.part.k.data, true);
der.startSequence(asn1.Ber.OctetString);
der.writeBuffer(k, asn1.Ber.OctetString);
der.endSequence();
}

@@ -100,8 +100,21 @@ // Copyright 2015 Joyent, Inc.

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) {
var p = parts[i];
p.name = algInfo.parts[i];
/*
* OpenSSH stores ed25519 "private" keys as seed + public key
* concat'd together (k followed by A). We want to keep them
* separate for other formats that don't do this.
*/
if (key.type === 'ed25519' && p.name === 'k')
p.data = p.data.slice(0, 32);
if (p.name !== 'curve' && algInfo.normalize !== false) {
var nd;
if (key.type === 'ed25519') {
nd = utils.zeroPadToLength(p.data, 32);
} else {
nd = utils.mpNormalize(p.data);
}
if (nd.toString('binary') !==
p.data.toString('binary')) {
p.data = nd;

@@ -141,4 +154,10 @@ normalized = false;

var data = key.part[parts[i]].data;
if (algInfo.normalize !== false)
data = utils.mpNormalize(data);
if (algInfo.normalize !== false) {
if (key.type === 'ed25519')
data = utils.zeroPadToLength(data, 32);
else
data = utils.mpNormalize(data);
}
if (key.type === 'ed25519' && parts[i] === 'k')
data = Buffer.concat([data, key.part.A.data]);
buf.writeBuffer(data);

@@ -145,0 +164,0 @@ }

@@ -17,5 +17,5 @@ // Copyright 2015 Joyent, Inc.

/*JSSTYLED*/
var SSHKEY_RE = /^([a-z0-9-]+)[ \t]+([a-zA-Z0-9+\/]+[=]*)([\n \t]+([^\n]+))?$/;
var SSHKEY_RE = /^([a-z0-9-]+)[ \t]+([a-zA-Z0-9+\/]+[=]*)([ \t]+([^ \t][^\n]*[\n]*)?)?$/;
/*JSSTYLED*/
var SSHKEY_RE2 = /^([a-z0-9-]+)[ \t]+([a-zA-Z0-9+\/ \t\n]+[=]*)(.*)$/;
var SSHKEY_RE2 = /^([a-z0-9-]+)[ \t\n]+([a-zA-Z0-9+\/][a-zA-Z0-9+\/ \t\n=]*)([^a-zA-Z0-9+\/ \t\n=].*)?$/;

@@ -75,3 +75,3 @@ function read(buf, options) {

*/
var data = m[2] + m[3];
var data = m[2] + (m[3] ? m[3] : '');
var realOffset = Math.ceil(ret.consumed / 3) * 4;

@@ -78,0 +78,0 @@ data = data.slice(0, realOffset - 2). /*JSSTYLED*/

@@ -73,3 +73,4 @@ // Copyright 2017 Joyent, Inc.

'ecdsa-sha384': '1.2.840.10045.4.3.3',
'ecdsa-sha512': '1.2.840.10045.4.3.4'
'ecdsa-sha512': '1.2.840.10045.4.3.4',
'ed25519-sha512': '1.3.101.112'
};

@@ -526,2 +527,4 @@ Object.keys(SIGN_ALGS).forEach(function (k) {

der.writeOID(SIGN_ALGS[sig.algo]);
if (sig.algo.match(/^rsa-/))
der.writeNull();
der.endSequence();

@@ -528,0 +531,0 @@

@@ -139,10 +139,21 @@ // Copyright 2017 Joyent, Inc.

* IA5String or UTF8String.
*
* If this identity was parsed from a DN, use the ASN.1 types
* from the original representation (otherwise this might not
* be a full match for the original in some validators).
*/
if (c.value.match(NOT_IA5)) {
if (c.asn1type === asn1.Ber.Utf8String ||
c.value.match(NOT_IA5)) {
var v = new Buffer(c.value, 'utf8');
der.writeBuffer(v, asn1.Ber.Utf8String);
} else if (c.value.match(NOT_PRINTABLE)) {
} else if (c.asn1type === asn1.Ber.IA5String ||
c.value.match(NOT_PRINTABLE)) {
der.writeString(c.value, asn1.Ber.IA5String);
} else {
der.writeString(c.value, asn1.Ber.PrintableString);
var type = asn1.Ber.PrintableString;
if (c.asn1type !== undefined)
type = c.asn1type;
der.writeString(c.value, type);
}

@@ -257,3 +268,3 @@ der.endSequence();

}
components.push({ oid: oid, value: value });
components.push({ oid: oid, asn1type: type, value: value });
der._offset = after;

@@ -260,0 +271,0 @@ }

@@ -34,2 +34,3 @@ // Copyright 2017 Joyent, Inc.

formats['openssh'] = formats['ssh-private'];
formats['dnssec'] = require('./formats/dnssec');

@@ -109,3 +110,2 @@ function Key(opts) {

return (this._hashCache[algo]);
var hash = crypto.createHash(algo).

@@ -261,4 +261,5 @@ update(this.toBuffer('rfc4253')).digest();

* [1,5] -- first explicitly tagged version
* [1,6] -- changed ed25519 part names
*/
Key.prototype._sshpkApiVersion = [1, 5];
Key.prototype._sshpkApiVersion = [1, 6];

@@ -265,0 +266,0 @@ Key._oldVersionDetect = function (obj) {

@@ -40,2 +40,3 @@ // Copyright 2017 Joyent, Inc.

formats['ssh'] = formats['ssh-private'];
formats['dnssec'] = require('./formats/dnssec');

@@ -95,10 +96,8 @@ function PrivateKey(opts) {

priv = this.part.r.data;
priv = this.part.k.data;
if (priv[0] === 0x00)
priv = priv.slice(1);
priv = priv.slice(0, 32);
pair = nacl.box.keyPair.fromSecretKey(new Uint8Array(priv));
pub = new Buffer(pair.publicKey);
priv = Buffer.concat([priv, pub]);

@@ -108,4 +107,4 @@ return (new PrivateKey({

parts: [
{ name: 'R', data: utils.mpNormalize(pub) },
{ name: 'r', data: priv }
{ name: 'A', data: utils.mpNormalize(pub) },
{ name: 'k', data: utils.mpNormalize(priv) }
]

@@ -117,10 +116,8 @@ }));

priv = this.part.r.data;
priv = this.part.k.data;
if (priv[0] === 0x00)
priv = priv.slice(1);
priv = priv.slice(0, 32);
pair = nacl.sign.keyPair.fromSeed(new Uint8Array(priv));
pub = new Buffer(pair.publicKey);
priv = Buffer.concat([priv, pub]);

@@ -130,4 +127,4 @@ return (new PrivateKey({

parts: [
{ name: 'R', data: utils.mpNormalize(pub) },
{ name: 'r', data: priv }
{ name: 'A', data: utils.mpNormalize(pub) },
{ name: 'k', data: utils.mpNormalize(priv) }
]

@@ -246,4 +243,5 @@ }));

* [1,4] -- first tagged version
* [1,5] -- changed ed25519 part names and format
*/
PrivateKey.prototype._sshpkApiVersion = [1, 4];
PrivateKey.prototype._sshpkApiVersion = [1, 5];

@@ -250,0 +248,0 @@ PrivateKey._oldVersionDetect = function (obj) {

@@ -7,3 +7,6 @@ // Copyright 2015 Joyent, Inc.

calculateDSAPublic: calculateDSAPublic,
calculateED25519Public: calculateED25519Public,
calculateX25519Public: calculateX25519Public,
mpNormalize: mpNormalize,
mpDenormalize: mpDenormalize,
ecNormalize: ecNormalize,

@@ -14,3 +17,7 @@ countZeros: countZeros,

opensslKeyDeriv: opensslKeyDeriv,
opensshCipherInfo: opensshCipherInfo
opensshCipherInfo: opensshCipherInfo,
publicFromPrivateECDSA: publicFromPrivateECDSA,
zeroPadToLength: zeroPadToLength,
writeBitString: writeBitString,
readBitString: readBitString
};

@@ -20,4 +27,10 @@

var PrivateKey = require('./private-key');
var Key = require('./key');
var crypto = require('crypto');
var algs = require('./algs');
var asn1 = require('asn1');
var ec, jsbn;
var nacl;
var MAX_CLASS_DEPTH = 3;

@@ -184,2 +197,20 @@

function readBitString(der, tag) {
if (tag === undefined)
tag = asn1.Ber.BitString;
var buf = der.readString(tag, true);
assert.strictEqual(buf[0], 0x00, 'bit strings with unused bits are ' +
'not supported (0x' + buf[0].toString(16) + ')');
return (buf.slice(1));
}
function writeBitString(der, buf, tag) {
if (tag === undefined)
tag = asn1.Ber.BitString;
var b = new Buffer(buf.length + 1);
b[0] = 0x00;
buf.copy(b, 1);
der.writeBuffer(b, tag);
}
function mpNormalize(buf) {

@@ -198,2 +229,25 @@ assert.buffer(buf);

function mpDenormalize(buf) {
assert.buffer(buf);
while (buf.length > 1 && buf[0] === 0x00)
buf = buf.slice(1);
return (buf);
}
function zeroPadToLength(buf, len) {
assert.buffer(buf);
assert.number(len);
while (buf.length > len) {
assert.equal(buf[0], 0x00);
buf = buf.slice(1);
}
while (buf.length < len) {
var b = new Buffer(buf.length + 1);
b[0] = 0x00;
buf.copy(b, 1);
buf = b;
}
return (buf);
}
function bigintToMpBuf(bigint) {

@@ -223,2 +277,22 @@ var buf = new Buffer(bigint.toByteArray());

function calculateED25519Public(k) {
assert.buffer(k);
if (nacl === undefined)
nacl = require('tweetnacl');
var kp = nacl.sign.keyPair.fromSeed(new Uint8Array(k));
return (new Buffer(kp.publicKey));
}
function calculateX25519Public(k) {
assert.buffer(k);
if (nacl === undefined)
nacl = require('tweetnacl');
var kp = nacl.box.keyPair.fromSeed(new Uint8Array(k));
return (new Buffer(kp.publicKey));
}
function addRSAMissing(key) {

@@ -255,2 +329,28 @@ assert.object(key);

function publicFromPrivateECDSA(curveName, priv) {
assert.string(curveName, 'curveName');
assert.buffer(priv);
if (ec === undefined)
ec = require('ecc-jsbn/lib/ec');
if (jsbn === undefined)
jsbn = require('jsbn').BigInteger;
var params = algs.curves[curveName];
var p = new jsbn(params.p);
var a = new jsbn(params.a);
var b = new jsbn(params.b);
var curve = new ec.ECCurveFp(p, a, b);
var G = curve.decodePointHex(params.G.toString('hex'));
var d = new jsbn(mpNormalize(priv));
var pub = G.multiply(d);
pub = new Buffer(curve.encodePointHex(pub), 'hex');
var parts = [];
parts.push({name: 'curve', data: new Buffer(curveName)});
parts.push({name: 'Q', data: pub});
var key = new Key({type: 'ecdsa', curve: curve, parts: parts});
return (key);
}
function opensshCipherInfo(cipher) {

@@ -257,0 +357,0 @@ var inf = {};

{
"name": "sshpk",
"version": "1.13.1",
"version": "1.13.2",
"description": "A library for finding and using SSH public keys",

@@ -5,0 +5,0 @@ "main": "lib/index.js",

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc