Skip to content

Commit

Permalink
add support for certificate-based authentication
Browse files Browse the repository at this point in the history
  • Loading branch information
mscdex committed Jul 14, 2013
1 parent 8f5503d commit 6018e0f
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 29 deletions.
36 changes: 22 additions & 14 deletions lib/Connection.js
Expand Up @@ -1201,16 +1201,17 @@ Connection.prototype.connect = function(opts) {
i += yLen;
}

var p = 11;
var p = 4 + 7;
keyInfo = {
type: this._privateKey.type,
fulltype: 'ssh-' + this._privateKey.type,
public: new Buffer(4 + 7
+ (this._privateKey.type === 'rsa'
? 4 + nLen + 4 + eLen
: 4 + pLen + 4 + qLen + 4 + gLen + 4 + yLen))
};
keyInfo.public.writeUInt32BE(7, 0, true);
keyInfo.public.write('ssh-' + keyInfo.type, 4, 7, 'ascii');
keyInfo.public.write(keyInfo.fulltype, 4, 7, 'ascii');
if (keyInfo.type === 'rsa') {
keyInfo.public.writeUInt32BE(eLen, p, true);
privKey.copy(keyInfo.public, p += 4, eStart, eStart + eLen);
Expand Down Expand Up @@ -1710,18 +1711,20 @@ Connection.prototype._authPK = function(sign) {
string public key to be used for authentication
*/
var self = this;
var pubKey, pubKeyType;
var pubKey, pubKeyType, pubKeyFullType;

if (this._agent && this._agentKeys) {
pubKey = this._agentKeys[this._agentKeys.i];
pubKeyType = this._agentKeys[this._agentKeys.i].toString('ascii', 8, 11);
pubKeyFullType = pubKey.toString('ascii', 4, 4 + pubKey.readUInt32BE(0, true));
pubKeyType = pubKeyFullType.substring(4, 7);
} else {
pubKey = this._publicKey.public;
pubKeyFullType = this._publicKey.fulltype;
pubKeyType = this._publicKey.type;
}

var userLen = Buffer.byteLength(this._username),
algoLen = 7,//4 + Buffer.byteLength(pubKeyType),
algoLen = Buffer.byteLength(pubKeyFullType),
pubKeyLen = pubKey.length,
sesLen = this._sessionid.length,
p = 0,
Expand Down Expand Up @@ -1749,7 +1752,7 @@ Connection.prototype._authPK = function(sign) {
sig.write('publickey', p += 4, 9, 'ascii');
sig[p += 9] = (sign ? 1 : 0);
sig.writeUInt32BE(algoLen, ++p, true);
sig.write('ssh-' + pubKeyType, p += 4, algoLen, 'ascii');
sig.write(pubKeyFullType, p += 4, algoLen, 'ascii');
sig.writeUInt32BE(pubKeyLen, p += algoLen, true);
pubKey.copy(sig, p += 4);

Expand All @@ -1758,7 +1761,10 @@ Connection.prototype._authPK = function(sign) {
return this._send(sig);
}

var signature, sigLen, privAlgoLen = 7, privAlgo;
var signature,
sigLen,
privAlgoLen = 7,
privAlgo;

if (this._agent && this._agentKeys) {
agentQuery(this._agent, pubKey, pubKeyType, sig, function(err, signed) {
Expand All @@ -1768,18 +1774,19 @@ Connection.prototype._authPK = function(sign) {
self._agentKeys = undefined;
return self._tryNextAuth();
}
privAlgo = pubKeyType;
if (privAlgo === 'rsa')
signature = signed.slice(15); // skip algoLen + algo + sigLen
else
privAlgo = 'ssh-' + pubKeyType;
if (pubKeyType === 'rsa') {
// skip algoLen + algo + sigLen
signature = signed.slice(4 + 7 + 4);
} else
signature = signed;
sigLen = signature.length;
sendSigReq();
});
return (this._sock.bufferSize > 0);
} else {
var privateKey = this._privateKey.privateOrig;
privAlgo = this._privateKey.type;
privAlgo = 'ssh-' + this._privateKey.type;

signature = crypto.createSign(this._privateKey.type === 'rsa'
? 'RSA-SHA1' : 'DSA-SHA1');
Expand Down Expand Up @@ -1839,12 +1846,13 @@ Connection.prototype._authPK = function(sign) {
buf.write('publickey', p += 4, 9, 'ascii');
buf[p += 9] = 1;
buf.writeUInt32BE(algoLen, ++p, true);
buf.write('ssh-' + pubKeyType, p += 4, algoLen, 'ascii');
buf.write(pubKeyFullType, p += 4, algoLen, 'ascii');
buf.writeUInt32BE(pubKeyLen, p += algoLen, true);
pubKey.copy(buf, p += 4);

buf.writeUInt32BE(4 + privAlgoLen + 4 + sigLen, p += pubKeyLen, true);
buf.writeUInt32BE(privAlgoLen, p += 4, true);
buf.write('ssh-' + privAlgo, p += 4, privAlgoLen, 'ascii');
buf.write(privAlgo, p += 4, privAlgoLen, 'ascii');
buf.writeUInt32BE(sigLen, p += privAlgoLen, true);
signature.copy(buf, p += 4);

Expand Down
29 changes: 14 additions & 15 deletions lib/keyParser.js
Expand Up @@ -3,7 +3,7 @@
var RE_HEADER_PPK = /^PuTTY-User-Key-File-2: ssh-(rsa|dss)$/i,
RE_HEADER_OPENSSH_PRIV = /^-----BEGIN (RSA|DSA) PRIVATE KEY-----$/i,
RE_FOOTER_OPENSSH_PRIV = /^-----END (?:RSA|DSA) PRIVATE KEY-----$/i,
RE_HEADER_OPENSSH_PUB = /^ssh-(rsa|dss) ([A-Z0-9a-z\/+=]+(?:$|\s+([\S].*)?)$)/i,
RE_HEADER_OPENSSH_PUB = /^(ssh-(rsa|dss)(?:-cert-v0[01]@openssh.com)?) ([A-Z0-9a-z\/+=]+(?:$|\s+([\S].*)?)$)/i,
RE_HEADER_RFC4176_PUB = /^---- BEGIN SSH2 PUBLIC KEY ----$/i,
RE_FOOTER_RFC4176_PUB = /^---- END SSH2 PUBLIC KEY ----$/i,
RE_HEADER = /^([^:]+):\s*([\S].*)?$/i;
Expand All @@ -15,6 +15,7 @@ module.exports = function(data) {
return false;

var ret = {
fulltype: undefined,
type: undefined,
extra: undefined,
comment: undefined,
Expand Down Expand Up @@ -89,10 +90,11 @@ module.exports = function(data) {
ret.privateOrig = new Buffer(orig);
} else if (m = RE_HEADER_OPENSSH_PUB.exec(data[0])) {
// OpenSSH public key
ret.type = m[1].toLowerCase();
ret.public = new Buffer(m[2], 'base64');
ret.fulltype = m[1];
ret.type = m[2].toLowerCase();
ret.public = new Buffer(m[3], 'base64');
ret.publicOrig = new Buffer(orig);
ret.comment = m[3];
ret.comment = m[4];
} else if ((m = RE_HEADER_RFC4176_PUB.exec(data[0]))
&& RE_FOOTER_RFC4176_PUB.test(data[data.length - 1])) {
if (!RE_HEADER.test(data[1])) {
Expand All @@ -117,21 +119,18 @@ module.exports = function(data) {
ret.public = new Buffer(data.slice(i, data.length - 1).join(''), 'base64');
}
len = ret.public.readUInt32BE(0, true);
if (len !== 7)
var fulltype = ret.public.toString('ascii', 4, 4 + len);
ret.fulltype = fulltype;
if (fulltype === 'ssh-dss')
ret.type = 'dss';
else if (fulltype === 'ssh-rsa')
ret.type = 'rsa';
else
return false;
else {
var type = ret.public.toString('ascii', 4, 11);
if (type === 'ssh-dss')
ret.type = 'dss';
else if (type === 'ssh-rsa')
ret.type = 'rsa';
else
return false;
}
ret.public = ret.public.slice(11);
ret.publicOrig = new Buffer(orig);
} else
return false;

return ret;
};
};

0 comments on commit 6018e0f

Please sign in to comment.