"Fossies" - the Fresh Open Source Software Archive

Member "Atom/resources/app/apm/node_modules/sshpk/lib/private-key.js" (8 Mar 2017, 6044 Bytes) of archive /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 = PrivateKey;
    4 
    5 var assert = require('assert-plus');
    6 var algs = require('./algs');
    7 var crypto = require('crypto');
    8 var Fingerprint = require('./fingerprint');
    9 var Signature = require('./signature');
   10 var errs = require('./errors');
   11 var util = require('util');
   12 var utils = require('./utils');
   13 var edCompat;
   14 var ed;
   15 
   16 try {
   17     edCompat = require('./ed-compat');
   18 } catch (e) {
   19     /* Just continue through, and bail out if we try to use it. */
   20 }
   21 
   22 var Key = require('./key');
   23 
   24 var InvalidAlgorithmError = errs.InvalidAlgorithmError;
   25 var KeyParseError = errs.KeyParseError;
   26 var KeyEncryptedError = errs.KeyEncryptedError;
   27 
   28 var formats = {};
   29 formats['auto'] = require('./formats/auto');
   30 formats['pem'] = require('./formats/pem');
   31 formats['pkcs1'] = require('./formats/pkcs1');
   32 formats['pkcs8'] = require('./formats/pkcs8');
   33 formats['rfc4253'] = require('./formats/rfc4253');
   34 formats['ssh-private'] = require('./formats/ssh-private');
   35 formats['openssh'] = formats['ssh-private'];
   36 formats['ssh'] = formats['ssh-private'];
   37 
   38 function PrivateKey(opts) {
   39     assert.object(opts, 'options');
   40     Key.call(this, opts);
   41 
   42     this._pubCache = undefined;
   43 }
   44 util.inherits(PrivateKey, Key);
   45 
   46 PrivateKey.formats = formats;
   47 
   48 PrivateKey.prototype.toBuffer = function (format, options) {
   49     if (format === undefined)
   50         format = 'pkcs1';
   51     assert.string(format, 'format');
   52     assert.object(formats[format], 'formats[format]');
   53     assert.optionalObject(options, 'options');
   54 
   55     return (formats[format].write(this, options));
   56 };
   57 
   58 PrivateKey.prototype.hash = function (algo) {
   59     return (this.toPublic().hash(algo));
   60 };
   61 
   62 PrivateKey.prototype.toPublic = function () {
   63     if (this._pubCache)
   64         return (this._pubCache);
   65 
   66     var algInfo = algs.info[this.type];
   67     var pubParts = [];
   68     for (var i = 0; i < algInfo.parts.length; ++i) {
   69         var p = algInfo.parts[i];
   70         pubParts.push(this.part[p]);
   71     }
   72 
   73     this._pubCache = new Key({
   74         type: this.type,
   75         source: this,
   76         parts: pubParts
   77     });
   78     if (this.comment)
   79         this._pubCache.comment = this.comment;
   80     return (this._pubCache);
   81 };
   82 
   83 PrivateKey.prototype.derive = function (newType, newSize) {
   84     assert.string(newType, 'type');
   85     assert.optionalNumber(newSize, 'size');
   86     var priv, pub;
   87 
   88     if (this.type === 'ed25519' && newType === 'curve25519') {
   89         if (ed === undefined)
   90             ed = require('jodid25519');
   91 
   92         priv = this.part.r.data;
   93         if (priv[0] === 0x00)
   94             priv = priv.slice(1);
   95         priv = priv.slice(0, 32);
   96 
   97         pub = ed.dh.publicKey(priv);
   98         priv = utils.mpNormalize(Buffer.concat([priv, pub]));
   99 
  100         return (new PrivateKey({
  101             type: 'curve25519',
  102             parts: [
  103                 { name: 'R', data: utils.mpNormalize(pub) },
  104                 { name: 'r', data: priv }
  105             ]
  106         }));
  107     } else if (this.type === 'curve25519' && newType === 'ed25519') {
  108         if (ed === undefined)
  109             ed = require('jodid25519');
  110 
  111         priv = this.part.r.data;
  112         if (priv[0] === 0x00)
  113             priv = priv.slice(1);
  114         priv = priv.slice(0, 32);
  115 
  116         pub = ed.eddsa.publicKey(priv.toString('binary'));
  117         pub = new Buffer(pub, 'binary');
  118 
  119         priv = utils.mpNormalize(Buffer.concat([priv, pub]));
  120 
  121         return (new PrivateKey({
  122             type: 'ed25519',
  123             parts: [
  124                 { name: 'R', data: utils.mpNormalize(pub) },
  125                 { name: 'r', data: priv }
  126             ]
  127         }));
  128     }
  129     throw (new Error('Key derivation not supported from ' + this.type +
  130         ' to ' + newType));
  131 };
  132 
  133 PrivateKey.prototype.createVerify = function (hashAlgo) {
  134     return (this.toPublic().createVerify(hashAlgo));
  135 };
  136 
  137 PrivateKey.prototype.createSign = function (hashAlgo) {
  138     if (hashAlgo === undefined)
  139         hashAlgo = this.defaultHashAlgorithm();
  140     assert.string(hashAlgo, 'hash algorithm');
  141 
  142     /* ED25519 is not supported by OpenSSL, use a javascript impl. */
  143     if (this.type === 'ed25519' && edCompat !== undefined)
  144         return (new edCompat.Signer(this, hashAlgo));
  145     if (this.type === 'curve25519')
  146         throw (new Error('Curve25519 keys are not suitable for ' +
  147             'signing or verification'));
  148 
  149     var v, nm, err;
  150     try {
  151         nm = hashAlgo.toUpperCase();
  152         v = crypto.createSign(nm);
  153     } catch (e) {
  154         err = e;
  155     }
  156     if (v === undefined || (err instanceof Error &&
  157         err.message.match(/Unknown message digest/))) {
  158         nm = 'RSA-';
  159         nm += hashAlgo.toUpperCase();
  160         v = crypto.createSign(nm);
  161     }
  162     assert.ok(v, 'failed to create verifier');
  163     var oldSign = v.sign.bind(v);
  164     var key = this.toBuffer('pkcs1');
  165     var type = this.type;
  166     v.sign = function () {
  167         var sig = oldSign(key);
  168         if (typeof (sig) === 'string')
  169             sig = new Buffer(sig, 'binary');
  170         sig = Signature.parse(sig, type, 'asn1');
  171         sig.hashAlgorithm = hashAlgo;
  172         return (sig);
  173     };
  174     return (v);
  175 };
  176 
  177 PrivateKey.parse = function (data, format, options) {
  178     if (typeof (data) !== 'string')
  179         assert.buffer(data, 'data');
  180     if (format === undefined)
  181         format = 'auto';
  182     assert.string(format, 'format');
  183     if (typeof (options) === 'string')
  184         options = { filename: options };
  185     assert.optionalObject(options, 'options');
  186     if (options === undefined)
  187         options = {};
  188     assert.optionalString(options.filename, 'options.filename');
  189     if (options.filename === undefined)
  190         options.filename = '(unnamed)';
  191 
  192     assert.object(formats[format], 'formats[format]');
  193 
  194     try {
  195         var k = formats[format].read(data, options);
  196         assert.ok(k instanceof PrivateKey, 'key is not a private key');
  197         if (!k.comment)
  198             k.comment = options.filename;
  199         return (k);
  200     } catch (e) {
  201         if (e.name === 'KeyEncryptedError')
  202             throw (e);
  203         throw (new KeyParseError(options.filename, format, e));
  204     }
  205 };
  206 
  207 PrivateKey.isPrivateKey = function (obj, ver) {
  208     return (utils.isCompatible(obj, PrivateKey, ver));
  209 };
  210 
  211 /*
  212  * API versions for PrivateKey:
  213  * [1,0] -- initial ver
  214  * [1,1] -- added auto, pkcs[18], openssh/ssh-private formats
  215  * [1,2] -- added defaultHashAlgorithm
  216  * [1,3] -- added derive, ed, createDH
  217  * [1,4] -- first tagged version
  218  */
  219 PrivateKey.prototype._sshpkApiVersion = [1, 4];
  220 
  221 PrivateKey._oldVersionDetect = function (obj) {
  222     assert.func(obj.toPublic);
  223     assert.func(obj.createSign);
  224     if (obj.derive)
  225         return ([1, 3]);
  226     if (obj.defaultHashAlgorithm)
  227         return ([1, 2]);
  228     if (obj.formats['auto'])
  229         return ([1, 1]);
  230     return ([1, 0]);
  231 };