"Fossies" - the Fresh Open Source Software Archive

Member "Atom/resources/app/apm/node_modules/sshpk/lib/formats/pkcs8.js" (11 Apr 2017, 11872 Bytes) of package /windows/misc/atom-windows.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Javascript source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 // Copyright 2015 Joyent, Inc.
    2 
    3 module.exports = {
    4     read: read,
    5     readPkcs8: readPkcs8,
    6     write: write,
    7     writePkcs8: writePkcs8,
    8 
    9     readECDSACurve: readECDSACurve,
   10     writeECDSACurve: writeECDSACurve
   11 };
   12 
   13 var assert = require('assert-plus');
   14 var asn1 = require('asn1');
   15 var algs = require('../algs');
   16 var utils = require('../utils');
   17 var Key = require('../key');
   18 var PrivateKey = require('../private-key');
   19 var pem = require('./pem');
   20 
   21 function read(buf, options) {
   22     return (pem.read(buf, options, 'pkcs8'));
   23 }
   24 
   25 function write(key, options) {
   26     return (pem.write(key, options, 'pkcs8'));
   27 }
   28 
   29 /* Helper to read in a single mpint */
   30 function readMPInt(der, nm) {
   31     assert.strictEqual(der.peek(), asn1.Ber.Integer,
   32         nm + ' is not an Integer');
   33     return (utils.mpNormalize(der.readString(asn1.Ber.Integer, true)));
   34 }
   35 
   36 function readPkcs8(alg, type, der) {
   37     /* Private keys in pkcs#8 format have a weird extra int */
   38     if (der.peek() === asn1.Ber.Integer) {
   39         assert.strictEqual(type, 'private',
   40             'unexpected Integer at start of public key');
   41         der.readString(asn1.Ber.Integer, true);
   42     }
   43 
   44     der.readSequence();
   45     var next = der.offset + der.length;
   46 
   47     var oid = der.readOID();
   48     switch (oid) {
   49     case '1.2.840.113549.1.1.1':
   50         der._offset = next;
   51         if (type === 'public')
   52             return (readPkcs8RSAPublic(der));
   53         else
   54             return (readPkcs8RSAPrivate(der));
   55     case '1.2.840.10040.4.1':
   56         if (type === 'public')
   57             return (readPkcs8DSAPublic(der));
   58         else
   59             return (readPkcs8DSAPrivate(der));
   60     case '1.2.840.10045.2.1':
   61         if (type === 'public')
   62             return (readPkcs8ECDSAPublic(der));
   63         else
   64             return (readPkcs8ECDSAPrivate(der));
   65     default:
   66         throw (new Error('Unknown key type OID ' + oid));
   67     }
   68 }
   69 
   70 function readPkcs8RSAPublic(der) {
   71     // bit string sequence
   72     der.readSequence(asn1.Ber.BitString);
   73     der.readByte();
   74     der.readSequence();
   75 
   76     // modulus
   77     var n = readMPInt(der, 'modulus');
   78     var e = readMPInt(der, 'exponent');
   79 
   80     // now, make the key
   81     var key = {
   82         type: 'rsa',
   83         source: der.originalInput,
   84         parts: [
   85             { name: 'e', data: e },
   86             { name: 'n', data: n }
   87         ]
   88     };
   89 
   90     return (new Key(key));
   91 }
   92 
   93 function readPkcs8RSAPrivate(der) {
   94     der.readSequence(asn1.Ber.OctetString);
   95     der.readSequence();
   96 
   97     var ver = readMPInt(der, 'version');
   98     assert.equal(ver[0], 0x0, 'unknown RSA private key version');
   99 
  100     // modulus then public exponent
  101     var n = readMPInt(der, 'modulus');
  102     var e = readMPInt(der, 'public exponent');
  103     var d = readMPInt(der, 'private exponent');
  104     var p = readMPInt(der, 'prime1');
  105     var q = readMPInt(der, 'prime2');
  106     var dmodp = readMPInt(der, 'exponent1');
  107     var dmodq = readMPInt(der, 'exponent2');
  108     var iqmp = readMPInt(der, 'iqmp');
  109 
  110     // now, make the key
  111     var key = {
  112         type: 'rsa',
  113         parts: [
  114             { name: 'n', data: n },
  115             { name: 'e', data: e },
  116             { name: 'd', data: d },
  117             { name: 'iqmp', data: iqmp },
  118             { name: 'p', data: p },
  119             { name: 'q', data: q },
  120             { name: 'dmodp', data: dmodp },
  121             { name: 'dmodq', data: dmodq }
  122         ]
  123     };
  124 
  125     return (new PrivateKey(key));
  126 }
  127 
  128 function readPkcs8DSAPublic(der) {
  129     der.readSequence();
  130 
  131     var p = readMPInt(der, 'p');
  132     var q = readMPInt(der, 'q');
  133     var g = readMPInt(der, 'g');
  134 
  135     // bit string sequence
  136     der.readSequence(asn1.Ber.BitString);
  137     der.readByte();
  138 
  139     var y = readMPInt(der, 'y');
  140 
  141     // now, make the key
  142     var key = {
  143         type: 'dsa',
  144         parts: [
  145             { name: 'p', data: p },
  146             { name: 'q', data: q },
  147             { name: 'g', data: g },
  148             { name: 'y', data: y }
  149         ]
  150     };
  151 
  152     return (new Key(key));
  153 }
  154 
  155 function readPkcs8DSAPrivate(der) {
  156     der.readSequence();
  157 
  158     var p = readMPInt(der, 'p');
  159     var q = readMPInt(der, 'q');
  160     var g = readMPInt(der, 'g');
  161 
  162     der.readSequence(asn1.Ber.OctetString);
  163     var x = readMPInt(der, 'x');
  164 
  165     /* The pkcs#8 format does not include the public key */
  166     var y = utils.calculateDSAPublic(g, p, x);
  167 
  168     var key = {
  169         type: 'dsa',
  170         parts: [
  171             { name: 'p', data: p },
  172             { name: 'q', data: q },
  173             { name: 'g', data: g },
  174             { name: 'y', data: y },
  175             { name: 'x', data: x }
  176         ]
  177     };
  178 
  179     return (new PrivateKey(key));
  180 }
  181 
  182 function readECDSACurve(der) {
  183     var curveName, curveNames;
  184     var j, c, cd;
  185 
  186     if (der.peek() === asn1.Ber.OID) {
  187         var oid = der.readOID();
  188 
  189         curveNames = Object.keys(algs.curves);
  190         for (j = 0; j < curveNames.length; ++j) {
  191             c = curveNames[j];
  192             cd = algs.curves[c];
  193             if (cd.pkcs8oid === oid) {
  194                 curveName = c;
  195                 break;
  196             }
  197         }
  198 
  199     } else {
  200         // ECParameters sequence
  201         der.readSequence();
  202         var version = der.readString(asn1.Ber.Integer, true);
  203         assert.strictEqual(version[0], 1, 'ECDSA key not version 1');
  204 
  205         var curve = {};
  206 
  207         // FieldID sequence
  208         der.readSequence();
  209         var fieldTypeOid = der.readOID();
  210         assert.strictEqual(fieldTypeOid, '1.2.840.10045.1.1',
  211             'ECDSA key is not from a prime-field');
  212         var p = curve.p = utils.mpNormalize(
  213             der.readString(asn1.Ber.Integer, true));
  214         /*
  215          * p always starts with a 1 bit, so count the zeros to get its
  216          * real size.
  217          */
  218         curve.size = p.length * 8 - utils.countZeros(p);
  219 
  220         // Curve sequence
  221         der.readSequence();
  222         curve.a = utils.mpNormalize(
  223             der.readString(asn1.Ber.OctetString, true));
  224         curve.b = utils.mpNormalize(
  225             der.readString(asn1.Ber.OctetString, true));
  226         if (der.peek() === asn1.Ber.BitString)
  227             curve.s = der.readString(asn1.Ber.BitString, true);
  228 
  229         // Combined Gx and Gy
  230         curve.G = der.readString(asn1.Ber.OctetString, true);
  231         assert.strictEqual(curve.G[0], 0x4,
  232             'uncompressed G is required');
  233 
  234         curve.n = utils.mpNormalize(
  235             der.readString(asn1.Ber.Integer, true));
  236         curve.h = utils.mpNormalize(
  237             der.readString(asn1.Ber.Integer, true));
  238         assert.strictEqual(curve.h[0], 0x1, 'a cofactor=1 curve is ' +
  239             'required');
  240 
  241         curveNames = Object.keys(algs.curves);
  242         var ks = Object.keys(curve);
  243         for (j = 0; j < curveNames.length; ++j) {
  244             c = curveNames[j];
  245             cd = algs.curves[c];
  246             var equal = true;
  247             for (var i = 0; i < ks.length; ++i) {
  248                 var k = ks[i];
  249                 if (cd[k] === undefined)
  250                     continue;
  251                 if (typeof (cd[k]) === 'object' &&
  252                     cd[k].equals !== undefined) {
  253                     if (!cd[k].equals(curve[k])) {
  254                         equal = false;
  255                         break;
  256                     }
  257                 } else if (Buffer.isBuffer(cd[k])) {
  258                     if (cd[k].toString('binary')
  259                         !== curve[k].toString('binary')) {
  260                         equal = false;
  261                         break;
  262                     }
  263                 } else {
  264                     if (cd[k] !== curve[k]) {
  265                         equal = false;
  266                         break;
  267                     }
  268                 }
  269             }
  270             if (equal) {
  271                 curveName = c;
  272                 break;
  273             }
  274         }
  275     }
  276     return (curveName);
  277 }
  278 
  279 function readPkcs8ECDSAPrivate(der) {
  280     var curveName = readECDSACurve(der);
  281     assert.string(curveName, 'a known elliptic curve');
  282 
  283     der.readSequence(asn1.Ber.OctetString);
  284     der.readSequence();
  285 
  286     var version = readMPInt(der, 'version');
  287     assert.equal(version[0], 1, 'unknown version of ECDSA key');
  288 
  289     var d = der.readString(asn1.Ber.OctetString, true);
  290     der.readSequence(0xa1);
  291 
  292     var Q = der.readString(asn1.Ber.BitString, true);
  293     Q = utils.ecNormalize(Q);
  294 
  295     var key = {
  296         type: 'ecdsa',
  297         parts: [
  298             { name: 'curve', data: new Buffer(curveName) },
  299             { name: 'Q', data: Q },
  300             { name: 'd', data: d }
  301         ]
  302     };
  303 
  304     return (new PrivateKey(key));
  305 }
  306 
  307 function readPkcs8ECDSAPublic(der) {
  308     var curveName = readECDSACurve(der);
  309     assert.string(curveName, 'a known elliptic curve');
  310 
  311     var Q = der.readString(asn1.Ber.BitString, true);
  312     Q = utils.ecNormalize(Q);
  313 
  314     var key = {
  315         type: 'ecdsa',
  316         parts: [
  317             { name: 'curve', data: new Buffer(curveName) },
  318             { name: 'Q', data: Q }
  319         ]
  320     };
  321 
  322     return (new Key(key));
  323 }
  324 
  325 function writePkcs8(der, key) {
  326     der.startSequence();
  327 
  328     if (PrivateKey.isPrivateKey(key)) {
  329         var sillyInt = new Buffer(1);
  330         sillyInt[0] = 0x0;
  331         der.writeBuffer(sillyInt, asn1.Ber.Integer);
  332     }
  333 
  334     der.startSequence();
  335     switch (key.type) {
  336     case 'rsa':
  337         der.writeOID('1.2.840.113549.1.1.1');
  338         if (PrivateKey.isPrivateKey(key))
  339             writePkcs8RSAPrivate(key, der);
  340         else
  341             writePkcs8RSAPublic(key, der);
  342         break;
  343     case 'dsa':
  344         der.writeOID('1.2.840.10040.4.1');
  345         if (PrivateKey.isPrivateKey(key))
  346             writePkcs8DSAPrivate(key, der);
  347         else
  348             writePkcs8DSAPublic(key, der);
  349         break;
  350     case 'ecdsa':
  351         der.writeOID('1.2.840.10045.2.1');
  352         if (PrivateKey.isPrivateKey(key))
  353             writePkcs8ECDSAPrivate(key, der);
  354         else
  355             writePkcs8ECDSAPublic(key, der);
  356         break;
  357     default:
  358         throw (new Error('Unsupported key type: ' + key.type));
  359     }
  360 
  361     der.endSequence();
  362 }
  363 
  364 function writePkcs8RSAPrivate(key, der) {
  365     der.writeNull();
  366     der.endSequence();
  367 
  368     der.startSequence(asn1.Ber.OctetString);
  369     der.startSequence();
  370 
  371     var version = new Buffer(1);
  372     version[0] = 0;
  373     der.writeBuffer(version, asn1.Ber.Integer);
  374 
  375     der.writeBuffer(key.part.n.data, asn1.Ber.Integer);
  376     der.writeBuffer(key.part.e.data, asn1.Ber.Integer);
  377     der.writeBuffer(key.part.d.data, asn1.Ber.Integer);
  378     der.writeBuffer(key.part.p.data, asn1.Ber.Integer);
  379     der.writeBuffer(key.part.q.data, asn1.Ber.Integer);
  380     if (!key.part.dmodp || !key.part.dmodq)
  381         utils.addRSAMissing(key);
  382     der.writeBuffer(key.part.dmodp.data, asn1.Ber.Integer);
  383     der.writeBuffer(key.part.dmodq.data, asn1.Ber.Integer);
  384     der.writeBuffer(key.part.iqmp.data, asn1.Ber.Integer);
  385 
  386     der.endSequence();
  387     der.endSequence();
  388 }
  389 
  390 function writePkcs8RSAPublic(key, der) {
  391     der.writeNull();
  392     der.endSequence();
  393 
  394     der.startSequence(asn1.Ber.BitString);
  395     der.writeByte(0x00);
  396 
  397     der.startSequence();
  398     der.writeBuffer(key.part.n.data, asn1.Ber.Integer);
  399     der.writeBuffer(key.part.e.data, asn1.Ber.Integer);
  400     der.endSequence();
  401 
  402     der.endSequence();
  403 }
  404 
  405 function writePkcs8DSAPrivate(key, der) {
  406     der.startSequence();
  407     der.writeBuffer(key.part.p.data, asn1.Ber.Integer);
  408     der.writeBuffer(key.part.q.data, asn1.Ber.Integer);
  409     der.writeBuffer(key.part.g.data, asn1.Ber.Integer);
  410     der.endSequence();
  411 
  412     der.endSequence();
  413 
  414     der.startSequence(asn1.Ber.OctetString);
  415     der.writeBuffer(key.part.x.data, asn1.Ber.Integer);
  416     der.endSequence();
  417 }
  418 
  419 function writePkcs8DSAPublic(key, der) {
  420     der.startSequence();
  421     der.writeBuffer(key.part.p.data, asn1.Ber.Integer);
  422     der.writeBuffer(key.part.q.data, asn1.Ber.Integer);
  423     der.writeBuffer(key.part.g.data, asn1.Ber.Integer);
  424     der.endSequence();
  425     der.endSequence();
  426 
  427     der.startSequence(asn1.Ber.BitString);
  428     der.writeByte(0x00);
  429     der.writeBuffer(key.part.y.data, asn1.Ber.Integer);
  430     der.endSequence();
  431 }
  432 
  433 function writeECDSACurve(key, der) {
  434     var curve = algs.curves[key.curve];
  435     if (curve.pkcs8oid) {
  436         /* This one has a name in pkcs#8, so just write the oid */
  437         der.writeOID(curve.pkcs8oid);
  438 
  439     } else {
  440         // ECParameters sequence
  441         der.startSequence();
  442 
  443         var version = new Buffer(1);
  444         version.writeUInt8(1, 0);
  445         der.writeBuffer(version, asn1.Ber.Integer);
  446 
  447         // FieldID sequence
  448         der.startSequence();
  449         der.writeOID('1.2.840.10045.1.1'); // prime-field
  450         der.writeBuffer(curve.p, asn1.Ber.Integer);
  451         der.endSequence();
  452 
  453         // Curve sequence
  454         der.startSequence();
  455         var a = curve.p;
  456         if (a[0] === 0x0)
  457             a = a.slice(1);
  458         der.writeBuffer(a, asn1.Ber.OctetString);
  459         der.writeBuffer(curve.b, asn1.Ber.OctetString);
  460         der.writeBuffer(curve.s, asn1.Ber.BitString);
  461         der.endSequence();
  462 
  463         der.writeBuffer(curve.G, asn1.Ber.OctetString);
  464         der.writeBuffer(curve.n, asn1.Ber.Integer);
  465         var h = curve.h;
  466         if (!h) {
  467             h = new Buffer(1);
  468             h[0] = 1;
  469         }
  470         der.writeBuffer(h, asn1.Ber.Integer);
  471 
  472         // ECParameters
  473         der.endSequence();
  474     }
  475 }
  476 
  477 function writePkcs8ECDSAPublic(key, der) {
  478     writeECDSACurve(key, der);
  479     der.endSequence();
  480 
  481     var Q = utils.ecNormalize(key.part.Q.data, true);
  482     der.writeBuffer(Q, asn1.Ber.BitString);
  483 }
  484 
  485 function writePkcs8ECDSAPrivate(key, der) {
  486     writeECDSACurve(key, der);
  487     der.endSequence();
  488 
  489     der.startSequence(asn1.Ber.OctetString);
  490     der.startSequence();
  491 
  492     var version = new Buffer(1);
  493     version[0] = 1;
  494     der.writeBuffer(version, asn1.Ber.Integer);
  495 
  496     der.writeBuffer(key.part.d.data, asn1.Ber.OctetString);
  497 
  498     der.startSequence(0xa1);
  499     var Q = utils.ecNormalize(key.part.Q.data, true);
  500     der.writeBuffer(Q, asn1.Ber.BitString);
  501     der.endSequence();
  502 
  503     der.endSequence();
  504     der.endSequence();
  505 }