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.
		
		
		
		
		
			
		
			
				
					
					
						
							107 lines
						
					
					
						
							3.6 KiB
						
					
					
				
			
		
		
	
	
							107 lines
						
					
					
						
							3.6 KiB
						
					
					
				var asn1 = require('./asn1') | 
						|
var aesid = require('./aesid.json') | 
						|
var fixProc = require('./fixProc') | 
						|
var ciphers = require('browserify-aes') | 
						|
var compat = require('pbkdf2') | 
						|
var Buffer = require('safe-buffer').Buffer | 
						|
module.exports = parseKeys | 
						|
 | 
						|
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) | 
						|
}
 | 
						|
 |