"Fossies" - the Fresh Open Source Software Archive

Member "Atom/resources/app/apm/node_modules/sshpk/lib/identity.js" (8 Mar 2017, 7412 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 2016 Joyent, Inc.
    2 
    3 module.exports = Identity;
    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 asn1 = require('asn1');
   14 
   15 /*JSSTYLED*/
   16 var DNS_NAME_RE = /^([*]|[a-z0-9][a-z0-9\-]{0,62})(?:\.([*]|[a-z0-9][a-z0-9\-]{0,62}))*$/i;
   17 
   18 var oids = {};
   19 oids.cn = '2.5.4.3';
   20 oids.o = '2.5.4.10';
   21 oids.ou = '2.5.4.11';
   22 oids.l = '2.5.4.7';
   23 oids.s = '2.5.4.8';
   24 oids.c = '2.5.4.6';
   25 oids.sn = '2.5.4.4';
   26 oids.dc = '0.9.2342.19200300.100.1.25';
   27 oids.uid = '0.9.2342.19200300.100.1.1';
   28 oids.mail = '0.9.2342.19200300.100.1.3';
   29 
   30 var unoids = {};
   31 Object.keys(oids).forEach(function (k) {
   32     unoids[oids[k]] = k;
   33 });
   34 
   35 function Identity(opts) {
   36     var self = this;
   37     assert.object(opts, 'options');
   38     assert.arrayOfObject(opts.components, 'options.components');
   39     this.components = opts.components;
   40     this.componentLookup = {};
   41     this.components.forEach(function (c) {
   42         if (c.name && !c.oid)
   43             c.oid = oids[c.name];
   44         if (c.oid && !c.name)
   45             c.name = unoids[c.oid];
   46         if (self.componentLookup[c.name] === undefined)
   47             self.componentLookup[c.name] = [];
   48         self.componentLookup[c.name].push(c);
   49     });
   50     if (this.componentLookup.cn && this.componentLookup.cn.length > 0) {
   51         this.cn = this.componentLookup.cn[0].value;
   52     }
   53     assert.optionalString(opts.type, 'options.type');
   54     if (opts.type === undefined) {
   55         if (this.components.length === 1 &&
   56             this.componentLookup.cn &&
   57             this.componentLookup.cn.length === 1 &&
   58             this.componentLookup.cn[0].value.match(DNS_NAME_RE)) {
   59             this.type = 'host';
   60             this.hostname = this.componentLookup.cn[0].value;
   61 
   62         } else if (this.componentLookup.dc &&
   63             this.components.length === this.componentLookup.dc.length) {
   64             this.type = 'host';
   65             this.hostname = this.componentLookup.dc.map(
   66                 function (c) {
   67                 return (c.value);
   68             }).join('.');
   69 
   70         } else if (this.componentLookup.uid &&
   71             this.components.length ===
   72             this.componentLookup.uid.length) {
   73             this.type = 'user';
   74             this.uid = this.componentLookup.uid[0].value;
   75 
   76         } else if (this.componentLookup.cn &&
   77             this.componentLookup.cn.length === 1 &&
   78             this.componentLookup.cn[0].value.match(DNS_NAME_RE)) {
   79             this.type = 'host';
   80             this.hostname = this.componentLookup.cn[0].value;
   81 
   82         } else if (this.componentLookup.uid &&
   83             this.componentLookup.uid.length === 1) {
   84             this.type = 'user';
   85             this.uid = this.componentLookup.uid[0].value;
   86 
   87         } else if (this.componentLookup.mail &&
   88             this.componentLookup.mail.length === 1) {
   89             this.type = 'email';
   90             this.email = this.componentLookup.mail[0].value;
   91 
   92         } else if (this.componentLookup.cn &&
   93             this.componentLookup.cn.length === 1) {
   94             this.type = 'user';
   95             this.uid = this.componentLookup.cn[0].value;
   96 
   97         } else {
   98             this.type = 'unknown';
   99         }
  100     } else {
  101         this.type = opts.type;
  102         if (this.type === 'host')
  103             this.hostname = opts.hostname;
  104         else if (this.type === 'user')
  105             this.uid = opts.uid;
  106         else if (this.type === 'email')
  107             this.email = opts.email;
  108         else
  109             throw (new Error('Unknown type ' + this.type));
  110     }
  111 }
  112 
  113 Identity.prototype.toString = function () {
  114     return (this.components.map(function (c) {
  115         return (c.name.toUpperCase() + '=' + c.value);
  116     }).join(', '));
  117 };
  118 
  119 /*
  120  * These are from X.680 -- PrintableString allowed chars are in section 37.4
  121  * table 8. Spec for IA5Strings is "1,6 + SPACE + DEL" where 1 refers to
  122  * ISO IR #001 (standard ASCII control characters) and 6 refers to ISO IR #006
  123  * (the basic ASCII character set).
  124  */
  125 /* JSSTYLED */
  126 var NOT_PRINTABLE = /[^a-zA-Z0-9 '(),+.\/:=?-]/;
  127 /* JSSTYLED */
  128 var NOT_IA5 = /[^\x00-\x7f]/;
  129 
  130 Identity.prototype.toAsn1 = function (der, tag) {
  131     der.startSequence(tag);
  132     this.components.forEach(function (c) {
  133         der.startSequence(asn1.Ber.Constructor | asn1.Ber.Set);
  134         der.startSequence();
  135         der.writeOID(c.oid);
  136         /*
  137          * If we fit in a PrintableString, use that. Otherwise use an
  138          * IA5String or UTF8String.
  139          */
  140         if (c.value.match(NOT_IA5)) {
  141             var v = new Buffer(c.value, 'utf8');
  142             der.writeBuffer(v, asn1.Ber.Utf8String);
  143         } else if (c.value.match(NOT_PRINTABLE)) {
  144             der.writeString(c.value, asn1.Ber.IA5String);
  145         } else {
  146             der.writeString(c.value, asn1.Ber.PrintableString);
  147         }
  148         der.endSequence();
  149         der.endSequence();
  150     });
  151     der.endSequence();
  152 };
  153 
  154 function globMatch(a, b) {
  155     if (a === '**' || b === '**')
  156         return (true);
  157     var aParts = a.split('.');
  158     var bParts = b.split('.');
  159     if (aParts.length !== bParts.length)
  160         return (false);
  161     for (var i = 0; i < aParts.length; ++i) {
  162         if (aParts[i] === '*' || bParts[i] === '*')
  163             continue;
  164         if (aParts[i] !== bParts[i])
  165             return (false);
  166     }
  167     return (true);
  168 }
  169 
  170 Identity.prototype.equals = function (other) {
  171     if (!Identity.isIdentity(other, [1, 0]))
  172         return (false);
  173     if (other.components.length !== this.components.length)
  174         return (false);
  175     for (var i = 0; i < this.components.length; ++i) {
  176         if (this.components[i].oid !== other.components[i].oid)
  177             return (false);
  178         if (!globMatch(this.components[i].value,
  179             other.components[i].value)) {
  180             return (false);
  181         }
  182     }
  183     return (true);
  184 };
  185 
  186 Identity.forHost = function (hostname) {
  187     assert.string(hostname, 'hostname');
  188     return (new Identity({
  189         type: 'host',
  190         hostname: hostname,
  191         components: [ { name: 'cn', value: hostname } ]
  192     }));
  193 };
  194 
  195 Identity.forUser = function (uid) {
  196     assert.string(uid, 'uid');
  197     return (new Identity({
  198         type: 'user',
  199         uid: uid,
  200         components: [ { name: 'uid', value: uid } ]
  201     }));
  202 };
  203 
  204 Identity.forEmail = function (email) {
  205     assert.string(email, 'email');
  206     return (new Identity({
  207         type: 'email',
  208         email: email,
  209         components: [ { name: 'mail', value: email } ]
  210     }));
  211 };
  212 
  213 Identity.parseDN = function (dn) {
  214     assert.string(dn, 'dn');
  215     var parts = dn.split(',');
  216     var cmps = parts.map(function (c) {
  217         c = c.trim();
  218         var eqPos = c.indexOf('=');
  219         var name = c.slice(0, eqPos).toLowerCase();
  220         var value = c.slice(eqPos + 1);
  221         return ({ name: name, value: value });
  222     });
  223     return (new Identity({ components: cmps }));
  224 };
  225 
  226 Identity.parseAsn1 = function (der, top) {
  227     var components = [];
  228     der.readSequence(top);
  229     var end = der.offset + der.length;
  230     while (der.offset < end) {
  231         der.readSequence(asn1.Ber.Constructor | asn1.Ber.Set);
  232         var after = der.offset + der.length;
  233         der.readSequence();
  234         var oid = der.readOID();
  235         var type = der.peek();
  236         var value;
  237         switch (type) {
  238         case asn1.Ber.PrintableString:
  239         case asn1.Ber.IA5String:
  240         case asn1.Ber.OctetString:
  241         case asn1.Ber.T61String:
  242             value = der.readString(type);
  243             break;
  244         case asn1.Ber.Utf8String:
  245             value = der.readString(type, true);
  246             value = value.toString('utf8');
  247             break;
  248         case asn1.Ber.CharacterString:
  249         case asn1.Ber.BMPString:
  250             value = der.readString(type, true);
  251             value = value.toString('utf16le');
  252             break;
  253         default:
  254             throw (new Error('Unknown asn1 type ' + type));
  255         }
  256         components.push({ oid: oid, value: value });
  257         der._offset = after;
  258     }
  259     der._offset = end;
  260     return (new Identity({
  261         components: components
  262     }));
  263 };
  264 
  265 Identity.isIdentity = function (obj, ver) {
  266     return (utils.isCompatible(obj, Identity, ver));
  267 };
  268 
  269 /*
  270  * API versions for Identity:
  271  * [1,0] -- initial ver
  272  */
  273 Identity.prototype._sshpkApiVersion = [1, 0];
  274 
  275 Identity._oldVersionDetect = function (obj) {
  276     return ([1, 0]);
  277 };