Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
80556 views
1
var asn1 = require('./asn1');
2
var aesid = require('./aesid.json');
3
var fixProc = require('./fixProc');
4
var ciphers = require('browserify-aes');
5
var compat = require('pbkdf2');
6
module.exports = parseKeys;
7
8
function parseKeys(buffer) {
9
var password;
10
if (typeof buffer === 'object' && !Buffer.isBuffer(buffer)) {
11
password = buffer.passphrase;
12
buffer = buffer.key;
13
}
14
if (typeof buffer === 'string') {
15
buffer = new Buffer(buffer);
16
}
17
18
var stripped = fixProc(buffer, password);
19
20
var type = stripped.tag;
21
var data = stripped.data;
22
var subtype,ndata;
23
switch (type) {
24
case 'PUBLIC KEY':
25
ndata = asn1.PublicKey.decode(data, 'der');
26
subtype = ndata.algorithm.algorithm.join('.');
27
switch(subtype) {
28
case '1.2.840.113549.1.1.1':
29
return asn1.RSAPublicKey.decode(ndata.subjectPublicKey.data, 'der');
30
case '1.2.840.10045.2.1':
31
ndata.subjectPrivateKey = ndata.subjectPublicKey;
32
return {
33
type: 'ec',
34
data: ndata
35
};
36
case '1.2.840.10040.4.1':
37
ndata.algorithm.params.pub_key = asn1.DSAparam.decode(ndata.subjectPublicKey.data, 'der');
38
return {
39
type: 'dsa',
40
data: ndata.algorithm.params
41
};
42
default: throw new Error('unknown key id ' + subtype);
43
}
44
throw new Error('unknown key type ' + type);
45
case 'ENCRYPTED PRIVATE KEY':
46
data = asn1.EncryptedPrivateKey.decode(data, 'der');
47
data = decrypt(data, password);
48
//falling through
49
case 'PRIVATE KEY':
50
ndata = asn1.PrivateKey.decode(data, 'der');
51
subtype = ndata.algorithm.algorithm.join('.');
52
switch(subtype) {
53
case '1.2.840.113549.1.1.1':
54
return asn1.RSAPrivateKey.decode(ndata.subjectPrivateKey, 'der');
55
case '1.2.840.10045.2.1':
56
return {
57
curve: ndata.algorithm.curve,
58
privateKey: asn1.ECPrivateKey.decode(ndata.subjectPrivateKey, 'der').privateKey
59
};
60
case '1.2.840.10040.4.1':
61
ndata.algorithm.params.priv_key = asn1.DSAparam.decode(ndata.subjectPrivateKey, 'der');
62
return {
63
type: 'dsa',
64
params: ndata.algorithm.params
65
};
66
default: throw new Error('unknown key id ' + subtype);
67
}
68
throw new Error('unknown key type ' + type);
69
case 'RSA PUBLIC KEY':
70
return asn1.RSAPublicKey.decode(data, 'der');
71
case 'RSA PRIVATE KEY':
72
return asn1.RSAPrivateKey.decode(data, 'der');
73
case 'DSA PRIVATE KEY':
74
return {
75
type: 'dsa',
76
params: asn1.DSAPrivateKey.decode(data, 'der')
77
};
78
case 'EC PRIVATE KEY':
79
data = asn1.ECPrivateKey.decode(data, 'der');
80
return {
81
curve: data.parameters.value,
82
privateKey: data.privateKey
83
};
84
default: throw new Error('unknown key type ' + type);
85
}
86
}
87
parseKeys.signature = asn1.signature;
88
function decrypt(data, password) {
89
var salt = data.algorithm.decrypt.kde.kdeparams.salt;
90
var iters = parseInt(data.algorithm.decrypt.kde.kdeparams.iters.toString(), 10);
91
var algo = aesid[data.algorithm.decrypt.cipher.algo.join('.')];
92
var iv = data.algorithm.decrypt.cipher.iv;
93
var cipherText = data.subjectPrivateKey;
94
var keylen = parseInt(algo.split('-')[1], 10)/8;
95
var key = compat.pbkdf2Sync(password, salt, iters, keylen);
96
var cipher = ciphers.createDecipheriv(algo, key, iv);
97
var out = [];
98
out.push(cipher.update(cipherText));
99
out.push(cipher.final());
100
return Buffer.concat(out);
101
}
102
103