node-forge 0.10.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/http.js CHANGED
@@ -6,7 +6,6 @@
6
6
  * Copyright (c) 2010-2014 Digital Bazaar, Inc. All rights reserved.
7
7
  */
8
8
  var forge = require('./forge');
9
- require('./debug');
10
9
  require('./tls');
11
10
  require('./util');
12
11
 
@@ -16,11 +15,6 @@ var http = module.exports = forge.http = forge.http || {};
16
15
  // logging category
17
16
  var cat = 'forge.http';
18
17
 
19
- // add array of clients to debug storage
20
- if(forge.debug) {
21
- forge.debug.set('forge.http', 'clients', []);
22
- }
23
-
24
18
  // normalizes an http header field name
25
19
  var _normalize = function(name) {
26
20
  return name.toLowerCase().replace(/(^.)|(-.)/g,
@@ -39,8 +33,8 @@ var _getStorageId = function(client) {
39
33
  // browsers (if this is undesirable)
40
34
  // navigator.userAgent
41
35
  return 'forge.http.' +
42
- client.url.scheme + '.' +
43
- client.url.host + '.' +
36
+ client.url.protocol.slice(0, -1) + '.' +
37
+ client.url.hostname + '.' +
44
38
  client.url.port;
45
39
  };
46
40
 
@@ -127,7 +121,7 @@ var _doRequest = function(client, socket) {
127
121
  // connect
128
122
  socket.options.request.connectTime = +new Date();
129
123
  socket.connect({
130
- host: client.url.host,
124
+ host: client.url.hostname,
131
125
  port: client.url.port,
132
126
  policyPort: client.policyPort,
133
127
  policyUrl: client.policyUrl
@@ -316,7 +310,7 @@ var _initSocket = function(client, socket, tlsOptions) {
316
310
  // prime socket by connecting and caching TLS session, will do
317
311
  // next request from there
318
312
  socket.connect({
319
- host: client.url.host,
313
+ host: client.url.hostname,
320
314
  port: client.url.port,
321
315
  policyPort: client.policyPort,
322
316
  policyUrl: client.policyUrl
@@ -411,7 +405,7 @@ var _readCookies = function(client, response) {
411
405
  *
412
406
  * @param options:
413
407
  * url: the url to connect to (scheme://host:port).
414
- * socketPool: the flash socket pool to use.
408
+ * socketPool: the flash socket pool to use.
415
409
  * policyPort: the flash policy port to use (if other than the
416
410
  * socket pool default), use 0 for flash default.
417
411
  * policyUrl: the flash policy file URL to use (if provided will
@@ -447,8 +441,10 @@ http.createClient = function(options) {
447
441
  // get scheme, host, and port from url
448
442
  options.url = (options.url ||
449
443
  window.location.protocol + '//' + window.location.host);
450
- var url = http.parseUrl(options.url);
451
- if(!url) {
444
+ var url;
445
+ try {
446
+ url = new URL(options.url);
447
+ } catch(e) {
452
448
  var error = new Error('Invalid url.');
453
449
  error.details = {url: options.url};
454
450
  throw error;
@@ -475,7 +471,7 @@ http.createClient = function(options) {
475
471
  // idle sockets
476
472
  idle: [],
477
473
  // whether or not the connections are secure
478
- secure: (url.scheme === 'https'),
474
+ secure: (url.protocol === 'https:'),
479
475
  // cookie jar (key'd off of name and then path, there is only 1 domain
480
476
  // and one setting for secure per client so name+path is unique)
481
477
  cookies: {},
@@ -484,11 +480,6 @@ http.createClient = function(options) {
484
480
  true : options.persistCookies
485
481
  };
486
482
 
487
- // add client to debug storage
488
- if(forge.debug) {
489
- forge.debug.get('forge.http', 'clients').push(client);
490
- }
491
-
492
483
  // load cookies from disk
493
484
  _loadCookies(client);
494
485
 
@@ -508,7 +499,7 @@ http.createClient = function(options) {
508
499
  if(depth === 0 && verified === true) {
509
500
  // compare common name to url host
510
501
  var cn = certs[depth].subject.getField('CN');
511
- if(cn === null || client.url.host !== cn.value) {
502
+ if(cn === null || client.url.hostname !== cn.value) {
512
503
  verified = {
513
504
  message: 'Certificate common name does not match url host.'
514
505
  };
@@ -523,7 +514,7 @@ http.createClient = function(options) {
523
514
  tlsOptions = {
524
515
  caStore: caStore,
525
516
  cipherSuites: options.cipherSuites || null,
526
- virtualHost: options.virtualHost || url.host,
517
+ virtualHost: options.virtualHost || url.hostname,
527
518
  verify: options.verify || _defaultCertificateVerify,
528
519
  getCertificate: options.getCertificate || null,
529
520
  getPrivateKey: options.getPrivateKey || null,
@@ -563,7 +554,7 @@ http.createClient = function(options) {
563
554
  client.send = function(options) {
564
555
  // add host header if not set
565
556
  if(options.request.getField('Host') === null) {
566
- options.request.setField('Host', client.url.fullHost);
557
+ options.request.setField('Host', client.url.origin);
567
558
  }
568
559
 
569
560
  // set default dummy handlers
@@ -1318,15 +1309,6 @@ http.createResponse = function() {
1318
1309
  return response;
1319
1310
  };
1320
1311
 
1321
- /**
1322
- * Parses the scheme, host, and port from an http(s) url.
1323
- *
1324
- * @param str the url string.
1325
- *
1326
- * @return the parsed url object or null if the url is invalid.
1327
- */
1328
- http.parseUrl = forge.util.parseUrl;
1329
-
1330
1312
  /**
1331
1313
  * Returns true if the given url is within the given cookie's domain.
1332
1314
  *
@@ -1347,11 +1329,11 @@ http.withinCookieDomain = function(url, cookie) {
1347
1329
  // ensure domain starts with a '.'
1348
1330
  // parse URL as necessary
1349
1331
  if(typeof url === 'string') {
1350
- url = http.parseUrl(url);
1332
+ url = new URL(url);
1351
1333
  }
1352
1334
 
1353
- // add '.' to front of URL host to match against domain
1354
- var host = '.' + url.host;
1335
+ // add '.' to front of URL hostname to match against domain
1336
+ var host = '.' + url.hostname;
1355
1337
 
1356
1338
  // if the host ends with domain then it falls within it
1357
1339
  var idx = host.lastIndexOf(domain);
package/lib/index.js CHANGED
@@ -10,7 +10,6 @@ require('./aes');
10
10
  require('./aesCipherSuites');
11
11
  require('./asn1');
12
12
  require('./cipher');
13
- require('./debug');
14
13
  require('./des');
15
14
  require('./ed25519');
16
15
  require('./hmac');
@@ -30,6 +29,5 @@ require('./pss');
30
29
  require('./random');
31
30
  require('./rc2');
32
31
  require('./ssh');
33
- require('./task');
34
32
  require('./tls');
35
33
  require('./util');
package/lib/log.js CHANGED
@@ -286,7 +286,7 @@ if(typeof(console) !== 'undefined' && 'log' in console) {
286
286
  }
287
287
 
288
288
  /*
289
- * Check for logging control query vars.
289
+ * Check for logging control query vars in current URL.
290
290
  *
291
291
  * console.level=<level-name>
292
292
  * Set's the console log level by name. Useful to override defaults and
@@ -297,16 +297,18 @@ if(typeof(console) !== 'undefined' && 'log' in console) {
297
297
  * after console.level is processed. Useful to force a level of verbosity
298
298
  * that could otherwise be limited by a user config.
299
299
  */
300
- if(sConsoleLogger !== null) {
301
- var query = forge.util.getQueryVariables();
302
- if('console.level' in query) {
300
+ if(sConsoleLogger !== null &&
301
+ typeof window !== 'undefined' && window.location
302
+ ) {
303
+ var query = new URL(window.location.href).searchParams;
304
+ if(query.has('console.level')) {
303
305
  // set with last value
304
306
  forge.log.setLevel(
305
- sConsoleLogger, query['console.level'].slice(-1)[0]);
307
+ sConsoleLogger, query.get('console.level').slice(-1)[0]);
306
308
  }
307
- if('console.lock' in query) {
309
+ if(query.has('console.lock')) {
308
310
  // set with last value
309
- var lock = query['console.lock'].slice(-1)[0];
311
+ var lock = query.get('console.lock').slice(-1)[0];
310
312
  if(lock == 'true') {
311
313
  forge.log.lock(sConsoleLogger);
312
314
  }
package/lib/oids.js CHANGED
@@ -42,6 +42,8 @@ _IN('1.2.840.10040.4.3', 'dsa-with-sha1');
42
42
  _IN('1.3.14.3.2.7', 'desCBC');
43
43
 
44
44
  _IN('1.3.14.3.2.26', 'sha1');
45
+ // Deprecated equivalent of sha1WithRSAEncryption
46
+ _IN('1.3.14.3.2.29', 'sha1WithRSASignature');
45
47
  _IN('2.16.840.1.101.3.4.2.1', 'sha256');
46
48
  _IN('2.16.840.1.101.3.4.2.2', 'sha384');
47
49
  _IN('2.16.840.1.101.3.4.2.3', 'sha512');
@@ -104,16 +106,19 @@ _IN('2.16.840.1.101.3.4.1.42', 'aes256-CBC');
104
106
 
105
107
  // certificate issuer/subject OIDs
106
108
  _IN('2.5.4.3', 'commonName');
107
- _IN('2.5.4.5', 'serialName');
109
+ _IN('2.5.4.4', 'surname');
110
+ _IN('2.5.4.5', 'serialNumber');
108
111
  _IN('2.5.4.6', 'countryName');
109
112
  _IN('2.5.4.7', 'localityName');
110
113
  _IN('2.5.4.8', 'stateOrProvinceName');
111
114
  _IN('2.5.4.9', 'streetAddress');
112
115
  _IN('2.5.4.10', 'organizationName');
113
116
  _IN('2.5.4.11', 'organizationalUnitName');
117
+ _IN('2.5.4.12', 'title');
114
118
  _IN('2.5.4.13', 'description');
115
119
  _IN('2.5.4.15', 'businessCategory');
116
120
  _IN('2.5.4.17', 'postalCode');
121
+ _IN('2.5.4.42', 'givenName');
117
122
  _IN('1.3.6.1.4.1.311.60.2.1.2', 'jurisdictionOfIncorporationStateOrProvinceName');
118
123
  _IN('1.3.6.1.4.1.311.60.2.1.3', 'jurisdictionOfIncorporationCountryName');
119
124
 
package/lib/pem.js CHANGED
@@ -106,8 +106,15 @@ pem.decode = function(str) {
106
106
  break;
107
107
  }
108
108
 
109
+ // accept "NEW CERTIFICATE REQUEST" as "CERTIFICATE REQUEST"
110
+ // https://datatracker.ietf.org/doc/html/rfc7468#section-7
111
+ var type = match[1];
112
+ if(type === 'NEW CERTIFICATE REQUEST') {
113
+ type = 'CERTIFICATE REQUEST';
114
+ }
115
+
109
116
  var msg = {
110
- type: match[1],
117
+ type: type,
111
118
  procType: null,
112
119
  contentDomain: null,
113
120
  dekInfo: null,
package/lib/pkcs7.js CHANGED
@@ -837,7 +837,7 @@ function _recipientFromAsn1(obj) {
837
837
  serialNumber: forge.util.createBuffer(capture.serial).toHex(),
838
838
  encryptedContent: {
839
839
  algorithm: asn1.derToOid(capture.encAlgorithm),
840
- parameter: capture.encParameter.value,
840
+ parameter: capture.encParameter ? capture.encParameter.value : undefined,
841
841
  content: capture.encKey
842
842
  }
843
843
  };
@@ -1124,8 +1124,11 @@ function _encryptedContentToAsn1(ec) {
1124
1124
  asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
1125
1125
  asn1.oidToDer(ec.algorithm).getBytes()),
1126
1126
  // Parameters (IV)
1127
- asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false,
1128
- ec.parameter.getBytes())
1127
+ !ec.parameter ?
1128
+ undefined :
1129
+ asn1.create(
1130
+ asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false,
1131
+ ec.parameter.getBytes())
1129
1132
  ]),
1130
1133
  // [0] EncryptedContent
1131
1134
  asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [
package/lib/pkcs7asn1.js CHANGED
@@ -397,7 +397,8 @@ p7v.recipientInfoValidator = {
397
397
  name: 'RecipientInfo.keyEncryptionAlgorithm.parameter',
398
398
  tagClass: asn1.Class.UNIVERSAL,
399
399
  constructed: false,
400
- captureAsn1: 'encParameter'
400
+ captureAsn1: 'encParameter',
401
+ optional: true
401
402
  }]
402
403
  }, {
403
404
  name: 'RecipientInfo.encryptedKey',
package/lib/prng.js CHANGED
@@ -317,7 +317,7 @@ prng.create = function(plugin) {
317
317
  // throw in more pseudo random
318
318
  next = seed >>> (i << 3);
319
319
  next ^= Math.floor(Math.random() * 0x0100);
320
- b.putByte(String.fromCharCode(next & 0xFF));
320
+ b.putByte(next & 0xFF);
321
321
  }
322
322
  }
323
323
  }
package/lib/util.js CHANGED
@@ -2258,261 +2258,6 @@ util.clearItems = function(api, id, location) {
2258
2258
  _callStorageFunction(_clearItems, arguments, location);
2259
2259
  };
2260
2260
 
2261
- /**
2262
- * Parses the scheme, host, and port from an http(s) url.
2263
- *
2264
- * @param str the url string.
2265
- *
2266
- * @return the parsed url object or null if the url is invalid.
2267
- */
2268
- util.parseUrl = function(str) {
2269
- // FIXME: this regex looks a bit broken
2270
- var regex = /^(https?):\/\/([^:&^\/]*):?(\d*)(.*)$/g;
2271
- regex.lastIndex = 0;
2272
- var m = regex.exec(str);
2273
- var url = (m === null) ? null : {
2274
- full: str,
2275
- scheme: m[1],
2276
- host: m[2],
2277
- port: m[3],
2278
- path: m[4]
2279
- };
2280
- if(url) {
2281
- url.fullHost = url.host;
2282
- if(url.port) {
2283
- if(url.port !== 80 && url.scheme === 'http') {
2284
- url.fullHost += ':' + url.port;
2285
- } else if(url.port !== 443 && url.scheme === 'https') {
2286
- url.fullHost += ':' + url.port;
2287
- }
2288
- } else if(url.scheme === 'http') {
2289
- url.port = 80;
2290
- } else if(url.scheme === 'https') {
2291
- url.port = 443;
2292
- }
2293
- url.full = url.scheme + '://' + url.fullHost;
2294
- }
2295
- return url;
2296
- };
2297
-
2298
- /* Storage for query variables */
2299
- var _queryVariables = null;
2300
-
2301
- /**
2302
- * Returns the window location query variables. Query is parsed on the first
2303
- * call and the same object is returned on subsequent calls. The mapping
2304
- * is from keys to an array of values. Parameters without values will have
2305
- * an object key set but no value added to the value array. Values are
2306
- * unescaped.
2307
- *
2308
- * ...?k1=v1&k2=v2:
2309
- * {
2310
- * "k1": ["v1"],
2311
- * "k2": ["v2"]
2312
- * }
2313
- *
2314
- * ...?k1=v1&k1=v2:
2315
- * {
2316
- * "k1": ["v1", "v2"]
2317
- * }
2318
- *
2319
- * ...?k1=v1&k2:
2320
- * {
2321
- * "k1": ["v1"],
2322
- * "k2": []
2323
- * }
2324
- *
2325
- * ...?k1=v1&k1:
2326
- * {
2327
- * "k1": ["v1"]
2328
- * }
2329
- *
2330
- * ...?k1&k1:
2331
- * {
2332
- * "k1": []
2333
- * }
2334
- *
2335
- * @param query the query string to parse (optional, default to cached
2336
- * results from parsing window location search query).
2337
- *
2338
- * @return object mapping keys to variables.
2339
- */
2340
- util.getQueryVariables = function(query) {
2341
- var parse = function(q) {
2342
- var rval = {};
2343
- var kvpairs = q.split('&');
2344
- for(var i = 0; i < kvpairs.length; i++) {
2345
- var pos = kvpairs[i].indexOf('=');
2346
- var key;
2347
- var val;
2348
- if(pos > 0) {
2349
- key = kvpairs[i].substring(0, pos);
2350
- val = kvpairs[i].substring(pos + 1);
2351
- } else {
2352
- key = kvpairs[i];
2353
- val = null;
2354
- }
2355
- if(!(key in rval)) {
2356
- rval[key] = [];
2357
- }
2358
- // disallow overriding object prototype keys
2359
- if(!(key in Object.prototype) && val !== null) {
2360
- rval[key].push(unescape(val));
2361
- }
2362
- }
2363
- return rval;
2364
- };
2365
-
2366
- var rval;
2367
- if(typeof(query) === 'undefined') {
2368
- // set cached variables if needed
2369
- if(_queryVariables === null) {
2370
- if(typeof(window) !== 'undefined' && window.location && window.location.search) {
2371
- // parse window search query
2372
- _queryVariables = parse(window.location.search.substring(1));
2373
- } else {
2374
- // no query variables available
2375
- _queryVariables = {};
2376
- }
2377
- }
2378
- rval = _queryVariables;
2379
- } else {
2380
- // parse given query
2381
- rval = parse(query);
2382
- }
2383
- return rval;
2384
- };
2385
-
2386
- /**
2387
- * Parses a fragment into a path and query. This method will take a URI
2388
- * fragment and break it up as if it were the main URI. For example:
2389
- * /bar/baz?a=1&b=2
2390
- * results in:
2391
- * {
2392
- * path: ["bar", "baz"],
2393
- * query: {"k1": ["v1"], "k2": ["v2"]}
2394
- * }
2395
- *
2396
- * @return object with a path array and query object.
2397
- */
2398
- util.parseFragment = function(fragment) {
2399
- // default to whole fragment
2400
- var fp = fragment;
2401
- var fq = '';
2402
- // split into path and query if possible at the first '?'
2403
- var pos = fragment.indexOf('?');
2404
- if(pos > 0) {
2405
- fp = fragment.substring(0, pos);
2406
- fq = fragment.substring(pos + 1);
2407
- }
2408
- // split path based on '/' and ignore first element if empty
2409
- var path = fp.split('/');
2410
- if(path.length > 0 && path[0] === '') {
2411
- path.shift();
2412
- }
2413
- // convert query into object
2414
- var query = (fq === '') ? {} : util.getQueryVariables(fq);
2415
-
2416
- return {
2417
- pathString: fp,
2418
- queryString: fq,
2419
- path: path,
2420
- query: query
2421
- };
2422
- };
2423
-
2424
- /**
2425
- * Makes a request out of a URI-like request string. This is intended to
2426
- * be used where a fragment id (after a URI '#') is parsed as a URI with
2427
- * path and query parts. The string should have a path beginning and
2428
- * delimited by '/' and optional query parameters following a '?'. The
2429
- * query should be a standard URL set of key value pairs delimited by
2430
- * '&'. For backwards compatibility the initial '/' on the path is not
2431
- * required. The request object has the following API, (fully described
2432
- * in the method code):
2433
- * {
2434
- * path: <the path string part>.
2435
- * query: <the query string part>,
2436
- * getPath(i): get part or all of the split path array,
2437
- * getQuery(k, i): get part or all of a query key array,
2438
- * getQueryLast(k, _default): get last element of a query key array.
2439
- * }
2440
- *
2441
- * @return object with request parameters.
2442
- */
2443
- util.makeRequest = function(reqString) {
2444
- var frag = util.parseFragment(reqString);
2445
- var req = {
2446
- // full path string
2447
- path: frag.pathString,
2448
- // full query string
2449
- query: frag.queryString,
2450
- /**
2451
- * Get path or element in path.
2452
- *
2453
- * @param i optional path index.
2454
- *
2455
- * @return path or part of path if i provided.
2456
- */
2457
- getPath: function(i) {
2458
- return (typeof(i) === 'undefined') ? frag.path : frag.path[i];
2459
- },
2460
- /**
2461
- * Get query, values for a key, or value for a key index.
2462
- *
2463
- * @param k optional query key.
2464
- * @param i optional query key index.
2465
- *
2466
- * @return query, values for a key, or value for a key index.
2467
- */
2468
- getQuery: function(k, i) {
2469
- var rval;
2470
- if(typeof(k) === 'undefined') {
2471
- rval = frag.query;
2472
- } else {
2473
- rval = frag.query[k];
2474
- if(rval && typeof(i) !== 'undefined') {
2475
- rval = rval[i];
2476
- }
2477
- }
2478
- return rval;
2479
- },
2480
- getQueryLast: function(k, _default) {
2481
- var rval;
2482
- var vals = req.getQuery(k);
2483
- if(vals) {
2484
- rval = vals[vals.length - 1];
2485
- } else {
2486
- rval = _default;
2487
- }
2488
- return rval;
2489
- }
2490
- };
2491
- return req;
2492
- };
2493
-
2494
- /**
2495
- * Makes a URI out of a path, an object with query parameters, and a
2496
- * fragment. Uses jQuery.param() internally for query string creation.
2497
- * If the path is an array, it will be joined with '/'.
2498
- *
2499
- * @param path string path or array of strings.
2500
- * @param query object with query parameters. (optional)
2501
- * @param fragment fragment string. (optional)
2502
- *
2503
- * @return string object with request parameters.
2504
- */
2505
- util.makeLink = function(path, query, fragment) {
2506
- // join path parts if needed
2507
- path = jQuery.isArray(path) ? path.join('/') : path;
2508
-
2509
- var qstr = jQuery.param(query || {});
2510
- fragment = fragment || '';
2511
- return path +
2512
- ((qstr.length > 0) ? ('?' + qstr) : '') +
2513
- ((fragment.length > 0) ? ('#' + fragment) : '');
2514
- };
2515
-
2516
2261
  /**
2517
2262
  * Check if an object is empty.
2518
2263
  *