# Code coverage report for parseASN1/index.js

## Statements: 90% (54 / 60) Branches: 83.33% (20 / 24) Functions: 100% (2 / 2) Lines: 90% (54 / 60) Ignored: none

All files » parseASN1/ » index.js

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    1011
    1
    1
    1
    1

    1
    26
    26
    7
    7

    26

    26
    7

    26
    26
    26
    26
    26

    11
    11
    11

    5

    2
    2

    4
    4

    4
    4

    6
    6
    6

    3

    1

    2
    2

    2

    4

    2

    1
    1

    1
    1
    4
    4
    4
    4
    4
    4
    4
    4
    4
    4
    4
    4
     var pemstrip = require('pemstrip');
    var asn1 = require('./asn1');
    var aesid = require('./aesid.json');
    var fixProc = require('./fixProc');
    module.exports = parseKeys;

    function parseKeys(buffer, crypto) {
      var password;
      if (typeof buffer === 'object' && !Buffer.isBuffer(buffer)) {
        password = buffer.passphrase;
        buffer = buffer.key;
      }
      Iif (typeof buffer === 'string') {
        buffer = new Buffer(buffer);
      }
      if (password) {
        buffer = fixProc(buffer, password, crypto);
      }
      var stripped = pemstrip.strip(buffer);
      var type = stripped.tag;
      var data = new Buffer(stripped.base64, 'base64');
      var subtype,ndata;
      switch (type) {
        case 'PUBLIC KEY':
          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(crypto, data, password);
          //falling 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(crypto, data, password) {
      var salt = data.algorithm.decrypt.kde.kdeparams.salt;
      var iters = data.algorithm.decrypt.kde.kdeparams.iters;
      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 = crypto.pbkdf2Sync(password, salt, iters, keylen);
      var cipher = crypto.createDecipheriv(algo, key, iv);
      var out = [];
      out.push(cipher.update(cipherText));
      out.push(cipher.final());
      return Buffer.concat(out);
    }