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