You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
104 lines
4.2 KiB
104 lines
4.2 KiB
2 years ago
|
import * as asn1 from "./asn1";
|
||
|
import * as aesid from "./aesid.json";
|
||
|
import fixProc from "./fixProc";
|
||
|
import * as ciphers from "../browserify-aes";
|
||
|
import * as compat from "../pbkdf2";
|
||
|
function parseKeys(buffer) {
|
||
|
var password;
|
||
|
if (typeof buffer === 'object' && !Buffer.isBuffer(buffer)) {
|
||
|
password = buffer.passphrase;
|
||
|
buffer = buffer.key;
|
||
|
}
|
||
|
if (typeof buffer === 'string') {
|
||
|
buffer = Buffer.from(buffer);
|
||
|
}
|
||
|
var stripped = fixProc(buffer, password);
|
||
|
var type = stripped.tag;
|
||
|
var data = stripped.data;
|
||
|
var subtype, ndata;
|
||
|
switch (type) {
|
||
|
case 'CERTIFICATE':
|
||
|
ndata = asn1.certificate.decode(data, 'der').tbsCertificate.subjectPublicKeyInfo;
|
||
|
// falls through
|
||
|
case 'PUBLIC KEY':
|
||
|
if (!ndata) {
|
||
|
ndata = asn1.PublicKey.decode(data, 'der');
|
||
|
}
|
||
|
subtype = ndata.algorithm.algorithm.join('.');
|
||
|
switch (subtype) {
|
||
|
case '1.2.840.113549.1.1.1':
|
||
|
return asn1.RSAPublicKey.decode(ndata.subjectPublicKey.data, 'der');
|
||
|
case '1.2.840.10045.2.1':
|
||
|
ndata.subjectPrivateKey = ndata.subjectPublicKey;
|
||
|
return {
|
||
|
type: 'ec',
|
||
|
data: ndata
|
||
|
};
|
||
|
case '1.2.840.10040.4.1':
|
||
|
ndata.algorithm.params.pub_key = asn1.DSAparam.decode(ndata.subjectPublicKey.data, 'der');
|
||
|
return {
|
||
|
type: 'dsa',
|
||
|
data: ndata.algorithm.params
|
||
|
};
|
||
|
default: throw new Error('unknown key id ' + subtype);
|
||
|
}
|
||
|
// throw new Error('unknown key type ' + type)
|
||
|
case 'ENCRYPTED PRIVATE KEY':
|
||
|
data = asn1.EncryptedPrivateKey.decode(data, 'der');
|
||
|
data = decrypt(data, password);
|
||
|
// falls through
|
||
|
case 'PRIVATE KEY':
|
||
|
ndata = asn1.PrivateKey.decode(data, 'der');
|
||
|
subtype = ndata.algorithm.algorithm.join('.');
|
||
|
switch (subtype) {
|
||
|
case '1.2.840.113549.1.1.1':
|
||
|
return asn1.RSAPrivateKey.decode(ndata.subjectPrivateKey, 'der');
|
||
|
case '1.2.840.10045.2.1':
|
||
|
return {
|
||
|
curve: ndata.algorithm.curve,
|
||
|
privateKey: asn1.ECPrivateKey.decode(ndata.subjectPrivateKey, 'der').privateKey
|
||
|
};
|
||
|
case '1.2.840.10040.4.1':
|
||
|
ndata.algorithm.params.priv_key = asn1.DSAparam.decode(ndata.subjectPrivateKey, 'der');
|
||
|
return {
|
||
|
type: 'dsa',
|
||
|
params: ndata.algorithm.params
|
||
|
};
|
||
|
default: throw new Error('unknown key id ' + subtype);
|
||
|
}
|
||
|
// throw new Error('unknown key type ' + type)
|
||
|
case 'RSA PUBLIC KEY':
|
||
|
return asn1.RSAPublicKey.decode(data, 'der');
|
||
|
case 'RSA PRIVATE KEY':
|
||
|
return asn1.RSAPrivateKey.decode(data, 'der');
|
||
|
case 'DSA PRIVATE KEY':
|
||
|
return {
|
||
|
type: 'dsa',
|
||
|
params: asn1.DSAPrivateKey.decode(data, 'der')
|
||
|
};
|
||
|
case 'EC PRIVATE KEY':
|
||
|
data = asn1.ECPrivateKey.decode(data, 'der');
|
||
|
return {
|
||
|
curve: data.parameters.value,
|
||
|
privateKey: data.privateKey
|
||
|
};
|
||
|
default: throw new Error('unknown key type ' + type);
|
||
|
}
|
||
|
}
|
||
|
parseKeys.signature = asn1.signature;
|
||
|
function decrypt(data, password) {
|
||
|
var salt = data.algorithm.decrypt.kde.kdeparams.salt;
|
||
|
var iters = parseInt(data.algorithm.decrypt.kde.kdeparams.iters.toString(), 10);
|
||
|
var algo = aesid[data.algorithm.decrypt.cipher.algo.join('.')];
|
||
|
var iv = data.algorithm.decrypt.cipher.iv;
|
||
|
var cipherText = data.subjectPrivateKey;
|
||
|
var keylen = parseInt(algo.split('-')[1], 10) / 8;
|
||
|
var key = compat.pbkdf2Sync(password, salt, iters, keylen, 'sha1');
|
||
|
var cipher = ciphers.createDecipheriv(algo, key, iv);
|
||
|
var out = [];
|
||
|
out.push(cipher.update(cipherText));
|
||
|
out.push(cipher.final());
|
||
|
return Buffer.concat(out);
|
||
|
}
|
||
|
export default parseKeys;
|