blob: 868ed63d053f8ab45c8f6d65c64e0c4091a000a9 [file] [log] [blame]
(function() {
var Auth, BigInteger, Promise, forge;
Promise = require('bluebird');
forge = require('node-forge');
BigInteger = forge.jsbn.BigInteger;
/*
The stucture of an ADB RSAPublicKey is as follows:
*define RSANUMBYTES 256 // 2048 bit key length
*define RSANUMWORDS (RSANUMBYTES / sizeof(uint32_t))
typedef struct RSAPublicKey {
int len; // Length of n[] in number of uint32_t
uint32_t n0inv; // -1 / n[0] mod 2^32
uint32_t n[RSANUMWORDS]; // modulus as little endian array
uint32_t rr[RSANUMWORDS]; // R^2 as little endian array
int exponent; // 3 or 65537
} RSAPublicKey;
*/
Auth = (function() {
var RE, readPublicKeyFromStruct;
function Auth() {}
RE = /^((?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?) (.*)$/;
readPublicKeyFromStruct = function(struct, comment) {
var e, key, len, md, n, offset;
if (!struct.length) {
throw new Error("Invalid public key");
}
offset = 0;
len = struct.readUInt32LE(offset) * 4;
offset += 4;
if (struct.length !== 4 + 4 + len + len + 4) {
throw new Error("Invalid public key");
}
offset += 4;
n = new Buffer(len);
struct.copy(n, 0, offset, offset + len);
[].reverse.call(n);
offset += len;
offset += len;
e = struct.readUInt32LE(offset);
if (!(e === 3 || e === 65537)) {
throw new Error("Invalid exponent " + e + ", only 3 and 65537 are supported");
}
key = forge.pki.setRsaPublicKey(new BigInteger(n.toString('hex'), 16), new BigInteger(e.toString(), 10));
md = forge.md.md5.create();
md.update(struct.toString('binary'));
key.fingerprint = md.digest().toHex().match(/../g).join(':');
key.comment = comment;
return key;
};
Auth.parsePublicKey = function(buffer) {
return new Promise(function(resolve, reject) {
var comment, match, struct;
if (match = RE.exec(buffer)) {
struct = new Buffer(match[1], 'base64');
comment = match[2];
return resolve(readPublicKeyFromStruct(struct, comment));
} else {
return reject(new Error("Unrecognizable public key format"));
}
});
};
return Auth;
})();
module.exports = Auth;
}).call(this);