Comparing version 1.4.5 to 1.4.6
@@ -31,3 +31,3 @@ // Copyright 2015 Joyent, Inc. | ||
nm + ' is not an Integer'); | ||
return (der.readString(asn1.Ber.Integer, true)); | ||
return (utils.mpNormalize(der.readString(asn1.Ber.Integer, true))); | ||
} | ||
@@ -175,4 +175,3 @@ | ||
var Q = der.readString(asn1.Ber.BitString, true); | ||
if (Q[0] === 0x0) | ||
Q = Q.slice(1); | ||
Q = utils.ecNormalize(Q); | ||
@@ -214,4 +213,3 @@ var key = { | ||
var Q = der.readString(asn1.Ber.BitString, true); | ||
if (Q[0] === 0x0) | ||
Q = Q.slice(1); | ||
Q = utils.ecNormalize(Q); | ||
@@ -311,7 +309,3 @@ var key = { | ||
var Q = key.part.Q.data; | ||
var prefix = new Buffer(1); | ||
prefix[0] = 0x0; | ||
if (Q[0] === 0x04) | ||
Q = Buffer.concat([prefix, Q]); | ||
var Q = utils.ecNormalize(key.part.Q.data, true); | ||
der.writeBuffer(Q, asn1.Ber.BitString); | ||
@@ -335,9 +329,5 @@ } | ||
der.startSequence(0xa1); | ||
var Q = key.part.Q.data; | ||
var prefix = new Buffer(1); | ||
prefix[0] = 0x0; | ||
if (Q[0] === 0x04) | ||
Q = Buffer.concat([prefix, Q]); | ||
var Q = utils.ecNormalize(key.part.Q.data, true); | ||
der.writeBuffer(Q, asn1.Ber.BitString); | ||
der.endSequence(); | ||
} |
@@ -30,3 +30,3 @@ // Copyright 2015 Joyent, Inc. | ||
nm + ' is not an Integer'); | ||
return (der.readString(asn1.Ber.Integer, true)); | ||
return (utils.mpNormalize(der.readString(asn1.Ber.Integer, true))); | ||
} | ||
@@ -298,4 +298,3 @@ | ||
var Q = der.readString(asn1.Ber.BitString, true); | ||
if (Q[0] === 0x0) | ||
Q = Q.slice(1); | ||
Q = utils.ecNormalize(Q); | ||
@@ -319,4 +318,3 @@ var key = { | ||
var Q = der.readString(asn1.Ber.BitString, true); | ||
if (Q[0] === 0x0) | ||
Q = Q.slice(1); | ||
Q = utils.ecNormalize(Q); | ||
@@ -490,7 +488,3 @@ var key = { | ||
var Q = key.part.Q.data; | ||
var pre = new Buffer(1); | ||
pre[0] = 0x0; | ||
if (Q[0] === 0x04) | ||
Q = Buffer.concat([pre, Q]); | ||
var Q = utils.ecNormalize(key.part.Q.data, true); | ||
der.writeBuffer(Q, asn1.Ber.BitString); | ||
@@ -513,7 +507,3 @@ } | ||
der.startSequence(0xa1); | ||
var pre = new Buffer(1); | ||
pre[0] = 0x0; | ||
var Q = key.part.Q.data; | ||
if (Q[0] === 0x04) | ||
Q = Buffer.concat([pre, Q]); | ||
var Q = utils.ecNormalize(key.part.Q.data, true); | ||
der.writeBuffer(Q, asn1.Ber.BitString); | ||
@@ -520,0 +510,0 @@ der.endSequence(); |
@@ -11,2 +11,3 @@ // Copyright 2015 Joyent, Inc. | ||
/* shared with ssh format */ | ||
readInternal: read, | ||
keyTypeToAlg: keyTypeToAlg, | ||
@@ -18,2 +19,3 @@ algToKeyType: algToKeyType | ||
var algs = require('../algs'); | ||
var utils = require('../utils'); | ||
var Key = require('../key'); | ||
@@ -77,5 +79,5 @@ var PrivateKey = require('../private-key'); | ||
'key must have at least one part'); | ||
assert.ok(partial || sshbuf.atEnd(), | ||
'leftover bytes at end of key'); | ||
key._rfc4253Cache = sshbuf.toBuffer(); | ||
var Constructor = Key; | ||
@@ -95,5 +97,18 @@ var algInfo = algs.info[key.type]; | ||
for (var i = 0; i < algInfo.parts.length; ++i) | ||
var normalized = true; | ||
for (var i = 0; i < algInfo.parts.length; ++i) { | ||
if (parts[i].name !== 'curve') { | ||
var p = parts[i]; | ||
var nd = utils.mpNormalize(p.data); | ||
if (nd !== p.data) { | ||
p.data = nd; | ||
normalized = false; | ||
} | ||
} | ||
parts[i].name = algInfo.parts[i]; | ||
} | ||
if (normalized) | ||
key._rfc4253Cache = sshbuf.toBuffer(); | ||
return (new Constructor(key)); | ||
@@ -119,7 +134,3 @@ } | ||
var data = key.part[parts[i]].data; | ||
if (parts[i] !== 'curve' && (data[0] & 0x80) == 0x80) { | ||
var pre = new Buffer(1); | ||
pre[0] = 0; | ||
data = Buffer.concat([pre, data]); | ||
} | ||
data = utils.mpNormalize(data); | ||
buf.writeBuffer(data); | ||
@@ -126,0 +137,0 @@ } |
@@ -17,3 +17,5 @@ // Copyright 2015 Joyent, Inc. | ||
/*JSSTYLED*/ | ||
var SSHKEY_RE = /^([a-z0-9-]+)\s+([a-zA-Z0-9+\/]+[=]*)\s*(.*)$/; | ||
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]+[=]*)/; | ||
@@ -26,14 +28,38 @@ function read(buf) { | ||
var m = buf.trim().match(SSHKEY_RE); | ||
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'); | ||
var key = rfc4253.read(kbuf); | ||
/* | ||
* 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; | ||
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.readPartial('public', kbuf); | ||
} | ||
} else { | ||
key = rfc4253.readPartial('public', kbuf); | ||
} | ||
assert.strictEqual(type, key.type); | ||
if (m[3] && m[3].length > 0) | ||
key.comment = m[3]; | ||
if (m[4] && m[4].length > 0) | ||
key.comment = m[4]; | ||
@@ -40,0 +66,0 @@ return (key); |
@@ -48,3 +48,3 @@ // Copyright 2015 Joyent, Inc. | ||
assert.ok(this._offset + len <= this._buffer.length, | ||
'length out of bounds'); | ||
'length out of bounds at +0x' + this._offset.toString(16)); | ||
var buf = this._buffer.slice(this._offset, this._offset + len); | ||
@@ -51,0 +51,0 @@ this._offset += len; |
@@ -6,3 +6,5 @@ // Copyright 2015 Joyent, Inc. | ||
addRSAMissing: addRSAMissing, | ||
calculateDSAPublic: calculateDSAPublic | ||
calculateDSAPublic: calculateDSAPublic, | ||
mpNormalize: mpNormalize, | ||
ecNormalize: ecNormalize | ||
}; | ||
@@ -41,2 +43,41 @@ | ||
function ecNormalize(buf, addZero) { | ||
assert.buffer(buf); | ||
if (buf[0] === 0x00 && buf[1] === 0x04) { | ||
if (addZero) | ||
return (buf); | ||
return (buf.slice(1)); | ||
} else if (buf[0] === 0x04) { | ||
if (!addZero) | ||
return (buf); | ||
} else { | ||
while (buf[0] === 0x00) | ||
buf = buf.slice(1); | ||
if (buf[0] === 0x02 || buf[0] === 0x03) | ||
throw (new Error('Compressed elliptic curve points ' + | ||
'are not supported')); | ||
if (buf[0] !== 0x04) | ||
throw (new Error('Not a valid elliptic curve point')); | ||
if (!addZero) | ||
return (buf); | ||
} | ||
var b = new Buffer(buf.length + 1); | ||
b[0] = 0x0; | ||
buf.copy(b, 1); | ||
return (b); | ||
} | ||
function mpNormalize(buf) { | ||
assert.buffer(buf); | ||
while (buf.length > 1 && buf[0] === 0x00 && (buf[1] & 0x80) === 0x00) | ||
buf = buf.slice(1); | ||
if ((buf[0] & 0x80) === 0x80) { | ||
var b = new Buffer(buf.length + 1); | ||
b[0] = 0x00; | ||
buf.copy(b, 1); | ||
buf = b; | ||
} | ||
return (buf); | ||
} | ||
function calculateDSAPublic(g, p, x) { | ||
@@ -43,0 +84,0 @@ assert.buffer(g); |
{ | ||
"name": "sshpk", | ||
"version": "1.4.5", | ||
"version": "1.4.6", | ||
"description": "A library for finding and using SSH public keys", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
81955
2234