PageSourceSearch

https://osuweb.cathaysec.com.tw/cathay-ui/cgjscrypt/CGJSCrypt_all.js

js cathaysec.com.tw collected 2026-09-24 10:47:24 UTC 686,973 bytes, 23,223 lines download raw bytes

1/**
2 * Utility functions for web applications.
3 *
4 * @author Dave Longley
5 *
6 * Copyright (c) 2010-2014 Digital Bazaar, Inc.
7 */
8(function() {
9/* ########## Begin module implementation ########## */
10function initModule(forge) {
11
12/* Utilities API */
13var util = forge.util = forge.util || {};
14
15// define setImmediate and nextTick
16(function() {
17  // use native nextTick
18  if(typeof process !== 'undefined' && process.nextTick) {
19    util.nextTick = process.nextTick;
20    if(typeof setImmediate === 'function') {
21      util.setImmediate = setImmediate;
22    } else {
23      // polyfill setImmediate with nextTick, older versions of node
24      // (those w/o setImmediate) won't totally starve IO
25      util.setImmediate = util.nextTick;
26    }
27    return;
28  }
29
30  // polyfill nextTick with native setImmediate
31  if(typeof setImmediate === 'function') {
32    util.setImmediate = function() { return setImmediate.apply(undefined, arguments); };
33    util.nextTick = function(callback) {
34      return setImmediate(callback);
35    };
36    return;
37  }
38
39  /* Note: A polyfill upgrade pattern is used here to allow combining
40  polyfills. For example, MutationObserver is fast, but blocks UI updates,
41  so it needs to allow UI updates periodically, so it falls back on
42  postMessage or setTimeout. */
43
44  // polyfill with setTimeout
45  util.setImmediate = function(callback) {
46    setTimeout(callback, 0);
47  };
48
49  // upgrade polyfill to use postMessage
50  if(typeof window !== 'undefined' &&
51    typeof window.postMessage === 'function') {
52    var msg = 'forge.setImmediate';
53    var callbacks = [];
54    util.setImmediate = function(callback) {
55      callbacks.push(callback);
56      // only send message when one hasn't been sent in
57      // the current turn of the event loop
58      if(callbacks.length === 1) {
59        window.postMessage(msg, '*');
60      }
61    };
62    function handler(event) {
63      if(event.source === window && event.data === msg) {
64        event.stopPropagation();
65        var copy = callbacks.slice();
66        callbacks.length = 0;
67        copy.forEach(function(callback) {
68          callback();
69        });
70      }
71    }
72    window.addEventListener('message', handler, true);
73  }
74
75  // upgrade polyfill to use MutationObserver
76  if(typeof MutationObserver !== 'undefined') {
77    // polyfill with MutationObserver
78    var now = Date.now();
79    var attr = true;
80    var div = document.createElement('div');
81    var callbacks = [];
82    new MutationObserver(function() {
83      var copy = callbacks.slice();
84      callbacks.length = 0;
85      copy.forEach(function(callback) {
86        callback();
87      });
88    }).observe(div, {attributes: true});
89    var oldSetImmediate = util.setImmediate;
90    util.setImmediate = function(callback) {
91      if(Date.now() - now > 15) {
92        now = Date.now();
93        oldSetImmediate(callback);
94      } else {
95        callbacks.push(callback);
96        // only trigger observer when it hasn't been triggered in
97        // the current turn of the event loop
98        if(callbacks.length === 1) {
99          div.setAttribute('a', attr = !attr);
100        }
101      }
102    };
103  }
104
105  util.nextTick = util.setImmediate;
106})();
107
108// define isArray
109util.isArray = Array.isArray || function(x) {
110  return Object.prototype.toString.call(x) === '[object Array]';
111};
112
113// define isArrayBuffer
114util.isArrayBuffer = function(x) {
115  return typeof ArrayBuffer !== 'undefined' && x instanceof ArrayBuffer;
116};
117
118// define isArrayBufferView
119util.isArrayBufferView = function(x) {
120  return x && util.isArrayBuffer(x.buffer) && x.byteLength !== undefined;
121};
122
123// TODO: set ByteBuffer to best available backing
124util.ByteBuffer = ByteStringBuffer;
125
126/** Buffer w/BinaryString backing */
127
128/**
129 * Constructor for a binary string backed byte buffer.
130 *
131 * @param [b] the bytes to wrap (either encoded as string, one byte per
132 *          character, or as an ArrayBuffer or Typed Array).
133 */
134function ByteStringBuffer(b) {
135  // TODO: update to match DataBuffer API
136
137  // the data in this buffer
138  this.data = '';
139  // the pointer for reading from this buffer
140  this.read = 0;
141
142  if(typeof b === 'string') {
143    this.data = b;
144  } else if(util.isArrayBuffer(b) || util.isArrayBufferView(b)) {
145    // convert native buffer to forge buffer
146    // FIXME: support native buffers internally instead
147    var arr = new Uint8Array(b);
148    try {
149      this.data = String.fromCharCode.apply(null, arr);
150    } catch(e) {
151      for(var i = 0; i < arr.length; ++i) {
152        this.putByte(arr[i]);
153      }
154    }
155  } else if(b instanceof ByteStringBuffer ||
156    (typeof b === 'object' && typeof b.data === 'string' &&
157    typeof b.read === 'number')) {
158    // copy existing buffer
159    this.data = b.data;
160    this.read = b.read;
161  }
162
163  // used for v8 optimization
164  this._constructedStringLength = 0;
165}
166util.ByteStringBuffer = ByteStringBuffer;
167
168/* Note: This is an optimization for V8-based browsers. When V8 concatenates
169  a string, the strings are only joined logically using a "cons string" or
170  "constructed/concatenated string". These containers keep references to one
171  another and can result in very large memory usage. For example, if a 2MB
172  string is constructed by concatenating 4 bytes together at a time, the
173  memory usage will be ~44MB; so ~22x increase. The strings are only joined
174  together when an operation requiring their joining takes place, such as
175  substr(). This function is called when adding data to this buffer to ensure
176  these types of strings are periodically joined to reduce the memory
177  footprint. */
178var _MAX_CONSTRUCTED_STRING_LENGTH = 4096;
179util.ByteStringBuffer.prototype._optimizeConstructedString = function(x) {
180  this._constructedStringLength += x;
181  if(this._constructedStringLength > _MAX_CONSTRUCTED_STRING_LENGTH) {
182    // this substr() should cause the constructed string to join
183    this.data.substr(0, 1);
184    this._constructedStringLength = 0;
185  }
186};
187
188/**
189 * Gets the number of bytes in this buffer.
190 *
191 * @return the number of bytes in this buffer.
192 */
193util.ByteStringBuffer.prototype.length = function() {
194  return this.data.length - this.read;
195};
196
197/**
198 * Gets whether or not this buffer is empty.
199 *
200 * @return true if this buffer is empty, false if not.
201 */
202util.ByteStringBuffer.prototype.isEmpty = function() {
203  return this.length() <= 0;
204};
205
206/**
207 * Puts a byte in this buffer.
208 *
209 * @param b the byte to put.
210 *
211 * @return this buffer.
212 */
213util.ByteStringBuffer.prototype.putByte = function(b) {
214  return this.putBytes(String.fromCharCode(b));
215};
216
217/**
218 * Puts a byte in this buffer N times.
219 *
220 * @param b the byte to put.
221 * @param n the number of bytes of value b to put.
222 *
223 * @return this buffer.
224 */
225util.ByteStringBuffer.prototype.fillWithByte = function(b, n) {
226  b = String.fromCharCode(b);
227  var d = this.data;
228  while(n > 0) {
229    if(n & 1) {
230      d += b;
231    }
232    n >>>= 1;
233    if(n > 0) {
234      b += b;
235    }
236  }
237  this.data = d;
238  this._optimizeConstructedString(n);
239  return this;
240};
241
242/**
243 * Puts bytes in this buffer.
244 *
245 * @param bytes the bytes (as a UTF-8 encoded string) to put.
246 *
247 * @return this buffer.
248 */
249util.ByteStringBuffer.prototype.putBytes = function(bytes) {
250  this.data += bytes;
251  this._optimizeConstructedString(bytes.length);
252  return this;
253};
254
255/**
256 * Puts a UTF-16 encoded string into this buffer.
257 *
258 * @param str the string to put.
259 *
260 * @return this buffer.
261 */
262util.ByteStringBuffer.prototype.putString = function(str) {
263  return this.putBytes(util.encodeUtf8(str));
264};
265
266/**
267 * Puts a 16-bit integer in this buffer in big-endian order.
268 *
269 * @param i the 16-bit integer.
270 *
271 * @return this buffer.
272 */
273util.ByteStringBuffer.prototype.putInt16 = function(i) {
274  return this.putBytes(
275    String.fromCharCode(i >> 8 & 0xFF) +
276    String.fromCharCode(i & 0xFF));
277};
278
279/**
280 * Puts a 24-bit integer in this buffer in big-endian order.
281 *
282 * @param i the 24-bit integer.
283 *
284 * @return this buffer.
285 */
286util.ByteStringBuffer.prototype.putInt24 = function(i) {
287  return this.putBytes(
288    String.fromCharCode(i >> 16 & 0xFF) +
289    String.fromCharCode(i >> 8 & 0xFF) +
290    String.fromCharCode(i & 0xFF));
291};
292
293/**
294 * Puts a 32-bit integer in this buffer in big-endian order.
295 *
296 * @param i the 32-bit integer.
297 *
298 * @return this buffer.
299 */
300util.ByteStringBuffer.prototype.putInt32 = function(i) {
301  return this.putBytes(
302    String.fromCharCode(i >> 24 & 0xFF) +
303    String.fromCharCode(i >> 16 & 0xFF) +
304    String.fromCharCode(i >> 8 & 0xFF) +
305    String.fromCharCode(i & 0xFF));
306};
307
308/**
309 * Puts a 16-bit integer in this buffer in little-endian order.
310 *
311 * @param i the 16-bit integer.
312 *
313 * @return this buffer.
314 */
315util.ByteStringBuffer.prototype.putInt16Le = function(i) {
316  return this.putBytes(
317    String.fromCharCode(i & 0xFF) +
318    String.fromCharCode(i >> 8 & 0xFF));
319};
320
321/**
322 * Puts a 24-bit integer in this buffer in little-endian order.
323 *
324 * @param i the 24-bit integer.
325 *
326 * @return this buffer.
327 */
328util.ByteStringBuffer.prototype.putInt24Le = function(i) {
329  return this.putBytes(
330    String.fromCharCode(i & 0xFF) +
331    String.fromCharCode(i >> 8 & 0xFF) +
332    String.fromCharCode(i >> 16 & 0xFF));
333};
334
335/**
336 * Puts a 32-bit integer in this buffer in little-endian order.
337 *
338 * @param i the 32-bit integer.
339 *
340 * @return this buffer.
341 */
342util.ByteStringBuffer.prototype.putInt32Le = function(i) {
343  return this.putBytes(
344    String.fromCharCode(i & 0xFF) +
345    String.fromCharCode(i >> 8 & 0xFF) +
346    String.fromCharCode(i >> 16 & 0xFF) +
347    String.fromCharCode(i >> 24 & 0xFF));
348};
349
350/**
351 * Puts an n-bit integer in this buffer in big-endian order.
352 *
353 * @param i the n-bit integer.
354 * @param n the number of bits in the integer.
355 *
356 * @return this buffer.
357 */
358util.ByteStringBuffer.prototype.putInt = function(i, n) {
359  var bytes = '';
360  do {
361    n -= 8;
362    bytes += String.fromCharCode((i >> n) & 0xFF);
363  } while(n > 0);
364  return this.putBytes(bytes);
365};
366
367/**
368 * Puts a signed n-bit integer in this buffer in big-endian order. Two's
369 * complement representation is used.
370 *
371 * @param i the n-bit integer.
372 * @param n the number of bits in the integer.
373 *
374 * @return this buffer.
375 */
376util.ByteStringBuffer.prototype.putSignedInt = function(i, n) {
377  if(i < 0) {
378    i += 2 << (n - 1);
379  }
380  return this.putInt(i, n);
381};
382
383/**
384 * Puts the given buffer into this buffer.
385 *
386 * @param buffer the buffer to put into this one.
387 *
388 * @return this buffer.
389 */
390util.ByteStringBuffer.prototype.putBuffer = function(buffer) {
391  return this.putBytes(buffer.getBytes());
392};
393
394/**
395 * Gets a byte from this buffer and advances the read pointer by 1.
396 *
397 * @return the byte.
398 */
399util.ByteStringBuffer.prototype.getByte = function() {
400  return this.data.charCodeAt(this.read++);
401};
402
403/**
404 * Gets a uint16 from this buffer in big-endian order and advances the read
405 * pointer by 2.
406 *
407 * @return the uint16.
408 */
409util.ByteStringBuffer.prototype.getInt16 = function() {
410  var rval = (
411    this.data.charCodeAt(this.read) << 8 ^
412    this.data.charCodeAt(this.read + 1));
413  this.read += 2;
414  return rval;
415};
416
417/**
418 * Gets a uint24 from this buffer in big-endian order and advances the read
419 * pointer by 3.
420 *
421 * @return the uint24.
422 */
423util.ByteStringBuffer.prototype.getInt24 = function() {
424  var rval = (
425    this.data.charCodeAt(this.read) << 16 ^
426    this.data.charCodeAt(this.read + 1) << 8 ^
427    this.data.charCodeAt(this.read + 2));
428  this.read += 3;
429  return rval;
430};
431
432/**
433 * Gets a uint32 from this buffer in big-endian order and advances the read
434 * pointer by 4.
435 *
436 * @return the word.
437 */
438util.ByteStringBuffer.prototype.getInt32 = function() {
439  var rval = (
440    this.data.charCodeAt(this.read) << 24 ^
441    this.data.charCodeAt(this.read + 1) << 16 ^
442    this.data.charCodeAt(this.read + 2) << 8 ^
443    this.data.charCodeAt(this.read + 3));
444  this.read += 4;
445  return rval;
446};
447
448/**
449 * Gets a uint16 from this buffer in little-endian order and advances the read
450 * pointer by 2.
451 *
452 * @return the uint16.
453 */
454util.ByteStringBuffer.prototype.getInt16Le = function() {
455  var rval = (
456    this.data.charCodeAt(this.read) ^
457    this.data.charCodeAt(this.read + 1) << 8);
458  this.read += 2;
459  return rval;
460};
461
462/**
463 * Gets a uint24 from this buffer in little-endian order and advances the read
464 * pointer by 3.
465 *
466 * @return the uint24.
467 */
468util.ByteStringBuffer.prototype.getInt24Le = function() {
469  var rval = (
470    this.data.charCodeAt(this.read) ^
471    this.data.charCodeAt(this.read + 1) << 8 ^
472    this.data.charCodeAt(this.read + 2) << 16);
473  this.read += 3;
474  return rval;
475};
476
477/**
478 * Gets a uint32 from this buffer in little-endian order and advances the read
479 * pointer by 4.
480 *
481 * @return the word.
482 */
483util.ByteStringBuffer.prototype.getInt32Le = function() {
484  var rval = (
485    this.data.charCodeAt(this.read) ^
486    this.data.charCodeAt(this.read + 1) << 8 ^
487    this.data.charCodeAt(this.read + 2) << 16 ^
488    this.data.charCodeAt(this.read + 3) << 24);
489  this.read += 4;
490  return rval;
491};
492
493/**
494 * Gets an n-bit integer from this buffer in big-endian order and advances the
495 * read pointer by n/8.
496 *
497 * @param n the number of bits in the integer.
498 *
499 * @return the integer.
500 */
501util.ByteStringBuffer.prototype.getInt = function(n) {
502  var rval = 0;
503  do {
504    rval = (rval << 8) + this.data.charCodeAt(this.read++);
505    n -= 8;
506  } while(n > 0);
507  return rval;
508};
509
510/**
511 * Gets a signed n-bit integer from this buffer in big-endian order, using
512 * two's complement, and advances the read pointer by n/8.
513 *
514 * @param n the number of bits in the integer.
515 *
516 * @return the integer.
517 */
518util.ByteStringBuffer.prototype.getSignedInt = function(n) {
519  var x = this.getInt(n);
520  var max = 2 << (n - 2);
521  if(x >= max) {
522    x -= max << 1;
523  }
524  return x;
525};
526
527/**
528 * Reads bytes out into a UTF-8 string and clears them from the buffer.
529 *
530 * @param count the number of bytes to read, undefined or null for all.
531 *
532 * @return a UTF-8 string of bytes.
533 */
534util.ByteStringBuffer.prototype.getBytes = function(count) {
535  var rval;
536  if(count) {
537    // read count bytes
538    count = Math.min(this.length(), count);
539    rval = this.data.slice(this.read, this.read + count);
540    this.read += count;
541  } else if(count === 0) {
542    rval = '';
543  } else {
544    // read all bytes, optimize to only copy when needed
545    rval = (this.read === 0) ? this.data : this.data.slice(this.read);
546    this.clear();
547  }
548  return rval;
549};
550
551/**
552 * Gets a UTF-8 encoded string of the bytes from this buffer without modifying
553 * the read pointer.
554 *
555 * @param count the number of bytes to get, omit to get all.
556 *
557 * @return a string full of UTF-8 encoded characters.
558 */
559util.ByteStringBuffer.prototype.bytes = function(count) {
560  return (typeof(count) === 'undefined' ?
561    this.data.slice(this.read) :
562    this.data.slice(this.read, this.read + count));
563};
564
565/**
566 * Gets a byte at the given index without modifying the read pointer.
567 *
568 * @param i the byte index.
569 *
570 * @return the byte.
571 */
572util.ByteStringBuffer.prototype.at = function(i) {
573  return this.data.charCodeAt(this.read + i);
574};
575
576/**
577 * Puts a byte at the given index without modifying the read pointer.
578 *
579 * @param i the byte index.
580 * @param b the byte to put.
581 *
582 * @return this buffer.
583 */
584util.ByteStringBuffer.prototype.setAt = function(i, b) {
585  this.data = this.data.substr(0, this.read + i) +
586    String.fromCharCode(b) +
587    this.data.substr(this.read + i + 1);
588  return this;
589};
590
591/**
592 * Gets the last byte without modifying the read pointer.
593 *
594 * @return the last byte.
595 */
596util.ByteStringBuffer.prototype.last = function() {
597  return this.data.charCodeAt(this.data.length - 1);
598};
599
600/**
601 * Creates a copy of this buffer.
602 *
603 * @return the copy.
604 */
605util.ByteStringBuffer.prototype.copy = function() {
606  var c = util.createBuffer(this.data);
607  c.read = this.read;
608  return c;
609};
610
611/**
612 * Compacts this buffer.
613 *
614 * @return this buffer.
615 */
616util.ByteStringBuffer.prototype.compact = function() {
617  if(this.read > 0) {
618    this.data = this.data.slice(this.read);
619    this.read = 0;
620  }
621  return this;
622};
623
624/**
625 * Clears this buffer.
626 *
627 * @return this buffer.
628 */
629util.ByteStringBuffer.prototype.clear = function() {
630  this.data = '';
631  this.read = 0;
632  return this;
633};
634
635/**
636 * Shortens this buffer by triming bytes off of the end of this buffer.
637 *
638 * @param count the number of bytes to trim off.
639 *
640 * @return this buffer.
641 */
642util.ByteStringBuffer.prototype.truncate = function(count) {
643  var len = Math.max(0, this.length() - count);
644  this.data = this.data.substr(this.read, len);
645  this.read = 0;
646  return this;
647};
648
649/**
650 * Converts this buffer to a hexadecimal string.
651 *
652 * @return a hexadecimal string.
653 */
654util.ByteStringBuffer.prototype.toHex = function() {
655  var rval = '';
656  for(var i = this.read; i < this.data.length; ++i) {
657    var b = this.data.charCodeAt(i);
658    if(b < 16) {
659      rval += '0';
660    }
661    rval += b.toString(16);
662  }
663  return rval;
664};
665
666/**
667 * Converts this buffer to a UTF-16 string (standard JavaScript string).
668 *
669 * @return a UTF-16 string.
670 */
671util.ByteStringBuffer.prototype.toString = function() {
672  return util.decodeUtf8(this.bytes());
673};
674
675/** End Buffer w/BinaryString backing */
676
677
678/** Buffer w/UInt8Array backing */
679
680/**
681 * FIXME: Experimental. Do not use yet.
682 *
683 * Constructor for an ArrayBuffer-backed byte buffer.
684 *
685 * The buffer may be constructed from a string, an ArrayBuffer, DataView, or a
686 * TypedArray.
687 *
688 * If a string is given, its encoding should be provided as an option,
689 * otherwise it will default to 'binary'. A 'binary' string is encoded such
690 * that each character is one byte in length and size.
691 *
692 * If an ArrayBuffer, DataView, or TypedArray is given, it will be used
693 * *directly* without any copying. Note that, if a write to the buffer requires
694 * more space, the buffer will allocate a new backing ArrayBuffer to
695 * accommodate. The starting read and write offsets for the buffer may be
696 * given as options.
697 *
698 * @param [b] the initial bytes for this buffer.
699 * @param options the options to use:
700 *          [readOffset] the starting read offset to use (default: 0).
701 *          [writeOffset] the starting write offset to use (default: the
702 *            length of the first parameter).
703 *          [growSize] the minimum amount, in bytes, to grow the buffer by to
704 *            accommodate writes (default: 1024).
705 *          [encoding] the encoding ('binary', 'utf8', 'utf16', 'hex') for the
706 *            first parameter, if it is a string (default: 'binary').
707 */
708function DataBuffer(b, options) {
709  // default options
710  options = options || {};
711
712  // pointers for read from/write to buffer
713  this.read = options.readOffset || 0;
714  this.growSize = options.growSize || 1024;
715
716  var isArrayBuffer = util.isArrayBuffer(b);
717  var isArrayBufferView = util.isArrayBufferView(b);
718  if(isArrayBuffer || isArrayBufferView) {
719    // use ArrayBuffer directly
720    if(isArrayBuffer) {
721      this.data = new DataView(b);
722    } else {
723      // TODO: adjust read/write offset based on the type of view
724      // or specify that this must be done in the options ... that the
725      // offsets are byte-based
726      this.data = new DataView(b.buffer, b.byteOffset, b.byteLength);
727    }
728    this.write = ('writeOffset' in options ?
729      options.writeOffset : this.data.byteLength);
730    return;
731  }
732
733  // initialize to empty array buffer and add any given bytes using putBytes
734  this.data = new DataView(new ArrayBuffer(0));
735  this.write = 0;
736
737  if(b !== null && b !== undefined) {
738    this.putBytes(b);
739  }
740
741  if('writeOffset' in options) {
742    this.write = options.writeOffset;
743  }
744}
745util.DataBuffer = DataBuffer;
746
747/**
748 * Gets the number of bytes in this buffer.
749 *
750 * @return the number of bytes in this buffer.
751 */
752util.DataBuffer.prototype.length = function() {
753  return this.write - this.read;
754};
755
756/**
757 * Gets whether or not this buffer is empty.
758 *
759 * @return true if this buffer is empty, false if not.
760 */
761util.DataBuffer.prototype.isEmpty = function() {
762  return this.length() <= 0;
763};
764
765/**
766 * Ensures this buffer has enough empty space to accommodate the given number
767 * of bytes. An optional parameter may be given that indicates a minimum
768 * amount to grow the buffer if necessary. If the parameter is not given,
769 * the buffer will be grown by some previously-specified default amount
770 * or heuristic.
771 *
772 * @param amount the number of bytes to accommodate.
773 * @param [growSize] the minimum amount, in bytes, to grow the buffer by if
774 *          necessary.
775 */
776util.DataBuffer.prototype.accommodate = function(amount, growSize) {
777  if(this.length() >= amount) {
778    return this;
779  }
780  growSize = Math.max(growSize || this.growSize, amount);
781
782  // grow buffer
783  var src = new Uint8Array(
784    this.data.buffer, this.data.byteOffset, this.data.byteLength);
785  var dst = new Uint8Array(this.length() + growSize);
786  dst.set(src);
787  this.data = new DataView(dst.buffer);
788
789  return this;
790};
791
792/**
793 * Puts a byte in this buffer.
794 *
795 * @param b the byte to put.
796 *
797 * @return this buffer.
798 */
799util.DataBuffer.prototype.putByte = function(b) {
800  this.accommodate(1);
801  this.data.setUint8(this.write++, b);
802  return this;
803};
804
805/**
806 * Puts a byte in this buffer N times.
807 *
808 * @param b the byte to put.
809 * @param n the number of bytes of value b to put.
810 *
811 * @return this buffer.
812 */
813util.DataBuffer.prototype.fillWithByte = function(b, n) {
814  this.accommodate(n);
815  for(var i = 0; i < n; ++i) {
816    this.data.setUint8(b);
817  }
818  return this;
819};
820
821/**
822 * Puts bytes in this buffer. The bytes may be given as a string, an
823 * ArrayBuffer, a DataView, or a TypedArray.
824 *
825 * @param bytes the bytes to put.
826 * @param [encoding] the encoding for the first parameter ('binary', 'utf8',
827 *          'utf16', 'hex'), if it is a string (default: 'binary').
828 *
829 * @return this buffer.
830 */
831util.DataBuffer.prototype.putBytes = function(bytes, encoding) {
832  if(util.isArrayBufferView(bytes)) {
833    var src = new Uint8Array(bytes.buffer, bytes.byteOffset, bytes.byteLength);
834    var len = src.byteLength - src.byteOffset;
835    this.accommodate(len);
836    var dst = new Uint8Array(this.data.buffer, this.write);
837    dst.set(src);
838    this.write += len;
839    return this;
840  }
841
842  if(util.isArrayBuffer(bytes)) {
843    var src = new Uint8Array(bytes);
844    this.accommodate(src.byteLength);
845    var dst = new Uint8Array(this.data.buffer);
846    dst.set(src, this.write);
847    this.write += src.byteLength;
848    return this;
849  }
850
851  // bytes is a util.DataBuffer or equivalent
852  if(bytes instanceof util.DataBuffer ||
853    (typeof bytes === 'object' &&
854    typeof bytes.read === 'number' && typeof bytes.write === 'number' &&
855    util.isArrayBufferView(bytes.data))) {
856    var src = new Uint8Array(bytes.data.byteLength, bytes.read, bytes.length());
857    this.accommodate(src.byteLength);
858    var dst = new Uint8Array(bytes.data.byteLength, this.write);
859    dst.set(src);
860    this.write += src.byteLength;
861    return this;
862  }
863
864  if(bytes instanceof util.ByteStringBuffer) {
865    // copy binary string and process as the same as a string parameter below
866    bytes = bytes.data;
867    encoding = 'binary';
868  }
869
870  // string conversion
871  encoding = encoding || 'binary';
872  if(typeof bytes === 'string') {
873    var view;
874
875    // decode from string
876    if(encoding === 'hex') {
877      this.accommodate(Math.ceil(bytes.length / 2));
878      view = new Uint8Array(this.data.buffer, this.write);
879      this.write += util.binary.hex.decode(bytes, view, this.write);
880      return this;
881    }
882    if(encoding === 'base64') {
883      this.accommodate(Math.ceil(bytes.length / 4) * 3);
884      view = new Uint8Array(this.data.buffer, this.write);
885      this.write += util.binary.base64.decode(bytes, view, this.write);
886      return this;
887    }
888
889    // encode text as UTF-8 bytes
890    if(encoding === 'utf8') {
891      // encode as UTF-8 then decode string as raw binary
892      bytes = util.encodeUtf8(bytes);
893      encoding = 'binary';
894    }
895
896    // decode string as raw binary
897    if(encoding === 'binary' || encoding === 'raw') {
898      // one byte per character
899      this.accommodate(bytes.length);
900      view = new Uint8Array(this.data.buffer, this.write);
901      this.write += util.binary.raw.decode(view);
902      return this;
903    }
904
905    // encode text as UTF-16 bytes
906    if(encoding === 'utf16') {
907      // two bytes per character
908      this.accommodate(bytes.length * 2);
909      view = new Uint16Array(this.data.buffer, this.write);
910      this.write += util.text.utf16.encode(view);
911      return this;
912    }
913
914    throw new Error('Invalid encoding: ' + encoding);
915  }
916
917  throw Error('Invalid parameter: ' + bytes);
918};
919
920/**
921 * Puts the given buffer into this buffer.
922 *
923 * @param buffer the buffer to put into this one.
924 *
925 * @return this buffer.
926 */
927util.DataBuffer.prototype.putBuffer = function(buffer) {
928  this.putBytes(buffer);
929  buffer.clear();
930  return this;
931};
932
933/**
934 * Puts a string into this buffer.
935 *
936 * @param str the string to put.
937 * @param [encoding] the encoding for the string (default: 'utf16').
938 *
939 * @return this buffer.
940 */
941util.DataBuffer.prototype.putString = function(str) {
942  return this.putBytes(str, 'utf16');
943};
944
945/**
946 * Puts a 16-bit integer in this buffer in big-endian order.
947 *
948 * @param i the 16-bit integer.
949 *
950 * @return this buffer.
951 */
952util.DataBuffer.prototype.putInt16 = function(i) {
953  this.accommodate(2);
954  this.data.setInt16(this.write, i);
955  this.write += 2;
956  return this;
957};
958
959/**
960 * Puts a 24-bit integer in this buffer in big-endian order.
961 *
962 * @param i the 24-bit integer.
963 *
964 * @return this buffer.
965 */
966util.DataBuffer.prototype.putInt24 = function(i) {
967  this.accommodate(3);
968  this.data.setInt16(this.write, i >> 8 & 0xFFFF);
969  this.data.setInt8(this.write, i >> 16 & 0xFF);
970  this.write += 3;
971  return this;
972};
973
974/**
975 * Puts a 32-bit integer in this buffer in big-endian order.
976 *
977 * @param i the 32-bit integer.
978 *
979 * @return this buffer.
980 */
981util.DataBuffer.prototype.putInt32 = function(i) {
982  this.accommodate(4);
983  this.data.setInt32(this.write, i);
984  this.write += 4;
985  return this;
986};
987
988/**
989 * Puts a 16-bit integer in this buffer in little-endian order.
990 *
991 * @param i the 16-bit integer.
992 *
993 * @return this buffer.
994 */
995util.DataBuffer.prototype.putInt16Le = function(i) {
996  this.accommodate(2);
997  this.data.setInt16(this.write, i, true);
998  this.write += 2;
999  return this;
1000};
1001
1002/**
1003 * Puts a 24-bit integer in this buffer in little-endian order.
1004 *
1005 * @param i the 24-bit integer.
1006 *
1007 * @return this buffer.
1008 */
1009util.DataBuffer.prototype.putInt24Le = function(i) {
1010  this.accommodate(3);
1011  this.data.setInt8(this.write, i >> 16 & 0xFF);
1012  this.data.setInt16(this.write, i >> 8 & 0xFFFF, true);
1013  this.write += 3;
1014  return this;
1015};
1016
1017/**
1018 * Puts a 32-bit integer in this buffer in little-endian order.
1019 *
1020 * @param i the 32-bit integer.
1021 *
1022 * @return this buffer.
1023 */
1024util.DataBuffer.prototype.putInt32Le = function(i) {
1025  this.accommodate(4);
1026  this.data.setInt32(this.write, i, true);
1027  this.write += 4;
1028  return this;
1029};
1030
1031/**
1032 * Puts an n-bit integer in this buffer in big-endian order.
1033 *
1034 * @param i the n-bit integer.
1035 * @param n the number of bits in the integer.
1036 *
1037 * @return this buffer.
1038 */
1039util.DataBuffer.prototype.putInt = function(i, n) {
1040  this.accommodate(n / 8);
1041  do {
1042    n -= 8;
1043    this.data.setInt8(this.write++, (i >> n) & 0xFF);
1044  } while(n > 0);
1045  return this;
1046};
1047
1048/**
1049 * Puts a signed n-bit integer in this buffer in big-endian order. Two's
1050 * complement representation is used.
1051 *
1052 * @param i the n-bit integer.
1053 * @param n the number of bits in the integer.
1054 *
1055 * @return this buffer.
1056 */
1057util.DataBuffer.prototype.putSignedInt = function(i, n) {
1058  this.accommodate(n / 8);
1059  if(i < 0) {
1060    i += 2 << (n - 1);
1061  }
1062  return this.putInt(i, n);
1063};
1064
1065/**
1066 * Gets a byte from this buffer and advances the read pointer by 1.
1067 *
1068 * @return the byte.
1069 */
1070util.DataBuffer.prototype.getByte = function() {
1071  return this.data.getInt8(this.read++);
1072};
1073
1074/**
1075 * Gets a uint16 from this buffer in big-endian order and advances the read
1076 * pointer by 2.
1077 *
1078 * @return the uint16.
1079 */
1080util.DataBuffer.prototype.getInt16 = function() {
1081  var rval = this.data.getInt16(this.read);
1082  this.read += 2;
1083  return rval;
1084};
1085
1086/**
1087 * Gets a uint24 from this buffer in big-endian order and advances the read
1088 * pointer by 3.
1089 *
1090 * @return the uint24.
1091 */
1092util.DataBuffer.prototype.getInt24 = function() {
1093  var rval = (
1094    this.data.getInt16(this.read) << 8 ^
1095    this.data.getInt8(this.read + 2));
1096  this.read += 3;
1097  return rval;
1098};
1099
1100/**
1101 * Gets a uint32 from this buffer in big-endian order and advances the read
1102 * pointer by 4.
1103 *
1104 * @return the word.
1105 */
1106util.DataBuffer.prototype.getInt32 = function() {
1107  var rval = this.data.getInt32(this.read);
1108  this.read += 4;
1109  return rval;
1110};
1111
1112/**
1113 * Gets a uint16 from this buffer in little-endian order and advances the read
1114 * pointer by 2.
1115 *
1116 * @return the uint16.
1117 */
1118util.DataBuffer.prototype.getInt16Le = function() {
1119  var rval = this.data.getInt16(this.read, true);
1120  this.read += 2;
1121  return rval;
1122};
1123
1124/**
1125 * Gets a uint24 from this buffer in little-endian order and advances the read
1126 * pointer by 3.
1127 *
1128 * @return the uint24.
1129 */
1130util.DataBuffer.prototype.getInt24Le = function() {
1131  var rval = (
1132    this.data.getInt8(this.read) ^
1133    this.data.getInt16(this.read + 1, true) << 8);
1134  this.read += 3;
1135  return rval;
1136};
1137
1138/**
1139 * Gets a uint32 from this buffer in little-endian order and advances the read
1140 * pointer by 4.
1141 *
1142 * @return the word.
1143 */
1144util.DataBuffer.prototype.getInt32Le = function() {
1145  var rval = this.data.getInt32(this.read, true);
1146  this.read += 4;
1147  return rval;
1148};
1149
1150/**
1151 * Gets an n-bit integer from this buffer in big-endian order and advances the
1152 * read pointer by n/8.
1153 *
1154 * @param n the number of bits in the integer.
1155 *
1156 * @return the integer.
1157 */
1158util.DataBuffer.prototype.getInt = function(n) {
1159  var rval = 0;
1160  do {
1161    rval = (rval << 8) + this.data.getInt8(this.read++);
1162    n -= 8;
1163  } while(n > 0);
1164  return rval;
1165};
1166
1167/**
1168 * Gets a signed n-bit integer from this buffer in big-endian order, using
1169 * two's complement, and advances the read pointer by n/8.
1170 *
1171 * @param n the number of bits in the integer.
1172 *
1173 * @return the integer.
1174 */
1175util.DataBuffer.prototype.getSignedInt = function(n) {
1176  var x = this.getInt(n);
1177  var max = 2 << (n - 2);
1178  if(x >= max) {
1179    x -= max << 1;
1180  }
1181  return x;
1182};
1183
1184/**
1185 * Reads bytes out into a UTF-8 string and clears them from the buffer.
1186 *
1187 * @param count the number of bytes to read, undefined or null for all.
1188 *
1189 * @return a UTF-8 string of bytes.
1190 */
1191util.DataBuffer.prototype.getBytes = function(count) {
1192  // TODO: deprecate this method, it is poorly named and
1193  // this.toString('binary') replaces it
1194  // add a toTypedArray()/toArrayBuffer() function
1195  var rval;
1196  if(count) {
1197    // read count bytes
1198    count = Math.min(this.length(), count);
1199    rval = this.data.slice(this.read, this.read + count);
1200    this.read += count;
1201  } else if(count === 0) {
1202    rval = '';
1203  } else {
1204    // read all bytes, optimize to only copy when needed
1205    rval = (this.read === 0) ? this.data : this.data.slice(this.read);
1206    this.clear();
1207  }
1208  return rval;
1209};
1210
1211/**
1212 * Gets a UTF-8 encoded string of the bytes from this buffer without modifying
1213 * the read pointer.
1214 *
1215 * @param count the number of bytes to get, omit to get all.
1216 *
1217 * @return a string full of UTF-8 encoded characters.
1218 */
1219util.DataBuffer.prototype.bytes = function(count) {
1220  // TODO: deprecate this method, it is poorly named, add "getString()"
1221  return (typeof(count) === 'undefined' ?
1222    this.data.slice(this.read) :
1223    this.data.slice(this.read, this.read + count));
1224};
1225
1226/**
1227 * Gets a byte at the given index without modifying the read pointer.
1228 *
1229 * @param i the byte index.
1230 *
1231 * @return the byte.
1232 */
1233util.DataBuffer.prototype.at = function(i) {
1234  return this.data.getUint8(this.read + i);
1235};
1236
1237/**
1238 * Puts a 
1238byte at the given index without modifying the read pointer.
1239 *
1240 * @param i the byte index.
1241 * @param b the byte to put.
1242 *
1243 * @return this buffer.
1244 */
1245util.DataBuffer.prototype.setAt = function(i, b) {
1246  this.data.setUint8(i, b);
1247  return this;
1248};
1249
1250/**
1251 * Gets the last byte without modifying the read pointer.
1252 *
1253 * @return the last byte.
1254 */
1255util.DataBuffer.prototype.last = function() {
1256  return this.data.getUint8(this.write - 1);
1257};
1258
1259/**
1260 * Creates a copy of this buffer.
1261 *
1262 * @return the copy.
1263 */
1264util.DataBuffer.prototype.copy = function() {
1265  return new util.DataBuffer(this);
1266};
1267
1268/**
1269 * Compacts this buffer.
1270 *
1271 * @return this buffer.
1272 */
1273util.DataBuffer.prototype.compact = function() {
1274  if(this.read > 0) {
1275    var src = new Uint8Array(this.data.buffer, this.read);
1276    var dst = new Uint8Array(src.byteLength);
1277    dst.set(src);
1278    this.data = new DataView(dst);
1279    this.write -= this.read;
1280    this.read = 0;
1281  }
1282  return this;
1283};
1284
1285/**
1286 * Clears this buffer.
1287 *
1288 * @return this buffer.
1289 */
1290util.DataBuffer.prototype.clear = function() {
1291  this.data = new DataView(new ArrayBuffer(0));
1292  this.read = this.write = 0;
1293  return this;
1294};
1295
1296/**
1297 * Shortens this buffer by triming bytes off of the end of this buffer.
1298 *
1299 * @param count the number of bytes to trim off.
1300 *
1301 * @return this buffer.
1302 */
1303util.DataBuffer.prototype.truncate = function(count) {
1304  this.write = Math.max(0, this.length() - count);
1305  this.read = Math.min(this.read, this.write);
1306  return this;
1307};
1308
1309/**
1310 * Converts this buffer to a hexadecimal string.
1311 *
1312 * @return a hexadecimal string.
1313 */
1314util.DataBuffer.prototype.toHex = function() {
1315  var rval = '';
1316  for(var i = this.read; i < this.data.byteLength; ++i) {
1317    var b = this.data.getUint8(i);
1318    if(b < 16) {
1319      rval += '0';
1320    }
1321    rval += b.toString(16);
1322  }
1323  return rval;
1324};
1325
1326/**
1327 * Converts this buffer to a string, using the given encoding. If no
1328 * encoding is given, 'utf8' (UTF-8) is used.
1329 *
1330 * @param [encoding] the encoding to use: 'binary', 'utf8', 'utf16', 'hex',
1331 *          'base64' (default: 'utf8').
1332 *
1333 * @return a string representation of the bytes in this buffer.
1334 */
1335util.DataBuffer.prototype.toString = function(encoding) {
1336  var view = new Uint8Array(this.data, this.read, this.length());
1337  encoding = encoding || 'utf8';
1338
1339  // encode to string
1340  if(encoding === 'binary' || encoding === 'raw') {
1341    return util.binary.raw.encode(view);
1342  }
1343  if(encoding === 'hex') {
1344    return util.binary.hex.encode(view);
1345  }
1346  if(encoding === 'base64') {
1347    return util.binary.base64.encode(view);
1348  }
1349
1350  // decode to text
1351  if(encoding === 'utf8') {
1352    return util.text.utf8.decode(view);
1353  }
1354  if(encoding === 'utf16') {
1355    return util.text.utf16.decode(view);
1356  }
1357
1358  throw new Error('Invalid encoding: ' + encoding);
1359};
1360
1361/** End Buffer w/UInt8Array backing */
1362
1363
1364/**
1365 * Creates a buffer that stores bytes. A value may be given to put into the
1366 * buffer that is either a string of bytes or a UTF-16 string that will
1367 * be encoded using UTF-8 (to do the latter, specify 'utf8' as the encoding).
1368 *
1369 * @param [input] the bytes to wrap (as a string) or a UTF-16 string to encode
1370 *          as UTF-8.
1371 * @param [encoding] (default: 'raw', other: 'utf8').
1372 */
1373util.createBuffer = function(input, encoding) {
1374  // TODO: deprecate, use new ByteBuffer() instead
1375  encoding = encoding || 'raw';
1376  if(input !== undefined && encoding === 'utf8') {
1377    input = util.encodeUtf8(input);
1378  }
1379  return new util.ByteBuffer(input);
1380};
1381
1382/**
1383 * Fills a string with a particular value. If you want the string to be a byte
1384 * string, pass in String.fromCharCode(theByte).
1385 *
1386 * @param c the character to fill the string with, use String.fromCharCode
1387 *          to fill the string with a byte value.
1388 * @param n the number of characters of value c to fill with.
1389 *
1390 * @return the filled string.
1391 */
1392util.fillString = function(c, n) {
1393  var s = '';
1394  while(n > 0) {
1395    if(n & 1) {
1396      s += c;
1397    }
1398    n >>>= 1;
1399    if(n > 0) {
1400      c += c;
1401    }
1402  }
1403  return s;
1404};
1405
1406/**
1407 * Performs a per byte XOR between two byte strings and returns the result as a
1408 * string of bytes.
1409 *
1410 * @param s1 first string of bytes.
1411 * @param s2 second string of bytes.
1412 * @param n the number of bytes to XOR.
1413 *
1414 * @return the XOR'd result.
1415 */
1416util.xorBytes = function(s1, s2, n) {
1417  var s3 = '';
1418  var b = '';
1419  var t = '';
1420  var i = 0;
1421  var c = 0;
1422  for(; n > 0; --n, ++i) {
1423    b = s1.charCodeAt(i) ^ s2.charCodeAt(i);
1424    if(c >= 10) {
1425      s3 += t;
1426      t = '';
1427      c = 0;
1428    }
1429    t += String.fromCharCode(b);
1430    ++c;
1431  }
1432  s3 += t;
1433  return s3;
1434};
1435
1436/**
1437 * Converts a hex string into a 'binary' encoded string of bytes.
1438 *
1439 * @param hex the hexadecimal string to convert.
1440 *
1441 * @return the binary-encoded string of bytes.
1442 */
1443util.hexToBytes = function(hex) {
1444  // TODO: deprecate: "Deprecated. Use util.binary.hex.decode instead."
1445  var rval = '';
1446  var i = 0;
1447  if(hex.length & 1 == 1) {
1448    // odd number of characters, convert first character alone
1449    i = 1;
1450    rval += String.fromCharCode(parseInt(hex[0], 16));
1451  }
1452  // convert 2 characters (1 byte) at a time
1453  for(; i < hex.length; i += 2) {
1454    rval += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
1455  }
1456  return rval;
1457};
1458
1459/**
1460 * Converts a 'binary' encoded string of bytes to hex.
1461 *
1462 * @param bytes the byte string to convert.
1463 *
1464 * @return the string of hexadecimal characters.
1465 */
1466util.bytesToHex = function(bytes) {
1467  // TODO: deprecate: "Deprecated. Use util.binary.hex.encode instead."
1468  return util.createBuffer(bytes).toHex();
1469};
1470
1471/**
1472 * Converts an 32-bit integer to 4-big-endian byte string.
1473 *
1474 * @param i the integer.
1475 *
1476 * @return the byte string.
1477 */
1478util.int32ToBytes = function(i) {
1479  return (
1480    String.fromCharCode(i >> 24 & 0xFF) +
1481    String.fromCharCode(i >> 16 & 0xFF) +
1482    String.fromCharCode(i >> 8 & 0xFF) +
1483    String.fromCharCode(i & 0xFF));
1484};
1485
1486// base64 characters, reverse mapping
1487var _base64 =
1488  'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
1488+/=';
1489var _base64Idx = [
1490/*43 -43 = 0*/
1491/*'+',  1,  2,  3,'/' */
1492   62, -1, -1, -1, 63,
1493
1494/*'0','1','2','3','4','5','6','7','8','9' */
1495   52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
1496
1497/*15, 16, 17,'=', 19, 20, 21 */
1498  -1, -1, -1, 64, -1, -1, -1,
1499
1500/*65 - 43 = 22*/
1501/*'A','B','C','D','E','F','G','H','I','J','K','L','M', */
1502   0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12,
1503
1504/*'N','O','P','Q','R','S','T','U','V','W','X','Y','Z' */
1505   13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
1506
1507/*91 - 43 = 48 */
1508/*48, 49, 50, 51, 52, 53 */
1509  -1, -1, -1, -1, -1, -1,
1510
1511/*97 - 43 = 54*/
1512/*'a','b','c','d','e','f','g','h','i','j','k','l','m' */
1513   26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
1514
1515/*'n','o','p','q','r','s','t','u','v','w','x','y','z' */
1516   39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
1517];
1518
1519/**
1520 * Base64 encodes a 'binary' encoded string of bytes.
1521 *
1522 * @param input the binary encoded string of bytes to base64-encode.
1523 * @param maxline the maximum number of encoded characters per line to use,
1524 *          defaults to none.
1525 *
1526 * @return the base64-encoded output.
1527 */
1528util.encode64 = function(input, maxline) {
1529  // TODO: deprecate: "Deprecated. Use util.binary.base64.encode instead."
1530  var line = '';
1531  var output = '';
1532  var chr1, chr2, chr3;
1533  var i = 0;
1534  while(i < input.length) {
1535    chr1 = input.charCodeAt(i++);
1536    chr2 = input.charCodeAt(i++);
1537    chr3 = input.charCodeAt(i++);
1538
1539    // encode 4 character group
1540    line += _base64.charAt(chr1 >> 2);
1541    line += _base64.charAt(((chr1 & 3) << 4) | (chr2 >> 4));
1542    if(isNaN(chr2)) {
1543      line += '==';
1544    } else {
1545      line += _base64.charAt(((chr2 & 15) << 2) | (chr3 >> 6));
1546      line += isNaN(chr3) ? '=' : _base64.charAt(chr3 & 63);
1547    }
1548
1549    if(maxline && line.length > maxline) {
1550      output += line.substr(0, maxline) + '\r\n';
1551      line = line.substr(maxline);
1552    }
1553  }
1554  output += line;
1555  return output;
1556};
1557
1558/**
1559 * Base64 decodes a string into a 'binary' encoded string of bytes.
1560 *
1561 * @param input the base64-encoded input.
1562 *
1563 * @return the binary encoded string.
1564 */
1565util.decode64 = function(input) {
1566  // TODO: deprecate: "Deprecated. Use util.binary.base64.decode instead."
1567
1568  // remove all non-base64 characters
1569  input = input.replace(/[^A-Za-z0-9\+\/\=]/g, '');
1570
1571  var output = '';
1572  var enc1, enc2, enc3, enc4;
1573  var i = 0;
1574
1575  while(i < input.length) {
1576    enc1 = _base64Idx[input.charCodeAt(i++) - 43];
1577    enc2 = _base64Idx[input.charCodeAt(i++) - 43];
1578    enc3 = _base64Idx[input.charCodeAt(i++) - 43];
1579    enc4 = _base64Idx[input.charCodeAt(i++) - 43];
1580
1581    output += String.fromCharCode((enc1 << 2) | (enc2 >> 4));
1582    if(enc3 !== 64) {
1583      // decoded at least 2 bytes
1584      output += String.fromCharCode(((enc2 & 15) << 4) | (enc3 >> 2));
1585      if(enc4 !== 64) {
1586        // decoded 3 bytes
1587        output += String.fromCharCode(((enc3 & 3) << 6) | enc4);
1588      }
1589    }
1590  }
1591
1592  return output;
1593};
1594
1595/**
1596 * UTF-8 encodes the given UTF-16 encoded string (a standard JavaScript
1597 * string). Non-ASCII characters will be encoded as multiple bytes according
1598 * to UTF-8.
1599 *
1600 * @param str the string to encode.
1601 *
1602 * @return the UTF-8 encoded string.
1603 */
1604util.encodeUtf8 = function(str) {
1605  return unescape(encodeURIComponent(str));
1606};
1607
1608/**
1609 * Decodes a UTF-8 encoded string into a UTF-16 string.
1610 *
1611 * @param str the string to decode.
1612 *
1613 * @return the UTF-16 encoded string (standard JavaScript string).
1614 */
1615util.decodeUtf8 = function(str) {
1616  return decodeURIComponent(escape(str));
1617};
1618
1619// binary encoding/decoding tools
1620// FIXME: Experimental. Do not use yet.
1621util.binary = {
1622  raw: {},
1623  hex: {},
1624  base64: {}
1625};
1626
1627/**
1628 * Encodes a Uint8Array as a binary-encoded string. This encoding uses
1629 * a value between 0 and 255 for each character.
1630 *
1631 * @param bytes the Uint8Array to encode.
1632 *
1633 * @return the binary-encoded string.
1634 */
1635util.binary.raw.encode = function(bytes) {
1636  return String.fromCharCode.apply(null, bytes);
1637};
1638
1639/**
1640 * Decodes a binary-encoded string to a Uint8Array. This encoding uses
1641 * a value between 0 and 255 for each character.
1642 *
1643 * @param str the binary-encoded string to decode.
1644 * @param [output] an optional Uint8Array to write the output to; if it
1645 *          is too small, an exception will be thrown.
1646 * @param [offset] the start offset for writing to the output (default: 0).
1647 *
1648 * @return the Uint8Array or the number of bytes written if output was given.
1649 */
1650util.binary.raw.decode = function(str, output, offset) {
1651  var out = output;
1652  if(!out) {
1653    out = new Uint8Array(str.length);
1654  }
1655  offset = offset || 0;
1656  var j = offset;
1657  for(var i = 0; i < str.length; ++i) {
1658    out[j++] = str.charCodeAt(i);
1659  }
1660  return output ? (j - offset) : out;
1661};
1662
1663/**
1664 * Encodes a 'binary' string, ArrayBuffer, DataView, TypedArray, or
1665 * ByteBuffer as a string of hexadecimal characters.
1666 *
1667 * @param bytes the bytes to convert.
1668 *
1669 * @return the string of hexadecimal characters.
1670 */
1671util.binary.hex.encode = util.bytesToHex;
1672
1673/**
1674 * Decodes a hex-encoded string to a Uint8Array.
1675 *
1676 * @param hex the hexadecimal string to convert.
1677 * @param [output] an optional Uint8Array to write the output to; if it
1678 *          is too small, an exception will be thrown.
1679 * @param [offset] the start offset for writing to the output (default: 0).
1680 *
1681 * @return the Uint8Array or the number of bytes written if output was given.
1682 */
1683util.binary.hex.decode = function(hex, output, offset) {
1684  var out = output;
1685  if(!out) {
1686    out = new Uint8Array(Math.ceil(hex.length / 2));
1687  }
1688  offset = offset || 0;
1689  var i = 0, j = offset;
1690  if(hex.length & 1) {
1691    // odd number of characters, convert first character alone
1692    i = 1;
1693    out[j++] = parseInt(hex[0], 16);
1694  }
1695  // convert 2 characters (1 byte) at a time
1696  for(; i < hex.length; i += 2) {
1697    out[j++] = parseInt(hex.substr(i, 2), 16);
1698  }
1699  return output ? (j - offset) : out;
1700};
1701
1702/**
1703 * Base64-encodes a Uint8Array.
1704 *
1705 * @param input the Uint8Array to encode.
1706 * @param maxline the maximum number of encoded characters per line to use,
1707 *          defaults to none.
1708 *
1709 * @return the base64-encoded output string.
1710 */
1711util.binary.base64.encode = function(input, maxline) {
1712  var line = '';
1713  var output = '';
1714  var chr1, chr2, chr3;
1715  var i = 0;
1716  while(i < input.byteLength) {
1717    chr1 = input[i++];
1718    chr2 = input[i++];
1719    chr3 = input[i++];
1720
1721    // encode 4 character group
1722    line += _base64.charAt(chr1 >> 2);
1723    line += _base64.charAt(((chr1 & 3) << 4) | (chr2 >> 4));
1724    if(isNaN(chr2)) {
1725      line += '==';
1726    } else {
1727      line += _base64.charAt(((chr2 & 15) << 2) | (chr3 >> 6));
1728      line += isNaN(chr3) ? '=' : _base64.charAt(chr3 & 63);
1729    }
1730
1731    if(maxline && line.length > maxline) {
1732      output += line.substr(0, maxline) + '\r\n';
1733      line = line.substr(maxline);
1734    }
1735  }
1736  output += line;
1737  return output;
1738};
1739
1740/**
1741 * Decodes a base64-encoded string to a Uint8Array.
1742 *
1743 * @param input the base64-encoded input string.
1744 * @param [output] an optional Uint8Array to write the output to; if it
1745 *          is too small, an exception will be thrown.
1746 * @param [offset] the start offset for writing to the output (default: 0).
1747 *
1748 * @return the Uint8Array or the number of bytes written if output was given.
1749 */
1750util.binary.base64.decode = function(input, output, offset) {
1751  var out = output;
1752  if(!out) {
1753    out = new Uint8Array(Math.ceil(input.length / 4) * 3);
1754  }
1755
1756  // remove all non-base64 characters
1757  input = input.replace(/[^A-Za-z0-9\+\/\=]/g, '');
1758
1759  offset = offset || 0;
1760  var enc1, enc2, enc3, enc4;
1761  var i = 0, j = offset;
1762
1763  while(i < input.length) {
1764    enc1 = _base64Idx[input.charCodeAt(i++) - 43];
1765    enc2 = _base64Idx[input.charCodeAt(i++) - 43];
1766    enc3 = _base64Idx[input.charCodeAt(i++) - 43];
1767    enc4 = _base64Idx[input.charCodeAt(i++) - 43];
1768
1769    out[j++] = (enc1 << 2) | (enc2 >> 4);
1770    if(enc3 !== 64) {
1771      // decoded at least 2 bytes
1772      out[j++] = ((enc2 & 15) << 4) | (enc3 >> 2);
1773      if(enc4 !== 64) {
1774        // decoded 3 bytes
1775        out[j++] = ((enc3 & 3) << 6) | enc4;
1776      }
1777    }
1778  }
1779
1780  // make sure result is the exact decoded length
1781  return output ?
1782         (j - offset) :
1783         out.subarray(0, j);
1784};
1785
1786// text encoding/decoding tools
1787// FIXME: Experimental. Do not use yet.
1788util.text = {
1789  utf8: {},
1790  utf16: {}
1791};
1792
1793/**
1794 * Encodes the given string as UTF-8 in a Uint8Array.
1795 *
1796 * @param str the string to encode.
1797 * @param [output] an optional Uint8Array to write the output to; if it
1798 *          is too small, an exception will be thrown.
1799 * @param [offset] the start offset for writing to the output (default: 0).
1800 *
1801 * @return the Uint8Array or the number of bytes written if output was given.
1802 */
1803util.text.utf8.encode = function(str, output, offset) {
1804  str = util.encodeUtf8(str);
1805  var out = output;
1806  if(!out) {
1807    out = new Uint8Array(str.length);
1808  }
1809  offset = offset || 0;
1810  var j = offset;
1811  for(var i = 0; i < str.length; ++i) {
1812    out[j++] = str.charCodeAt(i);
1813  }
1814  return output ? (j - offset) : out;
1815};
1816
1817/**
1818 * Decodes the UTF-8 contents from a Uint8Array.
1819 *
1820 * @param bytes the Uint8Array to decode.
1821 *
1822 * @return the resulting string.
1823 */
1824util.text.utf8.decode = function(bytes) {
1825  return util.decodeUtf8(String.fromCharCode.apply(null, bytes));
1826};
1827
1828/**
1829 * Encodes the given string as UTF-16 in a Uint8Array.
1830 *
1831 * @param str the string to encode.
1832 * @param [output] an optional Uint8Array to write the output to; if it
1833 *          is too small, an exception will be thrown.
1834 * @param [offset] the start offset for writing to the output (default: 0).
1835 *
1836 * @return the Uint8Array or the number of bytes written if output was given.
1837 */
1838util.text.utf16.encode = function(str, output, offset) {
1839  var out = output;
1840  if(!out) {
1841    out = new Uint8Array(str.length * 2);
1842  }
1843  var view = new Uint16Array(out.buffer);
1844  offset = offset || 0;
1845  var j = offset;
1846  var k = offset;
1847  for(var i = 0; i < str.length; ++i) {
1848    view[k++] = str.charCodeAt(i);
1849    j += 2;
1850  }
1851  return output ? (j - offset) : out;
1852};
1853
1854/**
1855 * Decodes the UTF-16 contents from a Uint8Array.
1856 *
1857 * @param bytes the Uint8Array to decode.
1858 *
1859 * @return the resulting string.
1860 */
1861util.text.utf16.decode = function(bytes) {
1862  return String.fromCharCode.apply(null, new Uint16Array(bytes.buffer));
1863};
1864
1865/**
1866 * Deflates the given data using a flash interface.
1867 *
1868 * @param api the flash interface.
1869 * @param bytes the data.
1870 * @param raw true to return only raw deflate data, false to include zlib
1871 *          header and trailer.
1872 *
1873 * @return the deflated data as a string.
1874 */
1875util.deflate = function(api, bytes, raw) {
1876  bytes = util.decode64(api.deflate(util.encode64(bytes)).rval);
1877
1878  // strip zlib header and trailer if necessary
1879  if(raw) {
1880    // zlib header is 2 bytes (CMF,FLG) where FLG indicates that
1881    // there is a 4-byte DICT (alder-32) block before the data if
1882    // its 5th bit is set
1883    var start = 2;
1884    var flg = bytes.charCodeAt(1);
1885    if(flg & 0x20) {
1886      start = 6;
1887    }
1888    // zlib trailer is 4 bytes of adler-32
1889    bytes = bytes.substring(start, bytes.length - 4);
1890  }
1891
1892  return bytes;
1893};
1894
1895/**
1896 * Inflates the given data using a flash interface.
1897 *
1898 * @param api the flash interface.
1899 * @param bytes the data.
1900 * @param raw true if the incoming data has no zlib header or trailer and is
1901 *          raw DEFLATE data.
1902 *
1903 * @return the inflated data as a string, null on error.
1904 */
1905util.inflate = function(api, bytes, raw) {
1906  // TODO: add zlib header and trailer if necessary/possible
1907  var rval = api.inflate(util.encode64(bytes)).rval;
1908  return (rval === null) ? null : util.decode64(rval);
1909};
1910
1911/**
1912 * Sets a storage object.
1913 *
1914 * @param api the storage interface.
1915 * @param id the storage ID to use.
1916 * @param obj the storage object, null to remove.
1917 */
1918var _setStorageObject = function(api, id, obj) {
1919  if(!api) {
1920    throw new Error('WebStorage not available.');
1921  }
1922
1923  var rval;
1924  if(obj === null) {
1925    rval = api.removeItem(id);
1926  } else {
1927    // json-encode and base64-encode object
1928    obj = util.encode64(JSON.stringify(obj));
1929    rval = api.setItem(id, obj);
1930  }
1931
1932  // handle potential flash error
1933  if(typeof(rval) !== 'undefined' && rval.rval !== true) {
1934    var error = new Error(rval.error.message);
1935    error.id = rval.error.id;
1936    error.name = rval.error.name;
1937    throw error;
1938  }
1939};
1940
1941/**
1942 * Gets a storage object.
1943 *
1944 * @param api the storage interface.
1945 * @param id the storage ID to use.
1946 *
1947 * @return the storage object entry or null if none exists.
1948 */
1949var _getStorageObject = function(api, id) {
1950  if(!api) {
1951    throw new Error('WebStorage not available.');
1952  }
1953
1954  // get the existing entry
1955  var rval = api.getItem(id);
1956
1957  /* Note: We check api.init because we can't do (api == localStorage)
1958    on IE because of "Class doesn't support Automation" exception. Only
1959    the flash api has an init method so this works too, but we need a
1960    better solution in the future. */
1961
1962  // flash returns item wrapped in an object, handle special case
1963  if(api.init) {
1964    if(rval.rval === null) {
1965      if(rval.error) {
1966        var error = new Error(rval.error.message);
1967        error.id = rval.error.id;
1968        error.name = rval.error.name;
1969        throw error;
1970      }
1971      // no error, but also no item
1972      rval = null;
1973    } else {
1974      rval = rval.rval;
1975    }
1976  }
1977
1978  // handle decoding
1979  if(rval !== null) {
1980    // base64-decode and json-decode data
1981    rval = JSON.parse(util.decode64(rval));
1982  }
1983
1984  return rval;
1985};
1986
1987/**
1988 * Stores an item in local storage.
1989 *
1990 * @param api the storage interface.
1991 * @param id the storage ID to use.
1992 * @param key the key for the item.
1993 * @param data the data for the item (any javascript object/primitive).
1994 */
1995var _setItem = function(api, id, key, data) {
1996  // get storage object
1997  var obj = _getStorageObject(api, id);
1998  if(obj === null) {
1999    // create a new storage object
2000    obj = {};
2001  }
2002  // update key
2003  obj[key] = data;
2004
2005  // set storage object
2006  _setStorageObject(api, id, obj);
2007};
2008
2009/**
2010 * Gets an item from local storage.
2011 *
2012 * @param api the storage interface.
2013 * @param id the storage ID to use.
2014 * @param key the key for the item.
2015 *
2016 * @return the item.
2017 */
2018var _getItem = function(api, id, key) {
2019  // get storage object
2020  var rval = _getStorageObject(api, id);
2021  if(rval !== null) {
2022    // return data at key
2023    rval = (key in rval) ? rval[key] : null;
2024  }
2025
2026  return rval;
2027};
2028
2029/**
2030 * Removes an item from local storage.
2031 *
2032 * @param api the storage interface.
2033 * @param id the storage ID to use.
2034 * @param key the key for the item.
2035 */
2036var _removeItem = function(api, id, key) {
2037  // get storage object
2038  var obj = _getStorageObject(api, id);
2039  if(obj !== null && key in obj) {
2040    // remove key
2041    delete obj[key];
2042
2043    // see if entry has no keys remaining
2044    var empty = true;
2045    for(var prop in obj) {
2046      empty = false;
2047      break;
2048    }
2049    if(empty) {
2050      // remove entry entirely if no keys are left
2051      obj = null;
2052    }
2053
2054    // set storage object
2055    _setStorageObject(api, id, obj);
2056  }
2057};
2058
2059/**
2060 * Clears the local disk storage identified by the given ID.
2061 *
2062 * @param api the storage interface.
2063 * @param id the storage ID to use.
2064 */
2065var _clearItems = function(api, id) {
2066  _setStorageObject(api, id, null);
2067};
2068
2069/**
2070 * Calls a storage function.
2071 *
2072 * @param func the function to call.
2073 * @param args the arguments for the function.
2074 * @param location the location argument.
2075 *
2076 * @return the return value from the function.
2077 */
2078var _callStorageFunction = function(func, args, location) {
2079  var rval = null;
2080
2081  // default storage types
2082  if(typeof(location) === 'undefined') {
2083    location = ['web', 'flash'];
2084  }
2085
2086  // apply storage types in order of preference
2087  var type;
2088  var done = false;
2089  var exception = null;
2090  for(var idx in location) {
2091    type = location[idx];
2092    try {
2093      if(type === 'flash' || type === 'both') {
2094        if(args[0] === null) {
2095          throw new Error('Flash local storage not available.');
2096        }
2097        rval = func.apply(this, args);
2098        done = (type === 'flash');
2099      }
2100      if(type === 'web' || type === 'both') {
2101        args[0] = localStorage;
2102        rval = func.apply(this, args);
2103        done = true;
2104      }
2105    } catch(ex) {
2106      exception = ex;
2107    }
2108    if(done) {
2109      break;
2110    }
2111  }
2112
2113  if(!done) {
2114    throw exception;
2115  }
2116
2117  return rval;
2118};
2119
2120/**
2121 * Stores an item on local disk.
2122 *
2123 * The available types of local storage include 'flash', 'web', and 'both'.
2124 *
2125 * The type 'flash' refers to flash local storage (SharedObject). In order
2126 * to use flash local storage, the 'api' parameter must be valid. The type
2127 * 'web' refers to WebStorage, if supported by the browser. The type 'both'
2128 * refers to storing using both 'flash' and 'web', not just one or the
2129 * other.
2130 *
2131 * The location array should list the storage types to use in order of
2132 * preference:
2133 *
2134 * ['flash']: flash only storage
2135 * ['web']: web only storage
2136 * ['both']: try to store in both
2137 * ['flash','web']: store in flash first, but if not available, 'web'
2138 * ['web','flash']: store in web first, but if not available, 'flash'
2139 *
2140 * The location array defaults to: ['web', 'flash']
2141 *
2142 * @param api the flash interface, null to use only WebStorage.
2143 * @param id the storage ID to use.
2144 * @param key the key for the item.
2145 * @param data the data for the item (any javascript object/primitive).
2146 * @param location an array with the preferred types of storage to use.
2147 */
2148util.setItem = function(api, id, key, data, location) {
2149  _callStorageFunction(_setItem, arguments, location);
2150};
2151
2152/**
2153 * Gets an item on local disk.
2154 *
2155 * Set setItem() for details on storage types.
2156 *
2157 * @param api the flash interface, null to use only WebStorage.
2158 * @param id the storage ID to use.
2159 * @param key the key for the item.
2160 * @param location an array with the preferred types of storage to use.
2161 *
2162 * @return the item.
2163 */
2164util.getItem = function(api, id, key, location) {
2165  return _callStorageFunction(_getItem, arguments, location);
2166};
2167
2168/**
2169 * Removes an item on local disk.
2170 *
2171 * Set setItem() for details on storage types.
2172 *
2173 * @param api the flash interface.
2174 * @param id the storage ID to use.
2175 * @param key the key for the item.
2176 * @param location an array with the preferred types of storage to use.
2177 */
2178util.removeItem = function(api, id, key, location) {
2179  _callStorageFunction(_removeItem, arguments, location);
2180};
2181
2182/**
2183 * Clears the local disk storage identified by the given ID.
2184 *
2185 * Set setItem() for details on storage types.
2186 *
2187 * @param api the flash interface if flash is available.
2188 * @param id the storage ID to use.
2189 * @param location an array with the preferred types of storage to use.
2190 */
2191util.clearItems = function(api, id, location) {
2192  _callStorageFunction(_clearItems, arguments, location);
2193};
2194
2195/**
2196 * Parses the scheme, host, and port from an http(s) url.
2197 *
2198 * @param str the url string.
2199 *
2200 * @return the parsed url object or null if the url is invalid.
2201 */
2202util.parseUrl = function(str) {
2203  // FIXME: this regex looks a bit broken
2204  var regex = /^(https?):\/\/([^:&^\/]*):?(\d*)(.*)$/g;
2205  regex.lastIndex = 0;
2206  var m = regex.exec(str);
2207  var url = (m === null) ? null : {
2208    full: str,
2209    scheme: m[1],
2210    host: m[2],
2211    port: m[3],
2212    path: m[4]
2213  };
2214  if(url) {
2215    url.fullHost = url.host;
2216    if(url.port) {
2217      if(url.port !== 80 && url.scheme === 'http') {
2218        url.fullHost += ':' + url.port;
2219      } else if(url.port !== 443 && url.scheme === 'https') {
2220        url.fullHost += ':' + url.port;
2221      }
2222    } else if(url.scheme === 'http') {
2223      url.port = 80;
2224    } else if(url.scheme === 'https') {
2225      url.port = 443;
2226    }
2227    url.full = url.scheme + '://' + url.fullHost;
2228  }
2229  return url;
2230};
2231
2232/* Storage for query variables */
2233var _queryVariables = null;
2234
2235/**
2236 * Returns the window location query variables. Query is parsed on the first
2237 * call and the same object is returned on subsequent calls. The mapping
2238 * is from keys to an array of values. Parameters without values will have
2239 * an object key set but no value added to the value array. Values are
2240 * unescaped.
2241 *
2242 * ...?k1=v1&k2=v2:
2243 * {
2244 *   "k1": ["v1"],
2245 *   "k2": ["v2"]
2246 * }
2247 *
2248 * ...?k1=v1&k1=v2:
2249 * {
2250 *   "k1": ["v1", "v2"]
2251 * }
2252 *
2253 * ...?k1=v1&k2:
2254 * {
2255 *   "k1": ["v1"],
2256 *   "k2": []
2257 * }
2258 *
2259 * ...?k1=v1&k1:
2260 * {
2261 *   "k1": ["v1"]
2262 * }
2263 *
2264 * ...?k1&k1:
2265 * {
2266 *   "k1": []
2267 * }
2268 *
2269 * @param query the query string to parse (optional, default to cached
2270 *          results from parsing window location search query).
2271 *
2272 * @return object mapping keys to variables.
2273 */
2274util.getQueryVariables = function(query) {
2275  var parse = function(q) {
2276    var rval = {};
2277    var kvpairs = q.split('&');
2278    for(var i = 0; i < kvpairs.length; i++) {
2279      var pos = kvpairs[i].indexOf('=');
2280      var key;
2281      var val;
2282      if(pos > 0) {
2283        key = kvpairs[i].substring(0, pos);
2284        val = kvpairs[i].substring(pos + 1);
2285      } else {
2286        key = kvpairs[i];
2287        val = null;
2288      }
2289      if(!(key in rval)) {
2290        rval[key] = [];
2291      }
2292      // disallow overriding object prototype keys
2293      if(!(key in Object.prototype) && val !== null) {
2294        rval[key].push(unescape(val));
2295      }
2296    }
2297    return rval;
2298  };
2299
2300   var rval;
2301   if(typeof(query) === 'undefined') {
2302     // set cached variables if needed
2303     if(_queryVariables === null) {
2304       if(typeof(window) !== 'undefined' && window.location && window.location.search) {
2305          // parse window search query
2306          _queryVariables = parse(window.location.search.substring(1));
2307       } else {
2308          // no query variables available
2309          _queryVariables = {};
2310       }
2311     }
2312     rval = _queryVariables;
2313   } else {
2314     // parse given query
2315     rval = parse(query);
2316   }
2317   return rval;
2318};
2319
2320/**
2321 * Parses a fragment into a path and query. This method will take a URI
2322 * fragment and break it up as if it were the main URI. For example:
2323 *    /bar/baz?a=1&b=2
2324 * results in:
2325 *    {
2326 *       path: ["bar", "baz"],
2327 *       query: {"k1": ["v1"], "k2": ["v2"]}
2328 *    }
2329 *
2330 * @return object with a path array and query object.
2331 */
2332util.parseFragment = function(fragment) {
2333  // default to whole fragment
2334  var fp = fragment;
2335  var fq = '';
2336  // split into path and query if possible at the first '?'
2337  var pos = fragment.indexOf('?');
2338  if(pos > 0) {
2339    fp = fragment.substring(0, pos);
2340    fq = fragment.substring(pos + 1);
2341  }
2342  // split path based on '/' and ignore first element if empty
2343  var path = fp.split('/');
2344  if(path.length > 0 && path[0] === '') {
2345    path.shift();
2346  }
2347  // convert query into object
2348  var query = (fq === '') ? {} : util.getQueryVariables(fq);
2349
2350  return {
2351    pathString: fp,
2352    queryString: fq,
2353    path: path,
2354    query: query
2355  };
2356};
2357
2358/**
2359 * Makes a request out of a URI-like request string. This is intended to
2360 * be used where a fragment id (after a URI '#') is parsed as a URI with
2361 * path and query parts. The string should have a path beginning and
2362 * delimited by '/' and optional query parameters following a '?'. The
2363 * query should be a standard URL set of key value pairs delimited by
2364 * '&'. For backwards compatibility the initial '/' on the path is not
2365 * required. The request object has the following API, (fully described
2366 * in the method code):
2367 *    {
2368 *       path: <the path string part>.
2369 *       query: <the query string part>,
2370 *       getPath(i): get part or all of the split path array,
2371 *       getQuery(k, i): get part or all of a query key array,
2372 *       getQueryLast(k, _default): get last element of a query key array.
2373 *    }
2374 *
2375 * @return object with request parameters.
2376 */
2377util.makeRequest = function(reqString) {
2378  var frag = util.parseFragment(reqString);
2379  var req = {
2380    // full path string
2381    path: frag.pathString,
2382    // full query string
2383    query: frag.queryString,
2384    /**
2385     * Get path or element in path.
2386     *
2387     * @param i optional path index.
2388     *
2389     * @return path or part of path if i provided.
2390     */
2391    getPath: function(i) {
2392      return (typeof(i) === 'undefined') ? frag.path : frag.path[i];
2393    },
2394    /**
2395     * Get query, values for a key, or value for a key index.
2396     *
2397     * @param k optional query key.
2398     * @param i optional query key index.
2399     *
2400     * @return query, values for a key, or value for a key index.
2401     */
2402    getQuery: function(k, i) {
2403      var rval;
2404      if(typeof(k) === 'undefined') {
2405        rval = frag.query;
2406      } else {
2407        rval = frag.query[k];
2408        if(rval && typeof(i) !== 'undefined') {
2409           rval = rval[i];
2410        }
2411      }
2412      return rval;
2413    },
2414    getQueryLast: function(k, _default) {
2415      var rval;
2416      var vals = req.getQuery(k);
2417      if(vals) {
2418        rval = vals[vals.length - 1];
2419      } else {
2420        rval = _default;
2421      }
2422      return rval;
2423    }
2424  };
2425  return req;
2426};
2427
2428/**
2429 * Makes a URI out of a path, an object with query parameters, and a
2430 * fragment. Uses jQuery.param() internally for query string creation.
2431 * If the path is an array, it will be joined with '/'.
2432 *
2433 * @param path string path or array of strings.
2434 * @param query object with query parameters. (optional)
2435 * @param fragment fragment string. (optional)
2436 *
2437 * @return string object with request parameters.
2438 */
2439util.makeLink = function(path, query, fragment) {
2440  // join path parts if needed
2441  path = jQuery.isArray(path) ? path.join('/') : path;
2442
2443  var qstr = jQuery.param(query || {});
2444  fragment = fragment || '';
2445  return path +
2446    ((qstr.length > 0) ? ('?' + qstr) : '') +
2447    ((fragment.length > 0) ? ('#' + fragment) : '');
2448};
2449
2450/**
2451 * Follows a path of keys deep into an object hierarchy and set a value.
2452 * If a key does not exist or it's value is not an object, create an
2453 * object in it's place. This can be destructive to a object tree if
2454 * leaf nodes are given as non-final path keys.
2455 * Used to avoid exceptions from missing parts of the path.
2456 *
2457 * @param object the starting object.
2458 * @param keys an array of string keys.
2459 * @param value the value to set.
2460 */
2461util.setPath = function(object, keys, value) {
2462  // need to start at an object
2463  if(typeof(object) === 'object' && object !== null) {
2464    var i = 0;
2465    var len = keys.length;
2466    while(i < len) {
2467      var next = keys[i++];
2468      if(i == len) {
2469        // last
2470        object[next] = value;
2471      } else {
2472        // more
2473        var hasNext = (next in object);
2474        if(!hasNext ||
2475          (hasNext && typeof(object[next]) !== 'object') ||
2476          (hasNext && object[next] === null)) {
2477          object[next] = {};
2478        }
2479        object = object[next];
2480      }
2481    }
2482  }
2483};
2484
2485/**
2486 * Follows a path of keys deep into an object hierarchy and return a value.
2487 * If a key does not exist, create an object in it's place.
2488 * Used to avoid exceptions from missing parts of the path.
2489 *
2490 * @param object the starting object.
2491 * @param keys an array of string keys.
2492 * @param _default value to return if path not found.
2493 *
2494 * @return the value at the path if found, else default if given, else
2495 *         undefined.
2496 */
2497util.getPath = function(object, keys, _default) {
2498  var i = 0;
2499  var len = keys.length;
2500  var hasNext = true;
2501  while(hasNext && i < len &&
2502    typeof(object) === 'object' && object !== null) {
2503    var next = keys[i++];
2504    hasNext = next in object;
2505    if(hasNext) {
2506      object = object[next];
2507    }
2508  }
2509  return (hasNext ? object : _default);
2510};
2511
2512/**
2513 * Follow a path of keys deep into an object hierarchy and delete the
2514 * last one. If a key does not exist, do nothing.
2515 * Used to avoid exceptions from missing parts of the path.
2516 *
2517 * @param object the starting object.
2518 * @param keys an array of string keys.
2519 */
2520util.deletePath = function(object, keys) {
2521  // need to start at an object
2522  if(typeof(object) === 'object' && object !== null) {
2523    var i = 0;
2524    var len = keys.length;
2525    while(i < len) {
2526      var next = keys[i++];
2527      if(i == len) {
2528        // last
2529        delete object[next];
2530      } else {
2531        // more
2532        if(!(next in object) ||
2533          (typeof(object[next]) !== 'object') ||
2534          (object[next] === null)) {
2535           break;
2536        }
2537        object = object[next];
2538      }
2539    }
2540  }
2541};
2542
2543/**
2544 * Check if an object is empty.
2545 *
2546 * Taken from:
2547 * http://stackoverflow.com/questions/679915/how-do-i-test-for-an-empty-javascript-object-from-json/679937#679937
2548 *
2549 * @param object the object to check.
2550 */
2551util.isEmpty = function(obj) {
2552  for(var prop in obj) {
2553    if(obj.hasOwnProperty(prop)) {
2554      return false;
2555    }
2556  }
2557  return true;
2558};
2559
2560/**
2561 * Format with simple printf-style interpolation.
2562 *
2563 * %%: literal '%'
2564 * %s,%o: convert next argument into a string.
2565 *
2566 * @param format the string to format.
2567 * @param ... arguments to interpolate into the format string.
2568 */
2569util.format = function(format) {
2570  var re = /%./g;
2571  // current match
2572  var match;
2573  // current part
2574  var part;
2575  // current arg index
2576  var argi = 0;
2577  // collected parts to recombine later
2578  var parts = [];
2579  // last index found
2580  var last = 0;
2581  // loop while matches remain
2582  while((match = re.exec(format))) {
2583    part = format.substring(last, re.lastIndex - 2);
2584    // don't add empty strings (ie, parts between %s%s)
2585    if(part.length > 0) {
2586      parts.push(part);
2587    }
2588    last = re.lastIndex;
2589    // switch on % code
2590    var code = match[0][1];
2591    switch(code) {
2592    case 's':
2593    case 'o':
2594      // check if enough arguments were given
2595      if(argi < arguments.length) {
2596        parts.push(arguments[argi++ + 1]);
2597      } else {
2598        parts.push('<?>');
2599      }
2600      break;
2601    // FIXME: do proper formating for numbers, etc
2602    //case 'f':
2603    //case 'd':
2604    case '%':
2605      parts.push('%');
2606      break;
2607    default:
2608      parts.push('<%' + code + '?>');
2609    }
2610  }
2611  // add trailing part of format string
2612  parts.push(format.substring(last));
2613  return parts.join('');
2614};
2615
2616/**
2617 * Formats a number.
2618 *
2619 * http://snipplr.com/view/5945/javascript-numberformat--ported-from-php/
2620 */
2621util.formatNumber = function(number, decimals, dec_point, thousands_sep) {
2622  // http://kevin.vanzonneveld.net
2623  // +   original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
2624  // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
2625  // +     bugfix by: Michael White (http://crestidg.com)
2626  // +     bugfix by: Benjamin Lupton
2627  // +     bugfix by: Allan Jensen (http://www.winternet.no)
2628  // +    revised by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
2629  // *     example 1: number_format(1234.5678, 2, '.', '');
2630  // *     returns 1: 1234.57
2631
2632  var n = number, c = isNaN(decimals = Math.abs(decimals)) ? 2 : decimals;
2633  var d = dec_point === undefined ? ',' : dec_point;
2634  var t = thousands_sep === undefined ?
2635   '.' : thousands_sep, s = n < 0 ? '-' : '';
2636  var i = parseInt((n = Math.abs(+n || 0).toFixed(c)), 10) + '';
2637  var j = (i.length > 3) ? i.length % 3 : 0;
2638  return s + (j ? i.substr(0, j) + t : '') +
2639    i.substr(j).replace(/(\d{3})(?=\d)/g, '$1' + t) +
2640    (c ? d + Math.abs(n - i).toFixed(c).slice(2) : '');
2641};
2642
2643/**
2644 * Formats a byte size.
2645 *
2646 * http://snipplr.com/view/5949/format-humanize-file-byte-size-presentation-in-javascript/
2647 */
2648util.formatSize = function(size) {
2649  if(size >= 1073741824) {
2650    size = util.formatNumber(size / 1073741824, 2, '.', '') + ' GiB';
2651  } else if(size >= 1048576) {
2652    size = util.formatNumber(size / 1048576, 2, '.', '') + ' MiB';
2653  } else if(size >= 1024) {
2654    size = util.formatNumber(size / 1024, 0) + ' KiB';
2655  } else {
2656    size = util.formatNumber(size, 0) + ' bytes';
2657  }
2658  return size;
2659};
2660
2661/**
2662 * Converts an IPv4 or IPv6 string representation into bytes (in network order).
2663 *
2664 * @param ip the IPv4 or IPv6 address to convert.
2665 *
2666 * @return the 4-byte IPv6 or 16-byte IPv6 address or null if the address can't
2667 *         be parsed.
2668 */
2669util.bytesFromIP = function(ip) {
2670  if(ip.indexOf('.') !== -1) {
2671    return util.bytesFromIPv4(ip);
2672  }
2673  if(ip.indexOf(':') !== -1) {
2674    return util.bytesFromIPv6(ip);
2675  }
2676  return null;
2677};
2678
2679/**
2680 * Converts an IPv4 string representation into bytes (in network order).
2681 *
2682 * @param ip the IPv4 address to convert.
2683 *
2684 * @return the 4-byte address or null if the address can't be parsed.
2685 */
2686util.bytesFromIPv4 = function(ip) {
2687  ip = ip.split('.');
2688  if(ip.length !== 4) {
2689    return null;
2690  }
2691  var b = util.createBuffer();
2692  for(var i = 0; i < ip.length; ++i) {
2693    var num = parseInt(ip[i], 10);
2694    if(isNaN(num)) {
2695      return null;
2696    }
2697    b.putByte(num);
2698  }
2699  return b.getBytes();
2700};
2701
2702/**
2703 * Converts an IPv6 string representation into bytes (in network order).
2704 *
2705 * @param ip the IPv6 address to convert.
2706 *
2707 * @return the 16-byte address or null if the address can't be parsed.
2708 */
2709util.bytesFromIPv6 = function(ip) {
2710  var blanks = 0;
2711  ip = ip.split(':').filter(function(e) {
2712    if(e.length === 0) ++blanks;
2713    return true;
2714  });
2715  var zeros = (8 - ip.length + blanks) * 2;
2716  var b = util.createBuffer();
2717  for(var i = 0; i < 8; ++i) {
2718    if(!ip[i] || ip[i].length === 0) {
2719      b.fillWithByte(0, zeros);
2720      zeros = 0;
2721      continue;
2722    }
2723    var bytes = util.hexToBytes(ip[i]);
2724    if(bytes.length < 2) {
2725      b.putByte(0);
2726    }
2727    b.putBytes(bytes);
2728  }
2729  return b.getBytes();
2730};
2731
2732/**
2733 * Converts 4-bytes into an IPv4 string representation or 16-bytes into
2734 * an IPv6 string representation. The bytes must be in network order.
2735 *
2736 * @param bytes the bytes to convert.
2737 *
2738 * @return the IPv4 or IPv6 string representation if 4 or 16 bytes,
2739 *         respectively, are given, otherwise null.
2740 */
2741util.bytesToIP = function(bytes) {
2742  if(bytes.length === 4) {
2743    return util.bytesToIPv4(bytes);
2744  }
2745  if(bytes.length === 16) {
2746    return util.bytesToIPv6(bytes);
2747  }
2748  return null;
2749};
2750
2751/**
2752 * Converts 4-bytes into an IPv4 string representation. The bytes must be
2753 * in network order.
2754 *
2755 * @param bytes the bytes to convert.
2756 *
2757 * @return the IPv4 string representation or null for an invalid # of bytes.
2758 */
2759util.bytesToIPv4 = function(bytes) {
2760  if(bytes.length !== 4) {
2761    return null;
2762  }
2763  var ip = [];
2764  for(var i = 0; i < bytes.length; ++i) {
2765    ip.push(bytes.charCodeAt(i));
2766  }
2767  return ip.join('.');
2768};
2769
2770/**
2771 * Converts 16-bytes into an IPv16 string representation. The bytes must be
2772 * in network order.
2773 *
2774 * @param bytes the bytes to convert.
2775 *
2776 * @return the IPv16 string representation or null for an invalid # of bytes.
2777 */
2778util.bytesToIPv6 = function(bytes) {
2779  if(bytes.length !== 16) {
2780    return null;
2781  }
2782  var ip = [];
2783  var zeroGroups = [];
2784  var zeroMaxGroup = 0;
2785  for(var i = 0; i < bytes.length; i += 2) {
2786    var hex = util.bytesToHex(bytes[i] + bytes[i + 1]);
2787    // canonicalize zero representation
2788    while(hex[0] === '0' && hex !== '0') {
2789      hex = hex.substr(1);
2790    }
2791    if(hex === '0') {
2792      var last = zeroGroups[zeroGroups.length - 1];
2793      var idx = ip.length;
2794      if(!last || idx !== last.end + 1) {
2795        zeroGroups.push({start: idx, end: idx});
2796      } else {
2797        last.end = idx;
2798        if((last.end - last.start) >
2799          (zeroGroups[zeroMaxGroup].end - zeroGroups[zeroMaxGroup].start)) {
2800          zeroMaxGroup = zeroGroups.length - 1;
2801        }
2802      }
2803    }
2804    ip.push(hex);
2805  }
2806  if(zeroGroups.length > 0) {
2807    var group = zeroGroups[zeroMaxGroup];
2808    // only shorten group of length > 0
2809    if(group.end - group.start > 0) {
2810      ip.splice(group.start, group.end - group.start + 1, '');
2811      if(group.start === 0) {
2812        ip.unshift('');
2813      }
2814      if(group.end === 7) {
2815        ip.push('');
2816      }
2817    }
2818  }
2819  return ip.join(':');
2820};
2821
2822/**
2823 * Estimates the number of processes that can be run concurrently. If
2824 * creating Web Workers, keep in mind that the main JavaScript process needs
2825 * its own core.
2826 *
2827 * @param options the options to use:
2828 *          update true to force an update (not use the cached value).
2829 * @param callback(err, max) called once the operation completes.
2830 */
2831util.estimateCores = function(options, callback) {
2832  if(typeof options === 'function') {
2833    callback = options;
2834    options = {};
2835  }
2836  options = options || {};
2837  if('cores' in util && !options.update) {
2838    return callback(null, util.cores);
2839  }
2840  if(typeof navigator !== 'undefined' &&
2841    'hardwareConcurrency' in navigator &&
2842    navigator.hardwareConcurrency > 0) {
2843    util.cores = navigator.hardwareConcurrency;
2844    return callback(null, util.cores);
2845  }
2846  if(typeof Worker === 'undefined') {
2847    // workers not available
2848    util.cores = 1;
2849    return callback(null, util.cores);
2850  }
2851  if(typeof Blob === 'undefined') {
2852    // can't estimate, default to 2
2853    util.cores = 2;
2854    return callback(null, util.cores);
2855  }
2856
2857  // create worker concurrency estimation code as blob
2858  var blobUrl = URL.createObjectURL(new Blob(['(',
2859    function() {
2860      self.addEventListener('message', function(e) {
2861        // run worker for 4 ms
2862        var st = Date.now();
2863        var et = st + 4;
2864        while(Date.now() < et);
2865        self.postMessage({st: st, et: et});
2866      });
2867    }.toString(),
2868  ')()'], {type: 'application/javascript'}));
2869
2870  // take 5 samples using 16 workers
2871  sample([], 5, 16);
2872
2873  function sample(max, samples, numWorkers) {
2874    if(samples === 0) {
2875      // get overlap average
2876      var avg = Math.floor(max.reduce(function(avg, x) {
2877        return avg + x;
2878      }, 0) / max.length);
2879      util.cores = Math.max(1, avg);
2880      URL.revokeObjectURL(blobUrl);
2881      return callback(null, util.cores);
2882    }
2883    map(numWorkers, function(err, results) {
2884      max.push(reduce(numWorkers, results));
2885      sample(max, samples - 1, numWorkers);
2886    });
2887  }
2888
2889  function map(numWorkers, callback) {
2890    var workers = [];
2891    var results = [];
2892    for(var i = 0; i < numWorkers; ++i) {
2893      var worker = new Worker(blobUrl);
2894      worker.addEventListener('message', function(e) {
2895        results.push(e.data);
2896        if(results.length === numWorkers) {
2897          for(var i = 0; i < numWorkers; ++i) {
2898            workers[i].terminate();
2899          }
2900          callback(null, results);
2901        }
2902      });
2903      workers.push(worker);
2904    }
2905    for(var i = 0; i < numWorkers; ++i) {
2906      workers[i].postMessage(i);
2907    }
2908  }
2909
2910  function reduce(numWorkers, results) {
2911    // find overlapping time windows
2912    var overlaps = [];
2913    for(var n = 0; n < numWorkers; ++n) {
2914      var r1 = results[n];
2915      var overlap = overlaps[n] = [];
2916      for(var i = 0; i < numWorkers; ++i) {
2917        if(n === i) {
2918          continue;
2919        }
2920        var r2 = results[i];
2921        if((r1.st > r2.st && r1.st < r2.et) ||
2922          (r2.st > r1.st && r2.st < r1.et)) {
2923          overlap.push(i);
2924        }
2925      }
2926    }
2927    // get maximum overlaps ... don't include overlapping worker itself
2928    // as the main JS process was also being scheduled during the work and
2929    // would have to be subtracted from the estimate anyway
2930    return overlaps.reduce(function(max, overlap) {
2931      return Math.max(max, overlap.length);
2932    }, 0);
2933  }
2934};
2935
2936} // end module implementation
2937
2938/* ########## Begin module wrapper ########## */
2939var name = 'util';
2940if(typeof define !== 'function') {
2941  // NodeJS -> AMD
2942  if(typeof module === 'object' && module.exports) {
2943    var nodeJS = true;
2944    define = function(ids, factory) {
2945      factory(require, module);
2946    };
2947  } else {
2948    // <script>
2949    if(typeof forge === 'undefined') {
2950      forge = {};
2951    }
2952    return initModule(forge);
2953  }
2954}
2955// AMD
2956var deps;
2957var defineFunc = function(require, module) {
2958  module.exports = function(forge) {
2959    var mods = deps.map(function(dep) {
2960      return require(dep);
2961    }).concat(initModule);
2962    // handle circular dependencies
2963    forge = forge || {};
2964    forge.defined = forge.defined || {};
2965    if(forge.defined[name]) {
2966      return forge[name];
2967    }
2968    forge.defined[name] = true;
2969    for(var i = 0; i < mods.length; ++i) {
2970      mods[i](forge);
2971    }
2972    return forge[name];
2973  };
2974};
2975var tmpDefine = define;
2976define = function(ids, factory) {
2977  deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2);
2978  if(nodeJS) {
2979    delete define;
2980    return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0));
2981  }
2982  define = tmpDefine;
2983  return define.apply(null, Array.prototype.slice.call(arguments, 0));
2984};
2985define(['require', 'module'], function() {
2986  defineFunc.apply(null, Array.prototype.slice.call(arguments, 0));
2987});
2988})();
2989
2990/**
2991 * Message Digest Algorithm 5 with 128-bit digest (MD5) implementation.
2992 *
2993 * @author Dave Longley
2994 *
2995 * Copyright (c) 2010-2014 Digital Bazaar, Inc.
2996 */
2997(function() {
2998/* ########## Begin module implementation ########## */
2999function initModule(forge) {
3000
3001var md5 = forge.md5 = forge.md5 || {};
3002forge.md = forge.md || {};
3003forge.md.algorithms = forge.md.algorithms || {};
3004forge.md.md5 = forge.md.algorithms.md5 = md5;
3005
3006/**
3007 * Creates an MD5 message digest object.
3008 *
3009 * @return a message digest object.
3010 */
3011md5.create = function() {
3012  // do initialization as necessary
3013  if(!_initialized) {
3014    _init();
3015  }
3016
3017  // MD5 state contains four 32-bit integers
3018  var _state = null;
3019
3020  // input buffer
3021  var _input = forge.util.createBuffer();
3022
3023  // used for word storage
3024  var _w = new Array(16);
3025
3026  // message digest object
3027  var md = {
3028    algorithm: 'md5',
3029    blockLength: 64,
3030    digestLength: 16,
3031    // 56-bit length of message so far (does not including padding)
3032    messageLength: 0,
3033    // true message length
3034    fullMessageLength: null,
3035    // size of message length in bytes
3036    messageLengthSize: 8
3037  };
3038
3039  /**
3040   * Starts the digest.
3041   *
3042   * @return this digest object.
3043   */
3044  md.start = function() {
3045    // up to 56-bit message length for convenience
3046    md.messageLength = 0;
3047
3048    // full message length (set md.messageLength64 for backwards-compatibility)
3049    md.fullMessageLength = md.messageLength64 = [];
3050    var int32s = md.messageLengthSize / 4;
3051    for(var i = 0; i < int32s; ++i) {
3052      md.fullMessageLength.push(0);
3053    }
3054    _input = forge.util.createBuffer();
3055    _state = {
3056      h0: 0x67452301,
3057      h1: 0xEFCDAB89,
3058      h2: 0x98BADCFE,
3059      h3: 0x10325476
3060    };
3061    return md;
3062  };
3063  // start digest automatically for first time
3064  md.start();
3065
3066  /**
3067   * Updates the digest with the given message input. The given input can
3068   * treated as raw input (no encoding will be applied) or an encoding of
3069   * 'utf8' maybe given to encode the input using UTF-8.
3070   *
3071   * @param msg the message input to update with.
3072   * @param encoding the encoding to use (default: 'raw', other: 'utf8').
3073   *
3074   * @return this digest object.
3075   */
3076  md.update = function(msg, encoding) {
3077    if(encoding === 'utf8') {
3078      msg = forge.util.encodeUtf8(msg);
3079    }
3080
3081    // update message length
3082    var len = msg.length;
3083    md.messageLength += len;
3084    len = [(len / 0x100000000) >>> 0, len >>> 0];
3085    for(var i = md.fullMessageLength.length - 1; i >= 0; --i) {
3086      md.fullMessageLength[i] += len[1];
3087      len[1] = len[0] + ((md.fullMessageLength[i] / 0x100000000) >>> 0);
3088      md.fullMessageLength[i] = md.fullMessageLength[i] >>> 0;
3089      len[0] = (len[1] / 0x100000000) >>> 0;
3090    }
3091
3092    // add bytes to input buffer
3093    _input.putBytes(msg);
3094
3095    // process bytes
3096    _update(_state, _w, _input);
3097
3098    // compact input buffer every 2K or if empty
3099    if(_input.read > 2048 || _input.length() === 0) {
3100      _input.compact();
3101    }
3102
3103    return md;
3104  };
3105
3106  /**
3107   * Produces the digest.
3108   *
3109   * @return a byte buffer containing the digest value.
3110   */
3111  md.digest = function() {
3112    /* Note: Here we copy the remaining bytes in the input buffer and
3113    add the appropriate MD5 padding. Then we do the final update
3114    on a copy of the state so that if the user wants to get
3115    intermediate digests they can do so. */
3116
3117    /* Determine the number of bytes that must be added to the message
3118    to ensure its length is congruent to 448 mod 512. In other words,
3119    the data to be digested must be a multiple of 512 bits (or 128 bytes).
3120    This data includes the message, some padding, and the length of the
3121    message. Since the length of the message will be encoded as 8 bytes (64
3122    bits), that means that the last segment of the data must have 56 bytes
3123    (448 bits) of message and padding. Therefore, the length of the message
3124    plus the padding must be congruent to 448 mod 512 because
3125    512 - 128 = 448.
3126
3127    In order to fill up the message length it must be filled with
3128    padding that begins with 1 bit followed by all 0 bits. Padding
3129    must *always* be present, so if the message length is already
3130    congruent to 448 mod 512, then 512 padding bits must be added. */
3131
3132    var finalBlock = forge.util.createBuffer();
3133    finalBlock.putBytes(_input.bytes());
3134
3135    // compute remaining size to be digested (include message length size)
3136    var remaining = (
3137      md.fullMessageLength[md.fullMessageLength.length - 1] +
3138      md.messageLengthSize);
3139
3140    // add padding for overflow blockSize - overflow
3141    // _padding starts with 1 byte with first bit is set (byte value 128), then
3142    // there may be up to (blockSize - 1) other pad bytes
3143    var overflow = remaining & (md.blockLength - 1);
3144    finalBlock.putBytes(_padding.substr(0, md.blockLength - overflow));
3145
3146    // serialize message length in bits in little-endian order; since length
3147    // is stored in bytes we multiply by 8 and add carry
3148    var bits, carry = 0;
3149    for(var i = md.fullMessageLength.length - 1; i >= 0; --i) {
3150      bits = md.fullMessageLength[i] * 8 + carry;
3151      carry = (bits / 0x100000000) >>> 0;
3152      finalBlock.putInt32Le(bits >>> 0);
3153    }
3154
3155    var s2 = {
3156      h0: _state.h0,
3157      h1: _state.h1,
3158      h2: _state.h2,
3159      h3: _state.h3
3160    };
3161    _update(s2, _w, finalBlock);
3162    var rval = forge.util.createBuffer();
3163    rval.putInt32Le(s2.h0);
3164    rval.putInt32Le(s2.h1);
3165    rval.putInt32Le(s2.h2);
3166    rval.putInt32Le(s2.h3);
3167    return rval;
3168  };
3169
3170  return md;
3171};
3172
3173// padding, constant tables for calculating md5
3174var _padding = null;
3175var _g = null;
3176var _r = null;
3177var _k = null;
3178var _initialized = false;
3179
3180/**
3181 * Initializes the constant tables.
3182 */
3183function _init() {
3184  // create padding
3185  _padding = String.fromCharCode(128);
3186  _padding += forge.util.fillString(String.fromCharCode(0x00), 64);
3187
3188  // g values
3189  _g = [
3190    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
3191    1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12,
3192    5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2,
3193    0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9];
3194
3195  // rounds table
3196  _r = [
3197    7, 12, 17, 22,  7, 12, 17, 22,  7, 12, 17, 22,  7, 12, 17, 22,
3198    5,  9, 14, 20,  5,  9, 14, 20,  5,  9, 14, 20,  5,  9, 14, 20,
3199    4, 11, 16, 23,  4, 11, 16, 23,  4, 11, 16, 23,  4, 11, 16, 23,
3200    6, 10, 15, 21,  6, 10, 15, 21,  6, 10, 15, 21,  6, 10, 15, 21];
3201
3202  // get the result of abs(sin(i + 1)) as a 32-bit integer
3203  _k = new Array(64);
3204  for(var i = 0; i < 64; ++i) {
3205    _k[i] = Math.floor(Math.abs(Math.sin(i + 1)) * 0x100000000);
3206  }
3207
3208  // now initialized
3209  _initialized = true;
3210}
3211
3212/**
3213 * Updates an MD5 state with the given byte buffer.
3214 *
3215 * @param s the MD5 state to update.
3216 * @param w the array to use to store words.
3217 * @param bytes the byte buffer to update with.
3218 */
3219function _update(s, w, bytes) {
3220  // consume 512 bit (64 byte) chunks
3221  var t, a, b, c, d, f, r, i;
3222  var len = bytes.length();
3223  while(len >= 64) {
3224    // initialize hash value for this chunk
3225    a = s.h0;
3226    b = s.h1;
3227    c = s.h2;
3228    d = s.h3;
3229
3230    // round 1
3231    for(i = 0; i < 16; ++i) {
3232      w[i] = bytes.getInt32Le();
3233      f = d ^ (b & (c ^ d));
3234      t = (a + f + _k[i] + w[i]);
3235      r = _r[i];
3236      a = d;
3237      d = c;
3238      c = b;
3239      b += (t << r) | (t >>> (32 - r));
3240    }
3241    // round 2
3242    for(; i < 32; ++i) {
3243      f = c ^ (d & (b ^ c));
3244      t = (a + f + _k[i] + w[_g[i]]);
3245      r = _r[i];
3246      a = d;
3247      d = c;
3248      c = b;
3249      b += (t << r) | (t >>> (32 - r));
3250    }
3251    // round 3
3252    for(; i < 48; ++i) {
3253      f = b ^ c ^ d;
3254      t = (a + f + _k[i] + w[_g[i]]);
3255      r = _r[i];
3256      a = d;
3257      d = c;
3258      c = b;
3259      b += (t << r) | (t >>> (32 - r));
3260    }
3261    // round 4
3262    for(; i < 64; ++i) {
3263      f = c ^ (b | ~d);
3264      t = (a + f + _k[i] + w[_g[i]]);
3265      r = _r[i];
3266      a = d;
3267      d = c;
3268      c = b;
3269      b += (t << r) | (t >>> (32 - r));
3270    }
3271
3272    // update hash state
3273    s.h0 = (s.h0 + a) | 0;
3274    s.h1 = (s.h1 + b) | 0;
3275    s.h2 = (s.h2 + c) | 0;
3276    s.h3 = (s.h3 + d) | 0;
3277
3278    len -= 64;
3279  }
3280}
3281
3282} // end module implementation
3283
3284/* ########## Begin module wrapper ########## */
3285var name = 'md5';
3286if(typeof define !== 'function') {
3287  // NodeJS -> AMD
3288  if(typeof module === 'object' && module.exports) {
3289    var nodeJS = true;
3290    define = function(ids, factory) {
3291      factory(require, module);
3292    };
3293  } else {
3294    // <script>
3295    if(typeof forge === 'undefined') {
3296      forge = {};
3297    }
3298    return initModule(forge);
3299  }
3300}
3301// AMD
3302var deps;
3303var defineFunc = function(require, module) {
3304  module.exports = function(forge) {
3305    var mods = deps.map(function(dep) {
3306      return require(dep);
3307    }).concat(initModule);
3308    // handle circular dependencies
3309    forge = forge || {};
3310    forge.defined = forge.defined || {};
3311    if(forge.defined[name]) {
3312      return forge[name];
3313    }
3314    forge.defined[name] = true;
3315    for(var i = 0; i < mods.length; ++i) {
3316      mods[i](forge);
3317    }
3318    return forge[name];
3319  };
3320};
3321var tmpDefine = define;
3322define = function(ids, factory) {
3323  deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2);
3324  if(nodeJS) {
3325    delete define;
3326    return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0));
3327  }
3328  define = tmpDefine;
3329  return define.apply(null, Array.prototype.slice.call(arguments, 0));
3330};
3331define(['require', 'module', './util'], function() {
3332  defineFunc.apply(null, Array.prototype.slice.call(arguments, 0));
3333});
3334})();
3335
3336/**
3337 * Secure Hash Algorithm with 160-bit digest (SHA-1) implementation.
3338 *
3339 * @author Dave Longley
3340 *
3341 * Copyright (c) 2010-2015 Digital Bazaar, Inc.
3342 */
3343(function() {
3344/* ########## Begin module implementation ########## */
3345function initModule(forge) {
3346
3347var sha1 = forge.sha1 = forge.sha1 || {};
3348forge.md = forge.md || {};
3349forge.md.algorithms = forge.md.algorithms || {};
3350forge.md.sha1 = forge.md.algorithms.sha1 = sha1;
3351
3352/**
3353 * Creates a SHA-1 message digest object.
3354 *
3355 * @return a message digest object.
3356 */
3357sha1.create = function() {
3358  // do initialization as necessary
3359  if(!_initialized) {
3360    _init();
3361  }
3362
3363  // SHA-1 state contains five 32-bit integers
3364  var _state = null;
3365
3366  // input buffer
3367  var _input = forge.util.createBuffer();
3368
3369  // used for word storage
3370  var _w = new Array(80);
3371
3372  // message digest object
3373  var md = {
3374    algorithm: 'sha1',
3375    blockLength: 64,
3376    digestLength: 20,
3377    // 56-bit length of message so far (does not including padding)
3378    messageLength: 0,
3379    // true message length
3380    fullMessageLength: null,
3381    // size of message length in bytes
3382    messageLengthSize: 8
3383  };
3384
3385  /**
3386   * Starts the digest.
3387   *
3388   * @return this digest object.
3389   */
3390  md.start = function() {
3391    // up to 56-bit message length for convenience
3392    md.messageLength = 0;
3393
3394    // full message length (set md.messageLength64 for backwards-compatibility)
3395    md.fullMessageLength = md.messageLength64 = [];
3396    var int32s = md.messageLengthSize / 4;
3397    for(var i = 0; i < int32s; ++i) {
3398      md.fullMessageLength.push(0);
3399    }
3400    _input = forge.util.createBuffer();
3401    _state = {
3402      h0: 0x67452301,
3403      h1: 0xEFCDAB89,
3404      h2: 0x98BADCFE,
3405      h3: 0x10325476,
3406      h4: 0xC3D2E1F0
3407    };
3408    return md;
3409  };
3410  // start digest automatically for first time
3411  md.start();
3412
3413  /**
3414   * Updates the digest with the given message input. The given input can
3415   * treated as raw input (no encoding will be applied) or an encoding of
3416   * 'utf8' maybe given to encode the input using UTF-8.
3417   *
3418   * @param msg the message input to update with.
3419   * @param encoding the encoding to use (default: 'raw', other: 'utf8').
3420   *
3421   * @return this digest object.
3422   */
3423  md.update = function(msg, encoding) {
3424    if(encoding === 'utf8') {
3425      msg = forge.util.encodeUtf8(msg);
3426    }
3427
3428    // update message length
3429    var len = msg.length;
3430    md.messageLength += len;
3431    len = [(len / 0x100000000) >>> 0, len >>> 0];
3432    for(var i = md.fullMessageLength.length - 1; i >= 0; --i) {
3433      md.fullMessageLength[i] += len[1];
3434      len[1] = len[0] + ((md.fullMessageLength[i] / 0x100000000) >>> 0);
3435      md.fullMessageLength[i] = md.fullMessageLength[i] >>> 0;
3436      len[0] = ((len[1] / 0x100000000) >>> 0);
3437    }
3438
3439    // add bytes to input buffer
3440    _input.putBytes(msg);
3441
3442    // process bytes
3443    _update(_state, _w, _input);
3444
3445    // compact input buffer every 2K or if empty
3446    if(_input.read > 2048 || _input.length() === 0) {
3447      _input.compact();
3448    }
3449
3450    return md;
3451  };
3452
3453   /**
3454    * Produces the digest.
3455    *
3456    * @return a byte buffer containing the digest value.
3457    */
3458   md.digest = function() {
3459    /* Note: Here we copy the remaining bytes in the input buffer and
3460    add the appropriate SHA-1 padding. Then we do the final update
3461    on a copy of the state so that if the user wants to get
3462    intermediate digests they can do so. */
3463
3464    /* Determine the number of bytes that must be added to the message
3465    to ensure its length is congruent to 448 mod 512. In other words,
3466    the data to be digested must be a multiple of 512 bits (or 128 bytes).
3467    This data includes the message, some padding, and the length of the
3468    message. Since the length of the message will be encoded as 8 bytes (64
3469    bits), that means that the last segment of the data must have 56 bytes
3470    (448 bits) of message and padding. Therefore, the length of the message
3471    plus the padding must be congruent to 448 mod 512 because
3472    512 - 128 = 448.
3473
3474    In order to fill up the message length it must be filled with
3475    padding that begins with 1 bit followed by all 0 bits. Padding
3476    must *always* be present, so if the message length is already
3477    congruent to 448 mod 512, then 512 padding bits must be added. */
3478
3479    var finalBlock = forge.util.createBuffer();
3480    finalBlock.putBytes(_input.bytes());
3481
3482    // compute remaining size to be digested (include message length size)
3483    var remaining = (
3484      md.fullMessageLength[md.fullMessageLength.length - 1] +
3485      md.messageLengthSize);
3486
3487    // add padding for overflow blockSize - overflow
3488    // _padding starts with 1 byte with first bit is set (byte value 128), then
3489    // there may be up to (blockSize - 1) other pad bytes
3490    var overflow = remaining & (md.blockLength - 1);
3491    finalBlock.putBytes(_padding.substr(0, md.blockLength - overflow));
3492
3493    // serialize message length in bits in big-endian order; since length
3494    // is stored in bytes we multiply by 8 and add carry from next int
3495    var next, carry;
3496    var bits = md.fullMessageLength[0] * 8;
3497    for(var i = 0; i < md.fullMessageLength.length - 1; ++i) {
3498      next = md.fullMessageLength[i + 1] * 8;
3499      carry = (next / 0x100000000) >>> 0;
3500      bits += carry;
3501      finalBlock.putInt32(bits >>> 0);
3502      bits = next >>> 0;
3503    }
3504    finalBlock.putInt32(bits);
3505
3506    var s2 = {
3507      h0: _state.h0,
3508      h1: _state.h1,
3509      h2: _state.h2,
3510      h3: _state.h3,
3511      h4: _state.h4
3512    };
3513    _update(s2, _w, finalBlock);
3514    var rval = forge.util.createBuffer();
3515    rval.putInt32(s2.h0);
3516    rval.putInt32(s2.h1);
3517    rval.putInt32(s2.h2);
3518    rval.putInt32(s2.h3);
3519    rval.putInt32(s2.h4);
3520    return rval;
3521  };
3522
3523  return md;
3524};
3525
3526// sha-1 padding bytes not initialized yet
3527var _padding = null;
3528var _initialized = false;
3529
3530/**
3531 * Initializes the constant tables.
3532 */
3533function _init() {
3534  // create padding
3535  _padding = String.fromCharCode(128);
3536  _padding += forge.util.fillString(String.fromCharCode(0x00), 64);
3537
3538  // now initialized
3539  _initialized = true;
3540}
3541
3542/**
3543 * Updates a SHA-1 state with the given byte buffer.
3544 *
3545 * @param s the SHA-1 state to update.
3546 * @param w the array to use to store words.
3547 * @param bytes the byte buffer to update with.
3548 */
3549function _update(s, w, bytes) {
3550  // consume 512 bit (64 byte) chunks
3551  var t, a, b, c, d, e, f, i;
3552  var len = bytes.length();
3553  while(len >= 64) {
3554    // the w array will be populated with sixteen 32-bit big-endian words
3555    // and then extended into 80 32-bit words according to SHA-1 algorithm
3556    // and for 32-79 using Max Locktyukhin's optimization
3557
3558    // initialize hash value for this chunk
3559    a = s.h0;
3560    b = s.h1;
3561    c = s.h2;
3562    d = s.h3;
3563    e = s.h4;
3564
3565    // round 1
3566    for(i = 0; i < 16; ++i) {
3567      t = bytes.getInt32();
3568      w[i] = t;
3569      f = d ^ (b & (c ^ d));
3570      t = ((a << 5) | (a >>> 27)) + f + e + 0x5A827999 + t;
3571      e = d;
3572      d = c;
3573      // `>>> 0` necessary to avoid iOS/Safari 10 optimization bug
3574      c = ((b << 30) | (b >>> 2)) >>> 0;
3575      b = a;
3576      a = t;
3577    }
3578    for(; i < 20; ++i) {
3579      t = (w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16]);
3580      t = (t << 1) | (t >>> 31);
3581      w[i] = t;
3582      f = d ^ (b & (c ^ d));
3583      t = ((a << 5) | (a >>> 27)) + f + e + 0x5A827999 + t;
3584      e = d;
3585      d = c;
3586      // `>>> 0` necessary to avoid iOS/Safari 10 optimization bug
3587      c = ((b << 30) | (b >>> 2)) >>> 0;
3588      b = a;
3589      a = t;
3590    }
3591    // round 2
3592    for(; i < 32; ++i) {
3593      t = (w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16]);
3594      t = (t << 1) | (t >>> 31);
3595      w[i] = t;
3596      f = b ^ c ^ d;
3597      t = ((a << 5) | (a >>> 27)) + f + e + 0x6ED9EBA1 + t;
3598      e = d;
3599      d = c;
3600      // `>>> 0` necessary to avoid iOS/Safari 10 optimization bug
3601      c = ((b << 30) | (b >>> 2)) >>> 0;
3602      b = a;
3603      a = t;
3604    }
3605    for(; i < 40; ++i) {
3606      t = (w[i - 6] ^ w[i - 16] ^ w[i - 28] ^ w[i - 32]);
3607      t = (t << 2) | (t >>> 30);
3608      w[i] = t;
3609      f = b ^ c ^ d;
3610      t = ((a << 5) | (a >>> 27)) + f + e + 0x6ED9EBA1 + t;
3611      e = d;
3612      d = c;
3613      // `>>> 0` necessary to avoid iOS/Safari 10 optimization bug
3614      c = ((b << 30) | (b >>> 2)) >>> 0;
3615      b = a;
3616      a = t;
3617    }
3618    // round 3
3619    for(; i < 60; ++i) {
3620      t = (w[i - 6] ^ w[i - 16] ^ w[i - 28] ^ w[i - 32]);
3621      t = (t << 2) | (t >>> 30);
3622      w[i] = t;
3623      f = (b & c) | (d & (b ^ c));
3624      t = ((a << 5) | (a >>> 27)) + f + e + 0x8F1BBCDC + t;
3625      e = d;
3626      d = c;
3627      // `>>> 0` necessary to avoid iOS/Safari 10 optimization bug
3628      c = ((b << 30) | (b >>> 2)) >>> 0;
3629      b = a;
3630      a = t;
3631    }
3632    // round 4
3633    for(; i < 80; ++i) {
3634      t = (w[i - 6] ^ w[i - 16] ^ w[i - 28] ^ w[i - 32]);
3635      t = (t << 2) | (t >>> 30);
3636      w[i] = t;
3637      f = b ^ c ^ d;
3638      t = ((a << 5) | (a >>> 27)) + f + e + 0xCA62C1D6 + t;
3639      e = d;
3640      d = c;
3641      // `>>> 0` necessary to avoid iOS/Safari 10 optimization bug
3642      c = ((b << 30) | (b >>> 2)) >>> 0;
3643      b = a;
3644      a = t;
3645    }
3646
3647    // update hash state
3648    s.h0 = (s.h0 + a) | 0;
3649    s.h1 = (s.h1 + b) | 0;
3650    s.h2 = (s.h2 + c) | 0;
3651    s.h3 = (s.h3 + d) | 0;
3652    s.h4 = (s.h4 + e) | 0;
3653
3654    len -= 64;
3655  }
3656}
3657
3658} // end module implementation
3659
3660/* ########## Begin module wrapper ########## */
3661var name = 'sha1';
3662if(typeof define !== 'function') {
3663  // NodeJS -> AMD
3664  if(typeof module === 'object' && module.exports) {
3665    var nodeJS = true;
3666    define = function(ids, factory) {
3667      factory(require, module);
3668    };
3669  } else {
3670    // <script>
3671    if(typeof forge === 'undefined') {
3672      forge = {};
3673    }
3674    return initModule(forge);
3675  }
3676}
3677// AMD
3678var deps;
3679var defineFunc = function(require, module) {
3680  module.exports = function(forge) {
3681    var mods = deps.map(function(dep) {
3682      return require(dep);
3683    }).concat(initModule);
3684    // handle circular dependencies
3685    forge = forge || {};
3686    forge.defined = forge.defined || {};
3687    if(forge.defined[name]) {
3688      return forge[name];
3689    }
3690    forge.defined[name] = true;
3691    for(var i = 0; i < mods.length; ++i) {
3692      mods[i](forge);
3693    }
3694    return forge[name];
3695  };
3696};
3697var tmpDefine = define;
3698define = function(ids, factory) {
3699  deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2);
3700  if(nodeJS) {
3701    delete define;
3702    return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0));
3703  }
3704  define = tmpDefine;
3705  return define.apply(null, Array.prototype.slice.call(arguments, 0));
3706};
3707define(['require', 'module', './util'], function() {
3708  defineFunc.apply(null, Array.prototype.slice.call(arguments, 0));
3709});
3710})();
3711
3712/**
3713 * Secure Hash Algorithm with 256-bit digest (SHA-256) implementation.
3714 *
3715 * See FIPS 180-2 for details.
3716 *
3717 * @author Dave Longley
3718 *
3719 * Copyright (c) 2010-2015 Digital Bazaar, Inc.
3720 */
3721(function() {
3722/* ########## Begin module implementation ########## */
3723function initModule(forge) {
3724
3725var sha256 = forge.sha256 = forge.sha256 || {};
3726forge.md = forge.md || {};
3727forge.md.algorithms = forge.md.algorithms || {};
3728forge.md.sha256 = forge.md.algorithms.sha256 = sha256;
3729
3730/**
3731 * Creates a SHA-256 message digest object.
3732 *
3733 * @return a message digest object.
3734 */
3735sha256.create = function() {
3736  // do initialization as necessary
3737  if(!_initialized) {
3738    _init();
3739  }
3740
3741  // SHA-256 state contains eight 32-bit integers
3742  var _state = null;
3743
3744  // input buffer
3745  var _input = forge.util.createBuffer();
3746
3747  // used for word storage
3748  var _w = new Array(64);
3749
3750  // message digest object
3751  var md = {
3752    algorithm: 'sha256',
3753    blockLength: 64,
3754    digestLength: 32,
3755    // 56-bit length of message so far (does not including padding)
3756    messageLength: 0,
3757    // true message length
3758    fullMessageLength: null,
3759    // size of message length in bytes
3760    messageLengthSize: 8
3761  };
3762
3763  /**
3764   * Starts the digest.
3765   *
3766   * @return this digest object.
3767   */
3768  md.start = function() {
3769    // up to 56-bit message length for convenience
3770    md.messageLength = 0;
3771
3772    // full message length (set md.messageLength64 for backwards-compatibility)
3773    md.fullMessageLength = md.messageLength64 = [];
3774    var int32s = md.messageLengthSize / 4;
3775    for(var i = 0; i < int32s; ++i) {
3776      md.fullMessageLength.push(0);
3777    }
3778    _input = forge.util.createBuffer();
3779    _state = {
3780      h0: 0x6A09E667,
3781      h1: 0xBB67AE85,
3782      h2: 0x3C6EF372,
3783      h3: 0xA54FF53A,
3784      h4: 0x510E527F,
3785      h5: 0x9B05688C,
3786      h6: 0x1F83D9AB,
3787      h7: 0x5BE0CD19
3788    };
3789    return md;
3790  };
3791  // start digest automatically for first time
3792  md.start();
3793
3794  /**
3795   * Updates the digest with the given message input. The given input can
3796   * treated as raw input (no encoding will be applied) or an encoding of
3797   * 'utf8' maybe given to encode the input using UTF-8.
3798   *
3799   * @param msg the message input to update with.
3800   * @param encoding the encoding to use (default: 'raw', other: 'utf8').
3801   *
3802   * @return this digest object.
3803   */
3804  md.update = function(msg, encoding) {
3805    if(encoding === 'utf8') {
3806      msg = forge.util.encodeUtf8(msg);
3807    }
3808
3809    // update message length
3810    var len = msg.length;
3811    md.messageLength += len;
3812    len = [(len / 0x100000000) >>> 0, len >>> 0];
3813    for(var i = md.fullMessageLength.length - 1; i >= 0; --i) {
3814      md.fullMessageLength[i] += len[1];
3815      len[1] = len[0] + ((md.fullMessageLength[i] / 0x100000000) >>> 0);
3816      md.fullMessageLength[i] = md.fullMessageLength[i] >>> 0;
3817      len[0] = ((len[1] / 0x100000000) >>> 0);
3818    }
3819
3820    // add bytes to input buffer
3821    _input.putBytes(msg);
3822
3823    // process bytes
3824    _update(_state, _w, _input);
3825
3826    // compact input buffer every 2K or if empty
3827    if(_input.read > 2048 || _input.length() === 0) {
3828      _input.compact();
3829    }
3830
3831    return md;
3832  };
3833
3834  /**
3835   * Produces the digest.
3836   *
3837   * @return a byte buffer containing the digest value.
3838   */
3839  md.digest = function() {
3840    /* Note: Here we copy the remaining bytes in the input buffer and
3841    add the appropriate SHA-256 padding. Then we do the final update
3842    on a copy of the state so that if the user wants to get
3843    intermediate digests they can do so. */
3844
3845    /* Determine the number of bytes that must be added to the message
3846    to ensure its length is congruent to 448 mod 512. In other words,
3847    the data to be digested must be a multiple of 512 bits (or 128 bytes).
3848    This data includes the message, some padding, and the length of the
3849    message. Since the length of the message will be encoded as 8 bytes (64
3850    bits), that means that the last segment of the data must have 56 bytes
3851    (448 bits) of message and padding. Therefore, the length of the message
3852    plus the padding must be congruent to 448 mod 512 because
3853    512 - 128 = 448.
3854
3855    In order to fill up the message length it must be filled with
3856    padding that begins with 1 bit followed by all 0 bits. Padding
3857    must *always* be present, so if the message length is already
3858    congruent to 448 mod 512, then 512 padding bits must be added. */
3859
3860    var finalBlock = forge.util.createBuffer();
3861    finalBlock.putBytes(_input.bytes());
3862
3863    // compute remaining size to be digested (include message length size)
3864    var remaining = (
3865      md.fullMessageLength[md.fullMessageLength.length - 1] +
3866      md.messageLengthSize);
3867
3868    // add padding for overflow blockSize - overflow
3869    // _padding starts with 1 byte with first bit is set (byte value 128), then
3870    // there may be up to (blockSize - 1) other pad bytes
3871    var overflow = remaining & (md.blockLength - 1);
3872    finalBlock.putBytes(_padding.substr(0, md.blockLength - overflow));
3873
3874    // serialize message length in bits in big-endian order; since length
3875    // is stored in bytes we multiply by 8 and add carry from next int
3876    var next, carry;
3877    var bits = md.fullMessageLength[0] * 8;
3878    for(var i = 0; i < md.fullMessageLength.length - 1; ++i) {
3879      next = md.fullMessageLength[i + 1] * 8;
3880      carry = (next / 0x100000000) >>> 0;
3881      bits += carry;
3882      finalBlock.putInt32(bits >>> 0);
3883      bits = next >>> 0;
3884    }
3885    finalBlock.putInt32(bits);
3886
3887    var s2 = {
3888      h0: _state.h0,
3889      h1: _state.h1,
3890      h2: _state.h2,
3891      h3: _state.h3,
3892      h4: _state.h4,
3893      h5: _state.h5,
3894      h6: _state.h6,
3895      h7: _state.h7
3896    };
3897    _update(s2, _w, finalBlock);
3898    var rval = forge.util.createBuffer();
3899    rval.putInt32(s2.h0);
3900    rval.putInt32(s2.h1);
3901    rval.putInt32(s2.h2);
3902    rval.putInt32(s2.h3);
3903    rval.putInt32(s2.h4);
3904    rval.putInt32(s2.h5);
3905    rval.putInt32(s2.h6);
3906    rval.putInt32(s2.h7);
3907    return rval;
3908  };
3909
3910  return md;
3911};
3912
3913// sha-256 padding bytes not initialized yet
3914var _padding = null;
3915var _initialized = false;
3916
3917// table of constants
3918var _k = null;
3919
3920/**
3921 * Initializes the constant tables.
3922 */
3923function _init() {
3924  // create padding
3925  _padding = String.fromCharCode(128);
3926  _padding += forge.util.fillString(String.fromCharCode(0x00), 64);
3927
3928  // create K table for SHA-256
3929  _k = [
3930    0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
3931    0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
3932    0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
3933    0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
3934    0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
3935    0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
3936    0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
3937    0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
3938    0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
3939    0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
3940    0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
3941    0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
3942    0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
3943    0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
3944    0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
3945    0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2];
3946
3947  // now initialized
3948  _initialized = true;
3949}
3950
3951/**
3952 * Updates a SHA-256 state with the given byte buffer.
3953 *
3954 * @param s the SHA-256 state to update.
3955 * @param w the array to use to store words.
3956 * @param bytes the byte buffer to update with.
3957 */
3958function _update(s, w, bytes) {
3959  // consume 512 bit (64 byte) chunks
3960  var t1, t2, s0, s1, ch, maj, i, a, b, c, d, e, f, g, h;
3961  var len = bytes.length();
3962  while(len >= 64) {
3963    // the w array will be populated with sixteen 32-bit big-endian words
3964    // and then extended into 64 32-bit words according to SHA-256
3965    for(i = 0; i < 16; ++i) {
3966      w[i] = bytes.getInt32();
3967    }
3968    for(; i < 64; ++i) {
3969      // XOR word 2 words ago rot right 17, rot right 19, shft right 10
3970      t1 = w[i - 2];
3971      t1 =
3972        ((t1 >>> 17) | (t1 << 15)) ^
3973        ((t1 >>> 19) | (t1 << 13)) ^
3974        (t1 >>> 10);
3975      // XOR word 15 words ago rot right 7, rot right 18, shft right 3
3976      t2 = w[i - 15];
3977      t2 =
3978        ((t2 >>> 7) | (t2 << 25)) ^
3979        ((t2 >>> 18) | (t2 << 14)) ^
3980        (t2 >>> 3);
3981      // sum(t1, word 7 ago, t2, word 16 ago) modulo 2^32
3982      w[i] = (t1 + w[i - 7] + t2 + w[i - 16]) | 0;
3983    }
3984
3985    // initialize hash value for this chunk
3986    a = s.h0;
3987    b = s.h1;
3988    c = s.h2;
3989    d = s.h3;
3990    e = s.h4;
3991    f = s.h5;
3992    g = s.h6;
3993    h = s.h7;
3994
3995    // round function
3996    for(i = 0; i < 64; ++i) {
3997      // Sum1(e)
3998      s1 =
3999        ((e >>> 6) | (e << 26)) ^
4000        ((e >>> 11) | (e << 21)) ^
4001        ((e >>> 25) | (e << 7));
4002      // Ch(e, f, g) (optimized the same way as SHA-1)
4003      ch = g ^ (e & (f ^ g));
4004      // Sum0(a)
4005      s0 =
4006        ((a >>> 2) | (a << 30)) ^
4007        ((a >>> 13) | (a << 19)) ^
4008        ((a >>> 22) | (a << 10));
4009      // Maj(a, b, c) (optimized the same way as SHA-1)
4010      maj = (a & b) | (c & (a ^ b));
4011
4012      // main algorithm
4013      t1 = h + s1 + ch + _k[i] + w[i];
4014      t2 = s0 + maj;
4015      h = g;
4016      g = f;
4017      f = e;
4018      // `>>> 0` necessary to avoid iOS/Safari 10 optimization bug
4019      // can't truncate with `| 0`
4020      e = (d + t1) >>> 0;
4021      d = c;
4022      c = b;
4023      b = a;
4024      // `>>> 0` necessary to avoid iOS/Safari 10 optimization bug
4025      // can't truncate with `| 0`
4026      a = (t1 + t2) >>> 0;
4027    }
4028
4029    // update hash state
4030    s.h0 = (s.h0 + a) | 0;
4031    s.h1 = (s.h1 + b) | 0;
4032    s.h2 = (s.h2 + c) | 0;
4033    s.h3 = (s.h3 + d) | 0;
4034    s.h4 = (s.h4 + e) | 0;
4035    s.h5 = (s.h5 + f) | 0;
4036    s.h6 = (s.h6 + g) | 0;
4037    s.h7 = (s.h7 + h) | 0;
4038    len -= 64;
4039  }
4040}
4041
4042} // end module implementation
4043
4044/* ########## Begin module wrapper ########## */
4045var name = 'sha256';
4046if(typeof define !== 'function') {
4047  // NodeJS -> AMD
4048  if(typeof module === 'object' && module.exports) {
4049    var nodeJS = true;
4050    define = function(ids, factory) {
4051      factory(require, module);
4052    };
4053  } else {
4054    // <script>
4055    if(typeof forge === 'undefined') {
4056      forge = {};
4057    }
4058    return initModule(forge);
4059  }
4060}
4061// AMD
4062var deps;
4063var defineFunc = function(require, module) {
4064  module.exports = function(forge) {
4065    var mods = deps.map(function(dep) {
4066      return require(dep);
4067    }).concat(initModule);
4068    // handle circular dependencies
4069    forge = forge || {};
4070    forge.defined = forge.defined || {};
4071    if(forge.defined[name]) {
4072      return forge[name];
4073    }
4074    forge.defined[name] = true;
4075    for(var i = 0; i < mods.length; ++i) {
4076      mods[i](forge);
4077    }
4078    return forge[name];
4079  };
4080};
4081var tmpDefine = define;
4082define = function(ids, factory) {
4083  deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2);
4084  if(nodeJS) {
4085    delete define;
4086    return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0));
4087  }
4088  define = tmpDefine;
4089  return define.apply(null, Array.prototype.slice.call(arguments, 0));
4090};
4091define(['require', 'module', './util'], function() {
4092  defineFunc.apply(null, Array.prototype.slice.call(arguments, 0));
4093});
4094})();
4095
4096/**
4097 * Cipher base API.
4098 *
4099 * @author Dave Longley
4100 *
4101 * Copyright (c) 2010-2014 Digital Bazaar, Inc.
4102 */
4103(function() {
4104/* ########## Begin module implementation ########## */
4105function initModule(forge) {
4106
4107forge.cipher = forge.cipher || {};
4108
4109// registered algorithms
4110forge.cipher.algorithms = forge.cipher.algorithms || {};
4111
4112/**
4113 * Creates a cipher object that can be used to encrypt data using the given
4114 * algorithm and key. The algorithm may be provided as a string value for a
4115 * previously registered algorithm or it may be given as a cipher algorithm
4116 * API object.
4117 *
4118 * @param algorithm the algorithm to use, either a string or an algorithm API
4119 *          object.
4120 * @param key the key to use, as a binary-encoded string of bytes or a
4121 *          byte buffer.
4122 *
4123 * @return the cipher.
4124 */
4125forge.cipher.createCipher = function(algorithm, key) {
4126  var api = algorithm;
4127  if(typeof api === 'string') {
4128    api = forge.cipher.getAlgorithm(api);
4129    if(api) {
4130      api = api();
4131    }
4132  }
4133  if(!api) {
4134    throw new Error('Unsupported algorithm: ' + algorithm);
4135  }
4136
4137  // assume block cipher
4138  return new forge.cipher.BlockCipher({
4139    algorithm: api,
4140    key: key,
4141    decrypt: false
4142  });
4143};
4144
4145/**
4146 * Creates a decipher object that can be used to decrypt data using the given
4147 * algorithm and key. The algorithm may be provided as a string value for a
4148 * previously registered algorithm or it may be given as a cipher algorithm
4149 * API object.
4150 *
4151 * @param algorithm the algorithm to use, either a string or an algorithm API
4152 *          object.
4153 * @param key the key to use, as a binary-encoded string of bytes or a
4154 *          byte buffer.
4155 *
4156 * @return the cipher.
4157 */
4158forge.cipher.createDecipher = function(algorithm, key) {
4159  var api = algorithm;
4160  if(typeof api === 'string') {
4161    api = forge.cipher.getAlgorithm(api);
4162    if(api) {
4163      api = api();
4164    }
4165  }
4166  if(!api) {
4167    throw new Error('Unsupported algorithm: ' + algorithm);
4168  }
4169
4170  // assume block cipher
4171  return new forge.cipher.BlockCipher({
4172    algorithm: api,
4173    key: key,
4174    decrypt: true
4175  });
4176};
4177
4178/**
4179 * Registers an algorithm by name. If the name was already registered, the
4180 * algorithm API object will be overwritten.
4181 *
4182 * @param name the name of the algorithm.
4183 * @param algorithm the algorithm API object.
4184 */
4185forge.cipher.registerAlgorithm = function(name, algorithm) {
4186  name = name.toUpperCase();
4187  forge.cipher.algorithms[name] = algorithm;
4188};
4189
4190/**
4191 * Gets a registered algorithm by name.
4192 *
4193 * @param name the name of the algorithm.
4194 *
4195 * @return the algorithm, if found, null if not.
4196 */
4197forge.cipher.getAlgorithm = function(name) {
4198  name = name.toUpperCase();
4199  if(name in forge.cipher.algorithms) {
4200    return forge.cipher.algorithms[name];
4201  }
4202  return null;
4203};
4204
4205var BlockCipher = forge.cipher.BlockCipher = function(options) {
4206  this.algorithm = options.algorithm;
4207  this.mode = this.algorithm.mode;
4208  this.blockSize = this.mode.blockSize;
4209  this._finish = false;
4210  this._input = null;
4211  this.output = null;
4212  this._op = options.decrypt ? this.mode.decrypt : this.mode.encrypt;
4213  this._decrypt = options.decrypt;
4214  this.algorithm.initialize(options);
4215};
4216
4217/**
4218 * Starts or restarts the encryption or decryption process, whichever
4219 * was previously configured.
4220 *
4221 * For non-GCM mode, the IV may be a binary-encoded string of bytes, an array
4222 * of bytes, a byte buffer, or an array of 32-bit integers. If the IV is in
4223 * bytes, then it must be Nb (16) bytes in length. If the IV is given in as
4224 * 32-bit integers, then it must be 4 integers long.
4225 *
4226 * Note: an IV is not required or used in ECB mode.
4227 *
4228 * For GCM-mode, the IV must be given as a binary-encoded string of bytes or
4229 * a byte buffer. The number of bytes should be 12 (96 bits) as recommended
4230 * by NIST SP-800-38D but another length may be given.
4231 *
4232 * @param options the options to use:
4233 *          iv the initialization vector to use as a binary-encoded string of
4234 *            bytes, null to reuse the last ciphered block from a previous
4235 *            update() (this "residue" method is for legacy support only).
4236 *          additionalData additional authentication data as a binary-encoded
4237 *            string of bytes, for 'GCM' mode, (default: none).
4238 *          tagLength desired length of authentication tag, in bits, for
4239 *            'GCM' mode (0-128, default: 128).
4240 *          tag the authentication tag to check if decrypting, as a
4241 *             binary-encoded string of bytes.
4242 *          output the output the buffer to write to, null to create one.
4243 */
4244BlockCipher.prototype.start = function(options) {
4245  options = options || {};
4246  var opts = {};
4247  for(var key in options) {
4248    opts[key] = options[key];
4249  }
4250  opts.decrypt = this._decrypt;
4251  this._finish = false;
4252  this._input = forge.util.createBuffer();
4253  this.output = options.output || forge.util.createBuffer();
4254  this.mode.start(opts);
4255};
4256
4257/**
4258 * Updates the next block according to the cipher mode.
4259 *
4260 * @param input the buffer to read from.
4261 */
4262BlockCipher.prototype.update = function(input) {
4263  if(input) {
4264    // input given, so empty it into the input buffer
4265    this._input.putBuffer(input);
4266  }
4267
4268  // do cipher operation until it needs more input and not finished
4269  while(!this._op.call(this.mode, this._input, this.output, this._finish) &&
4270    !this._finish) {}
4271
4272  // free consumed memory from input buffer
4273  this._input.compact();
4274};
4275
4276/**
4277 * Finishes encrypting or decrypting.
4278 *
4279 * @param pad a padding function to use in CBC mode, null for default,
4280 *          signature(blockSize, buffer, decrypt).
4281 *
4282 * @return true if successful, false on error.
4283 */
4284BlockCipher.prototype.finish = function(pad) {
4285  // backwards-compatibility w/deprecated padding API
4286  // Note: will overwrite padding functions even after another start() call
4287  if(pad && (this.mode.name === 'ECB' || this.mode.name === 'CBC')) {
4288    this.mode.pad = function(input) {
4289      return pad(this.blockSize, input, false);
4290    };
4291    this.mode.unpad = function(output) {
4292      return pad(this.blockSize, output, true);
4293    };
4294  }
4295
4296  // build options for padding and afterFinish functions
4297  var options = {};
4298  options.decrypt = this._decrypt;
4299
4300  // get # of bytes that won't fill a block
4301  options.overflow = this._input.length() % this.blockSize;
4302
4303  if(!this._decrypt && this.mode.pad) {
4304    if(!this.mode.pad(this._input, options)) {
4305      return false;
4306    }
4307  }
4308
4309  // do final update
4310  this._finish = true;
4311  this.update();
4312
4313  if(this._decrypt && this.mode.unpad) {
4314    if(!this.mode.unpad(this.output, options)) {
4315      return false;
4316    }
4317  }
4318
4319  if(this.mode.afterFinish) {
4320    if(!this.mode.afterFinish(this.output, options)) {
4321      return false;
4322    }
4323  }
4324
4325  return true;
4326};
4327
4328
4329} // end module implementation
4330
4331/* ########## Begin module wrapper ########## */
4332var name = 'cipher';
4333if(typeof define !== 'function') {
4334  // NodeJS -> AMD
4335  if(typeof module === 'object' && module.exports) {
4336    var nodeJS = true;
4337    define = function(ids, factory) {
4338      factory(require, module);
4339    };
4340  } else {
4341    // <script>
4342    if(typeof forge === 'undefined') {
4343      forge = {};
4344    }
4345    return initModule(forge);
4346  }
4347}
4348// AMD
4349var deps;
4350var defineFunc = function(require, module) {
4351  module.exports = function(forge) {
4352    var mods = deps.map(function(dep) {
4353      return require(dep);
4354    }).concat(initModule);
4355    // handle circular dependencies
4356    forge = forge || {};
4357    forge.defined = forge.defined || {};
4358    if(forge.defined[name]) {
4359      return forge[name];
4360    }
4361    forge.defined[name] = true;
4362    for(var i = 0; i < mods.length; ++i) {
4363      mods[i](forge);
4364    }
4365    return forge[name];
4366  };
4367};
4368var tmpDefine = define;
4369define = function(ids, factory) {
4370  deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2);
4371  if(nodeJS) {
4372    delete define;
4373    return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0));
4374  }
4375  define = tmpDefine;
4376  return define.apply(null, Array.prototype.slice.call(arguments, 0));
4377};
4378define(['require', 'module', './util'], function() {
4379  defineFunc.apply(null, Array.prototype.slice.call(arguments, 0));
4380});
4381})();
4382
4383/**
4384 * Supported cipher modes.
4385 *
4386 * @author Dave Longley
4387 *
4388 * Copyright (c) 2010-2014 Digital Bazaar, Inc.
4389 */
4390(function() {
4391/* ########## Begin module implementation ########## */
4392function initModule(forge) {
4393
4394forge.cipher = forge.cipher || {};
4395
4396// supported cipher modes
4397var modes = forge.cipher.modes = forge.cipher.modes || {};
4398
4399
4400/** Electronic codebook (ECB) (Don't use this; it's not secure) **/
4401
4402modes.ecb = function(options) {
4403  options = options || {};
4404  this.name = 'ECB';
4405  this.cipher = options.cipher;
4406  this.blockSize = options.blockSize || 16;
4407  this._ints = this.blockSize / 4;
4408  this._inBlock = new Array(this._ints);
4409  this._outBlock = new Array(this._ints);
4410};
4411
4412modes.ecb.prototype.start = function(options) {};
4413
4414modes.ecb.prototype.encrypt = function(input, output, finish) {
4415  // not enough input to encrypt
4416  if(input.length() < this.blockSize && !(finish && input.length() > 0)) {
4417    return true;
4418  }
4419
4420  // get next block
4421  for(var i = 0; i < this._ints; ++i) {
4422    this._inBlock[i] = input.getInt32();
4423  }
4424
4425  // encrypt block
4426  this.cipher.encrypt(this._inBlock, this._outBlock);
4427
4428  // write output
4429  for(var i = 0; i < this._ints; ++i) {
4430    output.putInt32(this._outBlock[i]);
4431  }
4432};
4433
4434modes.ecb.prototype.decrypt = function(input, output, finish) {
4435  // not enough input to decrypt
4436  if(input.length() < this.blockSize && !(finish && input.length() > 0)) {
4437    return true;
4438  }
4439
4440  // get next block
4441  for(var i = 0; i < this._ints; ++i) {
4442    this._inBlock[i] = input.getInt32();
4443  }
4444
4445  // decrypt block
4446  this.cipher.decrypt(this._inBlock, this._outBlock);
4447
4448  // write output
4449  for(var i = 0; i < this._ints; ++i) {
4450    output.putInt32(this._outBlock[i]);
4451  }
4452};
4453
4454modes.ecb.prototype.pad = function(input, options) {
4455  // add PKCS#7 padding to block (each pad byte is the
4456  // value of the number of pad bytes)
4457  var padding = (input.length() === this.blockSize ?
4458    this.blockSize : (this.blockSize - input.length()));
4459  input.fillWithByte(padding, padding);
4460  return true;
4461};
4462
4463modes.ecb.prototype.unpad = function(output, options) {
4464  // check for error: input data not a multiple of blockSize
4465  if(options.overflow > 0) {
4466    return false;
4467  }
4468
4469  // ensure padding byte count is valid
4470  var len = output.length();
4471  var count = output.at(len - 1);
4472  if(count > (this.blockSize << 2)) {
4473    return false;
4474  }
4475
4476  // trim off padding bytes
4477  output.truncate(count);
4478  return true;
4479};
4480
4481
4482/** Cipher-block Chaining (CBC) **/
4483
4484modes.cbc = function(options) {
4485  options = options || {};
4486  this.name = 'CBC';
4487  this.cipher = options.cipher;
4488  this.blockSize = options.blockSize || 16;
4489  this._ints = this.blockSize / 4;
4490  this._inBlock = new Array(this._ints);
4491  this._outBlock = new Array(this._ints);
4492};
4493
4494modes.cbc.prototype.start = function(options) {
4495  // Note: legacy support for using IV residue (has security flaws)
4496  // if IV is null, reuse block from previous processing
4497  if(options.iv === null) {
4498    // must have a previous block
4499    if(!this._prev) {
4500      throw new Error('Invalid IV parameter.');
4501    }
4502    this._iv = this._prev.slice(0);
4503  } else if(!('iv' in options)) {
4504    throw new Error('Invalid IV parameter.');
4505  } else {
4506    // save IV as "previous" block
4507    this._iv = transformIV(options.iv);
4508    this._prev = this._iv.slice(0);
4509  }
4510};
4511
4512modes.cbc.prototype.encrypt = function(input, output, finish) {
4513  // not enough input to encrypt
4514  if(input.length() < this.blockSize && !(finish && input.length() > 0)) {
4515    return true;
4516  }
4517
4518  // get next block
4519  // CBC XOR's IV (or previous block) with plaintext
4520  for(var i = 0; i < this._ints; ++i) {
4521    this._inBlock[i] = this._prev[i] ^ input.getInt32();
4522  }
4523
4524  // encrypt block
4525  this.cipher.encrypt(this._inBlock, this._outBlock);
4526
4527  // write output, save previous block
4528  for(var i = 0; i < this._ints; ++i) {
4529    output.putInt32(this._outBlock[i]);
4530  }
4531  this._prev = this._outBlock;
4532};
4533
4534modes.cbc.prototype.decrypt = function(input, output, finish) {
4535  // not enough input to decrypt
4536  if(input.length() < this.blockSize && !(finish && input.length() > 0)) {
4537    return true;
4538  }
4539
4540  // get next block
4541  for(var i = 0; i < this._ints; ++i) {
4542    this._inBlock[i] = input.getInt32();
4543  }
4544
4545  // decrypt block
4546  this.cipher.decrypt(this._inBlock, this._outBlock);
4547
4548  // write output, save previous ciphered block
4549  // CBC XOR's IV (or previous block) with ciphertext
4550  for(var i = 0; i < this._ints; ++i) {
4551    output.putInt32(this._prev[i] ^ this._outBlock[i]);
4552  }
4553  this._prev = this._inBlock.slice(0);
4554};
4555
4556modes.cbc.prototype.pad = function(input, options) {
4557  // add PKCS#7 padding to block (each pad byte is the
4558  // value of the number of pad bytes)
4559  var padding = (input.length() === this.blockSize ?
4560    this.blockSize : (this.blockSize - input.length()));
4561  input.fillWithByte(padding, padding);
4562  return true;
4563};
4564
4565modes.cbc.prototype.unpad = function(output, options) {
4566  // check for error: input data not a multiple of blockSize
4567  if(options.overflow > 0) {
4568    return false;
4569  }
4570
4571  // ensure padding byte count is valid
4572  var len = output.length();
4573  var count = output.at(len - 1);
4574  if(count > (this.blockSize << 2)) {
4575    return false;
4576  }
4577
4578  // trim off padding bytes
4579  output.truncate(count);
4580  return true;
4581};
4582
4583
4584/** Cipher feedback (CFB) **/
4585
4586modes.cfb = function(options) {
4587  options = options || {};
4588  this.name = 'CFB';
4589  this.cipher = options.cipher;
4590  this.blockSize = options.blockSize || 16;
4591  this._ints = this.blockSize / 4;
4592  this._inBlock = null;
4593  this._outBlock = new Array(this._ints);
4594  this._partialBlock = new Array(this._ints);
4595  this._partialOutput = forge.util.createBuffer();
4596  this._partialBytes = 0;
4597};
4598
4599modes.cfb.prototype.start = function(options) {
4600  if(!('iv' in options)) {
4601    throw new Error('Invalid IV parameter.');
4602  }
4603  // use IV as first input
4604  this._iv = transformIV(options.iv);
4605  this._inBlock = this._iv.slice(0);
4606  this._partialBytes = 0;
4607};
4608
4609modes.cfb.prototype.encrypt = function(input, output, finish) {
4610  // not enough input to encrypt
4611  var inputLength = input.length();
4612  if(inputLength === 0) {
4613    return true;
4614  }
4615
4616  // encrypt block
4617  this.cipher.encrypt(this._inBlock, this._outBlock);
4618
4619  // handle full block
4620  if(this._partialBytes === 0 && inputLength >= this.blockSize) {
4621    // XOR input with output, write input as output
4622    for(var i = 0; i < this._ints; ++i) {
4623      this._inBlock[i] = input.getInt32() ^ this._outBlock[i];
4624      output.putInt32(this._inBlock[i]);
4625    }
4626    return;
4627  }
4628
4629  // handle partial block
4630  var partialBytes = (this.blockSize - inputLength) % this.blockSize;
4631  if(partialBytes > 0) {
4632    partialBytes = this.blockSize - partialBytes;
4633  }
4634
4635  // XOR input with output, write input as partial output
4636  this._partialOutput.clear();
4637  for(var i = 0; i < this._ints; ++i) {
4638    this._partialBlock[i] = input.getInt32() ^ this._outBlock[i];
4639    this._partialOutput.putInt32(this._partialBlock[i]);
4640  }
4641
4642  if(partialBytes > 0) {
4643    // block still incomplete, restore input buffer
4644    input.read -= this.blockSize;
4645  } else {
4646    // block complete, update input block
4647    for(var i = 0; i < this._ints; ++i) {
4648      this._inBlock[i] = this._partialBlock[i];
4649    }
4650  }
4651
4652  // skip any previous partial bytes
4653  if(this._partialBytes > 0) {
4654    this._partialOutput.getBytes(this._partialBytes);
4655  }
4656
4657  if(partialBytes > 0 && !finish) {
4658    output.putBytes(this._partialOutput.getBytes(
4659      partialBytes - this._partialBytes));
4660    this._partialBytes = partialBytes;
4661    return true;
4662  }
4663
4664  output.putBytes(this._partialOutput.getBytes(
4665    inputLength - this._partialBytes));
4666  this._partialBytes = 0;
4667};
4668
4669modes.cfb.prototype.decrypt = function(input, output, finish) {
4670  // not enough input to decrypt
4671  var inputLength = input.length();
4672  if(inputLength === 0) {
4673    return true;
4674  }
4675
4676  // encrypt block (CFB always uses encryption mode)
4677  this.cipher.encrypt(this._inBlock, this._outBlock);
4678
4679  // handle full block
4680  if(this._partialBytes === 0 && inputLength >= this.blockSize) {
4681    // XOR input with output, write input as output
4682    for(var i = 0; i < this._ints; ++i) {
4683      this._inBlock[i] = input.getInt32();
4684      output.putInt32(this._inBlock[i] ^ this._outBlock[i]);
4685    }
4686    return;
4687  }
4688
4689  // handle partial block
4690  var partialBytes = (this.blockSize - inputLength) % this.blockSize;
4691  if(partialBytes > 0) {
4692    partialBytes = this.blockSize - partialBytes;
4693  }
4694
4695  // XOR input with output, write input as partial output
4696  this._partialOutput.clear();
4697  for(var i = 0; i < this._ints; ++i) {
4698    this._partialBlock[i] = input.getInt32();
4699    this._partialOutput.putInt32(this._partialBlock[i] ^ this._outBlock[i]);
4700  }
4701
4702  if(partialBytes > 0) {
4703    // block still incomplete, restore input buffer
4704    input.read -= this.blockSize;
4705  } else {
4706    // block complete, update input block
4707    for(var i = 0; i < this._ints; ++i) {
4708      this._inBlock[i] = this._partialBlock[i];
4709    }
4710  }
4711
4712  // skip any previous partial bytes
4713  if(this._partialBytes > 0) {
4714    this._partialOutput.getBytes(this._partialBytes);
4715  }
4716
4717  if(partialBytes > 0 && !finish) {
4718    output.putBytes(this._partialOutput.getBytes(
4719      partialBytes - this._partialBytes));
4720    this._partialBytes = partialBytes;
4721    return true;
4722  }
4723
4724  output.putBytes(this._partialOutput.getBytes(
4725    inputLength - this._partialBytes));
4726  this._partialBytes = 0;
4727};
4728
4729/** Output feedback (OFB) **/
4730
4731modes.ofb = function(options) {
4732  options = options || {};
4733  this.name = 'OFB';
4734  this.cipher = options.cipher;
4735  this.blockSize = options.blockSize || 16;
4736  this._ints = this.blockSize / 4;
4737  this._inBlock = null;
4738  this._outBlock = new Array(this._ints);
4739  this._partialOutput = forge.util.createBuffer();
4740  this._partialBytes = 0;
4741};
4742
4743modes.ofb.prototype.start = function(options) {
4744  if(!('iv' in options)) {
4745    throw new Error('Invalid IV parameter.');
4746  }
4747  // use IV as first input
4748  this._iv = transformIV(options.iv);
4749  this._inBlock = this._iv.slice(0);
4750  this._partialBytes = 0;
4751};
4752
4753modes.ofb.prototype.encrypt = function(input, output, finish) {
4754  // not enough input to encrypt
4755  var inputLength = input.length();
4756  if(input.length() === 0) {
4757    return true;
4758  }
4759
4760  // encrypt block (OFB always uses encryption mode)
4761  this.cipher.encrypt(this._inBlock, this._outBlock);
4762
4763  // handle full block
4764  if(this._partialBytes === 0 && inputLength >= this.blockSize) {
4765    // XOR input with output and update next input
4766    for(var i = 0; i < this._ints; ++i) {
4767      output.putInt32(input.getInt32() ^ this._outBlock[i]);
4768      this._inBlock[i] = this._outBlock[i];
4769    }
4770    return;
4771  }
4772
4773  // handle partial block
4774  var partialBytes = (this.blockSize - inputLength) % this.blockSize;
4775  if(partialBytes > 0) {
4776    partialBytes = this.blockSize - partialBytes;
4777  }
4778
4779  // XOR input with output
4780  this._partialOutput.clear();
4781  for(var i = 0; i < this._ints; ++i) {
4782    this._partialOutput.putInt32(input.getInt32() ^ this._outBlock[i]);
4783  }
4784
4785  if(partialBytes > 0) {
4786    // block still incomplete, restore input buffer
4787    input.read -= this.blockSize;
4788  } else {
4789    // block complete, update input block
4790    for(var i = 0; i < this._ints; ++i) {
4791      this._inBlock[i] = this._outBlock[i];
4792    }
4793  }
4794
4795  // skip any previous partial bytes
4796  if(this._partialBytes > 0) {
4797    this._partialOutput.getBytes(this._partialBytes);
4798  }
4799
4800  if(partialBytes > 0 && !finish) {
4801    output.putBytes(this._partialOutput.getBytes(
4802      partialBytes - this._partialBytes));
4803    this._partialBytes = partialBytes;
4804    return true;
4805  }
4806
4807  output.putBytes(this._partialOutput.getBytes(
4808    inputLength - this._partialBytes));
4809  this._partialBytes = 0;
4810};
4811
4812modes.ofb.prototype.decrypt = modes.ofb.prototype.encrypt;
4813
4814
4815/** Counter (CTR) **/
4816
4817modes.ctr = function(options) {
4818  options = options || {};
4819  this.name = 'CTR';
4820  this.cipher = options.cipher;
4821  this.blockSize = options.blockSize || 16;
4822  this._ints = this.blockSize / 4;
4823  this._inBlock = null;
4824  this._outBlock = new Array(this._ints);
4825  this._partialOutput = forge.util.createBuffer();
4826  this._partialBytes = 0;
4827};
4828
4829modes.ctr.prototype.start = function(options) {
4830  if(!('iv' in options)) {
4831    throw new Error('Invalid IV parameter.');
4832  }
4833  // use IV as first input
4834  this._iv = transformIV(options.iv);
4835  this._inBlock = this._iv.slice(0);
4836  this._partialBytes = 0;
4837};
4838
4839modes.ctr.prototype.encrypt = function(input, output, finish) {
4840  // not enough input to encrypt
4841  var inputLength = input.length();
4842  if(inputLength === 0) {
4843    return true;
4844  }
4845
4846  // encrypt block (CTR always uses encryption mode)
4847  this.cipher.encrypt(this._inBlock, this._outBlock);
4848
4849  // handle full block
4850  if(this._partialBytes === 0 && inputLength >= this.blockSize) {
4851    // XOR input with output
4852    for(var i = 0; i < this._ints; ++i) {
4853      output.putInt32(input.getInt32() ^ this._outBlock[i]);
4854    }
4855  } else {
4856    // handle partial block
4857    var partialBytes = (this.blockSize - inputLength) % this.blockSize;
4858    if(partialBytes > 0) {
4859      partialBytes = this.blockSize - partialBytes;
4860    }
4861
4862    // XOR input with output
4863    this._partialOutput.clear();
4864    for(var i = 0; i < this._ints; ++i) {
4865      this._partialOutput.putInt32(input.getInt32() ^ this._outBlock[i]);
4866    }
4867
4868    if(partialBytes > 0) {
4869      // block still incomplete, restore input buffer
4870      input.read -= this.blockSize;
4871    }
4872
4873    // skip any previous partial bytes
4874    if(this._partialBytes > 0) {
4875      this._partialOutput.getBytes(this._partialBytes);
4876    }
4877
4878    if(partialBytes > 0 && !finish) {
4879      output.putBytes(this._partialOutput.getBytes(
4880        partialBytes - this._partialBytes));
4881      this._partialBytes = partialBytes;
4882      return true;
4883    }
4884
4885    output.putBytes(this._partialOutput.getBytes(
4886      inputLength - this._partialBytes));
4887    this._partialBytes = 0;
4888  }
4889
4890  // block complete, increment counter (input block)
4891  inc32(this._inBlock);
4892};
4893
4894modes.ctr.prototype.decrypt = modes.ctr.prototype.encrypt;
4895
4896
4897/** Galois/Counter Mode (GCM) **/
4898
4899modes.gcm = function(options) {
4900  options = options || {};
4901  this.name = 'GCM';
4902  this.cipher = options.cipher;
4903  this.blockSize = options.blockSize || 16;
4904  this._ints = this.blockSize / 4;
4905  this._inBlock = new Array(this._ints);
4906  this._outBlock = new Array(this._ints);
4907  this._partialOutput = forge.util.createBuffer();
4908  this._partialBytes = 0;
4909
4910  // R is actually this value concatenated with 120 more zero bits, but
4911  // we only XOR against R so the other zeros have no effect -- we just
4912  // apply this value to the first integer in a block
4913  this._R = 0xE1000000;
4914};
4915
4916modes.gcm.prototype.start = function(options) {
4917  if(!('iv' in options)) {
4918    throw new Error('Invalid IV parameter.');
4919  }
4920  // ensure IV is a byte buffer
4921  var iv = forge.util.createBuffer(options.iv);
4922
4923  // no ciphered data processed yet
4924  this._cipherLength = 0;
4925
4926  // default additional data is none
4927  var additionalData;
4928  if('additionalData' in options) {
4929    additionalData = forge.util.createBuffer(options.additionalData);
4930  } else {
4931    additionalData = forge.util.createBuffer();
4932  }
4933
4934  // default tag length is 128 bits
4935  if('tagLength' in options) {
4936    this._tagLength = options.tagLength;
4937  } else {
4938    this._tagLength = 128;
4939  }
4940
4941  // if tag is given, ensure tag matches tag length
4942  this._tag = null;
4943  if(options.decrypt) {
4944    // save tag to check later
4945    this._tag = forge.util.createBuffer(options.tag).getBytes();
4946    if(this._tag.length !== (this._tagLength / 8)) {
4947      throw new Error('Authentication tag does not match tag length.');
4948    }
4949  }
4950
4951  // create tmp storage for hash calculation
4952  this._hashBlock = new Array(this._ints);
4953
4954  // no tag generated yet
4955  this.tag = null;
4956
4957  // generate hash subkey
4958  // (apply block cipher to "zero" block)
4959  this._hashSubkey = new Array(this._ints);
4960  this.cipher.encrypt([0, 0, 0, 0], this._hashSubkey);
4961
4962  // generate table M
4963  // use 4-bit tables (32 component decomposition of a 16 byte value)
4964  // 8-bit tables take more space and are known to have security
4965  // vulnerabilities (in native implementations)
4966  this.componentBits = 4;
4967  this._m = this.generateHashTable(this._hashSubkey, this.componentBits);
4968
4969  // Note: support IV length different from 96 bits? (only supporting
4970  // 96 bits is recommended by NIST SP-800-38D)
4971  // generate J_0
4972  var ivLength = iv.length();
4973  if(ivLength === 12) {
4974    // 96-bit IV
4975    this._j0 = [iv.getInt32(), iv.getInt32(), iv.getInt32(), 1];
4976  } else {
4977    // IV is NOT 96-bits
4978    this._j0 = [0, 0, 0, 0];
4979    while(iv.length() > 0) {
4980      this._j0 = this.ghash(
4981        this._hashSubkey, this._j0,
4982        [iv.getInt32(), iv.getInt32(), iv.getInt32(), iv.getInt32()]);
4983    }
4984    this._j0 = this.ghash(
4985      this._hashSubkey, this._j0, [0, 0].concat(from64To32(ivLength * 8)));
4986  }
4987
4988  // generate ICB (initial counter block)
4989  this._inBlock = this._j0.slice(0);
4990  inc32(this._inBlock);
4991  this._partialBytes = 0;
4992
4993  // consume authentication data
4994  additionalData = forge.util.createBuffer(additionalData);
4995  // save additional data length as a BE 64-bit number
4996  this._aDataLength = from64To32(additionalData.length() * 8);
4997  // pad additional data to 128 bit (16 byte) block size
4998  var overflow = additionalData.length() % this.blockSize;
4999  if(overflow) {
5000    additionalData.fillWithByte(0, this.blockSize - overflow);
5001  }
5002  this._s = [0, 0, 0, 0];
5003  while(additionalData.length() > 0) {
5004    this._s = this.ghash(this._hashSubkey, this._s, [
5005      additionalData.getInt32(),
5006      additionalData.getInt32(),
5007      additionalData.getInt32(),
5008      additionalData.getInt32()
5009    ]);
5010  }
5011};
5012
5013modes.gcm.prototype.encrypt = function(input, output, finish) {
5014  // not enough input to encrypt
5015  var inputLength = input.length();
5016  if(inputLength === 0) {
5017    return true;
5018  }
5019
5020  // encrypt block
5021  this.cipher.encrypt(this._inBlock, this._outBlock);
5022
5023  // handle full block
5024  if(this._partialBytes === 0 && inputLength >= this.blockSize) {
5025    // XOR input with output
5026    for(var i = 0; i < this._ints; ++i) {
5027      output.putInt32(this._outBlock[i] ^= input.getInt32());
5028    }
5029    this._cipherLength += this.blockSize;
5030  } else {
5031    // handle partial block
5032    var partialBytes = (this.blockSize - inputLength) % this.blockSize;
5033    if(partialBytes > 0) {
5034      partialBytes = this.blockSize - partialBytes;
5035    }
5036
5037    // XOR input with output
5038    this._partialOutput.clear();
5039    for(var i = 0; i < this._ints; ++i) {
5040      this._partialOutput.putInt32(input.getInt32() ^ this._outBlock[i]);
5041    }
5042
5043    if(partialBytes === 0 || finish) {
5044      // handle overflow prior to hashing
5045      if(finish) {
5046        // get block overflow
5047        var overflow = inputLength % this.blockSize;
5048        this._cipherLength += overflow;
5049        // truncate for hash function
5050        this._partialOutput.truncate(this.blockSize - overflow);
5051      } else {
5052        this._cipherLength += this.blockSize;
5053      }
5054
5055      // get output block for hashing
5056      for(var i = 0; i < this._ints; ++i) {
5057        this._outBlock[i] = this._partialOutput.getInt32();
5058      }
5059      this._partialOutput.read -= this.blockSize;
5060    }
5061
5062    // skip any previous partial bytes
5063    if(this._partialBytes > 0) {
5064      this._partialOutput.getBytes(this._partialBytes);
5065    }
5066
5067    if(partialBytes > 0 && !finish) {
5068      // block still incomplete, restore input buffer, get partial output,
5069      // and return early
5070      input.read -= this.blockSize;
5071      output.putBytes(this._partialOutput.getBytes(
5072        partialBytes - this._partialBytes));
5073      this._partialBytes = partialBytes;
5074      return true;
5075    }
5076
5077    output.putBytes(this._partialOutput.getBytes(
5078      inputLength - this._partialBytes));
5079    this._partialBytes = 0;
5080  }
5081
5082  // update hash block S
5083  this._s = this.ghash(this._hashSubkey, this._s, this._outBlock);
5084
5085  // increment counter (input block)
5086  inc32(this._inBlock);
5087};
5088
5089modes.gcm.prototype.decrypt = function(input, output, finish) {
5090  // not enough input to decrypt
5091  var inputLength = input.length();
5092  if(inputLength < this.blockSize && !(finish && inputLength > 0)) {
5093    return true;
5094  }
5095
5096  // encrypt block (GCM always uses encryption mode)
5097  this.cipher.encrypt(this._inBlock, this._outBlock);
5098
5099  // increment counter (input block)
5100  inc32(this._inBlock);
5101
5102  // update hash block S
5103  this._hashBlock[0] = input.getInt32();
5104  this._hashBlock[1] = input.getInt32();
5105  this._hashBlock[2] = input.getInt32();
5106  this._hashBlock[3] = input.getInt32();
5107  this._s = this.ghash(this._hashSubkey, this._s, this._hashBlock);
5108
5109  // XOR hash input with output
5110  for(var i = 0; i < this._ints; ++i) {
5111    output.putInt32(this._outBlock[i] ^ this._hashBlock[i]);
5112  }
5113
5114  // increment cipher data length
5115  if(inputLength < this.blockSize) {
5116    this._cipherLength += inputLength % this.blockSize;
5117  } else {
5118    this._cipherLength += this.blockSize;
5119  }
5120};
5121
5122modes.gcm.prototype.afterFinish = function(output, options) {
5123  var rval = true;
5124
5125  // handle overflow
5126  if(options.decrypt && options.overflow) {
5127    output.truncate(this.blockSize - options.overflow);
5128  }
5129
5130  // handle authentication tag
5131  this.tag = forge.util.createBuffer();
5132
5133  // concatenate additional data length with cipher length
5134  var lengths = this._aDataLength.concat(from64To32(this._cipherLength * 8));
5135
5136  // include lengths in hash
5137  this._s = this.ghash(this._hashSubkey, this._s, lengths);
5138
5139  // do GCTR(J_0, S)
5140  var tag = [];
5141  this.cipher.encrypt(this._j0, tag);
5142  for(var i = 0; i < this._ints; ++i) {
5143    this.tag.putInt32(this._s[i] ^ tag[i]);
5144  }
5145
5146  // trim tag to length
5147  this.tag.truncate(this.tag.length() % (this._tagLength / 8));
5148
5149  // check authentication tag
5150  if(options.decrypt && this.tag.bytes() !== this._tag) {
5151    rval = false;
5152  }
5153
5154  return rval;
5155};
5156
5157/**
5158 * See NIST SP-800-38D 6.3 (Algorithm 1). This function performs Galois
5159 * field multiplication. The field, GF(2^128), is defined by the polynomial:
5160 *
5161 * x^128 + x^7 + x^2 + x + 1
5162 *
5163 * Which is represented in little-endian binary form as: 11100001 (0xe1). When
5164 * the value of a coefficient is 1, a bit is set. The value R, is the
5165 * concatenation of this value and 120 zero bits, yielding a 128-bit value
5166 * which matches the block size.
5167 *
5168 * This function will multiply two elements (vectors of bytes), X and Y, in
5169 * the field GF(2^128). The result is initialized to zero. For each bit of
5170 * X (out of 128), x_i, if x_i is set, then the result is multiplied (XOR'd)
5171 * by the current value of Y. For each bit, the value of Y will be raised by
5172 * a power of x (multiplied by the polynomial x). This can be achieved by
5173 * shifting Y once to the right. If the current value of Y, prior to being
5174 * multiplied by x, has 0 as its LSB, then it is a 127th degree polynomial.
5175 * Otherwise, we must divide by R after shifting to find the remainder.
5176 *
5177 * @param x the first block to multiply by the second.
5178 * @param y the second block to multiply by the first.
5179 *
5180 * @return the block result of the multiplication.
5181 */
5182modes.gcm.prototype.multiply = function(x, y) {
5183  var z_i = [0, 0, 0, 0];
5184  var v_i = y.slice(0);
5185
5186  // calculate Z_128 (block has 128 bits)
5187  for(var i = 0; i < 128; ++i) {
5188    // if x_i is 0, Z_{i+1} = Z_i (unchanged)
5189    // else Z_{i+1} = Z_i ^ V_i
5190    // get x_i by finding 32-bit int position, then left shift 1 by remainder
5191    var x_i = x[(i / 32) | 0] & (1 << (31 - i % 32));
5192    if(x_i) {
5193      z_i[0] ^= v_i[0];
5194      z_i[1] ^= v_i[1];
5195      z_i[2] ^= v_i[2];
5196      z_i[3] ^= v_i[3];
5197    }
5198
5199    // if LSB(V_i) is 1, V_i = V_i >> 1
5200    // else V_i = (V_i >> 1) ^ R
5201    this.pow(v_i, v_i);
5202  }
5203
5204  return z_i;
5205};
5206
5207modes.gcm.prototype.pow = function(x, out) {
5208  // if LSB(x) is 1, x = x >>> 1
5209  // else x = (x >>> 1) ^ R
5210  var lsb = x[3] & 1;
5211
5212  // always do x >>> 1:
5213  // starting with the rightmost integer, shift each integer to the right
5214  // one bit, pulling in the bit from the integer to the left as its top
5215  // most bit (do this for the last 3 integers)
5216  for(var i = 3; i > 0; --i) {
5217    out[i] = (x[i] >>> 1) | ((x[i - 1] & 1) << 31);
5218  }
5219  // shift the first integer normally
5220  out[0] = x[0] >>> 1;
5221
5222  // if lsb was not set, then polynomial had a degree of 127 and doesn't
5223  // need to divided; otherwise, XOR with R to find the remainder; we only
5224  // need to XOR the first integer since R technically ends w/120 zero bits
5225  if(lsb) {
5226    out[0] ^= this._R;
5227  }
5228};
5229
5230modes.gcm.prototype.tableMultiply = function(x) {
5231  // assumes 4-bit tables are used
5232  var z = [0, 0, 0, 0];
5233  for(var i = 0; i < 32; ++i) {
5234    var idx = (i / 8) | 0;
5235    var x_i = (x[idx] >>> ((7 - (i % 8)) * 4)) & 0xF;
5236    var ah = this._m[i][x_i];
5237    z[0] ^= ah[0];
5238    z[1] ^= ah[1];
5239    z[2] ^= ah[2];
5240    z[3] ^= ah[3];
5241  }
5242  return z;
5243};
5244
5245/**
5246 * A continuing version of the GHASH algorithm that operates on a single
5247 * block. The hash block, last hash value (Ym) and the new block to hash
5248 * are given.
5249 *
5250 * @param h the hash block.
5251 * @param y the previous value for Ym, use [0, 0, 0, 0] for a new hash.
5252 * @param x the block to hash.
5253 *
5254 * @return the hashed value (Ym).
5255 */
5256modes.gcm.prototype.ghash = function(h, y, x) {
5257  y[0] ^= x[0];
5258  y[1] ^= x[1];
5259  y[2] ^= x[2];
5260  y[3] ^= x[3];
5261  return this.tableMultiply(y);
5262  //return this.multiply(y, h);
5263};
5264
5265/**
5266 * Precomputes a table for multiplying against the hash subkey. This
5267 * mechanism provides a substantial speed increase over multiplication
5268 * performed without a table. The table-based multiplication this table is
5269 * for solves X * H by multiplying each component of X by H and then
5270 * composing the results together using XOR.
5271 *
5272 * This function can be used to generate tables with different bit sizes
5273 * for the components, however, this implementation assumes there are
5274 * 32 components of X (which is a 16 byte vector), therefore each component
5275 * takes 4-bits (so the table is constructed with bits=4).
5276 *
5277 * @param h the hash subkey.
5278 * @param bits the bit size for a component.
5279 */
5280modes.gcm.prototype.generateHashTable = function(h, bits) {
5281  // TODO: There are further optimizations that would use only the
5282  // first table M_0 (or some variant) along with a remainder table;
5283  // this can be explored in the future
5284  var multiplier = 8 / bits;
5285  var perInt = 4 * multiplier;
5286  var size = 16 * multiplier;
5287  var m = new Array(size);
5288  for(var i = 0; i < size; ++i) {
5289    var tmp = [0, 0, 0, 0];
5290    var idx = (i / perInt) | 0;
5291    var shft = ((perInt - 1 - (i % perInt)) * bits);
5292    tmp[idx] = (1 << (bits - 1)) << shft;
5293    m[i] = this.generateSubHashTable(this.multiply(tmp, h), bits);
5294  }
5295  return m;
5296};
5297
5298/**
5299 * Generates a table for multiplying against the hash subkey for one
5300 * particular component (out of all possible component values).
5301 *
5302 * @param mid the pre-multiplied value for the middle key of the table.
5303 * @param bits the bit size for a component.
5304 */
5305modes.gcm.prototype.generateSubHashTable = function(mid, bits) {
5306  // compute the table quickly by minimizing the number of
5307  // POW operations -- they only need to be performed for powers of 2,
5308  // all other entries can be composed from those powers using XOR
5309  var size = 1 << bits;
5310  var half = size >>> 1;
5311  var m = new Array(size);
5312  m[half] = mid.slice(0);
5313  var i = half >>> 1;
5314  while(i > 0) {
5315    // raise m0[2 * i] and store in m0[i]
5316    this.pow(m[2 * i], m[i] = []);
5317    i >>= 1;
5318  }
5319  i = 2;
5320  while(i < half) {
5321    for(var j = 1; j < i; ++j) {
5322      var m_i = m[i];
5323      var m_j = m[j];
5324      m[i + j] = [
5325        m_i[0] ^ m_j[0],
5326        m_i[1] ^ m_j[1],
5327        m_i[2] ^ m_j[2],
5328        m_i[3] ^ m_j[3]
5329      ];
5330    }
5331    i *= 2;
5332  }
5333  m[0] = [0, 0, 0, 0];
5334  /* Note: We could avoid storing these by doing composition during multiply
5335  calculate top half using composition by speed is preferred. */
5336  for(i = half + 1; i < size; ++i) {
5337    var c = m[i ^ half];
5338    m[i] = [mid[0] ^ c[0], mid[1] ^ c[1], mid[2] ^ c[2], mid[3] ^ c[3]];
5339  }
5340  return m;
5341};
5342
5343
5344/** Utility functions */
5345
5346function transformIV(iv) {
5347  if(typeof iv === 'string') {
5348    // convert iv string into byte buffer
5349    iv = forge.util.createBuffer(iv);
5350  }
5351
5352  if(forge.util.isArray(iv) && iv.length > 4) {
5353    // convert iv byte array into byte buffer
5354    var tmp = iv;
5355    iv = forge.util.createBuffer();
5356    for(var i = 0; i < tmp.length; ++i) {
5357      iv.putByte(tmp[i]);
5358    }
5359  }
5360  if(!forge.util.isArray(iv)) {
5361    // convert iv byte buffer into 32-bit integer array
5362    iv = [iv.getInt32(), iv.getInt32(), iv.getInt32(), iv.getInt32()];
5363  }
5364
5365  return iv;
5366}
5367
5368function inc32(block) {
5369  // increment last 32 bits of block only
5370  block[block.length - 1] = (block[block.length - 1] + 1) & 0xFFFFFFFF;
5371}
5372
5373function from64To32(num) {
5374  // convert 64-bit number to two BE Int32s
5375  return [(num / 0x100000000) | 0, num & 0xFFFFFFFF];
5376}
5377
5378
5379} // end module implementation
5380
5381/* ########## Begin module wrapper ########## */
5382var name = 'cipherModes';
5383if(typeof define !== 'function') {
5384  // NodeJS -> AMD
5385  if(typeof module === 'object' && module.exports) {
5386    var nodeJS = true;
5387    define = function(ids, factory) {
5388      factory(require, module);
5389    };
5390  } else {
5391    // <script>
5392    if(typeof forge === 'undefined') {
5393      forge = {};
5394    }
5395    return initModule(forge);
5396  }
5397}
5398// AMD
5399var deps;
5400var defineFunc = function(require, module) {
5401  module.exports = function(forge) {
5402    var mods = deps.map(function(dep) {
5403      return require(dep);
5404    }).concat(initModule);
5405    // handle circular dependencies
5406    forge = forge || {};
5407    forge.defined = forge.defined || {};
5408    if(forge.defined[name]) {
5409      return forge[name];
5410    }
5411    forge.defined[name] = true;
5412    for(var i = 0; i < mods.length; ++i) {
5413      mods[i](forge);
5414    }
5415    return forge[name];
5416  };
5417};
5418var tmpDefine = define;
5419define = function(ids, factory) {
5420  deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2);
5421  if(nodeJS) {
5422    delete define;
5423    return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0));
5424  }
5425  define = tmpDefine;
5426  return define.apply(null, Array.prototype.slice.call(arguments, 0));
5427};
5428define(['require', 'module', './util'], function() {
5429  defineFunc.apply(null, Array.prototype.slice.call(arguments, 0));
5430});
5431})();
5432
5433/**
5434 * RC2 implementation.
5435 *
5436 * @author Stefan Siegl
5437 *
5438 * Copyright (c) 2012 Stefan Siegl <[email protected]>
5439 *
5440 * Information on the RC2 cipher is available from RFC #2268,
5441 * http://www.ietf.org/rfc/rfc2268.txt
5442 */
5443(function() {
5444/* ########## Begin module implementation ########## */
5445function initModule(forge) {
5446
5447var piTable = [
5448  0xd9, 0x78, 0xf9, 0xc4, 0x19, 0xdd, 0xb5, 0xed, 0x28, 0xe9, 0xfd, 0x79, 0x4a, 0xa0, 0xd8, 0x9d,
5449  0xc6, 0x7e, 0x37, 0x83, 0x2b, 0x76, 0x53, 0x8e, 0x62, 0x4c, 0x64, 0x88, 0x44, 0x8b, 0xfb, 0xa2,
5450  0x17, 0x9a, 0x59, 0xf5, 0x87, 0xb3, 0x4f, 0x13, 0x61, 0x45, 0x6d, 0x8d, 0x09, 0x81, 0x7d, 0x32,
5451  0xbd, 0x8f, 0x40, 0xeb, 0x86, 0xb7, 0x7b, 0x0b, 0xf0, 0x95, 0x21, 0x22, 0x5c, 0x6b, 0x4e, 0x82,
5452  0x54, 0xd6, 0x65, 0x93, 0xce, 0x60, 0xb2, 0x1c, 0x73, 0x56, 0xc0, 0x14, 0xa7, 0x8c, 0xf1, 0xdc,
5453  0x12, 0x75, 0xca, 0x1f, 0x3b, 0xbe, 0xe4, 0xd1, 0x42, 0x3d, 0xd4, 0x30, 0xa3, 0x3c, 0xb6, 0x26,
5454  0x6f, 0xbf, 0x0e, 0xda, 0x46, 0x69, 0x07, 0x57, 0x27, 0xf2, 0x1d, 0x9b, 0xbc, 0x94, 0x43, 0x03,
5455  0xf8, 0x11, 0xc7, 0xf6, 0x90, 0xef, 0x3e, 0xe7, 0x06, 0xc3, 0xd5, 0x2f, 0xc8, 0x66, 0x1e, 0xd7,
5456  0x08, 0xe8, 0xea, 0xde, 0x80, 0x52, 0xee, 0xf7, 0x84, 0xaa, 0x72, 0xac, 0x35, 0x4d, 0x6a, 0x2a,
5457  0x96, 0x1a, 0xd2, 0x71, 0x5a, 0x15, 0x49, 0x74, 0x4b, 0x9f, 0xd0, 0x5e, 0x04, 0x18, 0xa4, 0xec,
5458  0xc2, 0xe0, 0x41, 0x6e, 0x0f, 0x51, 0xcb, 0xcc, 0x24, 0x91, 0xaf, 0x50, 0xa1, 0xf4, 0x70, 0x39,
5459  0x99, 0x7c, 0x3a, 0x85, 0x23, 0xb8, 0xb4, 0x7a, 0xfc, 0x02, 0x36, 0x5b, 0x25, 0x55, 0x97, 0x31,
5460  0x2d, 0x5d, 0xfa, 0x98, 0xe3, 0x8a, 0x92, 0xae, 0x05, 0xdf, 0x29, 0x10, 0x67, 0x6c, 0xba, 0xc9,
5461  0xd3, 0x00, 0xe6, 0xcf, 0xe1, 0x9e, 0xa8, 0x2c, 0x63, 0x16, 0x01, 0x3f, 0x58, 0xe2, 0x89, 0xa9,
5462  0x0d, 0x38, 0x34, 0x1b, 0xab, 0x33, 0xff, 0xb0, 0xbb, 0x48, 0x0c, 0x5f, 0xb9, 0xb1, 0xcd, 0x2e,
5463  0xc5, 0xf3, 0xdb, 0x47, 0xe5, 0xa5, 0x9c, 0x77, 0x0a, 0xa6, 0x20, 0x68, 0xfe, 0x7f, 0xc1, 0xad
5464];
5465
5466var s = [1, 2, 3, 5];
5467
5468
5469/**
5470 * Rotate a word left by given number of bits.
5471 *
5472 * Bits that are shifted out on the left are put back in on the right
5473 * hand side.
5474 *
5475 * @param word The word to shift left.
5476 * @param bits The number of bits to shift by.
5477 * @return The rotated word.
5478 */
5479var rol = function(word, bits) {
5480  return ((word << bits) & 0xffff) | ((word & 0xffff) >> (16 - bits));
5481};
5482
5483/**
5484 * Rotate a word right by given number of bits.
5485 *
5486 * Bits that are shifted out on the right are put back in on the left
5487 * hand side.
5488 *
5489 * @param word The word to shift right.
5490 * @param bits The number of bits to shift by.
5491 * @return The rotated word.
5492 */
5493var ror = function(word, bits) {
5494  return ((word & 0xffff) >> bits) | ((word << (16 - bits)) & 0xffff);
5495};
5496
5497
5498/* RC2 API */
5499forge.rc2 = forge.rc2 || {};
5500
5501/**
5502 * Perform RC2 key expansion as per RFC #2268, section 2.
5503 *
5504 * @param key variable-length user key (between 1 and 128 bytes)
5505 * @param effKeyBits number of effective key bits (default: 128)
5506 * @return the expanded RC2 key (ByteBuffer of 128 bytes)
5507 */
5508forge.rc2.expandKey = function(key, effKeyBits) {
5509  if(typeof key === 'string') {
5510    key = forge.util.createBuffer(key);
5511  }
5512  effKeyBits = effKeyBits || 128;
5513
5514  /* introduce variables that match the names used in RFC #2268 */
5515  var L = key;
5516  var T = key.length();
5517  var T1 = effKeyBits;
5518  var T8 = Math.ceil(T1 / 8);
5519  var TM = 0xff >> (T1 & 0x07);
5520  var i;
5521
5522  for(i = T; i < 128; i ++) {
5523    L.putByte(piTable[(L.at(i - 1) + L.at(i - T)) & 0xff]);
5524  }
5525
5526  L.setAt(128 - T8, piTable[L.at(128 - T8) & TM]);
5527
5528  for(i = 127 - T8; i >= 0; i --) {
5529    L.setAt(i, piTable[L.at(i + 1) ^ L.at(i + T8)]);
5530  }
5531
5532  return L;
5533};
5534
5535
5536/**
5537 * Creates a RC2 cipher object.
5538 *
5539 * @param key the symmetric key to use (as base for key generation).
5540 * @param bits the number of effective key bits.
5541 * @param encrypt false for decryption, true for encryption.
5542 *
5543 * @return the cipher.
5544 */
5545var createCipher = function(key, bits, encrypt) {
5546  var _finish = false, _input = null, _output = null, _iv = null;
5547  var mixRound, mashRound;
5548  var i, j, K = [];
5549
5550  /* Expand key and fill into K[] Array */
5551  key = forge.rc2.expandKey(key, bits);
5552  for(i = 0; i < 64; i ++) {
5553    K.push(key.getInt16Le());
5554  }
5555
5556  if(encrypt) {
5557    /**
5558     * Perform one mixing round "in place".
5559     *
5560     * @param R Array of four words to perform mixing on.
5561     */
5562    mixRound = function(R) {
5563      for(i = 0; i < 4; i++) {
5564        R[i] += K[j] + (R[(i + 3) % 4] & R[(i + 2) % 4]) +
5565          ((~R[(i + 3) % 4]) & R[(i + 1) % 4]);
5566        R[i] = rol(R[i], s[i]);
5567        j ++;
5568      }
5569    };
5570
5571    /**
5572     * Perform one mashing round "in place".
5573     *
5574     * @param R Array of four words to perform mashing on.
5575     */
5576    mashRound = function(R) {
5577      for(i = 0; i < 4; i ++) {
5578        R[i] += K[R[(i + 3) % 4] & 63];
5579      }
5580    };
5581  } else {
5582    /**
5583     * Perform one r-mixing round "in place".
5584     *
5585     * @param R Array of four words to perform mixing on.
5586     */
5587    mixRound = function(R) {
5588      for(i = 3; i >= 0; i--) {
5589        R[i] = ror(R[i], s[i]);
5590        R[i] -= K[j] + (R[(i + 3) % 4] & R[(i + 2) % 4]) +
5591          ((~R[(i + 3) % 4]) & R[(i + 1) % 4]);
5592        j --;
5593      }
5594    };
5595
5596    /**
5597     * Perform one r-mashing round "in place".
5598     *
5599     * @param R Array of four words to perform mashing on.
5600     */
5601    mashRound = function(R) {
5602      for(i = 3; i >= 0; i--) {
5603        R[i] -= K[R[(i + 3) % 4] & 63];
5604      }
5605    };
5606  }
5607
5608  /**
5609   * Run the specified cipher execution plan.
5610   *
5611   * This function takes four words from the input buffer, applies the IV on
5612   * it (if requested) and runs the provided execution plan.
5613   *
5614   * The plan must be put together in form of a array of arrays.  Where the
5615   * outer one is simply a list of steps to perform and the inner one needs
5616   * to have two elements: the first one telling how many rounds to perform,
5617   * the second one telling what to do (i.e. the function to call).
5618   *
5619   * @param {Array} plan The plan to execute.
5620   */
5621  var runPlan = function(plan) {
5622    var R = [];
5623
5624    /* Get data from input buffer and fill the four words into R */
5625    for(i = 0; i < 4; i ++) {
5626      var val = _input.getInt16Le();
5627
5628      if(_iv !== null) {
5629        if(encrypt) {
5630          /* We're encrypting, apply the IV first. */
5631          val ^= _iv.getInt16Le();
5632        } else {
5633          /* We're decryption, keep cipher text for next block. */
5634          _iv.putInt16Le(val);
5635        }
5636      }
5637
5638      R.push(val & 0xffff);
5639    }
5640
5641    /* Reset global "j" variable as per spec. */
5642    j = encrypt ? 0 : 63;
5643
5644    /* Run execution plan. */
5645    for(var ptr = 0; ptr < plan.length; ptr ++) {
5646      for(var ctr = 0; ctr < plan[ptr][0]; ctr ++) {
5647        plan[ptr][1](R);
5648      }
5649    }
5650
5651    /* Write back result to output buffer. */
5652    for(i = 0; i < 4; i ++) {
5653      if(_iv !== null) {
5654        if(encrypt) {
5655          /* We're encrypting in CBC-mode, feed back encrypted bytes into
5656             IV buffer to carry it forward to next block. */
5657          _iv.putInt16Le(R[i]);
5658        } else {
5659          R[i] ^= _iv.getInt16Le();
5660        }
5661      }
5662
5663      _output.putInt16Le(R[i]);
5664    }
5665  };
5666
5667
5668  /* Create cipher object */
5669  var cipher = null;
5670  cipher = {
5671    /**
5672     * Starts or restarts the encryption or decryption process, whichever
5673     * was previously configured.
5674     *
5675     * To use the cipher in CBC mode, iv may be given either as a string
5676     * of bytes, or as a byte buffer.  For ECB mode, give null as iv.
5677     *
5678     * @param iv the initialization vector to use, null for ECB mode.
5679     * @param output the output the buffer to write to, null to create one.
5680     */
5681    start: function(iv, output) {
5682      if(iv) {
5683        /* CBC mode */
5684        if(typeof iv === 'string') {
5685          iv = forge.util.createBuffer(iv);
5686        }
5687      }
5688
5689      _finish = false;
5690      _input = forge.util.createBuffer();
5691      _output = output || new forge.util.createBuffer();
5692      _iv = iv;
5693
5694      cipher.output = _output;
5695    },
5696
5697    /**
5698     * Updates the next block.
5699     *
5700     * @param input the buffer to read from.
5701     */
5702    update: function(input) {
5703      if(!_finish) {
5704        // not finishing, so fill the input buffer with more input
5705        _input.putBuffer(input);
5706      }
5707
5708      while(_input.length() >= 8) {
5709        runPlan([
5710            [ 5, mixRound ],
5711            [ 1, mashRound ],
5712            [ 6, mixRound ],
5713            [ 1, mashRound ],
5714            [ 5, mixRound ]
5715          ]);
5716      }
5717    },
5718
5719    /**
5720     * Finishes encrypting or decrypting.
5721     *
5722     * @param pad a padding function to use, null for PKCS#7 padding,
5723     *           signature(blockSize, buffer, decrypt).
5724     *
5725     * @return true if successful, false on error.
5726     */
5727    finish: function(pad) {
5728      var rval = true;
5729
5730      if(encrypt) {
5731        if(pad) {
5732          rval = pad(8, _input, !encrypt);
5733        } else {
5734          // add PKCS#7 padding to block (each pad byte is the
5735          // value of the number of pad bytes)
5736          var padding = (_input.length() === 8) ? 8 : (8 - _input.length());
5737          _input.fillWithByte(padding, padding);
5738        }
5739      }
5740
5741      if(rval) {
5742        // do final update
5743        _finish = true;
5744        cipher.update();
5745      }
5746
5747      if(!encrypt) {
5748        // check for error: input data not a multiple of block size
5749        rval = (_input.length() === 0);
5750        if(rval) {
5751          if(pad) {
5752            rval = pad(8, _output, !encrypt);
5753          } else {
5754            // ensure padding byte count is valid
5755            var len = _output.length();
5756            var count = _output.at(len - 1);
5757
5758            if(count > len) {
5759              rval = false;
5760            } else {
5761              // trim off padding bytes
5762              _output.truncate(count);
5763            }
5764          }
5765        }
5766      }
5767
5768      return rval;
5769    }
5770  };
5771
5772  return cipher;
5773};
5774
5775
5776/**
5777 * Creates an RC2 cipher object to encrypt data in ECB or CBC mode using the
5778 * given symmetric key. The output will be stored in the 'output' member
5779 * of the returned cipher.
5780 *
5781 * The key and iv may be given as a string of bytes or a byte buffer.
5782 * The cipher is initialized to use 128 effective key bits.
5783 *
5784 * @param key the symmetric key to use.
5785 * @param iv the initialization vector to use.
5786 * @param output the buffer to write to, null to create one.
5787 *
5788 * @return the cipher.
5789 */
5790forge.rc2.startEncrypting = function(key, iv, output) {
5791  var cipher = forge.rc2.createEncryptionCipher(key, 128);
5792  cipher.start(iv, output);
5793  return cipher;
5794};
5795
5796/**
5797 * Creates an RC2 cipher object to encrypt data in ECB or CBC mode using the
5798 * given symmetric key.
5799 *
5800 * The key may be given as a string of bytes or a byte buffer.
5801 *
5802 * To start encrypting call start() on the cipher with an iv and optional
5803 * output buffer.
5804 *
5805 * @param key the symmetric key to use.
5806 *
5807 * @return the cipher.
5808 */
5809forge.rc2.createEncryptionCipher = function(key, bits) {
5810  return createCipher(key, bits, true);
5811};
5812
5813/**
5814 * Creates an RC2 cipher object to decrypt data in ECB or CBC mode using the
5815 * given symmetric key. The output will be stored in the 'output' member
5816 * of the returned cipher.
5817 *
5818 * The key and iv may be given as a string of bytes or a byte buffer.
5819 * The cipher is initialized to use 128 effective key bits.
5820 *
5821 * @param key the symmetric key to use.
5822 * @param iv the initialization vector to use.
5823 * @param output the buffer to write to, null to create one.
5824 *
5825 * @return the cipher.
5826 */
5827forge.rc2.startDecrypting = function(key, iv, output) {
5828  var cipher = forge.rc2.createDecryptionCipher(key, 128);
5829  cipher.start(iv, output);
5830  return cipher;
5831};
5832
5833/**
5834 * Creates an RC2 cipher object to decrypt data in ECB or CBC mode using the
5835 * given symmetric key.
5836 *
5837 * The key may be given as a string of bytes or a byte buffer.
5838 *
5839 * To start decrypting call start() on the cipher with an iv and optional
5840 * output buffer.
5841 *
5842 * @param key the symmetric key to use.
5843 *
5844 * @return the cipher.
5845 */
5846forge.rc2.createDecryptionCipher = function(key, bits) {
5847  return createCipher(key, bits, false);
5848};
5849
5850} // end module implementation
5851
5852/* ########## Begin module wrapper ########## */
5853var name = 'rc2';
5854if(typeof define !== 'function') {
5855  // NodeJS -> AMD
5856  if(typeof module === 'object' && module.exports) {
5857    var nodeJS = true;
5858    define = function(ids, factory) {
5859      factory(require, module);
5860    };
5861  } else {
5862    // <script>
5863    if(typeof forge === 'undefined') {
5864      forge = {};
5865    }
5866    return initModule(forge);
5867  }
5868}
5869// AMD
5870var deps;
5871var defineFunc = function(require, module) {
5872  module.exports = function(forge) {
5873    var mods = deps.map(function(dep) {
5874      return require(dep);
5875    }).concat(initModule);
5876    // handle circular dependencies
5877    forge = forge || {};
5878    forge.defined = forge.defined || {};
5879    if(forge.defined[name]) {
5880      return forge[name];
5881    }
5882    forge.defined[name] = true;
5883    for(var i = 0; i < mods.length; ++i) {
5884      mods[i](forge);
5885    }
5886    return forge[name];
5887  };
5888};
5889var tmpDefine = define;
5890define = function(ids, factory) {
5891  deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2);
5892  if(nodeJS) {
5893    delete define;
5894    return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0));
5895  }
5896  define = tmpDefine;
5897  return define.apply(null, Array.prototype.slice.call(arguments, 0));
5898};
5899define(['require', 'module', './util'], function() {
5900  defineFunc.apply(null, Array.prototype.slice.call(arguments, 0));
5901});
5902})();
5903
5904/**
5905 * DES (Data Encryption Standard) implementation.
5906 *
5907 * This implementation supports DES as well as 3DES-EDE in ECB and CBC mode.
5908 * It is based on the BSD-licensed implementation by Paul Tero:
5909 *
5910 * Paul Tero, July 2001
5911 * http://www.tero.co.uk/des/
5912 *
5913 * Optimised for performance with large blocks by Michael Hayworth, November 2001
5914 * http://www.netdealing.com
5915 *
5916 * THIS SOFTWARE IS PROVIDED "AS IS" AND
5917 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
5918 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
5919 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
5920 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
5921 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
5922 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
5923 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
5924 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5925 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5926 * SUCH DAMAGE.
5927 *
5928 * @author Stefan Siegl
5929 * @author Dave Longley
5930 *
5931 * Copyright (c) 2012 Stefan Siegl <[email protected]>
5932 * Copyright (c) 2012-2014 Digital Bazaar, Inc.
5933 */
5934(function() {
5935/* ########## Begin module implementation ########## */
5936function initModule(forge) {
5937
5938/* DES API */
5939forge.des = forge.des || {};
5940
5941/**
5942 * Deprecated. Instead, use:
5943 *
5944 * var cipher = forge.cipher.createCipher('DES-<mode>', key);
5945 * cipher.start({iv: iv});
5946 *
5947 * Creates an DES cipher object to encrypt data using the given symmetric key.
5948 * The output will be stored in the 'output' member of the returned cipher.
5949 *
5950 * The key and iv may be given as binary-encoded strings of bytes or
5951 * byte buffers.
5952 *
5953 * @param key the symmetric key to use (64 or 192 bits).
5954 * @param iv the initialization vector to use.
5955 * @param output the buffer to write to, null to create one.
5956 * @param mode the cipher mode to use (default: 'CBC' if IV is
5957 *          given, 'ECB' if null).
5958 *
5959 * @return the cipher.
5960 */
5961forge.des.startEncrypting = function(key, iv, output, mode) {
5962  var cipher = _createCipher({
5963    key: key,
5964    output: output,
5965    decrypt: false,
5966    mode: mode || (iv === null ? 'ECB' : 'CBC')
5967  });
5968  cipher.start(iv);
5969  return cipher;
5970};
5971
5972/**
5973 * Deprecated. Instead, use:
5974 *
5975 * var cipher = forge.cipher.createCipher('DES-<mode>', key);
5976 *
5977 * Creates an DES cipher object to encrypt data using the given symmetric key.
5978 *
5979 * The key may be given as a binary-encoded string of bytes or a byte buffer.
5980 *
5981 * @param key the symmetric key to use (64 or 192 bits).
5982 * @param mode the cipher mode to use (default: 'CBC').
5983 *
5984 * @return the cipher.
5985 */
5986forge.des.createEncryptionCipher = function(key, mode) {
5987  return _createCipher({
5988    key: key,
5989    output: null,
5990    decrypt: false,
5991    mode: mode
5992  });
5993};
5994
5995/**
5996 * Deprecated. Instead, use:
5997 *
5998 * var decipher = forge.cipher.createDecipher('DES-<mode>', key);
5999 * decipher.start({iv: iv});
6000 *
6001 * Creates an DES cipher object to decrypt data using the given symmetric key.
6002 * The output will be stored in the 'output' member of the returned cipher.
6003 *
6004 * The key and iv may be given as binary-encoded strings of bytes or
6005 * byte buffers.
6006 *
6007 * @param key the symmetric key to use (64 or 192 bits).
6008 * @param iv the initialization vector to use.
6009 * @param output the buffer to write to, null to create one.
6010 * @param mode the cipher mode to use (default: 'CBC' if IV is
6011 *          given, 'ECB' if null).
6012 *
6013 * @return the cipher.
6014 */
6015forge.des.startDecrypting = function(key, iv, output, mode) {
6016  var cipher = _createCipher({
6017    key: key,
6018    output: output,
6019    decrypt: true,
6020    mode: mode || (iv === null ? 'ECB' : 'CBC')
6021  });
6022  cipher.start(iv);
6023  return cipher;
6024};
6025
6026/**
6027 * Deprecated. Instead, use:
6028 *
6029 * var decipher = forge.cipher.createDecipher('DES-<mode>', key);
6030 *
6031 * Creates an DES cipher object to decrypt data using the given symmetric key.
6032 *
6033 * The key may be given as a binary-encoded string of bytes or a byte buffer.
6034 *
6035 * @param key the symmetric key to use (64 or 192 bits).
6036 * @param mode the cipher mode to use (default: 'CBC').
6037 *
6038 * @return the cipher.
6039 */
6040forge.des.createDecryptionCipher = function(key, mode) {
6041  return _createCipher({
6042    key: key,
6043    output: null,
6044    decrypt: true,
6045    mode: mode
6046  });
6047};
6048
6049/**
6050 * Creates a new DES cipher algorithm object.
6051 *
6052 * @param name the name of the algorithm.
6053 * @param mode the mode factory function.
6054 *
6055 * @return the DES algorithm object.
6056 */
6057forge.des.Algorithm = function(name, mode) {
6058  var self = this;
6059  self.name = name;
6060  self.mode = new mode({
6061    blockSize: 8,
6062    cipher: {
6063      encrypt: function(inBlock, outBlock) {
6064        return _updateBlock(self._keys, inBlock, outBlock, false);
6065      },
6066      decrypt: function(inBlock, outBlock) {
6067        return _updateBlock(self._keys, inBlock, outBlock, true);
6068      }
6069    }
6070  });
6071  self._init = false;
6072};
6073
6074/**
6075 * Initializes this DES algorithm by expanding its key.
6076 *
6077 * @param options the options to use.
6078 *          key the key to use with this algorithm.
6079 *          decrypt true if the algorithm should be initialized for decryption,
6080 *            false for encryption.
6081 */
6082forge.des.Algorithm.prototype.initialize = function(options) {
6083  if(this._init) {
6084    return;
6085  }
6086
6087  var key = forge.util.createBuffer(options.key);
6088  if(this.name.indexOf('3DES') === 0) {
6089    if(key.length() !== 24) {
6090      throw new Error('Invalid Triple-DES key size: ' + key.length() * 8);
6091    }
6092  }
6093
6094  // do key expansion to 16 or 48 subkeys (single or triple DES)
6095  this._keys = _createKeys(key);
6096  this._init = true;
6097};
6098
6099
6100/** Register DES algorithms **/
6101
6102registerAlgorithm('DES-ECB', forge.cipher.modes.ecb);
6103registerAlgorithm('DES-CBC', forge.cipher.modes.cbc);
6104registerAlgorithm('DES-CFB', forge.cipher.modes.cfb);
6105registerAlgorithm('DES-OFB', forge.cipher.modes.ofb);
6106registerAlgorithm('DES-CTR', forge.cipher.modes.ctr);
6107
6108registerAlgorithm('3DES-ECB', forge.cipher.modes.ecb);
6109registerAlgorithm('3DES-CBC', forge.cipher.modes.cbc);
6110registerAlgorithm('3DES-CFB', forge.cipher.modes.cfb);
6111registerAlgorithm('3DES-OFB', forge.cipher.modes.ofb);
6112registerAlgorithm('3DES-CTR', forge.cipher.modes.ctr);
6113
6114function registerAlgorithm(name, mode) {
6115  var factory = function() {
6116    return new forge.des.Algorithm(name, mode);
6117  };
6118  forge.cipher.registerAlgorithm(name, factory);
6119}
6120
6121
6122/** DES implementation **/
6123
6124var spfunction1 = [0x1010400,0,0x10000,0x1010404,0x1010004,0x10404,0x4,0x10000,0x400,0x1010400,0x1010404,0x400,0x1000404,0x1010004,0x1000000,0x4,0x404,0x1000400,0x1000400,0x10400,0x10400,0x1010000,0x1010000,0x1000404,0x10004,0x1000004,0x1000004,0x10004,0,0x404,0x10404,0x1000000,0x10000,0x1010404,0x4,0x1010000,0x1010400,0x1000000,0x1000000,0x400,0x1010004,0x10000,0x10400,0x1000004,0x400,0x4,0x1000404,0x10404,0x1010404,0x10004,0x1010000,0x1000404,0x1000004,0x404,0x10404,0x1010400,0x404,0x1000400,0x1000400,0,0x10004,0x10400,0,0x1010004];
6125var spfunction2 = [-0x7fef7fe0,-0x7fff8000,0x8000,0x108020,0x100000,0x20,-0x7fefffe0,-0x7fff7fe0,-0x7fffffe0,-0x7fef7fe0,-0x7fef8000,-0x80000000,-0x7fff8000,0x100000,0x20,-0x7fefffe0,0x108000,0x100020,-0x7fff7fe0,0,-0x80000000,0x8000,0x108020,-0x7ff00000,0x100020,-0x7fffffe0,0,0x108000,0x8020,-0x7fef8000,-0x7ff00000,0x8020,0,0x108020,-0x7fefffe0,0x100000,-0x7fff7fe0,-0x7ff00000,-0x7fef8000,0x8000,-0x7ff00000,-0x7fff8000,0x20,-0x7fef7fe0,0x108020,0x20,0x8000,-0x80000000,0x8020,-0x7fef8000,0x100000,-0x7fffffe0,0x100020,-0x7fff7fe0,-0x7fffffe0,0x100020,0x108000,0,-0x7fff8000,0x8020,-0x80000000,-0x7fefffe0,-0x7fef7fe0,0x108000];
6126var spfunction3 = [0x208,0x8020200,0,0x8020008,0x8000200,0,0x20208,0x8000200,0x20008,0x8000008,0x8000008,0x20000,0x8020208,0x20008,0x8020000,0x208,0x8000000,0x8,0x8020200,0x200,0x20200,0x8020000,0x8020008,0x20208,0x8000208,0x20200,0x20000,0x8000208,0x8,0x8020208,0x200,0x8000000,0x8020200,0x8000000,0x20008,0x208,0x20000,0x8020200,0x8000200,0,0x200,0x20008,0x8020208,0x8000200,0x8000008,0x200,0,0x8020008,0x8000208,0x20000,0x8000000,0x8020208,0x8,0x20208,0x20200,0x8000008,0x8020000,0x8000208,0x208,0x8020000,0x20208,0x8,0x8020008,0x20200];
6127var spfunction4 = [0x802001,0x2081,0x2081,0x80,0x802080,0x800081,0x800001,0x2001,0,0x802000,0x802000,0x802081,0x81,0,0x800080,0x800001,0x1,0x2000,0x800000,0x802001,0x80,0x800000,0x2001,0x2080,0x800081,0x1,0x2080,0x800080,0x2000,0x802080,0x802081,0x81,0x800080,0x800001,0x802000,0x802081,0x81,0,0,0x802000,0x2080,0x800080,0x800081,0x1,0x802001,0x2081,0x2081,0x80,0x802081,0x81,0x1,0x2000,0x800001,0x2001,0x802080,0x800081,0x2001,0x2080,0x800000,0x802001,0x80,0x800000,0x2000,0x802080];
6128var spfunction5 = [0x100,0x2080100,0x2080000,0x42000100,0x80000,0x100,0x40000000,0x2080000,0x40080100,0x80000,0x2000100,0x40080100,0x42000100,0x42080000,0x80100,0x40000000,0x2000000,0x40080000,0x40080000,0,0x40000100,
61280x42080100,0x42080100,0x2000100,0x42080000,0x40000100,0,0x42000000,0x2080100,0x2000000,0x42000000,0x80100,0x80000,0x42000100,0x100,0x2000000,0x40000000,0x2080000,0x42000100,0x40080100,0x2000100,0x40000000,0x42080000,0x2080100,0x40080100,0x100,0x2000000,0x42080000,0x42080100,0x80100,0x42000000,0x42080100,0x2080000,0,0x40080000,0x42000000,0x80100,0x2000100,0x40000100,0x80000,0,0x40080000,0x2080100,0x40000100];
6129var spfunction6 = [0x20000010,0x20400000,0x4000,0x20404010,0x20400000,0x10,0x20404010,0x400000,0x20004000,0x404010,0x400000,0x20000010,0x400010,0x20004000,0x20000000,0x4010,0,0x400010,0x20004010,0x4000,0x404000,0x20004010,0x10,0x20400010,0x20400010,0,0x404010,0x20404000,0x4010,0x404000,0x20404000,0x20000000,0x20004000,0x10,0x20400010,0x404000,0x20404010,0x400000,0x4010,0x20000010,0x400000,0x20004000,0x20000000,0x4010,0x20000010,0x20404010,0x404000,0x20400000,0x404010,0x20404000,0,0x20400010,0x10,0x4000,0x20400000,0x404010,0x4000,0x400010,0x20004010,0,0x20404000,0x20000000,0x400010,0x20004010];
6130var spfunction7 = [0x200000,0x4200002,0x4000802,0,0x800,0x4000802,0x200802,0x4200800,0x4200802,0x200000,0,0x4000002,0x2,0x4000000,0x4200002,0x802,0x4000800,0x200802,0x200002,0x4000800,0x4000002,0x4200000,0x4200800,0x200002,0x4200000,0x800,0x802,0x4200802,0x200800,0x2,0x4000000,0x200800,0x4000000,0x200800,0x200000,0x4000802,0x4000802,0x4200002,0x4200002,0x2,0x200002,0x4000000,0x4000800,0x200000,0x4200800,0x802,0x200802,0x4200800,0x802,0x4000002,0x4200802,0x4200000,0x200800,0,0x2,0x4200802,0,0x200802,0x4200000,0x800,0x4000002,0x4000800,0x800,0x200002];
6131var spfunction8 = [0x10001040,0x1000,0x40000,0x10041040,0x10000000,0x10001040,0x40,0x10000000,0x40040,0x10040000,0x10041040,0x41000,0x10041000,0x41040,0x1000,0x40,0x10040000,0x10000040,0x10001000,0x1040,0x41000,0x40040,0x10040040,0x10041000,0x1040,0,0,0x10040040,0x10000040,0x10001000,0x41040,0x40000,0x41040,0x40000,0x10041000,0x1000,0x40,0x10040040,0x1000,0x41040,0x10001000,0x40,0x10000040,0x10040000,0x10040040,0x10000000,0x40000,0x10001040,0,0x10041040,0x40040,0x10000040,0x10040000,0x10001000,0x10001040,0,0x10041040,0x41000,0x41000,0x1040,0x1040,0x40040,0x10000000,0x10041000];
6132
6133/**
6134 * Create necessary sub keys.
6135 *
6136 * @param key the 64-bit or 192-bit key.
6137 *
6138 * @return the expanded keys.
6139 */
6140function _createKeys(key) {
6141  var pc2bytes0  = [0,0x4,0x20000000,0x20000004,0x10000,0x10004,0x20010000,0x20010004,0x2
614100,0x204,0x20000200,0x20000204,0x10200,0x10204,0x20010200,0x20010204],
6142      pc2bytes1  = [0,0x1,0x100000,0x100001,0x4000000,0x4000001,0x4100000,0x4100001,0x100,0x101,0x100100,0x100101,0x4000100,0x4000101,0x4100100,0x4100101],
6143      pc2bytes2  = [0,0x8,0x800,0x808,0x1000000,0x1000008,0x1000800,0x1000808,0,0x8,0x800,0x808,0x1000000,0x1000008,0x1000800,0x1000808],
6144      pc2bytes3  = [0,0x200000,0x8000000,0x8200000,0x2000,0x202000,0x8002000,0x8202000,0x20000,0x220000,0x8020000,0x8220000,0x22000,0x222000,0x8022000,0x8222000],
6145      pc2bytes4  = [0,0x40000,0x10,0x40010,0,0x40000,0x10,0x40010,0x1000,0x41000,0x1010,0x41010,0x1000,0x41000,0x1010,0x41010],
6146      pc2bytes5  = [0,0x400,0x20,0x420,0,0x400,0x20,0x420,0x2000000,0x2000400,0x2000020,0x2000420,0x2000000,0x2000400,0x2000020,0x2000420],
6147      pc2bytes6  = [0,0x10000000,0x80000,0x10080000,0x2,0x10000002,0x80002,0x10080002,0,0x10000000,0x80000,0x10080000,0x2,0x10000002,0x80002,0x10080002],
6148      pc2bytes7  = [0,0x10000,0x800,0x10800,0x20000000,0x20010000,0x20000800,0x20010800,0x20000,0x30000,0x20800,0x30800,0x20020000,0x20030000,0x20020800,0x20030800],
6149      pc2bytes8  = [0,0x40000,0,0x40000,0x2,0x40002,0x2,0x40002,0x2000000,0x2040000,0x2000000,0x2040000,0x2000002,0x2040002,0x2000002,0x2040002],
6150      pc2bytes9  = [0,0x10000000,0x8,0x10000008,0,0x10000000,0x8,0x10000008,0x400,0x10000400,0x408,0x10000408,0x400,0x10000400,0x408,0x10000408],
6151      pc2bytes10 = [0,0x20,0,0x20,0x100000,0x100020,0x100000,0x100020,0x2000,0x2020,0x2000,0x2020,0x102000,0x102020,0x102000,0x102020],
6152      pc2bytes11 = [0,0x1000000,0x200,0x1000200,0x200000,0x1200000,0x200200,0x1200200,0x4000000,0x5000000,0x4000200,0x5000200,0x4200000,0x5200000,0x4200200,0x5200200],
6153      pc2bytes12 = [0,0x1000,0x8000000,0x8001000,0x80000,0x81000,0x8080000,0x8081000,0x10,0x1010,0x8000010,0x8001010,0x80010,0x81010,0x8080010,0x8081010],
6154      pc2bytes13 = [0,0x4,0x100,0x104,0,0x4,0x100,0x104,0x1,0x5,0x101,0x105,0x1,0x5,0x101,0x105];
6155
6156  // how many iterations (1 for des, 3 for triple des)
6157  // changed by Paul 16/6/2007 to use Triple DES for 9+ byte keys
6158  var iterations = key.length() > 8 ? 3 : 1;
6159
6160  // stores the return keys
6161  var keys = [];
6162
6163  // now define the left shifts which need to be done
6164  var shifts = [0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0];
6165
6166  var n = 0, tmp;
6167  for(var j = 0; j < iterations; j ++) {
6168    var left = key.getInt32();
6169    var right = key.getInt32();
6170
6171    tmp = ((left >>> 4) ^ right) & 0x0f0f0f0f;
6172    right ^= tmp;
6173    left ^= (tmp << 4);
6174
6175    tmp = ((right >>> -16) ^ left) & 0x0000ffff;
6176    left ^= tmp;
6177    right ^= (tmp << -16);
6178
6179    tmp = ((left >>> 2) ^ right) & 0x33333333;
6180    right ^= tmp;
6181    left ^= (tmp << 2);
6182
6183    tmp = ((right >>> -16) ^ left) & 0x0000ffff;
6184    left ^= tmp;
6185    right ^= (tmp << -16);
6186
6187    tmp = ((left >>> 1) ^ right) & 0x55555555;
6188    right ^= tmp;
6189    left ^= (tmp << 1);
6190
6191    tmp = ((right >>> 8) ^ left) & 0x00ff00ff;
6192    left ^= tmp;
6193    right ^= (tmp << 8);
6194
6195    tmp = ((left >>> 1) ^ right) & 0x55555555;
6196    right ^= tmp;
6197    left ^= (tmp << 1);
6198
6199    // right needs to be shifted and OR'd with last four bits of left
6200    tmp = (left << 8) | ((right >>> 20) & 0x000000f0);
6201
6202    // left needs to be put upside down
6203    left = ((right << 24) | ((right << 8) & 0xff0000) |
6204      ((right >>> 8) & 0xff00) | ((right >>> 24) & 0xf0));
6205    right = tmp;
6206
6207    // now go through and perform these shifts on the left and right keys
6208    for(var i = 0; i < shifts.length; ++i) {
6209      //shift the keys either one or two bits to the left
6210      if(shifts[i]) {
6211        left = (left << 2) | (left >>> 26);
6212        right = (right << 2) | (right >>> 26);
6213      } else {
6214        left = (left << 1) | (left >>> 27);
6215        right = (right << 1) | (right >>> 27);
6216      }
6217      left &= -0xf;
6218      right &= -0xf;
6219
6220      // now apply PC-2, in such a way that E is easier when encrypting or
6221      // decrypting this conversion will look like PC-2 except only the last 6
6222      // bits of each byte are used rather than 48 consecutive bits and the
6223      // order of lines will be according to how the S selection functions will
6224      // be applied: S2, S4, S6, S8, S1, S3, S5, S7
6225      var lefttmp = (
6226        pc2bytes0[left >>> 28] | pc2bytes1[(left >>> 24) & 0xf] |
6227        pc2bytes2[(left >>> 20) & 0xf] | pc2bytes3[(left >>> 16) & 0xf] |
6228        pc2bytes4[(left >>> 12) & 0xf] | pc2bytes5[(left >>> 8) & 0xf] |
6229        pc2bytes6[(left >>> 4) & 0xf]);
6230      var righttmp = (
6231        pc2bytes7[right >>> 28] | pc2bytes8[(right >>> 24) & 0xf] |
6232        pc2bytes9[(right >>> 20) & 0xf] | pc2bytes10[(right >>> 16) & 0xf] |
6233        pc2bytes11[(right >>> 12) & 0xf] | pc2bytes12[(right >>> 8) & 0xf] |
6234        pc2bytes13[(right >>> 4) & 0xf]);
6235      tmp = ((righttmp >>> 16) ^ lefttmp) & 0x0000ffff;
6236      keys[n++] = lefttmp ^ tmp;
6237      keys[n++] = righttmp ^ (tmp << 16);
6238    }
6239  }
6240
6241  return keys;
6242}
6243
6244/**
6245 * Updates a single block (1 byte) using DES. The update will either
6246 * encrypt or decrypt the block.
6247 *
6248 * @param keys the expanded keys.
6249 * @param input the input block (an array of 32-bit words).
6250 * @param output the updated output block.
6251 * @param decrypt true to decrypt the block, false to encrypt it.
6252 */
6253function _updateBlock(keys, input, output, decrypt) {
6254  // set up loops for single or triple DES
6255  var iterations = keys.length === 32 ? 3 : 9;
6256  var looping;
6257  if(iterations === 3) {
6258    looping = decrypt ? [30, -2, -2] : [0, 32, 2];
6259  } else {
6260    looping = (decrypt ?
6261      [94, 62, -2, 32, 64, 2, 30, -2, -2] :
6262      [0, 32, 2, 62, 30, -2, 64, 96, 2]);
6263  }
6264
6265  var tmp;
6266
6267  var left = input[0];
6268  var right = input[1];
6269
6270  // first each 64 bit chunk of the message must be permuted according to IP
6271  tmp = ((left >>> 4) ^ right) & 0x0f0f0f0f;
6272  right ^= tmp;
6273  left ^= (tmp << 4);
6274
6275  tmp = ((left >>> 16) ^ right) & 0x0000ffff;
6276  right ^= tmp;
6277  left ^= (tmp << 16);
6278
6279  tmp = ((right >>> 2) ^ left) & 0x33333333;
6280  left ^= tmp;
6281  right ^= (tmp << 2);
6282
6283  tmp = ((right >>> 8) ^ left) & 0x00ff00ff;
6284  left ^= tmp;
6285  right ^= (tmp << 8);
6286
6287  tmp = ((left >>> 1) ^ right) & 0x55555555;
6288  right ^= tmp;
6289  left ^= (tmp << 1);
6290
6291  // rotate left 1 bit
6292  left = ((left << 1) | (left >>> 31));
6293  right = ((right << 1) | (right >>> 31));
6294
6295  for(var j = 0; j < iterations; j += 3) {
6296    var endloop = looping[j + 1];
6297    var loopinc = looping[j + 2];
6298
6299    // now go through and perform the encryption or decryption
6300    for(var i = looping[j]; i != endloop; i += loopinc) {
6301      var right1 = right ^ keys[i];
6302      var right2 = ((right >>> 4) | (right << 28)) ^ keys[i + 1];
6303
6304      // passing these bytes through the S selection functions
6305      tmp = left;
6306      left = right;
6307      right = tmp ^ (
6308        spfunction2[(right1 >>> 24) & 0x3f] |
6309        spfunction4[(right1 >>> 16) & 0x3f] |
6310        spfunction6[(right1 >>>  8) & 0x3f] |
6311        spfunction8[right1 & 0x3f] |
6312        spfunction1[(right2 >>> 24) & 0x3f] |
6313        spfunction3[(right2 >>> 16) & 0x3f] |
6314        spfunction5[(right2 >>>  8) & 0x3f] |
6315        spfunction7[right2 & 0x3f]);
6316    }
6317    // unreverse left and right
6318    tmp = left;
6319    left = right;
6320    right = tmp;
6321  }
6322
6323  // rotate right 1 bit
6324  left = ((left >>> 1) | (left << 31));
6325  right = ((right >>> 1) | (right << 31));
6326
6327  // now perform IP-1, which is IP in the opposite direction
6328  tmp = ((left >>> 1) ^ right) & 0x55555555;
6329  right ^= tmp;
6330  left ^= (tmp << 1);
6331
6332  tmp = ((right >>> 8) ^ left) & 0x00ff00ff;
6333  left ^= tmp;
6334  right ^= (tmp << 8);
6335
6336  tmp = ((right >>> 2) ^ left) & 0x33333333;
6337  left ^= tmp;
6338  right ^= (tmp << 2);
6339
6340  tmp = ((left >>> 16) ^ right) & 0x0000ffff;
6341  right ^= tmp;
6342  left ^= (tmp << 16);
6343
6344  tmp = ((left >>> 4) ^ right) & 0x0f0f0f0f;
6345  right ^= tmp;
6346  left ^= (tmp << 4);
6347
6348  output[0] = left;
6349  output[1] = right;
6350}
6351
6352/**
6353 * Deprecated. Instead, use:
6354 *
6355 * forge.cipher.createCipher('DES-<mode>', key);
6356 * forge.cipher.createDecipher('DES-<mode>', key);
6357 *
6358 * Creates a deprecated DES cipher object. This object's mode will default to
6359 * CBC (cipher-block-chaining).
6360 *
6361 * The key may be given as a binary-encoded string of bytes or a byte buffer.
6362 *
6363 * @param options the options to use.
6364 *          key the symmetric key to use (64 or 192 bits).
6365 *          output the buffer to write to.
6366 *          decrypt true for decryption, false for encryption.
6367 *          mode the cipher mode to use (default: 'CBC').
6368 *
6369 * @return the cipher.
6370 */
6371function _createCipher(options) {
6372  options = options || {};
6373  var mode = (options.mode || 'CBC').toUpperCase();
6374  var algorithm = 'DES-' + mode;
6375
6376  var cipher;
6377  if(options.decrypt) {
6378    cipher = forge.cipher.createDecipher(algorithm, options.key);
6379  } else {
6380    cipher = forge.cipher.createCipher(algorithm, options.key);
6381  }
6382
6383  // backwards compatible start API
6384  var start = cipher.start;
6385  cipher.start = function(iv, options) {
6386    // backwards compatibility: support second arg as output buffer
6387    var output = null;
6388    if(options instanceof forge.util.ByteBuffer) {
6389      output = options;
6390      options = {};
6391    }
6392    options = options || {};
6393    options.output = output;
6394    options.iv = iv;
6395    start.call(cipher, options);
6396  };
6397
6398  return cipher;
6399}
6400
6401
6402} // end module implementation
6403
6404/* ########## Begin module wrapper ########## */
6405var name = 'des';
6406if(typeof define !== 'function') {
6407  // NodeJS -> AMD
6408  if(typeof module === 'object' && module.exports) {
6409    var nodeJS = true;
6410    define = function(ids, factory) {
6411      factory(require, module);
6412    };
6413  } else {
6414    // <script>
6415    if(typeof forge === 'undefined') {
6416      forge = {};
6417    }
6418    return initModule(forge);
6419  }
6420}
6421// AMD
6422var deps;
6423var defineFunc = function(require, module) {
6424  module.exports = function(forge) {
6425    var mods = deps.map(function(dep) {
6426      return require(dep);
6427    }).concat(initModule);
6428    // handle circular dependencies
6429    forge = forge || {};
6430    forge.defined = forge.defined || {};
6431    if(forge.defined[name]) {
6432      return forge[name];
6433    }
6434    forge.defined[name] = true;
6435    for(var i = 0; i < mods.length; ++i) {
6436      mods[i](forge);
6437    }
6438    return forge[name];
6439  };
6440};
6441var tmpDefine = define;
6442define = function(ids, factory) {
6443  deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2);
6444  if(nodeJS) {
6445    delete define;
6446    return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0));
6447  }
6448  define = tmpDefine;
6449  return define.apply(null, Array.prototype.slice.call(arguments, 0));
6450};
6451define(
6452  ['require', 'module', './cipher', './cipherModes', './util'], function() {
6453  defineFunc.apply(null, Array.prototype.slice.call(arguments, 0));
6454});
6455})();
6456
6457/**
6458 * Advanced Encryption Standard (AES) implementation.
6459 *
6460 * This implementation is based on the public domain library 'jscrypto' which
6461 * was written by:
6462 *
6463 * Emily Stark ([email protected])
6464 * Mike Hamburg ([email protected])
6465 * Dan Boneh ([email protected])
6466 *
6467 * Parts of this code are based on the OpenSSL implementation of AES:
6468 * http://www.openssl.org
6469 *
6470 * @author Dave Longley
6471 *
6472 * Copyright (c) 2010-2014 Digital Bazaar, Inc.
6473 */
6474(function() {
6475/* ########## Begin module implementation ########## */
6476function initModule(forge) {
6477
6478/* AES API */
6479forge.aes = forge.aes || {};
6480
6481/**
6482 * Deprecated. Instead, use:
6483 *
6484 * var cipher = forge.cipher.createCipher('AES-<mode>', key);
6485 * cipher.start({iv: iv});
6486 *
6487 * Creates an AES cipher object to encrypt data using the given symmetric key.
6488 * The output will be stored in the 'output' member of the returned cipher.
6489 *
6490 * The key and iv may be given as a string of bytes, an array of bytes,
6491 * a byte buffer, or an array of 32-bit words.
6492 *
6493 * @param key the symmetric key to use.
6494 * @param iv the initialization vector to use.
6495 * @param output the buffer to write to, null to create one.
6496 * @param mode the cipher mode to use (default: 'CBC').
6497 *
6498 * @return the cipher.
6499 */
6500forge.aes.startEncrypting = function(key, iv, output, mode) {
6501  var cipher = _createCipher({
6502    key: key,
6503    output: output,
6504    decrypt: false,
6505    mode: mode
6506  });
6507  cipher.start(iv);
6508  return cipher;
6509};
6510
6511/**
6512 * Deprecated. Instead, use:
6513 *
6514 * var cipher = forge.cipher.createCipher('AES-<mode>', key);
6515 *
6516 * Creates an AES cipher object to encrypt data using the given symmetric key.
6517 *
6518 * The key may be given as a string of bytes, an array of bytes, a
6519 * byte buffer, or an array of 32-bit words.
6520 *
6521 * @param key the symmetric key to use.
6522 * @param mode the cipher mode to use (default: 'CBC').
6523 *
6524 * @return the cipher.
6525 */
6526forge.aes.createEncryptionCipher = function(key, mode) {
6527  return _createCipher({
6528    key: key,
6529    output: null,
6530    decrypt: false,
6531    mode: mode
6532  });
6533};
6534
6535/**
6536 * Deprecated. Instead, use:
6537 *
6538 * var decipher = forge.cipher.createDecipher('AES-<mode>', key);
6539 * decipher.start({iv: iv});
6540 *
6541 * Creates an AES cipher object to decrypt data using the given symmetric key.
6542 * The output will be stored in the 'output' member of the returned cipher.
6543 *
6544 * The key and iv may be given as a string of bytes, an array of bytes,
6545 * a byte buffer, or an array of 32-bit words.
6546 *
6547 * @param key the symmetric key to use.
6548 * @param iv the initialization vector to use.
6549 * @param output the buffer to write to, null to create one.
6550 * @param mode the cipher mode to use (default: 'CBC').
6551 *
6552 * @return the cipher.
6553 */
6554forge.aes.startDecrypting = function(key, iv, output, mode) {
6555  var cipher = _createCipher({
6556    key: key,
6557    output: output,
6558    decrypt: true,
6559    mode: mode
6560  });
6561  cipher.start(iv);
6562  return cipher;
6563};
6564
6565/**
6566 * Deprecated. Instead, use:
6567 *
6568 * var decipher = forge.cipher.createDecipher('AES-<mode>', key);
6569 *
6570 * Creates an AES cipher object to decrypt data using the given symmetric key.
6571 *
6572 * The key may be given as a string of bytes, an array of bytes, a
6573 * byte buffer, or an array of 32-bit words.
6574 *
6575 * @param key the symmetric key to use.
6576 * @param mode the cipher mode to use (default: 'CBC').
6577 *
6578 * @return the cipher.
6579 */
6580forge.aes.createDecryptionCipher = function(key, mode) {
6581  return _createCipher({
6582    key: key,
6583    output: null,
6584    decrypt: true,
6585    mode: mode
6586  });
6587};
6588
6589/**
6590 * Creates a new AES cipher algorithm object.
6591 *
6592 * @param name the name of the algorithm.
6593 * @param mode the mode factory function.
6594 *
6595 * @return the AES algorithm object.
6596 */
6597forge.aes.Algorithm = function(name, mode) {
6598  if(!init) {
6599    initialize();
6600  }
6601  var self = this;
6602  self.name = name;
6603  self.mode = new mode({
6604    blockSize: 16,
6605    cipher: {
6606      encrypt: function(inBlock, outBlock) {
6607        return _updateBlock(self._w, inBlock, outBlock, false);
6608      },
6609      decrypt: function(inBlock, outBlock) {
6610        return _updateBlock(self._w, inBlock, outBlock, true);
6611      }
6612    }
6613  });
6614  self._init = false;
6615};
6616
6617/**
6618 * Initializes this AES algorithm by expanding its key.
6619 *
6620 * @param options the options to use.
6621 *          key the key to use with this algorithm.
6622 *          decrypt true if the algorithm should be initialized for decryption,
6623 *            false for encryption.
6624 */
6625forge.aes.Algorithm.prototype.initialize = function(options) {
6626  if(this._init) {
6627    return;
6628  }
6629
6630  var key = options.key;
6631  var tmp;
6632
6633  /* Note: The key may be a string of bytes, an array of bytes, a byte
6634    buffer, or an array of 32-bit integers. If the key is in bytes, then
6635    it must be 16, 24, or 32 bytes in length. If it is in 32-bit
6636    integers, it must be 4, 6, or 8 integers long. */
6637
6638  if(typeof key === 'string' &&
6639    (key.length === 16 || key.length === 24 || key.length === 32)) {
6640    // convert key string into byte buffer
6641    key = forge.util.createBuffer(key);
6642  } else if(forge.util.isArray(key) &&
6643    (key.length === 16 || key.length === 24 || key.length === 32)) {
6644    // convert key integer array into byte buffer
6645    tmp = key;
6646    key = forge.util.createBuffer();
6647    for(var i = 0; i < tmp.length; ++i) {
6648      key.putByte(tmp[i]);
6649    }
6650  }
6651
6652  // convert key byte buffer into 32-bit integer array
6653  if(!forge.util.isArray(key)) {
6654    tmp = key;
6655    key = [];
6656
6657    // key lengths of 16, 24, 32 bytes allowed
6658    var len = tmp.length();
6659    if(len === 16 || len === 24 || len === 32) {
6660      len = len >>> 2;
6661      for(var i = 0; i < len; ++i) {
6662        key.push(tmp.getInt32());
6663      }
6664    }
6665  }
6666
6667  // key must be an array of 32-bit integers by now
6668  if(!forge.util.isArray(key) ||
6669    !(key.length === 4 || key.length === 6 || key.length === 8)) {
6670    throw new Error('Invalid key parameter.');
6671  }
6672
6673  // encryption operation is always used for these modes
6674  var mode = this.mode.name;
6675  var encryptOp = (['CFB', 'OFB', 'CTR', 'GCM'].indexOf(mode) !== -1);
6676
6677  // do key expansion
6678  this._w = _expandKey(key, options.decrypt && !encryptOp);
6679  this._init = true;
6680};
6681
6682/**
6683 * Expands a key. Typically only used for testing.
6684 *
6685 * @param key the symmetric key to expand, as an array of 32-bit words.
6686 * @param decrypt true to expand for decryption, false for encryption.
6687 *
6688 * @return the expanded key.
6689 */
6690forge.aes._expandKey = function(key, decrypt) {
6691  if(!init) {
6692    initialize();
6693  }
6694  return _expandKey(key, decrypt);
6695};
6696
6697/**
6698 * Updates a single block. Typically only used for testing.
6699 *
6700 * @param w the expanded key to use.
6701 * @param input an array of block-size 32-bit words.
6702 * @param output an array of block-size 32-bit words.
6703 * @param decrypt true to decrypt, false to encrypt.
6704 */
6705forge.aes._updateBlock = _updateBlock;
6706
6707
6708/** Register AES algorithms **/
6709
6710registerAlgorithm('AES-ECB', forge.cipher.modes.ecb);
6711registerAlgorithm('AES-CBC', forge.cipher.modes.cbc);
6712registerAlgorithm('AES-CFB', forge.cipher.modes.cfb);
6713registerAlgorithm('AES-OFB', forge.cipher.modes.ofb);
6714registerAlgorithm('AES-CTR', forge.cipher.modes.ctr);
6715registerAlgorithm('AES-GCM', forge.cipher.modes.gcm);
6716
6717function registerAlgorithm(name, mode) {
6718  var factory = function() {
6719    return new forge.aes.Algorithm(name, mode);
6720  };
6721  forge.cipher.registerAlgorithm(name, factory);
6722}
6723
6724
6725/** AES implementation **/
6726
6727var init = false; // not yet initialized
6728var Nb = 4;       // number of words comprising the state (AES = 4)
6729var sbox;         // non-linear substitution table used in key expansion
6730var isbox;        // inversion of sbox
6731var rcon;         // round constant word array
6732var mix;          // mix-columns table
6733var imix;         // inverse mix-columns table
6734
6735/**
6736 * Performs initialization, ie: precomputes tables to optimize for speed.
6737 *
6738 * One way to understand how AES works is to imagine that 'addition' and
6739 * 'multiplication' are interfaces that require certain mathematical
6740 * properties to hold true (ie: they are associative) but they might have
6741 * different implementations and produce different kinds of results ...
6742 * provided that their mathematical properties remain true. AES defines
6743 * its own methods of addition and multiplication but keeps some important
6744 * properties the same, ie: associativity and distributivity. The
6745 * explanation below tries to shed some light on how AES defines addition
6746 * and multiplication of bytes and 32-bit words in order to perform its
6747 * encryption and decryption algorithms.
6748 *
6749 * The basics:
6750 *
6751 * The AES algorithm views bytes as binary representations of polynomials
6752 * that have either 1 or 0 as the coefficients. It defines the addition
6753 * or subtraction of two bytes as the XOR operation. It also defines the
6754 * multiplication of two bytes as a finite field referred to as GF(2^8)
6755 * (Note: 'GF' means "Galois Field" which is a field that contains a finite
6756 * number of elements so GF(2^8) has 256 elements).
6757 *
6758 * This means that any two bytes can be represented as binary polynomials;
6759 * when they multiplied together and modularly reduced by an irreducible
6760 * polynomial of the 8th degree, the results are the field GF(2^8). The
6761 * specific irreducible polynomial that AES uses in hexadecimal is 0x11b.
6762 * This multiplication is associative with 0x01 as the identity:
6763 *
6764 * (b * 0x01 = GF(b, 0x01) = b).
6765 *
6766 * The operation GF(b, 0x02) can be performed at the byte level by left
6767 * shifting b once and then XOR'ing it (to perform the modular reduction)
6768 * with 0x11b if b is >= 128. Repeated application of the multiplication
6769 * of 0x02 can be used to implement the multiplication of any two bytes.
6770 *
6771 * For instance, multiplying 0x57 and 0x13, denoted as GF(0x57, 0x13), can
6772 * be performed by factoring 0x13 into 0x01, 0x02, and 0x10. Then these
6773 * factors can each be multiplied by 0x57 and then added together. To do
6774 * the multiplication, values for 0x57 multiplied by each of these 3 factors
6775 * can be precomputed and stored in a table. To add them, the values from
6776 * the table are XOR'd together.
6777 *
6778 * AES also defines addition and multiplication of words, that is 4-byte
6779 * numbers represented as polynomials of 3 degrees where the coefficients
6780 * are the values of the bytes.
6781 *
6782 * The word [a0, a1, a2, a3] is a polynomial a3x^3 + a2x^2 + a1x + a0.
6783 *
6784 * Addition is performed by XOR'ing like powers of x. Multiplication
6785 * is performed in two steps, the first is an algebriac expansion as
6786 * you would do normally (where addition is XOR). But the result is
6787 * a polynomial larger than 3 degrees and thus it cannot fit in a word. So
6788 * next the result is modularly reduced by an AES-specific polynomial of
6789 * degree 4 which will always produce a polynomial of less than 4 degrees
6790 * such that it will fit in a word. In AES, this polynomial is x^4 + 1.
6791 *
6792 * The modular product of two polynomials 'a' and 'b' is thus:
6793 *
6794 * d(x) = d3x^3 + d2x^2 + d1x + d0
6795 * with
6796 * d0 = GF(a0, b0) ^ GF(a3, b1) ^ GF(a2, b2) ^ GF(a1, b3)
6797 * d1 = GF(a1, b0) ^ GF(a0, b1) ^ GF(a3, b2) ^ GF(a2, b3)
6798 * d2 = GF(a2, b0) ^ GF(a1, b1) ^ GF(a0, b2) ^ GF(a3, b3)
6799 * d3 = GF(a3, b0) ^ GF(a2, b1) ^ GF(a1, b2) ^ GF(a0, b3)
6800 *
6801 * As a matrix:
6802 *
6803 * [d0] = [a0 a3 a2 a1][b0]
6804 * [d1]   [a1 a0 a3 a2][b1]
6805 * [d2]   [a2 a1 a0 a3][b2]
6806 * [d3]   [a3 a2 a1 a0][b3]
6807 *
6808 * Special polynomials defined by AES (0x02 == {02}):
6809 * a(x)    = {03}x^3 + {01}x^2 + {01}x + {02}
6810 * a^-1(x) = {0b}x^3 + {0d}x^2 + {09}x + {0e}.
6811 *
6812 * These polynomials are used in the MixColumns() and InverseMixColumns()
6813 * operations, respectively, to cause each element in the state to affect
6814 * the output (referred to as diffusing).
6815 *
6816 * RotWord() uses: a0 = a1 = a2 = {00} and a3 = {01}, which is the
6817 * polynomial x3.
6818 *
6819 * The ShiftRows() method modifies the last 3 rows in the state (where
6820 * the state is 4 words with 4 bytes per word) by shifting bytes cyclically.
6821 * The 1st byte in the second row is moved to the end of the row. The 1st
6822 * and 2nd bytes in the third row are moved to the end of the row. The 1st,
6823 * 2nd, and 3rd bytes are moved in the fourth row.
6824 *
6825 * More details on how AES arithmetic works:
6826 *
6827 * In the polynomial representation of binary numbers, XOR performs addition
6828 * and subtraction and multiplication in GF(2^8) denoted as GF(a, b)
6829 * corresponds with the multiplication of polynomials modulo an irreducible
6830 * polynomial of degree 8. In other words, for AES, GF(a, b) will multiply
6831 * polynomial 'a' with polynomial 'b' and then do a modular reduction by
6832 * an AES-specific irreducible polynomial of degree 8.
6833 *
6834 * A polynomial is irreducible if its only divisors are one and itself. For
6835 * the AES algorithm, this irreducible polynomial is:
6836 *
6837 * m(x) = x^8 + x^4 + x^3 + x + 1,
6838 *
6839 * or {01}{1b} in hexadecimal notation, where each coefficient is a bit:
6840 * 100011011 = 283 = 0x11b.
6841 *
6842 * For example, GF(0x57, 0x83) = 0xc1 because
6843 *
6844 * 0x57 = 87  = 01010111 = x^6 + x^4 + x^2 + x + 1
6845 * 0x85 = 131 = 10000101 = x^7 + x + 1
6846 *
6847 * (x^6 + x^4 + x^2 + x + 1) * (x^7 + x + 1)
6848 * =  x^13 + x^11 + x^9 + x^8 + x^7 +
6849 *    x^7 + x^5 + x^3 + x^2 + x +
6850 *    x^6 + x^4 + x^2 + x + 1
6851 * =  x^13 + x^11 + x^9 + x^8 + x^6 + x^5 + x^4 + x^3 + 1 = y
6852 *    y modulo (x^8 + x^4 + x^3 + x + 1)
6853 * =  x^7 + x^6 + 1.
6854 *
6855 * The modular reduction by m(x) guarantees the result will be a binary
6856 * polynomial of less than degree 8, so that it can fit in a byte.
6857 *
6858 * The operation to multiply a binary polynomial b with x (the polynomial
6859 * x in binary representation is 00000010) is:
6860 *
6861 * b_7x^8 + b_6x^7 + b_5x^6 + b_4x^5 + b_3x^4 + b_2x^3 + b_1x^2 + b_0x^1
6862 *
6863 * To get GF(b, x) we must reduce that by m(x). If b_7 is 0 (that is the
6864 * most significant bit is 0 in b) then the result is already reduced. If
6865 * it is 1, then we can reduce it by subtracting m(x) via an XOR.
6866 *
6867 * It follows that multiplication by x (00000010 or 0x02) can be implemented
6868 * by performing a left shift followed by a conditional bitwise XOR with
6869 * 0x1b. This operation on bytes is denoted by xtime(). Multiplication by
6870 * higher powers of x can be implemented by repeated application of xtime().
6871 *
6872 * By adding intermediate results, multiplication by any constant can be
6873 * implemented. For instance:
6874 *
6875 * GF(0x57, 0x13) = 0xfe because:
6876 *
6877 * xtime(b) = (b & 128) ? (b << 1 ^ 0x11b) : (b << 1)
6878 *
6879 * Note: We XOR with 0x11b instead of 0x1b because in javascript our
6880 * datatype for b can be larger than 1 byte, so a left shift will not
6881 * automatically eliminate bits that overflow a byte ... by XOR'ing the
6882 * overflow bit with 1 (the extra one from 0x11b) we zero it out.
6883 *
6884 * GF(0x57, 0x02) = xtime(0x57) = 0xae
6885 * GF(0x57, 0x04) = xtime(0xae) = 0x47
6886 * GF(0x57, 0x08) = xtime(0x47) = 0x8e
6887 * GF(0x57, 0x10) = xtime(0x8e) = 0x07
6888 *
6889 * GF(0x57, 0x13) = GF(0x57, (0x01 ^ 0x02 ^ 0x10))
6890 *
6891 * And by the distributive property (since XOR is addition and GF() is
6892 * multiplication):
6893 *
6894 * = GF(0x57, 0x01) ^ GF(0x57, 0x02) ^ GF(0x57, 0x10)
6895 * = 0x57 ^ 0xae ^ 0x07
6896 * = 0xfe.
6897 */
6898function initialize() {
6899  init = true;
6900
6901  /* Populate the Rcon table. These are the values given by
6902    [x^(i-1),{00},{00},{00}] where x^(i-1) are powers of x (and x = 0x02)
6903    in the field of GF(2^8), where i starts at 1.
6904
6905    rcon[0] = [0x00, 0x00, 0x00, 0x00]
6906    rcon[1] = [0x01, 0x00, 0x00, 0x00] 2^(1-1) = 2^0 = 1
6907    rcon[2] = [0x02, 0x00, 0x00, 0x00] 2^(2-1) = 2^1 = 2
6908    ...
6909    rcon[9]  = [0x1B, 0x00, 0x00, 0x00] 2^(9-1)  = 2^8 = 0x1B
6910    rcon[10] = [0x36, 0x00, 0x00, 0x00] 2^(10-1) = 2^9 = 0x36
6911
6912    We only store the first byte because it is the only one used.
6913  */
6914  rcon = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36];
6915
6916  // compute xtime table which maps i onto GF(i, 0x02)
6917  var xtime = new Array(256);
6918  for(var i = 0; i < 128; ++i) {
6919    xtime[i] = i << 1;
6920    xtime[i + 128] = (i + 128) << 1 ^ 0x11B;
6921  }
6922
6923  // compute all other tables
6924  sbox = new Array(256);
6925  isbox = new Array(256);
6926  mix = new Array(4);
6927  imix = new Array(4);
6928  for(var i = 0; i < 4; ++i) {
6929    mix[i] = new Array(256);
6930    imix[i] = new Array(256);
6931  }
6932  var e = 0, ei = 0, e2, e4, e8, sx, sx2, me, ime;
6933  for(var i = 0; i < 256; ++i) {
6934    /* We need to generate the SubBytes() sbox and isbox tables so that
6935      we can perform byte substitutions. This requires us to traverse
6936      all of the elements in GF, find their multiplicative inverses,
6937      and apply to each the following affine transformation:
6938
6939      bi' = bi ^ b(i + 4) mod 8 ^ b(i + 5) mod 8 ^ b(i + 6) mod 8 ^
6940            b(i + 7) mod 8 ^ ci
6941      for 0 <= i < 8, where bi is the ith bit of the byte, and ci is the
6942      ith bit of a byte c with the value {63} or {01100011}.
6943
6944      It is possible to traverse every possible value in a Galois field
6945      using what is referred to as a 'generator'. There are many
6946      generators (128 out of 256): 3,5,6,9,11,82 to name a few. To fully
6947      traverse GF we iterate 255 times, multiplying by our generator
6948      each time.
6949
6950      On each iteration we can determine the multiplicative inverse for
6951      the current element.
6952
6953      Suppose there is an element in GF 'e'. For a given generator 'g',
6954      e = g^x. The multiplicative inverse of e is g^(255 - x). It turns
6955      out that if use the inverse of a generator as another generator
6956      it will produce all of the corresponding multiplicative inverses
6957      at the same time. For this reason, we choose 5 as our inverse
6958      generator because it only requires 2 multiplies and 1 add and its
6959      inverse, 82, requires relatively few operations as well.
6960
6961      In order to apply the affine transformation, the multiplicative
6962      inverse 'ei' of 'e' can be repeatedly XOR'd (4 times) with a
6963      bit-cycling of 'ei'. To do this 'ei' is first stored in 's' and
6964      'x'. Then 's' is left shifted and the high bit of 's' is made the
6965      low bit. The resulting value is stored in 's'. Then 'x' is XOR'd
6966      with 's' and stored in 'x'. On each subsequent iteration the same
6967      operation is performed. When 4 iterations are complete, 'x' is
6968      XOR'd with 'c' (0x63) and the transformed value is stored in 'x'.
6969      For example:
6970
6971      s = 01000001
6972      x = 01000001
6973
6974      iteration 1: s = 10000010, x ^= s
6975      iteration 2: s = 00000101, x ^= s
6976      iteration 3: s = 00001010, x ^= s
6977      iteration 4: s = 00010100, x ^= s
6978      x ^= 0x63
6979
6980      This can be done with a loop where s = (s << 1) | (s >> 7). However,
6981      it can also be done by using a single 16-bit (in this case 32-bit)
6982      number 'sx'. Since XOR is an associative operation, we can set 'sx'
6983      to 'ei' and then XOR it with 'sx' left-shifted 1,2,3, and 4 times.
6984      The most significant bits will flow into the high 8 bit positions
6985      and be correctly XOR'd with one another. All that remains will be
6986      to cycle the high 8 bits by XOR'ing them all with the lower 8 bits
6987      afterwards.
6988
6989      At the same time we're populating sbox and isbox we can precompute
6990      the multiplication we'll need to do to do MixColumns() later.
6991    */
6992
6993    // apply affine transformation
6994    sx = ei ^ (ei << 1) ^ (ei << 2) ^ (ei << 3) ^ (ei << 4);
6995    sx = (sx >> 8) ^ (sx & 255) ^ 0x63;
6996
6997    // update tables
6998    sbox[e] = sx;
6999    isbox[sx] = e;
7000
7001    /* Mixing columns is done using matrix multiplication. The columns
7002      that are to be mixed are each a single word in the current state.
7003      The state has Nb columns (4 columns). Therefore each column is a
7004      4 byte word. So to mix the columns in a single column 'c' where
7005      its rows are r0, r1, r2, and r3, we use the following matrix
7006      multiplication:
7007
7008      [2 3 1 1]*[r0,c]=[r'0,c]
7009      [1 2 3 1] [r1,c] [r'1,c]
7010      [1 1 2 3] [r2,c] [r'2,c]
7011      [3 1 1 2] [r3,c] [r'3,c]
7012
7013      r0, r1, r2, and r3 are each 1 byte of one of the words in the
7014      state (a column). To do matrix multiplication for each mixed
7015      column c' we multiply the corresponding row from the left matrix
7016      with the corresponding column from the right matrix. In total, we
7017      get 4 equations:
7018
7019      r0,c' = 2*r0,c + 3*r1,c + 1*r2,c + 1*r3,c
7020      r1,c' = 1*r0,c + 2*r1,c + 3*r2,c + 1*r3,c
7021      r2,c' = 1*r0,c + 1*r1,c + 2*r2,c + 3*r3,c
7022      r3,c' = 3*r0,c + 1*r1,c + 1*r2,c + 2*r3,c
7023
7024      As usual, the multiplication is as previously defined and the
7025      addition is XOR. In order to optimize mixing columns we can store
7026      the multiplication results in tables. If you think of the whole
7027      column as a word (it might help to visualize by mentally rotating
7028      the equations above by counterclockwise 90 degrees) then you can
7029      see that it would be useful to map the multiplications performed on
7030      each byte (r0, r1, r2, r3) onto a word as well. For instance, we
7031      could map 2*r0,1*r0,1*r0,3*r0 onto a word by storing 2*r0 in the
7032      highest 8 bits and 3*r0 in the lowest 8 bits (with the other two
7033      respectively in the middle). This means that a table can be
7034      constructed that uses r0 as an index to the word. We can do the
7035      same with r1, r2, and r3, creating a total of 4 tables.
7036
7037      To construct a full c', we can just look up each byte of c in
7038      their respective tables and XOR the results together.
7039
7040      Also, to build each table we only have to calculate the word
7041      for 2,1,1,3 for every byte ... which we can do on each iteration
7042      of this loop since we will iterate over every byte. After we have
7043      calculated 2,1,1,3 we can get the results for the other tables
7044      by cycling the byte at the end to the beginning. For instance
7045      we can take the result of table 2,1,1,3 and produce table 3,2,1,1
7046      by moving the right most byte to the left most position just like
7047      how you can imagine the 3 moved out of 2,1,1,3 and to the front
7048      to produce 3,2,1,1.
7049
7050      There is another optimization in that the same multiples of
7051      the current element we need in order to advance our generator
7052      to the next iteration can be reused in performing the 2,1,1,3
7053      calculation. We also calculate the inverse mix column tables,
7054      with e,9,d,b being the inverse of 2,1,1,3.
7055
7056      When we're done, and we need to actually mix columns, the first
7057      byte of each state word should be put through mix[0] (2,1,1,3),
7058      the second through mix[1] (3,2,1,1) and so forth. Then they should
7059      be XOR'd together to produce the fully mixed column.
7060    */
7061
7062    // calculate mix and imix table values
7063    sx2 = xtime[sx];
7064    e2 = xtime[e];
7065    e4 = xtime[e2];
7066    e8 = xtime[e4];
7067    me =
7068      (sx2 << 24) ^  // 2
7069      (sx << 16) ^   // 1
7070      (sx << 8) ^    // 1
7071      (sx ^ sx2);    // 3
7072    ime =
7073      (e2 ^ e4 ^ e8) << 24 ^  // E (14)
7074      (e ^ e8) << 16 ^        // 9
7075      (e ^ e4 ^ e8) << 8 ^    // D (13)
7076      (e ^ e2 ^ e8);          // B (11)
7077    // produce each of the mix tables by rotating the 2,1,1,3 value
7078    for(var n = 0; n < 4; ++n) {
7079      mix[n][e] = me;
7080      imix[n][sx] = ime;
7081      // cycle the right most byte to the left most position
7082      // ie: 2,1,1,3 becomes 3,2,1,1
7083      me = me << 24 | me >>> 8;
7084      ime = ime << 24 | ime >>> 8;
7085    }
7086
7087    // get next element and inverse
7088    if(e === 0) {
7089      // 1 is the inverse of 1
7090      e = ei = 1;
7091    } else {
7092      // e = 2e + 2*2*2*(10e)) = multiply e by 82 (chosen generator)
7093      // ei = ei + 2*2*ei = multiply ei by 5 (inverse generator)
7094      e = e2 ^ xtime[xtime[xtime[e2 ^ e8]]];
7095      ei ^= xtime[xtime[ei]];
7096    }
7097  }
7098}
7099
7100/**
7101 * Generates a key schedule using the AES key expansion algorithm.
7102 *
7103 * The AES algorithm takes the Cipher Key, K, and performs a Key Expansion
7104 * routine to generate a key schedule. The Key Expansion generates a total
7105 * of Nb*(Nr + 1) words: the algorithm requires an initial set of Nb words,
7106 * and each of the Nr rounds requires Nb words of key data. The resulting
7107 * key schedule consists of a linear array of 4-byte words, denoted [wi ],
7108 * with i in the range 0 ? i < Nb(Nr + 1).
7109 *
7110 * KeyExpansion(byte key[4*Nk], word w[Nb*(Nr+1)], Nk)
7111 * AES-128 (Nb=4, Nk=4, Nr=10)
7112 * AES-192 (Nb=4, Nk=6, Nr=12)
7113 * AES-256 (Nb=4, Nk=8, Nr=14)
7114 * Note: Nr=Nk+6.
7115 *
7116 * Nb is the number of columns (32-bit words) comprising the State (or
7117 * number of bytes in a block). For AES, Nb=4.
7118 *
7119 * @param key the key to schedule (as an array of 32-bit words).
7120 * @param decrypt true to modify the key schedule to decrypt, false not to.
7121 *
7122 * @return the generated key schedule.
7123 */
7124function _expandKey(key, decrypt) {
7125  // copy the key's words to initialize the key schedule
7126  var w = key.slice(0);
7127
7128  /* RotWord() will rotate a word, moving the first byte to the last
7129    byte's position (shifting the other bytes left).
7130
7131    We will be getting the value of Rcon at i / Nk. 'i' will iterate
7132    from Nk to (Nb * Nr+1). Nk = 4 (4 byte key), Nb = 4 (4 words in
7133    a block), Nr = Nk + 6 (10). Therefore 'i' will iterate from
7134    4 to 44 (exclusive). Each time we iterate 4 times, i / Nk will
7135    increase by 1. We use a counter iNk to keep track of this.
7136   */
7137
7138  // go through the rounds expanding the key
7139  var temp, iNk = 1;
7140  var Nk = w.length;
7141  var Nr1 = Nk + 6 + 1;
7142  var end = Nb * Nr1;
7143  for(var i = Nk; i < end; ++i) {
7144    temp = w[i - 1];
7145    if(i % Nk === 0) {
7146      // temp = SubWord(RotWord(temp)) ^ Rcon[i / Nk]
7147      temp =
7148        sbox[temp >>> 16 & 255] << 24 ^
7149        sbox[temp >>> 8 & 255] << 16 ^
7150        sbox[temp & 255] << 8 ^
7151        sbox[temp >>> 24] ^ (rcon[iNk] << 24);
7152      iNk++;
7153    } else if(Nk > 6 && (i % Nk === 4)) {
7154      // temp = SubWord(temp)
7155      temp =
7156        sbox[temp >>> 24] << 24 ^
7157        sbox[temp >>> 16 & 255] << 16 ^
7158        sbox[temp >>> 8 & 255] << 8 ^
7159        sbox[temp & 255];
7160    }
7161    w[i] = w[i - Nk] ^ temp;
7162  }
7163
7164   /* When we are updating a cipher block we always use the code path for
7165     encryption whether we are decrypting or not (to shorten code and
7166     simplify the generation of look up tables). However, because there
7167     are differences in the decryption algorithm, other than just swapping
7168     in different look up tables, we must transform our key schedule to
7169     account for these changes:
7170
7171     1. The decryption algorithm gets its key rounds in reverse order.
7172     2. The decryption algorithm adds the round key before mixing columns
7173       instead of afterwards.
7174
7175     We don't need to modify our key schedule to handle the first case,
7176     we can just traverse the key schedule in reverse order when decrypting.
7177
7178     The second case requires a little work.
7179
7180     The tables we built for performing rounds will take an input and then
7181     perform SubBytes() and MixColumns() or, for the decrypt version,
7182     InvSubBytes() and InvMixColumns(). But the decrypt algorithm requires
7183     us to AddRoundKey() before InvMixColumns(). This means we'll need to
7184     apply some transformations to the round key to inverse-mix its columns
7185     so they'll be correct for moving AddRoundKey() to after the state has
7186     had its columns inverse-mixed.
7187
7188     To inverse-mix the columns of the state when we're decrypting we use a
7189     lookup table that will apply InvSubBytes() and InvMixColumns() at the
7190     same time. However, the round key's bytes are not inverse-substituted
7191     in the decryption algorithm. To get around this problem, we can first
7192     substitute the bytes in the round key so that when we apply the
7193     transformation via the InvSubBytes()+InvMixColumns() table, it will
7194     undo our substitution leaving us with the original value that we
7195     want -- and then inverse-mix that value.
7196
7197     This change will correctly alter our key schedule so that we can XOR
7198     each round key with our already transformed decryption state. This
7199     allows us to use the same code path as the encryption algorithm.
7200
7201     We make one more change to the decryption key. Since the decryption
7202     algorithm runs in reverse from the encryption algorithm, we reverse
7203     the order of the round keys to avoid having to iterate over the key
7204     schedule backwards when running the encryption algorithm later in
7205     decryption mode. In addition to reversing the order of the round keys,
7206     we also swap each round key's 2nd and 4th rows. See the comments
7207     section where rounds are performed for more details about why this is
7208     done. These changes are done inline with the other substitution
7209     described above.
7210  */
7211  if(decrypt) {
7212    var tmp;
7213    var m0 = imix[0];
7214    var m1 = imix[1];
7215    var m2 = imix[2];
7216    var m3 = imix[3];
7217    var wnew = w.slice(0);
7218    end = w.length;
7219    for(var i = 0, wi = end - Nb; i < end; i += Nb, wi -= Nb) {
7220      // do not sub the first or last round key (round keys are Nb
7221      // words) as no column mixing is performed before they are added,
7222      // but do change the key order
7223      if(i === 0 || i === (end - Nb)) {
7224        wnew[i] = w[wi];
7225        wnew[i + 1] = w[wi + 3];
7226        wnew[i + 2] = w[wi + 2];
7227        wnew[i + 3] = w[wi + 1];
7228      } else {
7229        // substitute each round key byte because the inverse-mix
7230        // table will inverse-substitute it (effectively cancel the
7231        // substitution because round key bytes aren't sub'd in
7232        // decryption mode) and swap indexes 3 and 1
7233        for(var n = 0; n < Nb; ++n) {
7234          tmp = w[wi + n];
7235          wnew[i + (3&-n)] =
7236            m0[sbox[tmp >>> 24]] ^
7237            m1[sbox[tmp >>> 16 & 255]] ^
7238            m2[sbox[tmp >>> 8 & 255]] ^
7239            m3[sbox[tmp & 255]];
7240        }
7241      }
7242    }
7243    w = wnew;
7244  }
7245
7246  return w;
7247}
7248
7249/**
7250 * Updates a single block (16 bytes) using AES. The update will either
7251 * encrypt or decrypt the block.
7252 *
7253 * @param w the key schedule.
7254 * @param input the input block (an array of 32-bit words).
7255 * @param output the updated output block.
7256 * @param decrypt true to decrypt the block, false to encrypt it.
7257 */
7258function _updateBlock(w, input, output, decrypt) {
7259  /*
7260  Cipher(byte in[4*Nb], byte out[4*Nb], word w[Nb*(Nr+1)])
7261  begin
7262    byte state[4,Nb]
7263    state = in
7264    AddRoundKey(state, w[0, Nb-1])
7265    for round = 1 step 1 to Nr�1
7266      SubBytes(state)
7267      ShiftRows(state)
7268      MixColumns(state)
7269      AddRoundKey(state, w[round*Nb, (round+1)*Nb-1])
7270    end for
7271    SubBytes(state)
7272    ShiftRows(state)
7273    AddRoundKey(state, w[Nr*Nb, (Nr+1)*Nb-1])
7274    out = state
7275  end
7276
7277  InvCipher(byte in[4*Nb], byte out[4*Nb], word w[Nb*(Nr+1)])
7278  begin
7279    byte state[4,Nb]
7280    state = in
7281    AddRoundKey(state, w[Nr*Nb, (Nr+1)*Nb-1])
7282    for round = Nr-1 step -1 downto 1
7283      InvShiftRows(state)
7284      InvSubBytes(state)
7285      AddRoundKey(state, w[round*Nb, (round+1)*Nb-1])
7286      InvMixColumns(state)
7287    end for
7288    InvShiftRows(state)
7289    InvSubBytes(state)
7290    AddRoundKey(state, w[0, Nb-1])
7291    out = state
7292  end
7293  */
7294
7295  // Encrypt: AddRoundKey(state, w[0, Nb-1])
7296  // Decrypt: AddRoundKey(state, w[Nr*Nb, (Nr+1)*Nb-1])
7297  var Nr = w.length / 4 - 1;
7298  var m0, m1, m2, m3, sub;
7299  if(decrypt) {
7300    m0 = imix[0];
7301    m1 = imix[1];
7302    m2 = imix[2];
7303    m3 = imix[3];
7304    sub = isbox;
7305  } else {
7306    m0 = mix[0];
7307    m1 = mix[1];
7308    m2 = mix[2];
7309    m3 = mix[3];
7310    sub = sbox;
7311  }
7312  var a, b, c, d, a2, b2, c2;
7313  a = input[0] ^ w[0];
7314  b = input[decrypt ? 3 : 1] ^ w[1];
7315  c = input[2] ^ w[2];
7316  d = input[decrypt ? 1 : 3] ^ w[3];
7317  var i = 3;
7318
7319  /* In order to share code we follow the encryption algorithm when both
7320    encrypting and decrypting. To account for the changes required in the
7321    decryption algorithm, we use different lookup tables when decrypting
7322    and use a modified key schedule to account for the difference in the
7323    order of transformations applied when performing rounds. We also get
7324    key rounds in reverse order (relative to encryption). */
7325  for(var round = 1; round < Nr; ++round) {
7326    /* As described above, we'll be using table lookups to perform the
7327      column mixing. Each column is stored as a word in the state (the
7328      array 'input' has one column as a word at each index). In order to
7329      mix a column, we perform these transformations on each row in c,
7330      which is 1 byte in each word. The new column for c0 is c'0:
7331
7332               m0      m1      m2      m3
7333      r0,c'0 = 2*r0,c0 + 3*r1,c0 + 1*r2,c0 + 1*r3,c0
7334      r1,c'0 = 1*r0,c0 + 2*r1,c0 + 3*r2,c0 + 1*r3,c0
7335      r2,c'0 = 1*r0,c0 + 1*r1,c0 + 2*r2,c0 + 3*r3,c0
7336      r3,c'0 = 3*r0,c0 + 1*r1,c0 + 1*r2,c0 + 2*r3,c0
7337
7338      So using mix tables where c0 is a word with r0 being its upper
7339      8 bits and r3 being its lower 8 bits:
7340
7341      m0[c0 >> 24] will yield this word: [2*r0,1*r0,1*r0,3*r0]
7342      ...
7343      m3[c0 & 255] will yield this word: [1*r3,1*r3,3*r3,2*r3]
7344
7345      Therefore to mix the columns in each word in the state we
7346      do the following (& 255 omitted for brevity):
7347      c'0,r0 = m0[c0 >> 24] ^ m1[c1 >> 16] ^ m2[c2 >> 8] ^ m3[c3]
7348      c'0,r1 = m0[c0 >> 24] ^ m1[c1 >> 16] ^ m2[c2 >> 8] ^ m3[c3]
7349      c'0,r2 = m0[c0 >> 24] ^ m1[c1 >> 16] ^ m2[c2 >> 8] ^ m3[c3]
7350      c'0,r3 = m0[c0 >> 24] ^ m1[c1 >> 16] ^ m2[c2 >> 8] ^ m3[c3]
7351
7352      However, before mixing, the algorithm requires us to perform
7353      ShiftRows(). The ShiftRows() transformation cyclically shifts the
7354      last 3 rows of the state over different offsets. The first row
7355      (r = 0) is not shifted.
7356
7357      s'_r,c = s_r,(c + shift(r, Nb) mod Nb
7358      for 0 < r < 4 and 0 <= c < Nb and
7359      shift(1, 4) = 1
7360      shift(2, 4) = 2
7361      shift(3, 4) = 3.
7362
7363      This causes the first byte in r = 1 to be moved to the end of
7364      the row, the first 2 bytes in r = 2 to be moved to the end of
7365      the row, the first 3 bytes in r = 3 to be moved to the end of
7366      the row:
7367
7368      r1: [c0 c1 c2 c3] => [c1 c2 c3 c0]
7369      r2: [c0 c1 c2 c3]    [c2 c3 c0 c1]
7370      r3: [c0 c1 c2 c3]    [c3 c0 c1 c2]
7371
7372      We can make these substitutions inline with our column mixing to
7373      generate an updated set of equations to produce each word in the
7374      state (note the columns have changed positions):
7375
7376      c0 c1 c2 c3 => c0 c1 c2 c3
7377      c0 c1 c2 c3    c1 c2 c3 c0  (cycled 1 byte)
7378      c0 c1 c2 c3    c2 c3 c0 c1  (cycled 2 bytes)
7379      c0 c1 c2 c3    c3 c0 c1 c2  (cycled 3 bytes)
7380
7381      Therefore:
7382
7383      c'0 = 2*r0,c0 + 3*r1,c1 + 1*r2,c2 + 1*r3,c3
7384      c'0 = 1*r0,c0 + 2*r1,c1 + 3*r2,c2 + 1*r3,c3
7385      c'0 = 1*r0,c0 + 1*r1,c1 + 2*r2,c2 + 3*r3,c3
7386      c'0 = 3*r0,c0 + 1*r1,c1 + 1*r2,c2 + 2*r3,c3
7387
7388      c'1 = 2*r0,c1 + 3*r1,c2 + 1*r2,c3 + 1*r3,c0
7389      c'1 = 1*r0,c1 + 2*r1,c2 + 3*r2,c3 + 1*r3,c0
7390      c'1 = 1*r0,c1 + 1*r1,c2 + 2*r2,c3 + 3*r3,c0
7391      c'1 = 3*r0,c1 + 1*r1,c2 + 1*r2,c3 + 2*r3,c0
7392
7393      ... and so forth for c'2 and c'3. The important distinction is
7394      that the columns are cycling, with c0 being used with the m0
7395      map when calculating c0, but c1 being used with the m0 map when
7396      calculating c1 ... and so forth.
7397
7398      When performing the inverse we transform the mirror image and
7399      skip the bottom row, instead of the top one, and move upwards:
7400
7401      c3 c2 c1 c0 => c0 c3 c2 c1  (cycled 3 bytes) *same as encryption
7402      c3 c2 c1 c0    c1 c0 c3 c2  (cycled 2 bytes)
7403      c3 c2 c1 c0    c2 c1 c0 c3  (cycled 1 byte)  *same as encryption
7404      c3 c2 c1 c0    c3 c2 c1 c0
7405
7406      If you compare the resulting matrices for ShiftRows()+MixColumns()
7407      and for InvShiftRows()+InvMixColumns() the 2nd and 4th columns are
7408      different (in encrypt mode vs. decrypt mode). So in order to use
7409      the same code to handle both encryption and decryption, we will
7410      need to do some mapping.
7411
7412      If in encryption mode we let a=c0, b=c1, c=c2, d=c3, and r<N> be
7413      a row number in the state, then the resulting matrix in encryption
7414      mode for applying the above transformations would be:
7415
7416      r1: a b c d
7417      r2: b c d a
7418      r3: c d a b
7419      r4: d a b c
7420
7421      If we did the same in decryption mode we would get:
7422
7423      r1: a d c b
7424      r2: b a d c
7425      r3: c b a d
7426      r4: d c b a
7427
7428      If instead we swap d and b (set b=c3 and d=c1), then we get:
7429
7430      r1: a b c d
7431      r2: d a b c
7432      r3: c d a b
7433      r4: b c d a
7434
7435      Now the 1st and 3rd rows are the same as the encryption matrix. All
7436      we need to do then to make the mapping exactly the same is to swap
7437      the 2nd and 4th rows when in decryption mode. To do this without
7438      having to do it on each iteration, we swapped the 2nd and 4th rows
7439      in the decryption key schedule. We also have to do the swap above
7440      when we first pull in the input and when we set the final output. */
7441    a2 =
7442      m0[a >>> 24] ^
7443      m1[b >>> 16 & 255] ^
7444      m2[c >>> 8 & 255] ^
7445      m3[d & 255] ^ w[++i];
7446    b2 =
7447      m0[b >>> 24] ^
7448      m1[c >>> 16 & 255] ^
7449      m2[d >>> 8 & 255] ^
7450      m3[a & 255] ^ w[++i];
7451    c2 =
7452      m0[c >>> 24] ^
7453      m1[d >>> 16 & 255] ^
7454      m2[a >>> 8 & 255] ^
7455      m3[b & 255] ^ w[++i];
7456    d =
7457      m0[d >>> 24] ^
7458      m1[a >>> 16 & 255] ^
7459      m2[b >>> 8 & 255] ^
7460      m3[c & 255] ^ w[++i];
7461    a = a2;
7462    b = b2;
7463    c = c2;
7464  }
7465
7466  /*
7467    Encrypt:
7468    SubBytes(state)
7469    ShiftRows(state)
7470    AddRoundKey(state, w[Nr*Nb, (Nr+1)*Nb-1])
7471
7472    Decrypt:
7473    InvShiftRows(state)
7474    InvSubBytes(state)
7475    AddRoundKey(state, w[0, Nb-1])
7476   */
7477   // Note: rows are shifted inline
7478  output[0] =
7479    (sub[a >>> 24] << 24) ^
7480    (sub[b >>> 16 & 255] << 16) ^
7481    (sub[c >>> 8 & 255] << 8) ^
7482    (sub[d & 255]) ^ w[++i];
7483  output[decrypt ? 3 : 1] =
7484    (sub[b >>> 24] << 24) ^
7485    (sub[c >>> 16 & 255] << 16) ^
7486    (sub[d >>> 8 & 255] << 8) ^
7487    (sub[a & 255]) ^ w[++i];
7488  output[2] =
7489    (sub[c >>> 24] << 24) ^
7490    (sub[d >>> 16 & 255] << 16) ^
7491    (sub[a >>> 8 & 255] << 8) ^
7492    (sub[b & 255]) ^ w[++i];
7493  output[decrypt ? 1 : 3] =
7494    (sub[d >>> 24] << 24) ^
7495    (sub[a >>> 16 & 255] << 16) ^
7496    (sub[b >>> 8 & 255] << 8) ^
7497    (sub[c & 255]) ^ w[++i];
7498}
7499
7500/**
7501 * Deprecated. Instead, use:
7502 *
7503 * forge.cipher.createCipher('AES-<mode>', key);
7504 * forge.cipher.createDecipher('AES-<mode>', key);
7505 *
7506 * Creates a deprecated AES cipher object. This object's mode will default to
7507 * CBC (cipher-block-chaining).
7508 *
7509 * The key and iv may be given as a string of bytes, an array of bytes, a
7510 * byte buffer, or an array of 32-bit words.
7511 *
7512 * @param options the options to use.
7513 *          key the symmetric key to use.
7514 *          output the buffer to write to.
7515 *          decrypt true for decryption, false for encryption.
7516 *          mode the cipher mode to use (default: 'CBC').
7517 *
7518 * @return the cipher.
7519 */
7520function _createCipher(options) {
7521  options = options || {};
7522  var mode = (options.mode || 'CBC').toUpperCase();
7523  var algorithm = 'AES-' + mode;
7524
7525  var cipher;
7526  if(options.decrypt) {
7527    cipher = forge.cipher.createDecipher(algorithm, options.key);
7528  } else {
7529    cipher = forge.cipher.createCipher(algorithm, options.key);
7530  }
7531
7532  // backwards compatible start API
7533  var start = cipher.start;
7534  cipher.start = function(iv, options) {
7535    // backwards compatibility: support second arg as output buffer
7536    var output = null;
7537    if(options instanceof forge.util.ByteBuffer) {
7538      output = options;
7539      options = {};
7540    }
7541    options = options || {};
7542    options.output = output;
7543    options.iv = iv;
7544    start.call(cipher, options);
7545  };
7546
7547  return cipher;
7548}
7549
7550} // end module implementation
7551
7552/* ########## Begin module wrapper ########## */
7553var name = 'aes';
7554if(typeof define !== 'function') {
7555  // NodeJS -> AMD
7556  if(typeof module === 'object' && module.exports) {
7557    var nodeJS = true;
7558    define = function(ids, factory) {
7559      factory(require, module);
7560    };
7561  } else {
7562    // <script>
7563    if(typeof forge === 'undefined') {
7564      forge = {};
7565    }
7566    return initModule(forge);
7567  }
7568}
7569// AMD
7570var deps;
7571var defineFunc = function(require, module) {
7572  module.exports = function(forge) {
7573    var mods = deps.map(function(dep) {
7574      return require(dep);
7575    }).concat(initModule);
7576    // handle circular dependencies
7577    forge = forge || {};
7578    forge.defined = forge.defined || {};
7579    if(forge.defined[name]) {
7580      return forge[name];
7581    }
7582    forge.defined[name] = true;
7583    for(var i = 0; i < mods.length; ++i) {
7584      mods[i](forge);
7585    }
7586    return forge[name];
7587  };
7588};
7589var tmpDefine = define;
7590define = function(ids, factory) {
7591  deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2);
7592  if(nodeJS) {
7593    delete define;
7594    return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0));
7595  }
7596  define = tmpDefine;
7597  return define.apply(null, Array.prototype.slice.call(arguments, 0));
7598};
7599define(
7600  ['require', 'module', './cipher', './cipherModes', './util'], function() {
7601  defineFunc.apply(null, Array.prototype.slice.call(arguments, 0));
7602});
7603})();
7604
7605/**
7606 * A javascript implementation of a cryptographically-secure
7607 * Pseudo Random Number Generator (PRNG). The Fortuna algorithm is followed
7608 * here though the use of SHA-256 is not enforced; when generating an
7609 * a PRNG context, the hashing algorithm and block cipher used for
7610 * the generator are specified via a plugin.
7611 *
7612 * @author Dave Longley
7613 *
7614 * Copyright (c) 2010-2014 Digital Bazaar, Inc.
7615 */
7616(function() {
7617/* ########## Begin module implementation ########## */
7618function initModule(forge) {
7619
7620var _nodejs = (
7621  typeof process !== 'undefined' && process.versions && process.versions.node);
7622var _crypto = null;
7623if(!forge.disableNativeCode && _nodejs && !process.versions['node-webkit']) {
7624  _crypto = require('crypto');
7625}
7626
7627/* PRNG API */
7628var prng = forge.prng = forge.prng || {};
7629
7630/**
7631 * Creates a new PRNG context.
7632 *
7633 * A PRNG plugin must be passed in that will provide:
7634 *
7635 * 1. A function that initializes the key and seed of a PRNG context. It
7636 *   will be given a 16 byte key and a 16 byte seed. Any key expansion
7637 *   or transformation of the seed from a byte string into an array of
7638 *   integers (or similar) should be performed.
7639 * 2. The cryptographic function used by the generator. It takes a key and
7640 *   a seed.
7641 * 3. A seed increment function. It takes the seed and returns seed + 1.
7642 * 4. An api to create a message digest.
7643 *
7644 * For an example, see random.js.
7645 *
7646 * @param plugin the PRNG plugin to use.
7647 */
7648prng.create = function(plugin) {
7649  var ctx = {
7650    plugin: plugin,
7651    key: null,
7652    seed: null,
7653    time: null,
7654    // number of reseeds so far
7655    reseeds: 0,
7656    // amount of data generated so far
7657    generated: 0
7658  };
7659
7660  // create 32 entropy pools (each is a message digest)
7661  var md = plugin.md;
7662  var pools = new Array(32);
7663  for(var i = 0; i < 32; ++i) {
7664    pools[i] = md.create();
7665  }
7666  ctx.pools = pools;
7667
7668  // entropy pools are written to cyclically, starting at index 0
7669  ctx.pool = 0;
7670
7671  /**
7672   * Generates random bytes. The bytes may be generated synchronously or
7673   * asynchronously. Web workers must use the asynchronous interface or
7674   * else the behavior is undefined.
7675   *
7676   * @param count the number of random bytes to generate.
7677   * @param [callback(err, bytes)] called once the operation completes.
7678   *
7679   * @return count random bytes as a string.
7680   */
7681  ctx.generate = function(count, callback) {
7682    // do synchronously
7683    if(!callback) {
7684      return ctx.generateSync(count);
7685    }
7686
7687    // simple generator using counter-based CBC
7688    var cipher = ctx.plugin.cipher;
7689    var increment = ctx.plugin.increment;
7690    var formatKey = ctx.plugin.formatKey;
7691    var formatSeed = ctx.plugin.formatSeed;
7692    var b = forge.util.createBuffer();
7693
7694    // reset key for every request
7695    ctx.key = null;
7696
7697    generate();
7698
7699    function generate(err) {
7700      if(err) {
7701        return callback(err);
7702      }
7703
7704      // sufficient bytes generated
7705      if(b.length() >= count) {
7706        return callback(null, b.getBytes(count));
7707      }
7708
7709      // if amount of data generated is greater than 1 MiB, trigger reseed
7710      if(ctx.generated > 0xfffff) {
7711        ctx.key = null;
7712      }
7713
7714      if(ctx.key === null) {
7715        // prevent stack overflow
7716        return forge.util.nextTick(function() {
7717          _reseed(generate);
7718        });
7719      }
7720
7721      // generate the random bytes
7722      var bytes = cipher(ctx.key, ctx.seed);
7723      ctx.generated += bytes.length;
7724      b.putBytes(bytes);
7725
7726      // generate bytes for a new key and seed
7727      ctx.key = formatKey(cipher(ctx.key, increment(ctx.seed)));
7728      ctx.seed = formatSeed(cipher(ctx.key, ctx.seed));
7729
7730      forge.util.setImmediate(generate);
7731    }
7732  };
7733
7734  /**
7735   * Generates random bytes synchronously.
7736   *
7737   * @param count the number of random bytes to generate.
7738   *
7739   * @return count random bytes as a string.
7740   */
7741  ctx.generateSync = function(count) {
7742    // simple generator using counter-based CBC
7743    var cipher = ctx.plugin.cipher;
7744    var increment = ctx.plugin.increment;
7745    var formatKey = ctx.plugin.formatKey;
7746    var formatSeed = ctx.plugin.formatSeed;
7747
7748    // reset key for every request
7749    ctx.key = null;
7750
7751    var b = forge.util.createBuffer();
7752    while(b.length() < count) {
7753      // if amount of data generated is greater than 1 MiB, trigger reseed
7754      if(ctx.generated > 0xfffff) {
7755        ctx.key = null;
7756      }
7757
7758      if(ctx.key === null) {
7759        _reseedSync();
7760      }
7761
7762      // generate the random bytes
7763      var bytes = cipher(ctx.key, ctx.seed);
7764      ctx.generated += bytes.length;
7765      b.putBytes(bytes);
7766
7767      // generate bytes for a new key and seed
7768      ctx.key = formatKey(cipher(ctx.key, increment(ctx.seed)));
7769      ctx.seed = formatSeed(cipher(ctx.key, ctx.seed));
7770    }
7771
7772    return b.getBytes(count);
7773  };
7774
7775  /**
7776   * Private function that asynchronously reseeds a generator.
7777   *
7778   * @param callback(err) called once the operation completes.
7779   */
7780  function _reseed(callback) {
7781    if(ctx.pools[0].messageLength >= 32) {
7782      _seed();
7783      return callback();
7784    }
7785    // not enough seed data...
7786    var needed = (32 - ctx.pools[0].messageLength) << 5;
7787    ctx.seedFile(needed, function(err, bytes) {
7788      if(err) {
7789        return callback(err);
7790      }
7791      ctx.collect(bytes);
7792      _seed();
7793      callback();
7794    });
7795  }
7796
7797  /**
7798   * Private function that synchronously reseeds a generator.
7799   */
7800  function _reseedSync() {
7801    if(ctx.pools[0].messageLength >= 32) {
7802      return _seed();
7803    }
7804    // not enough seed data...
7805    var needed = (32 - ctx.pools[0].messageLength) << 5;
7806    ctx.collect(ctx.seedFileSync(needed));
7807    _seed();
7808  }
7809
7810  /**
7811   * Private function that seeds a generator once enough bytes are available.
7812   */
7813  function _seed() {
7814    // create a plugin-based message digest
7815    var md = ctx.plugin.md.create();
7816
7817    // digest pool 0's entropy and restart it
7818    md.update(ctx.pools[0].digest().getBytes());
7819    ctx.pools[0].start();
7820
7821    // digest the entropy of other pools whose index k meet the
7822    // condition '2^k mod n == 0' where n is the number of reseeds
7823    var k = 1;
7824    for(var i = 1; i < 32; ++i) {
7825      // prevent signed numbers from being used
7826      k = (k === 31) ? 0x80000000 : (k << 2);
7827      if(k % ctx.reseeds === 0) {
7828        md.update(ctx.pools[i].digest().getBytes());
7829        ctx.pools[i].start();
7830      }
7831    }
7832
7833    // get digest for key bytes and iterate again for seed bytes
7834    var keyBytes = md.digest().getBytes();
7835    md.start();
7836    md.update(keyBytes);
7837    var seedBytes = md.digest().getBytes();
7838
7839    // update
7840    ctx.key = ctx.plugin.formatKey(keyBytes);
7841    ctx.seed = ctx.plugin.formatSeed(seedBytes);
7842    ctx.reseeds = (ctx.reseeds === 0xffffffff) ? 0 : ctx.reseeds + 1;
7843    ctx.generated = 0;
7844  }
7845
7846  /**
7847   * The built-in default seedFile. This seedFile is used when entropy
7848   * is needed immediately.
7849   *
7850   * @param needed the number of bytes that are needed.
7851   *
7852   * @return the random bytes.
7853   */
7854  function defaultSeedFile(needed) {
7855    // use window.crypto.getRandomValues strong source of entropy if available
7856    var getRandomValues = null;
7857    if(typeof window !== 'undefined') {
7858      var _crypto = window.crypto || window.msCrypto;
7859      if(_crypto && _crypto.getRandomValues) {
7860        getRandomValues = function(arr) {
7861          return _crypto.getRandomValues(arr);
7862        };
7863      }
7864    }
7865
7866    var b = forge.util.createBuffer();
7867    if(getRandomValues) {
7868      while(b.length() < needed) {
7869        // max byte length is 65536 before QuotaExceededError is thrown
7870        // http://www.w3.org/TR/WebCryptoAPI/#RandomSource-method-getRandomValues
7871        var count = Math.max(1, Math.min(needed - b.length(), 65536) / 4);
7872        var entropy = new Uint32Array(Math.floor(count));
7873        try {
7874          getRandomValues(entropy);
7875          for(var i = 0; i < entropy.length; ++i) {
7876            b.putInt32(entropy[i]);
7877          }
7878        } catch(e) {
7879          /* only ignore QuotaExceededError */
7880          if(!(typeof QuotaExceededError !== 'undefined' &&
7881            e instanceof QuotaExceededError)) {
7882            throw e;
7883          }
7884        }
7885      }
7886    }
7887
7888    // be sad and add some weak random data
7889    if(b.length() < needed) {
7890      /* Draws from Park-Miller "minimal standard" 31 bit PRNG,
7891      implemented with David G. Carta's optimization: with 32 bit math
7892      and without division (Public Domain). */
7893      var hi, lo, next;
7894      var seed = Math.floor(Math.random() * 0x010000);
7895      while(b.length() < needed) {
7896        lo = 16807 * (seed & 0xFFFF);
7897        hi = 16807 * (seed >> 16);
7898        lo += (hi & 0x7FFF) << 16;
7899        lo += hi >> 15;
7900        lo = (lo & 0x7FFFFFFF) + (lo >> 31);
7901        seed = lo & 0xFFFFFFFF;
7902
7903        // consume lower 3 bytes of seed
7904        for(var i = 0; i < 3; ++i) {
7905          // throw in more pseudo random
7906          next = seed >>> (i << 3);
7907          next ^= Math.floor(Math.random() * 0x0100);
7908          b.putByte(String.fromCharCode(next & 0xFF));
7909        }
7910      }
7911    }
7912
7913    return b.getBytes(needed);
7914  }
7915  // initialize seed file APIs
7916  if(_crypto) {
7917    // use nodejs async API
7918    ctx.seedFile = function(needed, callback) {
7919      _crypto.randomBytes(needed, function(err, bytes) {
7920        if(err) {
7921          return callback(err);
7922        }
7923        callback(null, bytes.toString());
7924      });
7925    };
7926    // use nodejs sync API
7927    ctx.seedFileSync = function(needed) {
7928      return _crypto.randomBytes(needed).toString();
7929    };
7930  } else {
7931    ctx.seedFile = function(needed, callback) {
7932      try {
7933        callback(null, defaultSeedFile(needed));
7934      } catch(e) {
7935        callback(e);
7936      }
7937    };
7938    ctx.seedFileSync = defaultSeedFile;
7939  }
7940
7941  /**
7942   * Adds entropy to a prng ctx's accumulator.
7943   *
7944   * @param bytes the bytes of entropy as a string.
7945   */
7946  ctx.collect = function(bytes) {
7947    // iterate over pools distributing entropy cyclically
7948    var count = bytes.length;
7949    for(var i = 0; i < count; ++i) {
7950      ctx.pools[ctx.pool].update(bytes.substr(i, 1));
7951      ctx.pool = (ctx.pool === 31) ? 0 : ctx.pool + 1;
7952    }
7953  };
7954
7955  /**
7956   * Collects an integer of n bits.
7957   *
7958   * @param i the integer entropy.
7959   * @param n the number of bits in the integer.
7960   */
7961  ctx.collectInt = function(i, n) {
7962    var bytes = '';
7963    for(var x = 0; x < n; x += 8) {
7964      bytes += String.fromCharCode((i >> x) & 0xFF);
7965    }
7966    ctx.collect(bytes);
7967  };
7968
7969  /**
7970   * Registers a Web Worker to receive immediate entropy from the main thread.
7971   * This method is required until Web Workers can access the native crypto
7972   * API. This method should be called twice for each created worker, once in
7973   * the main thread, and once in the worker itself.
7974   *
7975   * @param worker the worker to register.
7976   */
7977  ctx.registerWorker = function(worker) {
7978    // worker receives random bytes
7979    if(worker === self) {
7980      ctx.seedFile = function(needed, callback) {
7981        function listener(e) {
7982          var data = e.data;
7983          if(data.forge && data.forge.prng) {
7984            self.removeEventListener('message', listener);
7985            callback(data.forge.prng.err, data.forge.prng.bytes);
7986          }
7987        }
7988        self.addEventListener('message', listener);
7989        self.postMessage({forge: {prng: {needed: needed}}});
7990      };
7991    } else {
7992      // main thread sends random bytes upon request
7993      var listener = function(e) {
7994        var data = e.data;
7995        if(data.forge && data.forge.prng) {
7996          ctx.seedFile(data.forge.prng.needed, function(err, bytes) {
7997            worker.postMessage({forge: {prng: {err: err, bytes: bytes}}});
7998          });
7999        }
8000      };
8001      // TODO: do we need to remove the event listener when the worker dies?
8002      worker.addEventListener('message', listener);
8003    }
8004  };
8005
8006  return ctx;
8007};
8008
8009} // end module implementation
8010
8011/* ########## Begin module wrapper ########## */
8012var name = 'prng';
8013if(typeof define !== 'function') {
8014  // NodeJS -> AMD
8015  if(typeof module === 'object' && module.exports) {
8016    var nodeJS = true;
8017    define = function(ids, factory) {
8018      factory(require, module);
8019    };
8020  } else {
8021    // <script>
8022    if(typeof forge === 'undefined') {
8023      forge = {};
8024    }
8025    return initModule(forge);
8026  }
8027}
8028// AMD
8029var deps;
8030var defineFunc = function(require, module) {
8031  module.exports = function(forge) {
8032    var mods = deps.map(function(dep) {
8033      return require(dep);
8034    }).concat(initModule);
8035    // handle circular dependencies
8036    forge = forge || {};
8037    forge.defined = forge.defined || {};
8038    if(forge.defined[name]) {
8039      return forge[name];
8040    }
8041    forge.defined[name] = true;
8042    for(var i = 0; i < mods.length; ++i) {
8043      mods[i](forge);
8044    }
8045    return forge[name];
8046  };
8047};
8048var tmpDefine = define;
8049define = function(ids, factory) {
8050  deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2);
8051  if(nodeJS) {
8052    delete define;
8053    return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0));
8054  }
8055  define = tmpDefine;
8056  return define.apply(null, Array.prototype.slice.call(arguments, 0));
8057};
8058define(['require', 'module', './md', './util'], function() {
8059  defineFunc.apply(null, Array.prototype.slice.call(arguments, 0));
8060});
8061
8062})();
8063
8064/**
8065 * An API for getting cryptographically-secure random bytes. The bytes are
8066 * generated using the Fortuna algorithm devised by Bruce Schneier and
8067 * Niels Ferguson.
8068 *
8069 * Getting strong random bytes is not yet easy to do in javascript. The only
8070 * truish random entropy that can be collected is from the mouse, keyboard, or
8071 * from timing with respect to page loads, etc. This generator makes a poor
8072 * attempt at providing random bytes when those sources haven't yet provided
8073 * enough entropy to initially seed or to reseed the PRNG.
8074 *
8075 * @author Dave Longley
8076 *
8077 * Copyright (c) 2009-2014 Digital Bazaar, Inc.
8078 */
8079(function() {
8080/* ########## Begin module implementation ########## */
8081function initModule(forge) {
8082
8083// forge.random already defined
8084if(forge.random && forge.random.getBytes) {
8085  return;
8086}
8087
8088(function(jQuery) {
8089
8090// the default prng plugin, uses AES-128
8091var prng_aes = {};
8092var _prng_aes_output = new Array(4);
8093var _prng_aes_buffer = forge.util.createBuffer();
8094prng_aes.formatKey = function(key) {
8095  // convert the key into 32-bit integers
8096  var tmp = forge.util.createBuffer(key);
8097  key = new Array(4);
8098  key[0] = tmp.getInt32();
8099  key[1] = tmp.getInt32();
8100  key[2] = tmp.getInt32();
8101  key[3] = tmp.getInt32();
8102
8103  // return the expanded key
8104  return forge.aes._expandKey(key, false);
8105};
8106prng_aes.formatSeed = function(seed) {
8107  // convert seed into 32-bit integers
8108  var tmp = forge.util.createBuffer(seed);
8109  seed = new Array(4);
8110  seed[0] = tmp.getInt32();
8111  seed[1] = tmp.getInt32();
8112  seed[2] = tmp.getInt32();
8113  seed[3] = tmp.getInt32();
8114  return seed;
8115};
8116prng_aes.cipher = function(key, seed) {
8117  forge.aes._updateBlock(key, seed, _prng_aes_output, false);
8118  _prng_aes_buffer.putInt32(_prng_aes_output[0]);
8119  _prng_aes_buffer.putInt32(_prng_aes_output[1]);
8120  _prng_aes_buffer.putInt32(_prng_aes_output[2]);
8121  _prng_aes_buffer.putInt32(_prng_aes_output[3]);
8122  return _prng_aes_buffer.getBytes();
8123};
8124prng_aes.increment = function(seed) {
8125  // FIXME: do we care about carry or signed issues?
8126  ++seed[3];
8127  return seed;
8128};
8129prng_aes.md = forge.md.sha256;
8130
8131/**
8132 * Creates a new PRNG.
8133 */
8134function spawnPrng() {
8135  var ctx = forge.prng.create(prng_aes);
8136
8137  /**
8138   * Gets random bytes. If a native secure crypto API is unavailable, this
8139   * method tries to make the bytes more unpredictable by drawing from data that
8140   * can be collected from the user of the browser, eg: mouse movement.
8141   *
8142   * If a callback is given, this method will be called asynchronously.
8143   *
8144   * @param count the number of random bytes to get.
8145   * @param [callback(err, bytes)] called once the operation completes.
8146   *
8147   * @return the random bytes in a string.
8148   */
8149  ctx.getBytes = function(count, callback) {
8150    return ctx.generate(count, callback);
8151  };
8152
8153  /**
8154   * Gets random bytes asynchronously. If a native secure crypto API is
8155   * unavailable, this method tries to make the bytes more unpredictable by
8156   * drawing from data that can be collected from the user of the browser,
8157   * eg: mouse movement.
8158   *
8159   * @param count the number of random bytes to get.
8160   *
8161   * @return the random bytes in a string.
8162   */
8163  ctx.getBytesSync = function(count) {
8164    return ctx.generate(count);
8165  };
8166
8167  return ctx;
8168}
8169
8170// create default prng context
8171var _ctx = spawnPrng();
8172
8173// add other sources of entropy only if window.crypto.getRandomValues is not
8174// available -- otherwise this source will be automatically used by the prng
8175var _nodejs = (
8176  typeof process !== 'undefined' && process.versions && process.versions.node);
8177var getRandomValues = null;
8178if(typeof window !== 'undefined') {
8179  var _crypto = window.crypto || window.msCrypto;
8180  if(_crypto && _crypto.getRandomValues) {
8181    getRandomValues = function(arr) {
8182      return _crypto.getRandomValues(arr);
8183    };
8184  }
8185}
8186if(forge.disableNativeCode || (!_nodejs && !getRandomValues)) {
8187  // if this is a web worker, do not use weak entropy, instead register to
8188  // receive strong entropy asynchronously from the main thread
8189  if(typeof window === 'undefined' || window.document === undefined) {
8190    // FIXME:
8191  }
8192
8193  // get load time entropy
8194  _ctx.collectInt(+new Date(), 32);
8195
8196  // add some entropy from navigator object
8197  if(typeof(navigator) !== 'undefined') {
8198    var _navBytes = '';
8199    for(var key in navigator) {
8200      try {
8201        if(typeof(navigator[key]) == 'string') {
8202          _navBytes += navigator[key];
8203        }
8204      } catch(e) {
8205        /* Some navigator keys might not be accessible, e.g. the geolocation
8206          attribute throws an exception if touched in Mozilla chrome://
8207          context.
8208
8209          Silently ignore this and just don't use this as a source of
8210          entropy. */
8211      }
8212    }
8213    _ctx.collect(_navBytes);
8214    _navBytes = null;
8215  }
8216
8217  // add mouse and keyboard collectors if jquery is available
8218  if(jQuery) {
8219    // set up mouse entropy capture
8220    jQuery().mousemove(function(e) {
8221      // add mouse coords
8222      _ctx.collectInt(e.clientX, 16);
8223      _ctx.collectInt(e.clientY, 16);
8224    });
8225
8226    // set up keyboard entropy capture
8227    jQuery().keypress(function(e) {
8228      _ctx.collectInt(e.charCode, 8);
8229    });
8230  }
8231}
8232
8233/* Random API */
8234if(!forge.random) {
8235  forge.random = _ctx;
8236} else {
8237  // extend forge.random with _ctx
8238  for(var key in _ctx) {
8239    forge.random[key] = _ctx[key];
8240  }
8241}
8242
8243// expose spawn PRNG
8244forge.random.createInstance = spawnPrng;
8245
8246})(typeof(jQuery) !== 'undefined' ? jQuery : null);
8247
8248} // end module implementation
8249
8250/* ########## Begin module wrapper ########## */
8251var name = 'random';
8252if(typeof define !== 'function') {
8253  // NodeJS -> AMD
8254  if(typeof module === 'object' && module.exports) {
8255    var nodeJS = true;
8256    define = function(ids, factory) {
8257      factory(require, module);
8258    };
8259  } else {
8260    // <script>
8261    if(typeof forge === 'undefined') {
8262      forge = {};
8263    }
8264    return initModule(forge);
8265  }
8266}
8267// AMD
8268var deps;
8269var defineFunc = function(require, module) {
8270  module.exports = function(forge) {
8271    var mods = deps.map(function(dep) {
8272      return require(dep);
8273    }).concat(initModule);
8274    // handle circular dependencies
8275    forge = forge || {};
8276    forge.defined = forge.defined || {};
8277    if(forge.defined[name]) {
8278      return forge[name];
8279    }
8280    forge.defined[name] = true;
8281    for(var i = 0; i < mods.length; ++i) {
8282      mods[i](forge);
8283    }
8284    return forge[name];
8285  };
8286};
8287var tmpDefine = define;
8288define = function(ids, factory) {
8289  deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2);
8290  if(nodeJS) {
8291    delete define;
8292    return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0));
8293  }
8294  define = tmpDefine;
8295  return define.apply(null, Array.prototype.slice.call(arguments, 0));
8296};
8297define(['require', 'module', './aes', './md', './prng', './util'], function() {
8298  defineFunc.apply(null, Array.prototype.slice.call(arguments, 0));
8299});
8300})();
8301
8302// Copyright (c) 2005  Tom Wu
8303// All Rights Reserved.
8304// See "LICENSE" for details.
8305
8306// Basic JavaScript BN library - subset useful for RSA encryption.
8307
8308/*
8309Licensing (LICENSE)
8310-------------------
8311
8312This software is covered under the following copyright:
8313*/
8314/*
8315 * Copyright (c) 2003-2005  Tom Wu
8316 * All Rights Reserved.
8317 *
8318 * Permission is hereby granted, free of charge, to any person obtaining
8319 * a copy of this software and associated documentation files (the
8320 * "Software"), to deal in the Software without restriction, including
8321 * without limitation the rights to use, copy, modify, merge, publish,
8322 * distribute, sublicense, and/or sell copies of the Software, and to
8323 * permit persons to whom the Software is furnished to do so, subject to
8324 * the following conditions:
8325 *
8326 * The above copyright notice and this permission notice shall be
8327 * included in all copies or substantial portions of the Software.
8328 *
8329 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
8330 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
8331 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
8332 *
8333 * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
8334 * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
8335 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
8336 * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
8337 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
8338 *
8339 * In addition, the following condition applies:
8340 *
8341 * All redistributions must retain an intact copy of this copyright notice
8342 * and disclaimer.
8343 */
8344/*
8345Address all questions regarding this license to:
8346
8347  Tom Wu
8348  [email protected]
8349*/
8350
8351(function() {
8352/* ########## Begin module implementation ########## */
8353function initModule(forge) {
8354
8355// Bits per digit
8356var dbits;
8357
8358// JavaScript engine analysis
8359var canary = 0xdeadbeefcafe;
8360var j_lm = ((canary&0xffffff)==0xefcafe);
8361
8362// (public) Constructor
8363function BigInteger(a,b,c) {
8364  this.data = [];
8365  if(a != null)
8366    if("number" == typeof a) this.fromNumber(a,b,c);
8367    else if(b == null && "string" != typeof a) this.fromString(a,256);
8368    else this.fromString(a,b);
8369}
8370
8371// return new, unset BigInteger
8372function nbi() { return new BigInteger(null); }
8373
8374// am: Compute w_j += (x*this_i), propagate carries,
8375// c is initial carry, returns final carry.
8376// c < 3*dvalue, x < 2*dvalue, this_i < dvalue
8377// We need to select the fastest one that works in this environment.
8378
8379// am1: use a single mult and divide to get the high bits,
8380// max digit bits should be 26 because
8381// max internal value = 2*dvalue^2-2*dvalue (< 2^53)
8382function am1(i,x,w,j,c,n) {
8383  while(--n >= 0) {
8384    var v = x*this.data[i++]+w.data[j]+c;
8385    c = Math.floor(v/0x4000000);
8386    w.data[j++] = v&0x3ffffff;
8387  }
8388  return c;
8389}
8390// am2 avoids a big mult-and-extract completely.
8391// Max digit bits should be <= 30 because we do bitwise ops
8392// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31)
8393function am2(i,x,w,j,c,n) {
8394  var xl = x&0x7fff, xh = x>>15;
8395  while(--n >= 0) {
8396    var l = this.data[i]&0x7fff;
8397    var h = this.data[i++]>>15;
8398    var m = xh*l+h*xl;
8399    l = xl*l+((m&0x7fff)<<15)+w.data[j]+(c&0x3fffffff);
8400    c = (l>>>30)+(m>>>15)+xh*h+(c>>>30);
8401    w.data[j++] = l&0x3fffffff;
8402  }
8403  return c;
8404}
8405// Alternately, set max digit bits to 28 since some
8406// browsers slow down when dealing with 32-bit numbers.
8407function am3(i,x,w,j,c,n) {
8408  var xl = x&0x3fff, xh = x>>14;
8409  while(--n >= 0) {
8410    var l = this.data[i]&0x3fff;
8411    var h = this.data[i++]>>14;
8412    var m = xh*l+h*xl;
8413    l = xl*l+((m&0x3fff)<<14)+w.data[j]+c;
8414    c = (l>>28)+(m>>14)+xh*h;
8415    w.data[j++] = l&0xfffffff;
8416  }
8417  return c;
8418}
8419
8420// node.js (no browser)
8421if(typeof(navigator) === 'undefined')
8422{
8423   BigInteger.prototype.am = am3;
8424   dbits = 28;
8425} else if(j_lm && (navigator.appName == "Microsoft Internet Explorer")) {
8426  BigInteger.prototype.am = am2;
8427  dbits = 30;
8428} else if(j_lm && (navigator.appName != "Netscape")) {
8429  BigInteger.prototype.am = am1;
8430  dbits = 26;
8431} else { // Mozilla/Netscape seems to prefer am3
8432  BigInteger.prototype.am = am3;
8433  dbits = 28;
8434}
8435
8436BigInteger.prototype.DB = dbits;
8437BigInteger.prototype.DM = ((1<<dbits)-1);
8438BigInteger.prototype.DV = (1<<dbits);
8439
8440var BI_FP = 52;
8441BigInteger.prototype.FV = Math.pow(2,BI_FP);
8442BigInteger.prototype.F1 = BI_FP-dbits;
8443BigInteger.prototype.F2 = 2*dbits-BI_FP;
8444
8445// Digit conversions
8446var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz";
8447var BI_RC = new Array();
8448var rr,vv;
8449rr = "0".charCodeAt(0);
8450for(vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv;
8451rr = "a".charCodeAt(0);
8452for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
8453rr = "A".charCodeAt(0);
8454for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
8455
8456function int2char(n) { return BI_RM.charAt(n); }
8457function intAt(s,i) {
8458  var c = BI_RC[s.charCodeAt(i)];
8459  return (c==null)?-1:c;
8460}
8461
8462// (protected) copy this to r
8463function bnpCopyTo(r) {
8464  for(var i = this.t-1; i >= 0; --i) r.data[i] = this.data[i];
8465  r.t = this.t;
8466  r.s = this.s;
8467}
8468
8469// (protected) set from integer value x, -DV <= x < DV
8470function bnpFromInt(x) {
8471  this.t = 1;
8472  this.s = (x<0)?-1:0;
8473  if(x > 0) this.data[0] = x;
8474  else if(x < -1) this.data[0] = x+this.DV;
8475  else this.t = 0;
8476}
8477
8478// return bigint initialized to value
8479function nbv(i) { var r = nbi(); r.fromInt(i); return r; }
8480
8481// (protected) set from string and radix
8482function bnpFromString(s,b) {
8483  var k;
8484  if(b == 16) k = 4;
8485  else if(b == 8) k = 3;
8486  else if(b == 256) k = 8; // byte array
8487  else if(b == 2) k = 1;
8488  else if(b == 32) k = 5;
8489  else if(b == 4) k = 2;
8490  else { this.fromRadix(s,b); return; }
8491  this.t = 0;
8492  this.s = 0;
8493  var i = s.length, mi = false, sh = 0;
8494  while(--i >= 0) {
8495    var x = (k==8)?s[i]&0xff:intAt(s,i);
8496    if(x < 0) {
8497      if(s.charAt(i) == "-") mi = true;
8498      continue;
8499    }
8500    mi = false;
8501    if(sh == 0)
8502      this.data[this.t++] = x;
8503    else if(sh+k > this.DB) {
8504      this.data[this.t-1] |= (x&((1<<(this.DB-sh))-1))<<sh;
8505      this.data[this.t++] = (x>>(this.DB-sh));
8506    } else
8507      this.data[this.t-1] |= x<<sh;
8508    sh += k;
8509    if(sh >= this.DB) sh -= this.DB;
8510  }
8511  if(k == 8 && (s[0]&0x80) != 0) {
8512    this.s = -1;
8513    if(sh > 0) this.data[this.t-1] |= ((1<<(this.DB-sh))-1)<<sh;
8514  }
8515  this.clamp();
8516  if(mi) BigInteger.ZERO.subTo(this,this);
8517}
8518
8519// (protected) clamp off excess high words
8520function bnpClamp() {
8521  var c = this.s&this.DM;
8522  while(this.t > 0 && this.data[this.t-1] == c) --this.t;
8523}
8524
8525// (public) return string representation in given radix
8526function bnToString(b) {
8527  if(this.s < 0) return "-"+this.negate().toString(b);
8528  var k;
8529  if(b == 16) k = 4;
8530  else if(b == 8) k = 3;
8531  else if(b == 2) k = 1;
8532  else if(b == 32) k = 5;
8533  else if(b == 4) k = 2;
8534  else return this.toRadix(b);
8535  var km = (1<<k)-1, d, m = false, r = "", i = this.t;
8536  var p = this.DB-(i*this.DB)%k;
8537  if(i-- > 0) {
8538    if(p < this.DB && (d = this.data[i]>>p) > 0) { m = true; r = int2char(d); }
8539    while(i >= 0) {
8540      if(p < k) {
8541        d = (this.data[i]&((1<<p)-1))<<(k-p);
8542        d |= this.data[--i]>>(p+=this.DB-k);
8543      } else {
8544        d = (this.data[i]>>(p-=k))&km;
8545        if(p <= 0) { p += this.DB; --i; }
8546      }
8547      if(d > 0) m = true;
8548      if(m) r += int2char(d);
8549    }
8550  }
8551  return m?r:"0";
8552}
8553
8554// (public) -this
8555function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; }
8556
8557// (public) |this|
8558function bnAbs() { return (this.s<0)?this.negate():this; }
8559
8560// (public) return + if this > a, - if this < a, 0 if equal
8561function bnCompareTo(a) {
8562  var r = this.s-a.s;
8563  if(r != 0) return r;
8564  var i = this.t;
8565  r = i-a.t;
8566  if(r != 0) return (this.s<0)?-r:r;
8567  while(--i >= 0) if((r=this.data[i]-a.data[i]) != 0) return r;
8568  return 0;
8569}
8570
8571// returns bit length of the integer x
8572function nbits(x) {
8573  var r = 1, t;
8574  if((t=x>>>16) != 0) { x = t; r += 16; }
8575  if((t=x>>8) != 0) { x = t; r += 8; }
8576  if((t=x>>4) != 0) { x = t; r += 4; }
8577  if((t=x>>2) != 0) { x = t; r += 2; }
8578  if((t=x>>1) != 0) { x = t; r += 1; }
8579  return r;
8580}
8581
8582// (public) return the number of bits in "this"
8583function bnBitLength() {
8584  if(this.t <= 0) return 0;
8585  return this.DB*(this.t-1)+nbits(this.data[this.t-1]^(this.s&this.DM));
8586}
8587
8588// (protected) r = this << n*DB
8589function bnpDLShiftTo(n,r) {
8590  var i;
8591  for(i = this.t-1; i >= 0; --i) r.data[i+n] = this.data[i];
8592  for(i = n-1; i >= 0; --i) r.data[i] = 0;
8593  r.t = this.t+n;
8594  r.s = this.s;
8595}
8596
8597// (protected) r = this >> n*DB
8598function bnpDRShiftTo(n,r) {
8599  for(var i = n; i < this.t; ++i) r.data[i-n] = this.data[i];
8600  r.t = Math.max(this.t-n,0);
8601  r.s = this.s;
8602}
8603
8604// (protected) r = this << n
8605function bnpLShiftTo(n,r) {
8606  var bs = n%this.DB;
8607  var cbs = this.DB-bs;
8608  var bm = (1<<cbs)-1;
8609  var ds = Math.floor(n/this.DB), c = (this.s<<bs)&this.DM, i;
8610  for(i = this.t-1; i >= 0; --i) {
8611    r.data[i+ds+1] = (this.data[i]>>cbs)|c;
8612    c = (this.data[i]&bm)<<bs;
8613  }
8614  for(i = ds-1; i >= 0; --i) r.data[i] = 0;
8615  r.data[ds] = c;
8616  r.t = this.t+ds+1;
8617  r.s = this.s;
8618  r.clamp();
8619}
8620
8621// (protected) r = this >> n
8622function bnpRShiftTo(n,r) {
8623  r.s = this.s;
8624  var ds = Math.floor(n/this.DB);
8625  if(ds >= this.t) { r.t = 0; return; }
8626  var bs = n%this.DB;
8627  var cbs = this.DB-bs;
8628  var bm = (1<<bs)-1;
8629  r.data[0] = this.data[ds]>>bs;
8630  for(var i = ds+1; i < this.t; ++i) {
8631    r.data[i-ds-1] |= (this.data[i]&bm)<<cbs;
8632    r.data[i-ds] = this.data[i]>>bs;
8633  }
8634  if(bs >
8634 0) r.data[this.t-ds-1] |= (this.s&bm)<<cbs;
8635  r.t = this.t-ds;
8636  r.clamp();
8637}
8638
8639// (protected) r = this - a
8640function bnpSubTo(a,r) {
8641  var i = 0, c = 0, m = Math.min(a.t,this.t);
8642  while(i < m) {
8643    c += this.data[i]-a.data[i];
8644    r.data[i++] = c&this.DM;
8645    c >>= this.DB;
8646  }
8647  if(a.t < this.t) {
8648    c -= a.s;
8649    while(i < this.t) {
8650      c += this.data[i];
8651      r.data[i++] = c&this.DM;
8652      c >>= this.DB;
8653    }
8654    c += this.s;
8655  } else {
8656    c += this.s;
8657    while(i < a.t) {
8658      c -= a.data[i];
8659      r.data[i++] = c&this.DM;
8660      c >>= this.DB;
8661    }
8662    c -= a.s;
8663  }
8664  r.s = (c<0)?-1:0;
8665  if(c < -1) r.data[i++] = this.DV+c;
8666  else if(c > 0) r.data[i++] = c;
8667  r.t = i;
8668  r.clamp();
8669}
8670
8671// (protected) r = this * a, r != this,a (HAC 14.12)
8672// "this" should be the larger one if appropriate.
8673function bnpMultiplyTo(a,r) {
8674  var x = this.abs(), y = a.abs();
8675  var i = x.t;
8676  r.t = i+y.t;
8677  while(--i >= 0) r.data[i] = 0;
8678  for(i = 0; i < y.t; ++i) r.data[i+x.t] = x.am(0,y.data[i],r,i,0,x.t);
8679  r.s = 0;
8680  r.clamp();
8681  if(this.s != a.s) BigInteger.ZERO.subTo(r,r);
8682}
8683
8684// (protected) r = this^2, r != this (HAC 14.16)
8685function bnpSquareTo(r) {
8686  var x = this.abs();
8687  var i = r.t = 2*x.t;
8688  while(--i >= 0) r.data[i] = 0;
8689  for(i = 0; i < x.t-1; ++i) {
8690    var c = x.am(i,x.data[i],r,2*i,0,1);
8691    if((r.data[i+x.t]+=x.am(i+1,2*x.data[i],r,2*i+1,c,x.t-i-1)) >= x.DV) {
8692      r.data[i+x.t] -= x.DV;
8693      r.data[i+x.t+1] = 1;
8694    }
8695  }
8696  if(r.t > 0) r.data[r.t-1] += x.am(i,x.data[i],r,2*i,0,1);
8697  r.s = 0;
8698  r.clamp();
8699}
8700
8701// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20)
8702// r != q, this != m.  q or r may be null.
8703function bnpDivRemTo(m,q,r) {
8704  var pm = m.abs();
8705  if(pm.t <= 0) return;
8706  var pt = this.abs();
8707  if(pt.t < pm.t) {
8708    if(q != null) q.fromInt(0);
8709    if(r != null) this.copyTo(r);
8710    return;
8711  }
8712  if(r == null) r = nbi();
8713  var y = nbi(), ts = this.s, ms = m.s;
8714  var nsh = this.DB-nbits(pm.data[pm.t-1]);	// normalize modulus
8715  if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); } else { pm.copyTo(y); pt.copyTo(r); }
8716  var ys = y.t;
8717  var y0 = y.data[ys-1];
8718  if(y0 == 0) return;
8719  var yt = y0*(1<<this.F1)+((ys>1)?y.data[ys-2]>>this.F2:0);
8720  var d1 = this.FV/yt, d2 = (1<<this.F1)/yt, e = 1<<this.F2;
8721  var i = r.t, j = i-ys, t = (q==null)?nbi():q;
8722  y.dlShiftTo(j,t);
8723  if(r.compareTo(t) >= 0) {
8724    r.data[r.t++] = 1;
8725    r.subTo(t,r);
8726  }
8727  BigInteger.ONE.dlShiftTo(ys,t);
8728  t.subTo(y,y);	// "negative" y so we can replace sub with am later
8729  while(y.t < ys) y.data[y.t++] = 0;
8730  while(--j >= 0) {
8731    // Estimate quotient digit
8732    var qd = (r.data[--i]==y0)?this.DM:Math.floor(r.data[i]*d1+(r.data[i-1]+e)*d2);
8733    if((r.data[i]+=y.am(0,qd,r,j,0,ys)) < qd) {	// Try it out
8734      y.dlShiftTo(j,t);
8735      r.subTo(t,r);
8736      while(r.data[i] < --qd) r.subTo(t,r);
8737    }
8738  }
8739  if(q != null) {
8740    r.drShiftTo(ys,q);
8741    if(ts != ms) BigInteger.ZERO.subTo(q,q);
8742  }
8743  r.t = ys;
8744  r.clamp();
8745  if(nsh > 0) r.rShiftTo(nsh,r);	// Denormalize remainder
8746  if(ts < 0) BigInteger.ZERO.subTo(r,r);
8747}
8748
8749// (public) this mod a
8750function bnMod(a) {
8751  var r = nbi();
8752  this.abs().divRemTo(a,null,r);
8753  if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r);
8754  return r;
8755}
8756
8757// Modular reduction using "classic" algorithm
8758function Classic(m) { this.m = m; }
8759function cConvert(x) {
8760  if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m);
8761  else return x;
8762}
8763function cRevert(x) { return x; }
8764function cReduce(x) { x.divRemTo(this.m,null,x); }
8765function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
8766function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
8767
8768Classic.prototype.convert = cConvert;
8769Classic.prototype.revert = cRevert;
8770Classic.prototype.reduce = cReduce;
8771Classic.prototype.mulTo = cMulTo;
8772Classic.prototype.sqrTo = cSqrTo;
8773
8774// (protected) return "-1/this % 2^DB"; useful for Mont. reduction
8775// justification:
8776//         xy == 1 (mod m)
8777//         xy =  1+km
8778//   xy(2-xy) = (1+km)(1-km)
8779// x[y(2-xy)] = 1-k^2m^2
8780// x[y(2-xy)] == 1 (mod m^2)
8781// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2
8782// should reduce x and y(2-xy) by m^2 at each step to keep size bounded.
8783// JS multiply "overflows" differently from C/C++, so care is needed here.
8784function bnpInvDigit() {
8785  if(this.t < 1) return 0;
8786  var x = this.data[0];
8787  if((x&1) == 0) return 0;
8788  var y = x&3;		// y == 1/x mod 2^2
8789  y = (y*(2-(x&0xf)*y))&0xf;	// y == 1/x mod 2^4
8790  y = (y*(2-(x&0xff)*y))&0xff;	// y == 1/x mod 2^8
8791  y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff;	// y == 1/x mod 2^16
8792  // last step - calculate inverse mod DV directly;
8793  // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints
8794  y = (y*(2-x*y%this.DV))%this.DV;		// y == 1/x mod 2^dbits
8795  // we really want the negative inverse, and -DV < y < DV
8796  return (y>0)?this.DV-y:-y;
8797}
8798
8799// Montgomery reduction
8800function Montgomery(m) {
8801  this.m = m;
8802  this.mp = m.invDigit();
8803  this.mpl = this.mp&0x7fff;
8804  this.mph = this.mp>>15;
8805  this.um = (1<<(m.DB-15))-1;
8806  this.mt2 = 2*m.t;
8807}
8808
8809// xR mod m
8810function montConvert(x) {
8811  var r = nbi();
8812  x.abs().dlShiftTo(this.m.t,r);
8813  r.divRemTo(this.m,null,r);
8814  if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r);
8815  return r;
8816}
8817
8818// x/R mod m
8819function montRevert(x) {
8820  var r = nbi();
8821  x.copyTo(r);
8822  this.reduce(r);
8823  return r;
8824}
8825
8826// x = x/R mod m (HAC 14.32)
8827function montReduce(x) {
8828  while(x.t <= this.mt2)	// pad x so am has enough room later
8829    x.data[x.t++] = 0;
8830  for(var i = 0; i < this.m.t; ++i) {
8831    // faster way of calculating u0 = x.data[i]*mp mod DV
8832    var j = x.data[i]&0x7fff;
8833    var u0 = (j*this.mpl+(((j*this.mph+(x.data[i]>>15)*this.mpl)&this.um)<<15))&x.DM;
8834    // use am to combine the multiply-shift-add into one call
8835    j = i+this.m.t;
8836    x.data[j] += this.m.am(0,u0,x,i,0,this.m.t);
8837    // propagate carry
8838    while(x.data[j] >= x.DV) { x.data[j] -= x.DV; x.data[++j]++; }
8839  }
8840  x.clamp();
8841  x.drShiftTo(this.m.t,x);
8842  if(x.compareTo(this.m) >= 0) x.subTo(this.m,x);
8843}
8844
8845// r = "x^2/R mod m"; x != r
8846function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
8847
8848// r = "xy/R mod m"; x,y != r
8849function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
8850
8851Montgomery.prototype.convert = montConvert;
8852Montgomery.prototype.revert = montRevert;
8853Montgomery.prototype.reduce = montReduce;
8854Montgomery.prototype.mulTo = montMulTo;
8855Montgomery.prototype.sqrTo = montSqrTo;
8856
8857// (protected) true iff this is even
8858function bnpIsEven() { return ((this.t>0)?(this.data[0]&1):this.s) == 0; }
8859
8860// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79)
8861function bnpExp(e,z) {
8862  if(e > 0xffffffff || e < 1) return BigInteger.ONE;
8863  var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1;
8864  g.copyTo(r);
8865  while(--i >= 0) {
8866    z.sqrTo(r,r2);
8867    if((e&(1<<i)) > 0) z.mulTo(r2,g,r);
8868    else { var t = r; r = r2; r2 = t; }
8869  }
8870  return z.revert(r);
8871}
8872
8873// (public) this^e % m, 0 <= e < 2^32
8874function bnModPowInt(e,m) {
8875  var z;
8876  if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m);
8877  return this.exp(e,z);
8878}
8879
8880// protected
8881BigInteger.prototype.copyTo = bnpCopyTo;
8882BigInteger.prototype.fromInt = bnpFromInt;
8883BigInteger.prototype.fromString = bnpFromString;
8884BigInteger.prototype.clamp = bnpClamp;
8885BigInteger.prototype.dlShiftTo = bnpDLShiftTo;
8886BigInteger.prototype.drShiftTo = bnpDRShiftTo;
8887BigInteger.prototype.lShiftTo = bnpLShiftTo;
8888BigInteger.prototype.rShiftTo = bnpRShiftTo;
8889BigInteger.prototype.subTo = bnpSubTo;
8890BigInteger.prototype.multiplyTo = bnpMultiplyTo;
8891BigInteger.prototype.squareTo = bnpSquareTo;
8892BigInteger.prototype.divRemTo = bnpDivRemTo;
8893BigInteger.prototype.invDigit = bnpInvDigit;
8894BigInteger.prototype.isEven = bnpIsEven;
8895BigInteger.prototype.exp = bnpExp;
8896
8897// public
8898BigInteger.prototype.toString = bnToString;
8899BigInteger.prototype.negate = bnNegate;
8900BigInteger.prototype.abs = bnAbs;
8901BigInteger.prototype.compareTo = bnCompareTo;
8902BigInteger.prototype.bitLength = bnBitLength;
8903BigInteger.prototype.mod = bnMod;
8904BigInteger.prototype.modPowInt = bnModPowInt;
8905
8906// "constants"
8907BigInteger.ZERO = nbv(0);
8908BigInteger.ONE = nbv(1);
8909
8910// jsbn2 lib
8911
8912//Copyright (c) 2005-2009  Tom Wu
8913//All Rights Reserved.
8914//See "LICENSE" for details (See jsbn.js for LICENSE).
8915
8916//Extended JavaScript BN functions, required for RSA private ops.
8917
8918//Version 1.1: new BigInteger("0", 10) returns "proper" zero
8919
8920//(public)
8921function bnClone() { var r = nbi(); this.copyTo(r); return r; }
8922
8923//(public) return value as integer
8924function bnIntValue() {
8925if(this.s < 0) {
8926 if(this.t == 1) return this.data[0]-this.DV;
8927 else if(this.t == 0) return -1;
8928} else if(this.t == 1) return this.data[0];
8929else if(this.t == 0) return 0;
8930// assumes 16 < DB < 32
8931return ((this.data[1]&((1<<(32-this.DB))-1))<<this.DB)|this.data[0];
8932}
8933
8934//(public) return value as byte
8935function bnByteValue() { return (this.t==0)?this.s:(this.data[0]<<24)>>24; }
8936
8937//(public) return value as short (assumes DB>=16)
8938function bnShortValue() { return (this.t==0)?this.s:(this.data[0]<<16)>>16; }
8939
8940//(protected) return x s.t. r^x < DV
8941function bnpChunkSize(r) { return Math.floor(Math.LN2*this.DB/Math.log(r)); }
8942
8943//(public) 0 if this == 0, 1 if this > 0
8944function bnSigNum() {
8945if(this.s < 0) return -1;
8946else if(this.t <= 0 || (this.t == 1 && this.data[0] <= 0)) return 0;
8947else return 1;
8948}
8949
8950//(protected) convert to radix string
8951function bnpToRadix(b) {
8952if(b == null) b = 10;
8953if(this.signum() == 0 || b < 2 || b > 36) return "0";
8954var cs = this.chunkSize(b);
8955var a = Math.pow(b,cs);
8956var d = nbv(a), y = nbi(), z = nbi(), r = "";
8957this.divRemTo(d,y,z);
8958while(y.signum() > 0) {
8959 r = (a+z.intValue()).toString(b).substr(1) + r;
8960 y.divRemTo(d,y,z);
8961}
8962return z.intValue().toString(b) + r;
8963}
8964
8965//(protected) convert from radix string
8966function bnpFromRadix(s,b) {
8967this.fromInt(0);
8968if(b == null) b = 10;
8969var cs = this.chunkSize(b);
8970var d = Math.pow(b,cs), mi = false, j = 0, w = 0;
8971for(var i = 0; i < s.length; ++i) {
8972 var x = intAt(s,i);
8973 if(x < 0) {
8974   if(s.charAt(i) == "-" && this.signum() == 0) mi = true;
8975   continue;
8976 }
8977 w = b*w+x;
8978 if(++j >= cs) {
8979   this.dMultiply(d);
8980   this.dAddOffset(w,0);
8981   j = 0;
8982   w = 0;
8983 }
8984}
8985if(j > 0) {
8986 this.dMultiply(Math.pow(b,j));
8987 this.dAddOffset(w,0);
8988}
8989if(mi) BigInteger.ZERO.subTo(this,this);
8990}
8991
8992//(protected) alternate constructor
8993function bnpFromNumber(a,b,c) {
8994if("number" == typeof b) {
8995 // new BigInteger(int,int,RNG)
8996 if(a < 2) this.fromInt(1);
8997 else {
8998   this.fromNumber(a,c);
8999   if(!this.testBit(a-1))  // force MSB set
9000     this.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,this);
9001   if(this.isEven()) this.dAddOffset(1,0); // force odd
9002   while(!this.isProbablePrime(b)) {
9003     this.dAddOffset(2,0);
9004     if(this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a-1),this);
9005   }
9006 }
9007} else {
9008 // new BigInteger(int,RNG)
9009 var x = new Array(), t = a&7;
9010 x.length = (a>>3)+1;
9011 b.nextBytes(x);
9012 if(t > 0) x[0] &= ((1<<t)-1); else x[0] = 0;
9013 this.fromString(x,256);
9014}
9015}
9016
9017//(public) convert to bigendian byte array
9018function bnToByteArray() {
9019var i = this.t, r = new Array();
9020r[0] = this.s;
9021var p = this.DB-(i*this.DB)%8, d, k = 0;
9022if(i-- > 0) {
9023 if(p < this.DB && (d = this.data[i]>>p) != (this.s&this.DM)>>p)
9024   r[k++] = d|(this.s<<(this.DB-p));
9025 while(i >= 0) {
9026   if(p < 8) {
9027     d = (this.data[i]&((1<<p)-1))<<(8-p);
9028     d |= this.data[--i]>>(p+=this.DB-8);
9029   } else {
9030     d = (this.data[i]>>(p-=8))&0xff;
9031     if(p <= 0) { p += this.DB; --i; }
9032   }
9033   if((d&0x80) != 0) d |= -256;
9034   if(k == 0 && (this.s&0x80) != (d&0x80)) ++k;
9035   if(k > 0 || d != this.s) r[k++] = d;
9036 }
9037}
9038return r;
9039}
9040
9041function bnEquals(a) { return(this.compareTo(a)==0); }
9042function bnMin(a) { return(this.compareTo(a)<0)?this:a; }
9043function bnMax(a) { return(this.compareTo(a)>0)?this:a; }
9044
9045//(protected) r = this op a (bitwise)
9046function bnpBitwiseTo(a,op,r) {
9047var i, f, m = Math.min(a.t,this.t);
9048for(i = 0; i < m; ++i) r.data[i] = op(this.data[i],a.data[i]);
9049if(a.t < this.t) {
9050 f = a.s&this.DM;
9051 for(i = m; i < this.t; ++i) r.data[i] = op(this.data[i],f);
9052 r.t = this.t;
9053} else {
9054 f = this.s&this.DM;
9055 for(i = m; i < a.t; ++i) r.data[i] = op(f,a.data[i]);
9056 r.t = a.t;
9057}
9058r.s = op(this.s,a.s);
9059r.clamp();
9060}
9061
9062//(public) this & a
9063function op_and(x,y) { return x&y; }
9064function bnAnd(a) { var r = nbi(); this.bitwiseTo(a,op_and,r); return r; }
9065
9066//(public) this | a
9067function op_or(x,y) { return x|y; }
9068function bnOr(a) { var r = nbi(); this.bitwiseTo(a,op_or,r); return r; }
9069
9070//(public) this ^ a
9071function op_xor(x,y) { return x^y; }
9072function bnXor(a) { var r = nbi(); this.bitwiseTo(a,op_xor,r); return r; }
9073
9074//(public) this & ~a
9075function op_andnot(x,y) { return x&~y; }
9076function bnAndNot(a) { var r = nbi(); this.bitwiseTo(a,op_andnot,r); return r; }
9077
9078//(public) ~this
9079function bnNot() {
9080var r = nbi();
9081for(var i = 0; i < this.t; ++i) r.data[i] = this.DM&~this.data[i];
9082r.t = this.t;
9083r.s = ~this.s;
9084return r;
9085}
9086
9087//(public) this << n
9088function bnShiftLeft(n) {
9089var r = nbi();
9090if(n < 0) this.rShiftTo(-n,r); else this.lShiftTo(n,r);
9091return r;
9092}
9093
9094//(public) this >> n
9095function bnShiftRight(n) {
9096var r = nbi();
9097if(n < 0) this.lShiftTo(-n,r); else this.rShiftTo(n,r);
9098return r;
9099}
9100
9101//return index of lowest 1-bit in x, x < 2^31
9102function lbit(x) {
9103if(x == 0) return -1;
9104var r = 0;
9105if((x&0xffff) == 0) { x >>= 16; r += 16; }
9106if((x&0xff) == 0) { x >>= 8; r += 8; }
9107if((x&0xf) == 0) { x >>= 4; r += 4; }
9108if((x&3) == 0) { x >>= 2; r += 2; }
9109if((x&1) == 0) ++r;
9110return r;
9111}
9112
9113//(public) returns index of lowest 1-bit (or -1 if none)
9114function bnGetLowestSetBit() {
9115for(var i = 0; i < this.t; ++i)
9116 if(this.data[i] != 0) return i*this.DB+lbit(this.data[i]);
9117if(this.s < 0) return this.t*this.DB;
9118return -1;
9119}
9120
9121//return number of 1 bits in x
9122function cbit(x) {
9123var r = 0;
9124while(x != 0) { x &= x-1; ++r; }
9125return r;
9126}
9127
9128//(public) return number of set bits
9129function bnBitCount() {
9130var r = 0, x = this.s&this.DM;
9131for(var i = 0; i < this.t; ++i) r += cbit(this.data[i]^x);
9132return r;
9133}
9134
9135//(public) true iff nth bit is set
9136function bnTestBit(n) {
9137var j = Math.floor(n/this.DB);
9138if(j >= this.t) return(this.s!=0);
9139return((this.data[j]&(1<<(n%this.DB)))!=0);
9140}
9141
9142//(protected) this op (1<<n)
9143function bnpChangeBit(n,op) {
9144var r = BigInteger.ONE.shiftLeft(n);
9145this.bitwiseTo(r,op,r);
9146return r;
9147}
9148
9149//(public) this | (1<<n)
9150function bnSetBit(n) { return this.changeBit(n,op_or); }
9151
9152//(public) this & ~(1<<n)
9153function bnClearBit(n) { return this.changeBit(n,op_andnot); }
9154
9155//(public) this ^ (1<<n)
9156function bnFlipBit(n) { return this.changeBit(n,op_xor); }
9157
9158//(protected) r = this + a
9159function bnpAddTo(a,r) {
9160var i = 0, c = 0, m = Math.min(a.t,this.t);
9161while(i < m) {
9162 c += this.data[i]+a.data[i];
9163 r.data[i++] = c&this.DM;
9164 c >>= this.DB;
9165}
9166if(a.t < this.t) {
9167 c += a.s;
9168 while(i < this.t) {
9169   c += this.data[i];
9170   r.data[i++] = c&this.DM;
9171   c >>= this.DB;
9172 }
9173 c += this.s;
9174} else {
9175 c += this.s;
9176 while(i < a.t) {
9177   c += a.data[i];
9178   r.data[i++] = c&this.DM;
9179   c >>= this.DB;
9180 }
9181 c += a.s;
9182}
9183r.s = (c<0)?-1:0;
9184if(c > 0) r.data[i++] = c;
9185else if(c < -1) r.data[i++] = this.DV+c;
9186r.t = i;
9187r.clamp();
9188}
9189
9190//(public) this + a
9191function bnAdd(a) { var r = nbi(); this.addTo(a,r); return r; }
9192
9193//(public) this - a
9194function bnSubtract(a) { var r = nbi(); this.subTo(a,r); return r; }
9195
9196//(public) this * a
9197function bnMultiply(a) { var r = nbi(); this.multiplyTo(a,r); return r; }
9198
9199//(public) this / a
9200function bnDivide(a) { var r = nbi(); this.divRemTo(a,r,null); return r; }
9201
9202//(public) this % a
9203function bnRemainder(a) { var r = nbi(); this.divRemTo(a,null,r); return r; }
9204
9205//(public) [this/a,this%a]
9206function bnDivideAndRemainder(a) {
9207var q = nbi(), r = nbi();
9208this.divRemTo(a,q,r);
9209return new Array(q,r);
9210}
9211
9212//(protected) this *= n, this >= 0, 1 < n < DV
9213function bnpDMultiply(n) {
9214this.data[this.t] = this.am(0,n-1,this,0,0,this.t);
9215++this.t;
9216this.clamp();
9217}
9218
9219//(protected) this += n << w words, this >= 0
9220function bnpDAddOffset(n,w) {
9221if(n == 0) return;
9222while(this.t <= w) this.data[this.t++] = 0;
9223this.data[w] += n;
9224while(this.data[w] >= this.DV) {
9225 this.data[w] -= this.DV;
9226 if(++w >= this.t) this.data[this.t++] = 0;
9227 ++this.data[w];
9228}
9229}
9230
9231//A "null" reducer
9232function NullExp() {}
9233function nNop(x) { return x; }
9234function nMulTo(x,y,r) { x.multiplyTo(y,r); }
9235function nSqrTo(x,r) { x.squareTo(r); }
9236
9237NullExp.prototype.convert = nNop;
9238NullExp.prototype.revert = nNop;
9239NullExp.prototype.mulTo = nMulTo;
9240NullExp.prototype.sqrTo = nSqrTo;
9241
9242//(public) this^e
9243function bnPow(e) { return this.exp(e,new NullExp()); }
9244
9245//(protected) r = lower n words of "this * a", a.t <= n
9246//"this" should be the larger one if appropriate.
9247function bnpMultiplyLowerTo(a,n,r) {
9248var i = Math.min(this.t+a.t,n);
9249r.s = 0; // assumes a,this >= 0
9250r.t = i;
9251while(i > 0) r.data[--i] = 0;
9252var j;
9253for(j = r.t-this.t; i < j; ++i) r.data[i+this.t] = this.am(0,a.data[i],r,i,0,this.t);
9254for(j = Math.min(a.t,n); i < j; ++i) this.am(0,a.data[i],r,i,0,n-i);
9255r.clamp();
9256}
9257
9258//(protected) r = "this * a" without lower n words, n > 0
9259//"this" should be the larger one if appropriate.
9260function bnpMultiplyUpperTo(a,n,r) {
9261--n;
9262var i = r.t = this.t+a.t-n;
9263r.s = 0; // assumes a,this >= 0
9264while(--i >= 0) r.data[i] = 0;
9265for(i = Math.max(n-this.t,0); i < a.t; ++i)
9266 r.data[this.t+i-n] = this.am(n-i,a.data[i],r,0,0,this.t+i-n);
9267r.clamp();
9268r.drShiftTo(1,r);
9269}
9270
9271//Barrett modular reduction
9272function Barrett(m) {
9273// setup Barrett
9274this.r2 = nbi();
9275this.q3 = nbi();
9276BigInteger.ONE.dlShiftTo(2*m.t,this.r2);
9277this.mu = this.r2.divide(m);
9278this.m = m;
9279}
9280
9281function barrettConvert(x) {
9282if(x.s < 0 || x.t > 2*this.m.t) return x.mod(this.m);
9283else if(x.compareTo(this.m) < 0) return x;
9284else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; }
9285}
9286
9287function barrettRevert(x) { return x; }
9288
9289//x = x mod m (HAC 14.42)
9290function barrettReduce(x) {
9291x.drShiftTo(this.m.t-1,this.r2);
9292if(x.t > this.m.t+1) { x.t = this.m.t+1; x.clamp(); }
9293this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3);
9294this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2);
9295while(x.compareTo(this.r2) < 0) x.dAddOffset(1,this.m.t+1);
9296x.subTo(this.r2,x);
9297while(x.compareTo(this.m) >= 0) x.subTo(this.m,x);
9298}
9299
9300//r = x^2 mod m; x != r
9301function barrettSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
9302
9303//r = x*y mod m; x,y != r
9304function barrettMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
9305
9306Barrett.prototype.convert = barrettConvert;
9307Barrett.prototype.revert = barrettRevert;
9308Barrett.prototype.reduce = barrettReduce;
9309Barrett.prototype.mulTo = barrettMulTo;
9310Barrett.prototype.sqrTo = barrettSqrTo;
9311
9312//(public) this^e % m (HAC 14.85)
9313function bnModPow(e,m) {
9314var i = e.bitLength(), k, r = nbv(1), z;
9315if(i <= 0) return r;
9316else if(i < 18) k = 1;
9317else if(i < 48) k = 3;
9318else if(i < 144) k = 4;
9319else if(i < 768) k = 5;
9320else k = 6;
9321if(i < 8)
9322 z = new Classic(m);
9323else if(m.isEven())
9324 z = new Barrett(m);
9325else
9326 z = new Montgomery(m);
9327
9328// precomputation
9329var g = new Array(), n = 3, k1 = k-1, km = (1<<k)-1;
9330g[1] = z.convert(this);
9331if(k > 1) {
9332 var g2 = nbi();
9333 z.sqrTo(g[1],g2);
9334 while(n <= km) {
9335   g[n] = nbi();
9336   z.mulTo(g2,g[n-2],g[n]);
9337   n += 2;
9338 }
9339}
9340
9341var j = e.t-1, w, is1 = true, r2 = nbi(), t;
9342i = nbits(e.data[j])-1;
9343while(j >= 0) {
9344 if(i >= k1) w = (e.data[j]>>(i-k1))&km;
9345 else {
9346   w = (e.data[j]&((1<<(i+1))-1))<<(k1-i);
9347   if(j > 0) w |= e.data[j-1]>>(this.DB+i-k1);
9348 }
9349
9350 n = k;
9351 while((w&1) == 0) { w >>= 1; --n; }
9352 if((i -= n) < 0) { i += this.DB; --j; }
9353 if(is1) {  // ret == 1, don't bother squaring or multiplying it
9354   g[w].copyTo(r);
9355   is1 = false;
9356 } else {
9357   while(n > 1) { z.sqrTo(r,r2); z.sqrTo(r2,r); n -= 2; }
9358   if(n > 0) z.sqrTo(r,r2); else { t = r; r = r2; r2 = t; }
9359   z.mulTo(r2,g[w],r);
9360 }
9361
9362 while(j >= 0 && (e.data[j]&(1<<i)) == 0) {
9363   z.sqrTo(r,r2); t = r; r = r2; r2 = t;
9364   if(--i < 0) { i = this.DB-1; --j; }
9365 }
9366}
9367return z.revert(r);
9368}
9369
9370//(public) gcd(this,a) (HAC 14.54)
9371function bnGCD(a) {
9372var x = (this.s<0)?this.negate():this.clone();
9373var y = (a.s<0)?a.negate():a.clone();
9374if(x.compareTo(y) < 0) { var t = x; x = y; y = t; }
9375var i = x.getLowestSetBit(), g = y.getLowestSetBit();
9376if(g < 0) return x;
9377if(i < g) g = i;
9378if(g > 0) {
9379 x.rShiftTo(g,x);
9380 y.rShiftTo(g,y);
9381}
9382while(x.signum() > 0) {
9383 if((i = x.getLowestSetBit()) > 0) x.rShiftTo(i,x);
9384 if((i = y.getLowestSetBit()) > 0) y.rShiftTo(i,y);
9385 if(x.compareTo(y) >= 0) {
9386   x.subTo(y,x);
9387   x.rShiftTo(1,x);
9388 } else {
9389   y.subTo(x,y);
9390   y.rShiftTo(1,y);
9391 }
9392}
9393if(g > 0) y.lShiftTo(g,y);
9394return y;
9395}
9396
9397//(protected) this % n, n < 2^26
9398function bnpModInt(n) {
9399if(n <= 0) return 0;
9400var d = this.DV%n, r = (this.s<0)?n-1:0;
9401if(this.t > 0)
9402 if(d == 0) r = this.data[0]%n;
9403 else for(var i = this.t-1; i >= 0; --i) r = (d*r+this.data[i])%n;
9404return r;
9405}
9406
9407//(public) 1/this % m (HAC 14.61)
9408function bnModInverse(m) {
9409var ac = m.isEven();
9410if((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO;
9411var u = m.clone(), v = this.clone();
9412var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1);
9413while(u.signum() != 0) {
9414 while(u.isEven()) {
9415   u.rShiftTo(1,u);
9416   if(ac) {
9417     if(!a.isEven() || !b.isEven()) { a.addTo(this,a); b.subTo(m,b); }
9418     a.rShiftTo(1,a);
9419   } else if(!b.isEven()) b.subTo(m,b);
9420   b.rShiftTo(1,b);
9421 }
9422 while(v.isEven()) {
9423   v.rShiftTo(1,v);
9424   if(ac) {
9425     if(!c.isEven() || !d.isEven()) { c.addTo(this,c); d.subTo(m,d); }
9426     c.rShiftTo(1,c);
9427   } else if(!d.isEven()) d.subTo(m,d);
9428   d.rShiftTo(1,d);
9429 }
9430 if(u.compareTo(v) >= 0) {
9431   u.subTo(v,u);
9432   if(ac) a.subTo(c,a);
9433   b.subTo(d,b);
9434 } else {
9435   v.subTo(u,v);
9436   if(ac) c.subTo(a,c);
9437   d.subTo(b,d);
9438 }
9439}
9440if(v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO;
9441if(d.compareTo(m) >= 0) return d.subtract(m);
9442if(d.signum() < 0) d.addTo(m,d); else return d;
9443if(d.signum() < 0) return d.add(m); else return d;
9444}
9445
9446var lowprimes = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509];
9447var lplim = (1<<26)/lowprimes[lowprimes.length-1];
9448
9449//(public) test primality with certainty >= 1-.5^t
9450function bnIsProbablePrime(t) {
9451var i, x = this.abs();
9452if(x.t == 1 && x.data[0] <= lowprimes[lowprimes.length-1]) {
9453 for(i = 0; i < lowprimes.length; ++i)
9454   if(x.data[0] == lowprimes[i]) return true;
9455 return false;
9456}
9457if(x.isEven()) return false;
9458i = 1;
9459while(i < lowprimes.length) {
9460 var m = lowprimes[i], j = i+1;
9461 while(j < lowprimes.length && m < lplim) m *= lowprimes[j++];
9462 m = x.modInt(m);
9463 while(i < j) if(m%lowprimes[i++] == 0) return false;
9464}
9465return x.millerRabin(t);
9466}
9467
9468//(protected) true if probably prime (HAC 4.24, Miller-Rabin)
9469function bnpMillerRabin(t) {
9470var n1 = this.subtract(BigInteger.ONE);
9471var k = n1.getLowestSetBit();
9472if(k <= 0) return false;
9473var r = n1.shiftRight(k);
9474var prng = bnGetPrng();
9475var a;
9476for(var i = 0; i < t; ++i) {
9477 // select witness 'a' at random from between 1 and n1
9478 do {
9479   a = new BigInteger(this.bitLength(), prng);
9480 }
9481 while(a.compareTo(BigInteger.ONE) <= 0 || a.compareTo(n1) >= 0);
9482 var y = a.modPow(r,this);
9483 if(y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) {
9484   var j = 1;
9485   while(j++ < k && y.compareTo(n1) != 0) {
9486     y = y.modPowInt(2,this);
9487     if(y.compareTo(BigInteger.ONE) == 0) return false;
9488   }
9489   if(y.compareTo(n1) != 0) return false;
9490 }
9491}
9492return true;
9493}
9494
9495// get pseudo random number generator
9496function bnGetPrng() {
9497  // create prng with api that matches BigInteger secure random
9498  return {
9499    // x is an array to fill with bytes
9500    nextBytes: function(x) {
9501      for(var i = 0; i < x.length; ++i) {
9502        x[i] = Math.floor(Math.random() * 0x0100);
9503      }
9504    }
9505  };
9506}
9507
9508//protected
9509BigInteger.prototype.chunkSize = bnpChunkSize;
9510BigInteger.prototype.toRadix = bnpToRadix;
9511BigInteger.prototype.fromRadix = bnpFromRadix;
9512BigInteger.prototype.fromNumber = bnpFromNumber;
9513BigInteger.prototype.bitwiseTo = bnpBitwiseTo;
9514BigInteger.prototype.changeBit = bnpChangeBit;
9515BigInteger.prototype.addTo = bnpAddTo;
9516BigInteger.prototype.dMultiply = bnpDMultiply;
9517BigInteger.prototype.dAddOffset = bnpDAddOffset;
9518BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo;
9519BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo;
9520BigInteger.prototype.modInt = bnpModInt;
9521BigInteger.prototype.millerRabin = bnpMillerRabin;
9522
9523//public
9524BigInteger.prototype.clone = bnClone;
9525BigInteger.prototype.intValue = bnIntValue;
9526BigInteger.prototype.byteValue = bnByteValue;
9527BigInteger.prototype.shortValue = bnShortValue;
9528BigInteger.prototype.signum = bnSigNum;
9529BigInteger.prototype.toByteArray = bnToByteArray;
9530BigInteger.prototype.equals = bnEquals;
9531BigInteger.prototype.min = bnMin;
9532BigInteger.prototype.max = bnMax;
9533BigInteger.prototype.and = bnAnd;
9534BigInteger.prototype.or = bnOr;
9535BigInteger.prototype.xor = bnXor;
9536BigInteger.prototype.andNot = bnAndNot;
9537BigInteger.prototype.not = bnNot;
9538BigInteger.prototype.shiftLeft = bnShiftLeft;
9539BigInteger.prototype.shiftRight = bnShiftRight;
9540BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit;
9541BigInteger.prototype.bitCount = bnBitCount;
9542BigInteger.prototype.testBit = bnTestBit;
9543BigInteger.prototype.setBit = bnSetBit;
9544BigInteger.prototype.clearBit = bnClearBit;
9545BigInteger.prototype.flipBit = bnFlipBit;
9546BigInteger.prototype.add = bnAdd;
9547BigInteger.prototype.subtract = bnSubtract;
9548BigInteger.prototype.multiply = bnMultiply;
9549BigInteger.prototype.divide = bnDivide;
9550BigInteger.prototype.remainder = bnRemainder;
9551BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder;
9552BigInteger.prototype.modPow = bnModPow;
9553BigInteger.prototype.modInverse = bnModInverse;
9554BigInteger.prototype.pow = bnPow;
9555BigInteger.prototype.gcd = bnGCD;
9556BigInteger.prototype.isProbablePrime = bnIsProbablePrime;
9557
9558//BigInteger interfaces not implemented in jsbn:
9559
9560//BigInteger(int signum, byte[] magnitude)
9561//double doubleValue()
9562//float floatValue()
9563//int hashCode()
9564//long longValue()
9565//static BigInteger valueOf(long val)
9566
9567forge.jsbn = forge.jsbn || {};
9568forge.jsbn.BigInteger = BigInteger;
9569
9570} // end module implementation
9571
9572/* ########## Begin module wrapper ########## */
9573var name = 'jsbn';
9574if(typeof define !== 'function') {
9575  // NodeJS -> AMD
9576  if(typeof module === 'object' && module.exports) {
9577    var nodeJS = true;
9578    define = function(ids, factory) {
9579      factory(require, module);
9580    };
9581  } else {
9582    // <script>
9583    if(typeof forge === 'undefined') {
9584      forge = {};
9585    }
9586    return initModule(forge);
9587  }
9588}
9589// AMD
9590var deps;
9591var defineFunc = function(require, module) {
9592  module.exports = function(forge) {
9593    var mods = deps.map(function(dep) {
9594      return require(dep);
9595    }).concat(initModule);
9596    // handle circular dependencies
9597    forge = forge || {};
9598    forge.defined = forge.defined || {};
9599    if(forge.defined[name]) {
9600      return forge[name];
9601    }
9602    forge.defined[name] = true;
9603    for(var i = 0; i < mods.length; ++i) {
9604      mods[i](forge);
9605    }
9606    return forge[name];
9607  };
9608};
9609var tmpDefine = define;
9610define = function(ids, factory) {
9611  deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2);
9612  if(nodeJS) {
9613    delete define;
9614    return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0));
9615  }
9616  define = tmpDefine;
9617  return define.apply(null, Array.prototype.slice.call(arguments, 0));
9618};
9619define(['require', 'module'], function() {
9620  defineFunc.apply(null, Array.prototype.slice.call(arguments, 0));
9621});
9622})();
9623
9624/**
9625 * Javascript implementation of Abstract Syntax Notation Number One.
9626 *
9627 * @author Dave Longley
9628 *
9629 * Copyright (c) 2010-2015 Digital Bazaar, Inc.
9630 *
9631 * An API for storing data using the Abstract Syntax Notation Number One
9632 * format using DER (Distinguished Encoding Rules) encoding. This encoding is
9633 * commonly used to store data for PKI, i.e. X.509 Certificates, and this
9634 * implementation exists for that purpose.
9635 *
9636 * Abstract Syntax Notation Number One (ASN.1) is used to define the abstract
9637 * syntax of information without restricting the way the information is encoded
9638 * for transmission. It provides a standard that allows for open systems
9639 * communication. ASN.1 defines the syntax of information data and a number of
9640 * simple data types as well as a notation for describing them and specifying
9641 * values for them.
9642 *
9643 * The RSA algorithm creates public and private keys that are often stored in
9644 * X.509 or PKCS#X formats -- which use ASN.1 (encoded in DER format). This
9645 * class provides the most basic functionality required to store and load DSA
9646 * keys that are encoded according to ASN.1.
9647 *
9648 * The most common binary encodings for ASN.1 are BER (Basic Encoding Rules)
9649 * and DER (Distinguished Encoding Rules). DER is just a subset of BER that
9650 * has stricter requirements for how data must be encoded.
9651 *
9652 * Each ASN.1 structure has a tag (a byte identifying the ASN.1 structure type)
9653 * and a byte array for the value of this ASN1 structure which may be data or a
9654 * list of ASN.1 structures.
9655 *
9656 * Each ASN.1 structure using BER is (Tag-Length-Value):
9657 *
9658 * | byte 0 | bytes X | bytes Y |
9659 * |--------|---------|----------
9660 * |  tag   | length  |  value  |
9661 *
9662 * ASN.1 allows for tags to be of "High-tag-number form" which allows a tag to
9663 * be two or more octets, but that is not supported by this class. A tag is
9664 * only 1 byte. Bits 1-5 give the tag number (ie the data type within a
9665 * particular 'class'), 6 indicates whether or not the ASN.1 value is
9666 * constructed from other ASN.1 values, and bits 7 and 8 give the 'class'. If
9667 * bits 7 and 8 are both zero, the class is UNIVERSAL. If only bit 7 is set,
9668 * then the class is APPLICATION. If only bit 8 is set, then the class is
9669 * CONTEXT_SPECIFIC. If both bits 7 and 8 are set, then the class is PRIVATE.
9670 * The tag numbers for the data types for the class UNIVERSAL are listed below:
9671 *
9672 * UNIVERSAL 0 Reserved for use by the encoding rules
9673 * UNIVERSAL 1 Boolean type
9674 * UNIVERSAL 2 Integer type
9675 * UNIVERSAL 3 Bitstring type
9676 * UNIVERSAL 4 Octetstring type
9677 * UNIVERSAL 5 Null type
9678 * UNIVERSAL 6 Object identifier type
9679 * UNIVERSAL 7 Object descriptor type
9680 * UNIVERSAL 8 External type and Instance-of type
9681 * UNIVERSAL 9 Real type
9682 * UNIVERSAL 10 Enumerated type
9683 * UNIVERSAL 11 Embedded-pdv type
9684 * UNIVERSAL 12 UTF8String type
9685 * UNIVERSAL 13 Relative object identifier type
9686 * UNIVERSAL 14-15 Reserved for future editions
9687 * UNIVERSAL 16 Sequence and Sequence-of types
9688 * UNIVERSAL 17 Set and Set-of types
9689 * UNIVERSAL 18-22, 25-30 Character string types
9690 * UNIVERSAL 23-24 Time types
9691 *
9692 * The length of an ASN.1 structure is specified after the tag identifier.
9693 * There is a definite form and an indefinite form. The indefinite form may
9694 * be used if the encoding is constructed and not all immediately available.
9695 * The indefinite form is encoded using a length byte with only the 8th bit
9696 * set. The end of the constructed object is marked using end-of-contents
9697 * octets (two zero bytes).
9698 *
9699 * The definite form looks like this:
9700 *
9701 * The length may take up 1 or more bytes, it depends on the length of the
9702 * value of the ASN.1 structure. DER encoding requires that if the ASN.1
9703 * structure has a value that has a length greater than 127, more than 1 byte
9704 * will be used to store its length, otherwise just one byte will be used.
9705 * This is strict.
9706 *
9707 * In the case that the length of the ASN.1 value is less than 127, 1 octet
9708 * (byte) is used to store the "short form" length. The 8th bit has a value of
9709 * 0 indicating the length is "short form" and not "long form" and bits 7-1
9710 * give the length of the data. (The 8th bit is the left-most, most significant
9711 * bit: also known as big endian or network format).
9712 *
9713 * In the case that the length of the ASN.1 value is greater than 127, 2 to
9714 * 127 octets (bytes) are used to store the "long form" length. The first
9715 * byte's 8th bit is set to 1 to indicate the length is "long form." Bits 7-1
9716 * give the number of additional octets. All following octets are in base 256
9717 * with the most significant digit first (typical big-endian binary unsigned
9718 * integer storage). So, for instance, if the length of a value was 257, the
9719 * first byte would be set to:
9720 *
9721 * 10000010 = 130 = 0x82.
9722 *
9723 * This indicates there are 2 octets (base 256) for the length. The second and
9724 * third bytes (the octets just mentioned) would store the length in base 256:
9725 *
9726 * octet 2: 00000001 = 1 * 256^1 = 256
9727 * octet 3: 00000001 = 1 * 256^0 = 1
9728 * total = 257
9729 *
9730 * The algorithm for converting a js integer value of 257 to base-256 is:
9731 *
9732 * var value = 257;
9733 * var bytes = [];
9734 * bytes[0] = (value >>> 8) & 0xFF; // most significant byte first
9735 * bytes[1] = value & 0xFF;        // least significant byte last
9736 *
9737 * On the ASN.1 UNIVERSAL Object Identifier (OID) type:
9738 *
9739 * An OID can be written like: "value1.value2.value3...valueN"
9740 *
9741 * The DER encoding rules:
9742 *
9743 * The first byte has the value 40 * value1 + value2.
9744 * The following bytes, if any, encode the remaining values. Each value is
9745 * encoded in base 128, most significant digit first (big endian), with as
9746 * few digits as possible, and the most significant bit of each byte set
9747 * to 1 except the last in each value's encoding. For example: Given the
9748 * OID "1.2.840.113549", its DER encoding is (remember each byte except the
9749 * last one in each encoding is OR'd with 0x80):
9750 *
9751 * byte 1: 40 * 1 + 2 = 42 = 0x2A.
9752 * bytes 2-3: 128 * 6 + 72 = 840 = 6 72 = 6 72 = 0x0648 = 0x8648
9753 * bytes 4-6: 16384 * 6 + 128 * 119 + 13 = 6 119 13 = 0x06770D = 0x86F70D
9754 *
9755 * The final value is: 0x2A864886F70D.
9756 * The full OID (including ASN.1 tag and length of 6 bytes) is:
9757 * 0x06062A864886F70D
9758 */
9759(function() {
9760/* ########## Begin module implementation ########## */
9761function initModule(forge) {
9762
9763/* ASN.1 API */
9764var asn1 = forge.asn1 = forge.asn1 || {};
9765
9766/**
9767 * ASN.1 classes.
9768 */
9769asn1.Class = {
9770  UNIVERSAL:        0x00,
9771  APPLICATION:      0x40,
9772  CONTEXT_SPECIFIC: 0x80,
9773  PRIVATE:          0xC0
9774};
9775
9776/**
9777 * ASN.1 types. Not all types are supported by this implementation, only
9778 * those necessary to implement a simple PKI are implemented.
9779 */
9780asn1.Type = {
9781  NONE:             0,
9782  BOOLEAN:          1,
9783  INTEGER:          2,
9784  BITSTRING:        3,
9785  OCTETSTRING:      4,
9786  NULL:             5,
9787  OID:              6,
9788  ODESC:            7,
9789  EXTERNAL:         8,
9790  REAL:             9,
9791  ENUMERATED:      10,
9792  EMBEDDED:        11,
9793  UTF8:            12,
9794  ROID:            13,
9795  SEQUENCE:        16,
9796  SET:             17,
9797  PRINTABLESTRING: 19,
9798  IA5STRING:       22,
9799  UTCTIME:         23,
9800  GENERALIZEDTIME: 24,
9801  BMPSTRING:       30
9802};
9803
9804/**
9805 * Creates a new asn1 object.
9806 *
9807 * @param tagClass the tag class for the object.
9808 * @param type the data type (tag number) for the object.
9809 * @param constructed true if the asn1 object is in constructed form.
9810 * @param value the value for the object, if it is not constructed.
9811 *
9812 * @return the asn1 object.
9813 */
9814asn1.create = function(tagClass, type, constructed, value) {
9815  /* An asn1 object has a tagClass, a type, a constructed flag, and a
9816    value. The value's type depends on the constructed flag. If
9817    constructed, it will contain a list of other asn1 objects. If not,
9818    it will contain the ASN.1 value as an array of bytes formatted
9819    according to the ASN.1 data type. */
9820
9821  // remove undefined values
9822  if(forge.util.isArray(value)) {
9823    var tmp = [];
9824    for(var i = 0; i < value.length; ++i) {
9825      if(value[i] !== undefined) {
9826        tmp.push(value[i]);
9827      }
9828    }
9829    value = tmp;
9830  }
9831
9832  return {
9833    tagClass: tagClass,
9834    type: type,
9835    constructed: constructed,
9836    composed: constructed || forge.util.isArray(value),
9837    value: value
9838  };
9839};
9840
9841/**
9842 * Gets the length of a BER-encoded ASN.1 value.
9843 *
9844 * In case the length is not specified, undefined is returned.
9845 *
9846 * @param b the BER-encoded ASN.1 byte buffer, starting with the first
9847 *          length byte.
9848 *
9849 * @return the length of the BER-encoded ASN.1 value or undefined.
9850 */
9851var _getValueLength = asn1.getBerValueLength = function(b) {
9852  // TODO: move this function and related DER/BER functions to a der.js
9853  // file; better abstract ASN.1 away from der/ber.
9854  var b2 = b.getByte();
9855  if(b2 === 0x80) {
9856    return undefined;
9857  }
9858
9859  // see if the length is "short form" or "long form" (bit 8 set)
9860  var length;
9861  var longForm = b2 & 0x80;
9862  if(!longForm) {
9863    // length is just the first byte
9864    length = b2;
9865  } else {
9866    // the number of bytes the length is specified in bits 7 through 1
9867    // and each length byte is in big-endian base-256
9868    length = b.getInt((b2 & 0x7F) << 3);
9869  }
9870  return length;
9871};
9872
9873/**
9874 * Parses an asn1 object from a byte buffer in DER format.
9875 *
9876 * @param bytes the byte buffer to parse from.
9877 * @param strict true to be strict when checking value lengths, false to
9878 *          allow truncated values (default: true).
9879 *
9880 * @return the parsed asn1 object.
9881 */
9882asn1.fromDer = function(bytes, strict) {
9883  if(strict === undefined) {
9884    strict = true;
9885  }
9886
9887  // wrap in buffer if needed
9888  if(typeof bytes === 'string') {
9889    bytes = forge.util.createBuffer(bytes);
9890  }
9891
9892  // minimum length for ASN.1 DER structure is 2
9893  if(bytes.length() < 2) {
9894    var error = new Error('Too few bytes to parse DER.');
9895    error.bytes = bytes.length();
9896    throw error;
9897  }
9898
9899  // get the first byte
9900  var b1 = bytes.getByte();
9901
9902  // get the tag class
9903  var tagClass = (b1 & 0xC0);
9904
9905  // get the type (bits 1-5)
9906  var type = b1 & 0x1F;
9907
9908  // get the value length
9909  var length = _getValueLength(bytes);
9910
9911  // ensure there are enough bytes to get the value
9912  if(bytes.length() < length) {
9913    if(strict) {
9914      var error = new Error('Too few bytes to read ASN.1 value.');
9915      error.detail = bytes.length() + ' < ' + length;
9916      throw error;
9917    }
9918    // Note: be lenient with truncated values
9919    length = bytes.length();
9920  }
9921
9922  // prepare to get value
9923  var value;
9924
9925  // constructed flag is bit 6 (32 = 0x20) of the first byte
9926  var constructed = ((b1 & 0x20) === 0x20);
9927
9928  // determine if the value is composed of other ASN.1 objects (if its
9929  // constructed it will be and if its a BITSTRING it may be)
9930  var composed = constructed;
9931  if(!composed && tagClass === asn1.Class.UNIVERSAL &&
9932    type === asn1.Type.BITSTRING && length > 1) {
9933    /* The first octet gives the number of bits by which the length of the
9934      bit string is less than the next multiple of eight (this is called
9935      the "number of unused bits").
9936
9937      The second and following octets give the value of the bit string
9938      converted to an octet string. */
9939    // if there are no unused bits, maybe the bitstring holds ASN.1 objs
9940    var read = bytes.read;
9941    var unused = bytes.getByte();
9942    if(unused === 0) {
9943      // if the first byte indicates UNIVERSAL or CONTEXT_SPECIFIC,
9944      // and the length is valid, assume we've got an ASN.1 object
9945      b1 = bytes.getByte();
9946      var tc = (b1 & 0xC0);
9947      if(tc === asn1.Class.UNIVERSAL || tc === asn1.Class.CONTEXT_SPECIFIC) {
9948        try {
9949          var len = _getValueLength(bytes);
9950          composed = (len === length - (bytes.read - read));
9951          if(composed) {
9952            // adjust read/length to account for unused bits byte
9953            ++read;
9954            --length;
9955          }
9956        } catch(ex) {}
9957      }
9958    }
9959    // restore read pointer
9960    bytes.read = read;
9961  }
9962
9963  if(composed) {
9964    // parse child asn1 objects from the value
9965    value = [];
9966    if(length === undefined) {
9967      // asn1 object of indefinite length, read until end tag
9968      for(;;) {
9969        if(bytes.bytes(2) === String.fromCharCode(0, 0)) {
9970          bytes.getBytes(2);
9971          break;
9972        }
9973        value.push(asn1.fromDer(bytes, strict));
9974      }
9975    } else {
9976      // parsing asn1 object of definite length
9977      var start = bytes.length();
9978      while(length > 0) {
9979        value.push(asn1.fromDer(bytes, strict));
9980        length -= start - bytes.length();
9981        start = bytes.length();
9982      }
9983    }
9984  } else {
9985    // asn1 not composed, get raw value
9986    // TODO: do DER to OID conversion and vice-versa in .toDer?
9987
9988    if(length === undefined) {
9989      if(strict) {
9990        throw new Error('Non-constructed ASN.1 object of indefinite length.');
9991      }
9992      // be lenient and use remaining bytes
9993      length = bytes.length();
9994    }
9995
9996    if(type === asn1.Type.BMPSTRING) {
9997      value = '';
9998      for(var i = 0; i < length; i += 2) {
9999        value += String.fromCharCode(bytes.getInt16());
10000      }
10001    } else {
10002      value = bytes.getBytes(length);
10003    }
10004  }
10005
10006  // create and return asn1 object
10007  return asn1.create(tagClass, type, constructed, value);
10008};
10009
10010/**
10011 * Converts the given asn1 object to a buffer of bytes in DER format.
10012 *
10013 * @param asn1 the asn1 object to convert to bytes.
10014 *
10015 * @return the buffer of bytes.
10016 */
10017asn1.toDer = function(obj) {
10018  var bytes = forge.util.createBuffer();
10019
10020  // build the first byte
10021  var b1 = obj.tagClass | obj.type;
10022
10023  // for storing the ASN.1 value
10024  var value = forge.util.createBuffer();
10025
10026  // if composed, use each child asn1 object's DER bytes as value
10027  if(obj.composed) {
10028    // turn on 6th bit (0x20 = 32) to indicate asn1 is constructed
10029    // from other asn1 objects
10030    if(obj.constructed) {
10031      b1 |= 0x20;
10032    } else {
10033      // type is a bit string, add unused bits of 0x00
10034      value.putByte(0x00);
10035    }
10036
10037    // add all of the child DER bytes together
10038    for(var i = 0; i < obj.value.length; ++i) {
10039      if(obj.value[i] !== undefined) {
10040        value.putBuffer(asn1.toDer(obj.value[i]));
10041      }
10042    }
10043  } else {
10044    // use asn1.value directly
10045    if(obj.type === asn1.Type.BMPSTRING) {
10046      for(var i = 0; i < obj.value.length; ++i) {
10047        value.putInt16(obj.value.charCodeAt(i));
10048      }
10049    } else {
10050      // ensure integer is minimally-encoded
10051      if(obj.type === asn1.Type.INTEGER &&
10052        obj.value.length > 1 &&
10053        // leading 0x00 for positive integer
10054        ((obj.value.charCodeAt(0) === 0 &&
10055        (obj.value.charCodeAt(1) & 0x80) === 0) ||
10056        // leading 0xFF for negative integer
10057        (obj.value.charCodeAt(0) === 0xFF &&
10058        (obj.value.charCodeAt(1) & 0x80) === 0x80))) {
10059        value.putBytes(obj.value.substr(1));
10060      } else {
10061        value.putBytes(obj.value);
10062      }
10063    }
10064  }
10065
10066  // add tag byte
10067  bytes.putByte(b1);
10068
10069  // use "short form" encoding
10070  if(value.length() <= 127) {
10071    // one byte describes the length
10072    // bit 8 = 0 and bits 7-1 = length
10073    bytes.putByte(value.length() & 0x7F);
10074  } else {
10075    // use "long form" encoding
10076    // 2 to 127 bytes describe the length
10077    // first byte: bit 8 = 1 and bits 7-1 = # of additional bytes
10078    // other bytes: length in base 256, big-endian
10079    var len = value.length();
10080    var lenBytes = '';
10081    do {
10082      lenBytes += String.fromCharCode(len & 0xFF);
10083      len = len >>> 8;
10084    } while(len > 0);
10085
10086    // set first byte to # bytes used to store the length and turn on
10087    // bit 8 to indicate long-form length is used
10088    bytes.putByte(lenBytes.length | 0x80);
10089
10090    // concatenate length bytes in reverse since they were generated
10091    // little endian and we need big endian
10092    for(var i = lenBytes.length - 1; i >= 0; --i) {
10093      bytes.putByte(lenBytes.charCodeAt(i));
10094    }
10095  }
10096
10097  // concatenate value bytes
10098  bytes.putBuffer(value);
10099  return bytes;
10100};
10101
10102/**
10103 * Converts an OID dot-separated string to a byte buffer. The byte buffer
10104 * contains only the DER-encoded value, not any tag or length bytes.
10105 *
10106 * @param oid the OID dot-separated string.
10107 *
10108 * @return the byte buffer.
10109 */
10110asn1.oidToDer = function(oid) {
10111  // split OID into individual values
10112  var values = oid.split('.');
10113  var bytes = forge.util.createBuffer();
10114
10115  // first byte is 40 * value1 + value2
10116  bytes.putByte(40 * parseInt(values[0], 10) + parseInt(values[1], 10));
10117  // other bytes are each value in base 128 with 8th bit set except for
10118  // the last byte for each value
10119  var last, valueBytes, value, b;
10120  for(var i = 2; i < values.length; ++i) {
10121    // produce value bytes in reverse because we don't know how many
10122    // bytes it will take to store the value
10123    last = true;
10124    valueBytes = [];
10125    value = parseInt(values[i], 10);
10126    do {
10127      b = value & 0x7F;
10128      value = value >>> 7;
10129      // if value is not last, then turn on 8th bit
10130      if(!last) {
10131        b |= 0x80;
10132      }
10133      valueBytes.push(b);
10134      last = false;
10135    } while(value > 0);
10136
10137    // add value bytes in reverse (needs to be in big endian)
10138    for(var n = valueBytes.length - 1; n >= 0; --n) {
10139      bytes.putByte(valueBytes[n]);
10140    }
10141  }
10142
10143  return bytes;
10144};
10145
10146/**
10147 * Converts a DER-encoded byte buffer to an OID dot-separated string. The
10148 * byte buffer should contain only the DER-encoded value, not any tag or
10149 * length bytes.
10150 *
10151 * @param bytes the byte buffer.
10152 *
10153 * @return the OID dot-separated string.
10154 */
10155asn1.derToOid = function(bytes) {
10156  var oid;
10157
10158  // wrap in buffer if needed
10159  if(typeof bytes === 'string') {
10160    bytes = forge.util.createBuffer(bytes);
10161  }
10162
10163  // first byte is 40 * value1 + value2
10164  var b = bytes.getByte();
10165  oid = Math.floor(b / 40) + '.' + (b % 40);
10166
10167  // other bytes are each value in base 128 with 8th bit set except for
10168  // the last byte for each value
10169  var value = 0;
10170  while(bytes.length() > 0) {
10171    b = bytes.getByte();
10172    value = value << 7;
10173    // not the last byte for the value
10174    if(b & 0x80) {
10175      value += b & 0x7F;
10176    } else {
10177      // last byte
10178      oid += '.' + (value + b);
10179      value = 0;
10180    }
10181  }
10182
10183  return oid;
10184};
10185
10186/**
10187 * Converts a UTCTime value to a date.
10188 *
10189 * Note: GeneralizedTime has 4 digits for the year and is used for X.509
10190 * dates passed 2049. Parsing that structure hasn't been implemented yet.
10191 *
10192 * @param utc the UTCTime value to convert.
10193 *
10194 * @return the date.
10195 */
10196asn1.utcTimeToDate = function(utc) {
10197  /* The following formats can be used:
10198
10199    YYMMDDhhmmZ
10200    YYMMDDhhmm+hh'mm'
10201    YYMMDDhhmm-hh'mm'
10202    YYMMDDhhmmssZ
10203    YYMMDDhhmmss+hh'mm'
10204    YYMMDDhhmmss-hh'mm'
10205
10206    Where:
10207
10208    YY is the least significant two digits of the year
10209    MM is the month (01 to 12)
10210    DD is the day (01 to 31)
10211    hh is the hour (00 to 23)
10212    mm are the minutes (00 to 59)
10213    ss are the seconds (00 to 59)
10214    Z indicates that local time is GMT, + indicates that local time is
10215    later than GMT, and - indicates that local time is earlier than GMT
10216    hh' is the absolute value of the offset from GMT in hours
10217    mm' is the absolute value of the offset from GMT in minutes */
10218  var date = new Date();
10219
10220  // if YY >= 50 use 19xx, if YY < 50 use 20xx
10221  var year = parseInt(utc.substr(0, 2), 10);
10222  year = (year >= 50) ? 1900 + year : 2000 + year;
10223  var MM = parseInt(utc.substr(2, 2), 10) - 1; // use 0-11 for month
10224  var DD = parseInt(utc.substr(4, 2), 10);
10225  var hh = parseInt(utc.substr(6, 2), 10);
10226  var mm = parseInt(utc.substr(8, 2), 10);
10227  var ss = 0;
10228
10229  // not just YYMMDDhhmmZ
10230  if(utc.length > 11) {
10231    // get character after minutes
10232    var c = utc.charAt(10);
10233    var end = 10;
10234
10235    // see if seconds are present
10236    if(c !== '+' && c !== '-') {
10237      // get seconds
10238      ss = parseInt(utc.substr(10, 2), 10);
10239      end += 2;
10240    }
10241  }
10242
10243  // update date
10244  date.setUTCFullYear(year, MM, DD);
10245  date.setUTCHours(hh, mm, ss, 0);
10246
10247  if(end) {
10248    // get +/- after end of time
10249    c = utc.charAt(end);
10250    if(c === '+' || c === '-') {
10251      // get hours+minutes offset
10252      var hhoffset = parseInt(utc.substr(end + 1, 2), 10);
10253      var mmoffset = parseInt(utc.substr(end + 4, 2), 10);
10254
10255      // calculate offset in milliseconds
10256      var offset = hhoffset * 60 + mmoffset;
10257      offset *= 60000;
10258
10259      // apply offset
10260      if(c === '+') {
10261        date.setTime(+date - offset);
10262      } else {
10263        date.setTime(+date + offset);
10264      }
10265    }
10266  }
10267
10268  return date;
10269};
10270
10271/**
10272 * Converts a GeneralizedTime value to a date.
10273 *
10274 * @param gentime the GeneralizedTime value to convert.
10275 *
10276 * @return the date.
10277 */
10278asn1.generalizedTimeToDate = function(gentime) {
10279  /* The following formats can be used:
10280
10281    YYYYMMDDHHMMSS
10282    YYYYMMDDHHMMSS.fff
10283    YYYYMMDDHHMMSSZ
10284    YYYYMMDDHHMMSS.fffZ
10285    YYYYMMDDHHMMSS+hh'mm'
10286    YYYYMMDDHHMMSS.fff+hh'mm'
10287    YYYYMMDDHHMMSS-hh'mm'
10288    YYYYMMDDHHMMSS.fff-hh'mm'
10289
10290    Where:
10291
10292    YYYY is the year
10293    MM is the month (01 to 12)
10294    DD is the day (01 to 31)
10295    hh is the hour (00 to 23)
10296    mm are the minutes (00 to 59)
10297    ss are the seconds (00 to 59)
10298    .fff is the second fraction, accurate to three decimal places
10299    Z indicates that local time is GMT, + indicates that local time is
10300    later than GMT, and - indicates that local time is earlier than GMT
10301    hh' is the absolute value of the offset from GMT in hours
10302    mm' is the absolute value of the offset from GMT in minutes */
10303  var date = new Date();
10304
10305  var YYYY = parseInt(gentime.substr(0, 4), 10);
10306  var MM = parseInt(gentime.substr(4, 2), 10) - 1; // use 0-11 for month
10307  var DD = parseInt(gentime.substr(6, 2), 10);
10308  var hh = parseInt(gentime.substr(8, 2), 10);
10309  var mm = parseInt(gentime.substr(10, 2), 10);
10310  var ss = parseInt(gentime.substr(12, 2), 10);
10311  var fff = 0;
10312  var offset = 0;
10313  var isUTC = false;
10314
10315  if(gentime.charAt(gentime.length - 1) === 'Z') {
10316    isUTC = true;
10317  }
10318
10319  var end = gentime.length - 5, c = gentime.charAt(end);
10320  if(c === '+' || c === '-') {
10321    // get hours+minutes offset
10322    var hhoffset = parseInt(gentime.substr(end + 1, 2), 10);
10323    var mmoffset = parseInt(gentime.substr(end + 4, 2), 10);
10324
10325    // calculate offset in milliseconds
10326    offset = hhoffset * 60 + mmoffset;
10327    offset *= 60000;
10328
10329    // apply offset
10330    if(c === '+') {
10331      offset *= -1;
10332    }
10333
10334    isUTC = true;
10335  }
10336
10337  // check for second fraction
10338  if(gentime.charAt(14) === '.') {
10339    fff = parseFloat(gentime.substr(14), 10) * 1000;
10340  }
10341
10342  if(isUTC) {
10343    date.setUTCFullYear(YYYY, MM, DD);
10344    date.setUTCHours(hh, mm, ss, fff);
10345
10346    // apply offset
10347    date.setTime(+date + offset);
10348  } else {
10349    date.setFullYear(YYYY, MM, DD);
10350    date.setHours(hh, mm, ss, fff);
10351  }
10352
10353  return date;
10354};
10355
10356/**
10357 * Converts a date to a UTCTime value.
10358 *
10359 * Note: GeneralizedTime has 4 digits for the year and is used for X.509
10360 * dates passed 2049. Converting to a GeneralizedTime hasn't been
10361 * implemented yet.
10362 *
10363 * @param date the date to convert.
10364 *
10365 * @return the UTCTime value.
10366 */
10367asn1.dateToUtcTime = function(date) {
10368  // TODO: validate; currently assumes proper format
10369  if(typeof date === 'string') {
10370    return date;
10371  }
10372
10373  var rval = '';
10374
10375  // create format YYMMDDhhmmssZ
10376  var format = [];
10377  format.push(('' + date.getUTCFullYear()).substr(2));
10378  format.push('' + (date.getUTCMonth() + 1));
10379  format.push('' + date.getUTCDate());
10380  format.push('' + date.getUTCHours());
10381  format.push('' + date.getUTCMinutes());
10382  format.push('' + date.getUTCSeconds());
10383
10384  // ensure 2 digits are used for each format entry
10385  for(var i = 0; i < format.length; ++i) {
10386    if(format[i].length < 2) {
10387      rval += '0';
10388    }
10389    rval += format[i];
10390  }
10391  rval += 'Z';
10392
10393  return rval;
10394};
10395
10396/**
10397 * Converts a date to a GeneralizedTime value.
10398 *
10399 * @param date the date to convert.
10400 *
10401 * @return the GeneralizedTime value as a string.
10402 */
10403asn1.dateToGeneralizedTime = function(date) {
10404  // TODO: validate; currently assumes proper format
10405  if(typeof date === 'string') {
10406    return date;
10407  }
10408
10409  var rval = '';
10410
10411  // create format YYYYMMDDHHMMSSZ
10412  var format = [];
10413  format.push('' + date.getUTCFullYear());
10414  format.push('' + (date.getUTCMonth() + 1));
10415  format.push('' + date.getUTCDate());
10416  format.push('' + date.getUTCHours());
10417  format.push('' + date.getUTCMinutes());
10418  format.push('' + date.getUTCSeconds());
10419
10420  // ensure 2 digits are used for each format entry
10421  for(var i = 0; i < format.length; ++i) {
10422    if(format[i].length < 2) {
10423      rval += '0';
10424    }
10425    rval += format[i];
10426  }
10427  rval += 'Z';
10428
10429  return rval;
10430};
10431
10432/**
10433 * Converts a javascript integer to a DER-encoded byte buffer to be used
10434 * as the value for an INTEGER type.
10435 *
10436 * @param x the integer.
10437 *
10438 * @return the byte buffer.
10439 */
10440asn1.integerToDer = function(x) {
10441  var rval = forge.util.createBuffer();
10442  if(x >= -0x80 && x < 0x80) {
10443    return rval.putSignedInt(x, 8);
10444  }
10445  if(x >= -0x8000 && x < 0x8000) {
10446    return rval.putSignedInt(x, 16);
10447  }
10448  if(x >= -0x800000 && x < 0x800000) {
10449    return rval.putSignedInt(x, 24);
10450  }
10451  if(x >= -0x80000000 && x < 0x80000000) {
10452    return rval.putSignedInt(x, 32);
10453  }
10454  var error = new Error('Integer too large; max is 32-bits.');
10455  error.integer = x;
10456  throw error;
10457};
10458
10459/**
10460 * Converts a DER-encoded byte buffer to a javascript integer. This is
10461 * typically used to decode the value of an INTEGER type.
10462 *
10463 * @param bytes the byte buffer.
10464 *
10465 * @return the integer.
10466 */
10467asn1.derToInteger = function(bytes) {
10468  // wrap in buffer if needed
10469  if(typeof bytes === 'string') {
10470    bytes = forge.util.createBuffer(bytes);
10471  }
10472
10473  var n = bytes.length() * 8;
10474  if(n > 32) {
10475    throw new Error('Integer too large; max is 32-bits.');
10476  }
10477  return bytes.getSignedInt(n);
10478};
10479
10480/**
10481 * Validates the that given ASN.1 object is at least a super set of the
10482 * given ASN.1 structure. Only tag classes and types are checked. An
10483 * optional map may also be provided to capture ASN.1 values while the
10484 * structure is checked.
10485 *
10486 * To capture an ASN.1 value, set an object in the validator's 'capture'
10487 * parameter to the key to use in the capture map. To capture the full
10488 * ASN.1 object, specify 'captureAsn1'.
10489 *
10490 * Objects in the validator may set a field 'optional' to true to indicate
10491 * that it isn't necessary to pass validation.
10492 *
10493 * @param obj the ASN.1 object to validate.
10494 * @param v the ASN.1 structure validator.
10495 * @param capture an optional map to capture values in.
10496 * @param errors an optional array for storing validation errors.
10497 *
10498 * @return true on success, false on failure.
10499 */
10500asn1.validate = function(obj, v, capture, errors) {
10501  var rval = false;
10502
10503  // ensure tag class and type are the same if specified
10504  if((obj.tagClass === v.tagClass || typeof(v.tagClass) === 'undefined') &&
10505    (obj.type === v.type || typeof(v.type) === 'undefined')) {
10506    // ensure constructed flag is the same if specified
10507    if(obj.constructed === v.constructed ||
10508      typeof(v.constructed) === 'undefined') {
10509      rval = true;
10510
10511      // handle sub values
10512      if(v.value && forge.util.isArray(v.value)) {
10513        var j = 0;
10514        for(var i = 0; rval && i < v.value.length; ++i) {
10515          rval = v.value[i].optional || false;
10516          if(obj.value[j]) {
10517            rval = asn1.validate(obj.value[j], v.value[i], capture, errors);
10518            if(rval) {
10519              ++j;
10520            } else if(v.value[i].optional) {
10521              rval = true;
10522            }
10523          }
10524          if(!rval && errors) {
10525            errors.push(
10526              '[' + v.name + '] ' +
10527              'Tag class "' + v.tagClass + '", type "' +
10528              v.type + '" expected value length "' +
10529              v.value.length + '", got "' +
10530              obj.value.length + '"');
10531          }
10532        }
10533      }
10534
10535      if(rval && capture) {
10536        if(v.capture) {
10537          capture[v.capture] = obj.value;
10538        }
10539        if(v.captureAsn1) {
10540          capture[v.captureAsn1] = obj;
10541        }
10542      }
10543    } else if(errors) {
10544      errors.push(
10545        '[' + v.name + '] ' +
10546        'Expected constructed "' + v.constructed + '", got "' +
10547        obj.constructed + '"');
10548    }
10549  } else if(errors) {
10550    if(obj.tagClass !== v.tagClass) {
10551      errors.push(
10552        '[' + v.name + '] ' +
10553        'Expected tag class "' + v.tagClass + '", got "' +
10554        obj.tagClass + '"');
10555    }
10556    if(obj.type !== v.type) {
10557      errors.push(
10558        '[' + v.name + '] ' +
10559        'Expected type "' + v.type + '", got "' + obj.type + '"');
10560    }
10561  }
10562  return rval;
10563};
10564
10565// regex for testing for non-latin characters
10566var _nonLatinRegex = /[^\\u0000-\\u00ff]/;
10567
10568/**
10569 * Pretty prints an ASN.1 object to a string.
10570 *
10571 * @param obj the object to write out.
10572 * @param level the level in the tree.
10573 * @param indentation the indentation to use.
10574 *
10575 * @return the string.
10576 */
10577asn1.prettyPrint = function(obj, level, indentation) {
10578  var rval = '';
10579
10580  // set default level and indentation
10581  level = level || 0;
10582  indentation = indentation || 2;
10583
10584  // start new line for deep levels
10585  if(level > 0) {
10586    rval += '\n';
10587  }
10588
10589  // create indent
10590  var indent = '';
10591  for(var i = 0; i < level * indentation; ++i) {
10592    indent += ' ';
10593  }
10594
10595  // print class:type
10596  rval += indent + 'Tag: ';
10597  switch(obj.tagClass) {
10598  case asn1.Class.UNIVERSAL:
10599    rval += 'Universal:';
10600    break;
10601  case asn1.Class.APPLICATION:
10602    rval += 'Application:';
10603    break;
10604  case asn1.Class.CONTEXT_SPECIFIC:
10605    rval += 'Context-Specific:';
10606    break;
10607  case asn1.Class.PRIVATE:
10608    rval += 'Private:';
10609    break;
10610  }
10611
10612  if(obj.tagClass === asn1.Class.UNIVERSAL) {
10613    rval += obj.type;
10614
10615    // known types
10616    switch(obj.type) {
10617    case asn1.Type.NONE:
10618      rval += ' (None)';
10619      break;
10620    case asn1.Type.BOOLEAN:
10621      rval += ' (Boolean)';
10622      break;
10623    case asn1.Type.BITSTRING:
10624      rval += ' (Bit string)';
10625      break;
10626    case asn1.Type.INTEGER:
10627      rval += ' (Integer)';
10628      break;
10629    case asn1.Type.OCTETSTRING:
10630      rval += ' (Octet string)';
10631      break;
10632    case asn1.Type.NULL:
10633      rval += ' (Null)';
10634      break;
10635    case asn1.Type.OID:
10636      rval += ' (Object Identifier)';
10637      break;
10638    case asn1.Type.ODESC:
10639      rval += ' (Object Descriptor)';
10640      break;
10641    case asn1.Type.EXTERNAL:
10642      rval += ' (External or Instance of)';
10643      break;
10644    case asn1.Type.REAL:
10645      rval += ' (Real)';
10646      break;
10647    case asn1.Type.ENUMERATED:
10648      rval += ' (Enumerated)';
10649      break;
10650    case asn1.Type.EMBEDDED:
10651      rval += ' (Embedded PDV)';
10652      break;
10653    case asn1.Type.UTF8:
10654      rval += ' (UTF8)';
10655      break;
10656    case asn1.Type.ROID:
10657      rval += ' (Relative Object Identifier)';
10658      break;
10659    case asn1.Type.SEQUENCE:
10660      rval += ' (Sequence)';
10661      break;
10662    case asn1.Type.SET:
10663      rval += ' (Set)';
10664      break;
10665    case asn1.Type.PRINTABLESTRING:
10666      rval += ' (Printable String)';
10667      break;
10668    case asn1.Type.IA5String:
10669      rval += ' (IA5String (ASCII))';
10670      break;
10671    case asn1.Type.UTCTIME:
10672      rval += ' (UTC time)';
10673      break;
10674    case asn1.Type.GENERALIZEDTIME:
10675      rval += ' (Generalized time)';
10676      break;
10677    case asn1.Type.BMPSTRING:
10678      rval += ' (BMP String)';
10679      break;
10680    }
10681  } else {
10682    rval += obj.type;
10683  }
10684
10685  rval += '\n';
10686  rval += indent + 'Constructed: ' + obj.constructed + '\n';
10687
10688  if(obj.composed) {
10689    var subvalues = 0;
10690    var sub = '';
10691    for(var i = 0; i < obj.value.length; ++i) {
10692      if(obj.value[i] !== undefined) {
10693        subvalues += 1;
10694        sub += asn1.prettyPrint(obj.value[i], level + 1, indentation);
10695        if((i + 1) < obj.value.length) {
10696          sub += ',';
10697        }
10698      }
10699    }
10700    rval += indent + 'Sub values: ' + subvalues + sub;
10701  } else {
10702    rval += indent + 'Value: ';
10703    if(obj.type === asn1.Type.OID) {
10704      var oid = asn1.derToOid(obj.value);
10705      rval += oid;
10706      if(forge.pki && forge.pki.oids) {
10707        if(oid in forge.pki.oids) {
10708          rval += ' (' + forge.pki.oids[oid] + ') ';
10709        }
10710      }
10711    }
10712    if(obj.type === asn1.Type.INTEGER) {
10713      try {
10714        rval += asn1.derToInteger(obj.value);
10715      } catch(ex) {
10716        rval += '0x' + forge.util.bytesToHex(obj.value);
10717      }
10718    } else if(obj.type === asn1.Type.OCTETSTRING) {
10719      if(!_nonLatinRegex.test(obj.value)) {
10720        rval += '(' + obj.value + ') ';
10721      }
10722      rval += '0x' + forge.util.bytesToHex(obj.value);
10723    } else if(obj.type === asn1.Type.UTF8) {
10724      rval += forge.util.decodeUtf8(obj.value);
10725    } else if(obj.type === asn1.Type.PRINTABLESTRING ||
10726      obj.type === asn1.Type.IA5String) {
10727      rval += obj.value;
10728    } else if(_nonLatinRegex.test(obj.value)) {
10729      rval += '0x' + forge.util.bytesToHex(obj.value);
10730    } else if(obj.value.length === 0) {
10731      rval += '[null]';
10732    } else {
10733      rval += obj.value;
10734    }
10735  }
10736
10737  return rval;
10738};
10739
10740} // end module implementation
10741
10742/* ########## Begin module wrapper ########## */
10743var name = 'asn1';
10744if(typeof define !== 'function') {
10745  // NodeJS -> AMD
10746  if(typeof module === 'object' && module.exports) {
10747    var nodeJS = true;
10748    define = function(ids, factory) {
10749      factory(require, module);
10750    };
10751  } else {
10752    // <script>
10753    if(typeof forge === 'undefined') {
10754      forge = {};
10755    }
10756    return initModule(forge);
10757  }
10758}
10759// AMD
10760var deps;
10761var defineFunc = function(require, module) {
10762  module.exports = function(forge) {
10763    var mods = deps.map(function(dep) {
10764      return require(dep);
10765    }).concat(initModule);
10766    // handle circular dependencies
10767    forge = forge || {};
10768    forge.defined = forge.defined || {};
10769    if(forge.defined[name]) {
10770      return forge[name];
10771    }
10772    forge.defined[name] = true;
10773    for(var i = 0; i < mods.length; ++i) {
10774      mods[i](forge);
10775    }
10776    return forge[name];
10777  };
10778};
10779var tmpDefine = define;
10780define = function(ids, factory) {
10781  deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2);
10782  if(nodeJS) {
10783    delete define;
10784    return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0));
10785  }
10786  define = tmpDefine;
10787  return define.apply(null, Array.prototype.slice.call(arguments, 0));
10788};
10789define(['require', 'module', './util', './oids'], function() {
10790  defineFunc.apply(null, Array.prototype.slice.call(arguments, 0));
10791});
10792})();
10793
10794/**
10795 * Javascript implementation of basic PEM (Privacy Enhanced Mail) algorithms.
10796 *
10797 * See: RFC 1421.
10798 *
10799 * @author Dave Longley
10800 *
10801 * Copyright (c) 2013-2014 Digital Bazaar, Inc.
10802 *
10803 * A Forge PEM object has the following fields:
10804 *
10805 * type: identifies the type of message (eg: "RSA PRIVATE KEY").
10806 *
10807 * procType: identifies the type of processing performed on the message,
10808 *   it has two subfields: version and type, eg: 4,ENCRYPTED.
10809 *
10810 * contentDomain: identifies the type of content in the message, typically
10811 *   only uses the value: "RFC822".
10812 *
10813 * dekInfo: identifies the message encryption algorithm and mode and includes
10814 *   any parameters for the algorithm, it has two subfields: algorithm and
10815 *   parameters, eg: DES-CBC,F8143EDE5960C597.
10816 *
10817 * headers: contains all other PEM encapsulated headers -- where order is
10818 *   significant (for pairing data like recipient ID + key info).
10819 *
10820 * body: the binary-encoded body.
10821 */
10822(function() {
10823/* ########## Begin module implementation ########## */
10824function initModule(forge) {
10825
10826// shortcut for pem API
10827var pem = forge.pem = forge.pem || {};
10828
10829/**
10830 * Encodes (serializes) the given PEM object.
10831 *
10832 * @param msg the PEM message object to encode.
10833 * @param options the options to use:
10834 *          maxline the maximum characters per line for the body, (default: 64).
10835 *
10836 * @return the PEM-formatted string.
10837 */
10838pem.encode = function(msg, options) {
10839  options = options || {};
10840  var rval = '-----BEGIN ' + msg.type + '-----\r\n';
10841
10842  // encode special headers
10843  var header;
10844  if(msg.procType) {
10845    header = {
10846      name: 'Proc-Type',
10847      values: [String(msg.procType.version), msg.procType.type]
10848    };
10849    rval += foldHeader(header);
10850  }
10851  if(msg.contentDomain) {
10852    header = {name: 'Content-Domain', values: [msg.contentDomain]};
10853    rval += foldHeader(header);
10854  }
10855  if(msg.dekInfo) {
10856    header = {name: 'DEK-Info', values: [msg.dekInfo.algorithm]};
10857    if(msg.dekInfo.parameters) {
10858      header.values.push(msg.dekInfo.parameters);
10859    }
10860    rval += foldHeader(header);
10861  }
10862
10863  if(msg.headers) {
10864    // encode all other headers
10865    for(var i = 0; i < msg.headers.length; ++i) {
10866      rval += foldHeader(msg.headers[i]);
10867    }
10868  }
10869
10870  // terminate header
10871  if(msg.procType) {
10872    rval += '\r\n';
10873  }
10874
10875  // add body
10876  rval += forge.util.encode64(msg.body, options.maxline || 64) + '\r\n';
10877
10878  rval += '-----END ' + msg.type + '-----\r\n';
10879  return rval;
10880};
10881
10882/**
10883 * Decodes (deserializes) all PEM messages found in the given string.
10884 *
10885 * @param str the PEM-formatted string to decode.
10886 *
10887 * @return the PEM message objects in an array.
10888 */
10889pem.decode = function(str) {
10890  var rval = [];
10891
10892  // split string into PEM messages (be lenient w/EOF on BEGIN line)
10893  var rMessage = /\s*-----BEGIN ([A-Z0-9- ]+)-----\r?\n?([\x21-\x7e\s]+?(?:\r?\n\r?\n))?([:A-Za-z0-9+\/=\s]+?)-----END \1-----/g;
10894  var rHeader = /([\x21-\x7e]+):\s*([\x21-\x7e\s^:]+)/;
10895  var rCRLF = /\r?\n/;
10896  var match;
10897  while(true) {
10898    match = rMessage.exec(str);
10899    if(!match) {
10900      break;
10901    }
10902
10903    var msg = {
10904      type: match[1],
10905      procType: null,
10906      contentDomain: null,
10907      dekInfo: null,
10908      headers: [],
10909      body: forge.util.decode64(match[3])
10910    };
10911    rval.push(msg);
10912
10913    // no headers
10914    if(!match[2]) {
10915      continue;
10916    }
10917
10918    // parse headers
10919    var lines = match[2].split(rCRLF);
10920    var li = 0;
10921    while(match && li < lines.length) {
10922      // get line, trim any rhs whitespace
10923      var line = lines[li].replace(/\s+$/, '');
10924
10925      // RFC2822 unfold any following folded lines
10926      for(var nl = li + 1; nl < lines.length; ++nl) {
10927        var next = lines[nl];
10928        if(!/\s/.test(next[0])) {
10929          break;
10930        }
10931        line += next;
10932        li = nl;
10933      }
10934
10935      // parse header
10936      match = line.match(rHeader);
10937      if(match) {
10938        var header = {name: match[1], values: []};
10939        var values = match[2].split(',');
10940        for(var vi = 0; vi < values.length; ++vi) {
10941          header.values.push(ltrim(values[vi]));
10942        }
10943
10944        // Proc-Type must be the first header
10945        if(!msg.procType) {
10946          if(header.name !== 'Proc-Type') {
10947            throw new Error('Invalid PEM formatted message. The first ' +
10948              'encapsulated header must be "Proc-Type".');
10949          } else if(header.values.length !== 2) {
10950            throw new Error('Invalid PEM formatted message. The "Proc-Type" ' +
10951              'header must have two subfields.');
10952          }
10953          msg.procType = {version: values[0], type: values[1]};
10954        } else if(!msg.contentDomain && header.name === 'Content-Domain') {
10955          // special-case Content-Domain
10956          msg.contentDomain = values[0] || '';
10957        } else if(!msg.dekInfo && header.name === 'DEK-Info') {
10958          // special-case DEK-Info
10959          if(header.values.length === 0) {
10960            throw new Error('Invalid PEM formatted message. The "DEK-Info" ' +
10961              'header must have at least one subfield.');
10962          }
10963          msg.dekInfo = {algorithm: values[0], parameters: values[1] || null};
10964        } else {
10965          msg.headers.push(header);
10966        }
10967      }
10968
10969      ++li;
10970    }
10971
10972    if(msg.procType === 'ENCRYPTED' && !msg.dekInfo) {
10973      throw new Error('Invalid PEM formatted message. The "DEK-Info" ' +
10974        'header must be present if "Proc-Type" is "ENCRYPTED".');
10975    }
10976  }
10977
10978  if(rval.length === 0) {
10979    throw new Error('Invalid PEM formatted message.');
10980  }
10981
10982  return rval;
10983};
10984
10985function foldHeader(header) {
10986  var rval = header.name + ': ';
10987
10988  // ensure values with CRLF are folded
10989  var values = [];
10990  var insertSpace = function(match, $1) {
10991    return ' ' + $1;
10992  };
10993  for(var i = 0; i < header.values.length; ++i) {
10994    values.push(header.values[i].replace(/^(\S+\r\n)/, insertSpace));
10995  }
10996  rval += values.join(',') + '\r\n';
10997
10998  // do folding
10999  var length = 0;
11000  var candidate = -1;
11001  for(var i = 0; i < rval.length; ++i, ++length) {
11002    if(length > 65 && candidate !== -1) {
11003      var insert = rval[candidate];
11004      if(insert === ',') {
11005        ++candidate;
11006        rval = rval.substr(0, candidate) + '\r\n ' + rval.substr(candidate);
11007      } else {
11008        rval = rval.substr(0, candidate) +
11009          '\r\n' + insert + rval.substr(candidate + 1);
11010      }
11011      length = (i - candidate - 1);
11012      candidate = -1;
11013      ++i;
11014    } else if(rval[i] === ' ' || rval[i] === '\t' || rval[i] === ',') {
11015      candidate = i;
11016    }
11017  }
11018
11019  return rval;
11020}
11021
11022function ltrim(str) {
11023  return str.replace(/^\s+/, '');
11024}
11025
11026} // end module implementation
11027
11028/* ########## Begin module wrapper ########## */
11029var name = 'pem';
11030if(typeof define !== 'function') {
11031  // NodeJS -> AMD
11032  if(typeof module === 'object' && module.exports) {
11033    var nodeJS = true;
11034    define = function(ids, factory) {
11035      factory(require, module);
11036    };
11037  } else {
11038    // <script>
11039    if(typeof forge === 'undefined') {
11040      forge = {};
11041    }
11042    return initModule(forge);
11043  }
11044}
11045// AMD
11046var deps;
11047var defineFunc = function(require, module) {
11048  module.exports = function(forge) {
11049    var mods = deps.map(function(dep) {
11050      return require(dep);
11051    }).concat(initModule);
11052    // handle circular dependencies
11053    forge = forge || {};
11054    forge.defined = forge.defined || {};
11055    if(forge.defined[name]) {
11056      return forge[name];
11057    }
11058    forge.defined[name] = true;
11059    for(var i = 0; i < mods.length; ++i) {
11060      mods[i](forge);
11061    }
11062    return forge[name];
11063  };
11064};
11065var tmpDefine = define;
11066define = function(ids, factory) {
11067  deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2);
11068  if(nodeJS) {
11069    delete define;
11070    return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0));
11071  }
11072  define = tmpDefine;
11073  return define.apply(null, Array.prototype.slice.call(arguments, 0));
11074};
11075define(['require', 'module', './util'], function() {
11076  defineFunc.apply(null, Array.prototype.slice.call(arguments, 0));
11077});
11078})();
11079
11080/**
11081 * Javascript implementation of basic RSA algorithms.
11082 *
11083 * @author Dave Longley
11084 *
11085 * Copyright (c) 2010-2014 Digital Bazaar, Inc.
11086 *
11087 * The only algorithm currently supported for PKI is RSA.
11088 *
11089 * An RSA key is often stored in ASN.1 DER format. The SubjectPublicKeyInfo
11090 * ASN.1 structure is composed of an algorithm of type AlgorithmIdentifier
11091 * and a subjectPublicKey of type bit string.
11092 *
11093 * The AlgorithmIdentifier contains an Object Identifier (OID) and parameters
11094 * for the algorithm, if any. In the case of RSA, there aren't any.
11095 *
11096 * SubjectPublicKeyInfo ::= SEQUENCE {
11097 *   algorithm AlgorithmIdentifier,
11098 *   subjectPublicKey BIT STRING
11099 * }
11100 *
11101 * AlgorithmIdentifer ::= SEQUENCE {
11102 *   algorithm OBJECT IDENTIFIER,
11103 *   parameters ANY DEFINED BY algorithm OPTIONAL
11104 * }
11105 *
11106 * For an RSA public key, the subjectPublicKey is:
11107 *
11108 * RSAPublicKey ::= SEQUENCE {
11109 *   modulus            INTEGER,    -- n
11110 *   publicExponent     INTEGER     -- e
11111 * }
11112 *
11113 * PrivateKeyInfo ::= SEQUENCE {
11114 *   version                   Version,
11115 *   privateKeyAlgorithm       PrivateKeyAlgorithmIdentifier,
11116 *   privateKey                PrivateKey,
11117 *   attributes           [0]  IMPLICIT Attributes OPTIONAL
11118 * }
11119 *
11120 * Version ::= INTEGER
11121 * PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
11122 * PrivateKey ::= OCTET STRING
11123 * Attributes ::= SET OF Attribute
11124 *
11125 * An RSA private key as the following structure:
11126 *
11127 * RSAPrivateKey ::= SEQUENCE {
11128 *   version Version,
11129 *   modulus INTEGER, -- n
11130 *   publicExponent INTEGER, -- e
11131 *   privateExponent INTEGER, -- d
11132 *   prime1 INTEGER, -- p
11133 *   prime2 INTEGER, -- q
11134 *   exponent1 INTEGER, -- d mod (p-1)
11135 *   exponent2 INTEGER, -- d mod (q-1)
11136 *   coefficient INTEGER -- (inverse of q) mod p
11137 * }
11138 *
11139 * Version ::= INTEGER
11140 *
11141 * The OID for the RSA key algorithm is: 1.2.840.113549.1.1.1
11142 */
11143(function() {
11144function initModule(forge) {
11145/* ########## Begin module implementation ########## */
11146
11147if(typeof BigInteger === 'undefined') {
11148  var BigInteger = forge.jsbn.BigInteger;
11149}
11150
11151// shortcut for asn.1 API
11152var asn1 = forge.asn1;
11153
11154/*
11155 * RSA encryption and decryption, see RFC 2313.
11156 */
11157forge.pki = forge.pki || {};
11158forge.pki.rsa = forge.rsa = forge.rsa || {};
11159var pki = forge.pki;
11160
11161// for finding primes, which are 30k+i for i = 1, 7, 11, 13, 17, 19, 23, 29
11162var GCD_30_DELTA = [6, 4, 2, 4, 2, 4, 6, 2];
11163
11164// validator for a PrivateKeyInfo structure
11165var privateKeyValidator = {
11166  // PrivateKeyInfo
11167  name: 'PrivateKeyInfo',
11168  tagClass: asn1.Class.UNIVERSAL,
11169  type: asn1.Type.SEQUENCE,
11170  constructed: true,
11171  value: [{
11172    // Version (INTEGER)
11173    name: 'PrivateKeyInfo.version',
11174    tagClass: asn1.Class.UNIVERSAL,
11175    type: asn1.Type.INTEGER,
11176    constructed: false,
11177    capture: 'privateKeyVersion'
11178  }, {
11179    // privateKeyAlgorithm
11180    name: 'PrivateKeyInfo.privateKeyAlgorithm',
11181    tagClass: asn1.Class.UNIVERSAL,
11182    type: asn1.Type.SEQUENCE,
11183    constructed: true,
11184    value: [{
11185      name: 'AlgorithmIdentifier.algorithm',
11186      tagClass: asn1.Class.UNIVERSAL,
11187      type: asn1.Type.OID,
11188      constructed: false,
11189      capture: 'privateKeyOid'
11190    }]
11191  }, {
11192    // PrivateKey
11193    name: 'PrivateKeyInfo',
11194    tagClass: asn1.Class.UNIVERSAL,
11195    type: asn1.Type.OCTETSTRING,
11196    constructed: false,
11197    capture: 'privateKey'
11198  }]
11199};
11200
11201// validator for an RSA private key
11202var rsaPrivateKeyValidator = {
11203  // RSAPrivateKey
11204  name: 'RSAPrivateKey',
11205  tagClass: asn1.Class.UNIVERSAL,
11206  type: asn1.Type.SEQUENCE,
11207  constructed: true,
11208  value: [{
11209    // Version (INTEGER)
11210    name: 'RSAPrivateKey.version',
11211    tagClass: asn1.Class.UNIVERSAL,
11212    type: asn1.Type.INTEGER,
11213    constructed: false,
11214    capture: 'privateKeyVersion'
11215  }, {
11216    // modulus (n)
11217    name: 'RSAPrivateKey.modulus',
11218    tagClass: asn1.Class.UNIVERSAL,
11219    type: asn1.Type.INTEGER,
11220    constructed: false,
11221    capture: 'privateKeyModulus'
11222  }, {
11223    // publicExponent (e)
11224    name: 'RSAPrivateKey.publicExponent',
11225    tagClass: asn1.Class.UNIVERSAL,
11226    type: asn1.Type.INTEGER,
11227    constructed: false,
11228    capture: 'privateKeyPublicExponent'
11229  }, {
11230    // privateExponent (d)
11231    name: 'RSAPrivateKey.privateExponent',
11232    tagClass: asn1.Class.UNIVERSAL,
11233    type: asn1.Type.INTEGER,
11234    constructed: false,
11235    capture: 'privateKeyPrivateExponent'
11236  }, {
11237    // prime1 (p)
11238    name: 'RSAPrivateKey.prime1',
11239    tagClass: asn1.Class.UNIVERSAL,
11240    type: asn1.Type.INTEGER,
11241    constructed: false,
11242    capture: 'privateKeyPrime1'
11243  }, {
11244    // prime2 (q)
11245    name: 'RSAPrivateKey.prime2',
11246    tagClass: asn1.Class.UNIVERSAL,
11247    type: asn1.Type.INTEGER,
11248    constructed: false,
11249    capture: 'privateKeyPrime2'
11250  }, {
11251    // exponent1 (d mod (p-1))
11252    name: 'RSAPrivateKey.exponent1',
11253    tagClass: asn1.Class.UNIVERSAL,
11254    type: asn1.Type.INTEGER,
11255    constructed: false,
11256    capture: 'privateKeyExponent1'
11257  }, {
11258    // exponent2 (d mod (q-1))
11259    name: 'RSAPrivateKey.exponent2',
11260    tagClass: asn1.Class.UNIVERSAL,
11261    type: asn1.Type.INTEGER,
11262    constructed: false,
11263    capture: 'privateKeyExponent2'
11264  }, {
11265    // coefficient ((inverse of q) mod p)
11266    name: 'RSAPrivateKey.coefficient',
11267    tagClass: asn1.Class.UNIVERSAL,
11268    type: asn1.Type.INTEGER,
11269    constructed: false,
11270    capture: 'privateKeyCoefficient'
11271  }]
11272};
11273
11274// validator for an RSA public key
11275var rsaPublicKeyValidator = {
11276  // RSAPublicKey
11277  name: 'RSAPublicKey',
11278  tagClass: asn1.Class.UNIVERSAL,
11279  type: asn1.Type.SEQUENCE,
11280  constructed: true,
11281  value: [{
11282    // modulus (n)
11283    name: 'RSAPublicKey.modulus',
11284    tagClass: asn1.Class.UNIVERSAL,
11285    type: asn1.Type.INTEGER,
11286    constructed: false,
11287    capture: 'publicKeyModulus'
11288  }, {
11289    // publicExponent (e)
11290    name: 'RSAPublicKey.exponent',
11291    tagClass: asn1.Class.UNIVERSAL,
11292    type: asn1.Type.INTEGER,
11293    constructed: false,
11294    capture: 'publicKeyExponent'
11295  }]
11296};
11297
11298// validator for an SubjectPublicKeyInfo structure
11299// Note: Currently only works with an RSA public key
11300var publicKeyValidator = forge.pki.rsa.publicKeyValidator = {
11301  name: 'SubjectPublicKeyInfo',
11302  tagClass: asn1.Class.UNIVERSAL,
11303  type: asn1.Type.SEQUENCE,
11304  constructed: true,
11305  captureAsn1: 'subjectPublicKeyInfo',
11306  value: [{
11307    name: 'SubjectPublicKeyInfo.AlgorithmIdentifier',
11308    tagClass: asn1.Class.UNIVERSAL,
11309    type: asn1.Type.SEQUENCE,
11310    constructed: true,
11311    value: [{
11312      name: 'AlgorithmIdentifier.algorithm',
11313      tagClass: asn1.Class.UNIVERSAL,
11314      type: asn1.Type.OID,
11315      constructed: false,
11316      capture: 'publicKeyOid'
11317    }]
11318  }, {
11319    // subjectPublicKey
11320    name: 'SubjectPublicKeyInfo.subjectPublicKey',
11321    tagClass: asn1.Class.UNIVERSAL,
11322    type: asn1.Type.BITSTRING,
11323    constructed: false,
11324    value: [{
11325      // RSAPublicKey
11326      name: 'SubjectPublicKeyInfo.subjectPublicKey.RSAPublicKey',
11327      tagClass: asn1.Class.UNIVERSAL,
11328      type: asn1.Type.SEQUENCE,
11329      constructed: true,
11330      optional: true,
11331      captureAsn1: 'rsaPublicKey'
11332    }]
11333  }]
11334};
11335
11336/**
11337 * Wrap digest in DigestInfo object.
11338 *
11339 * This function implements EMSA-PKCS1-v1_5-ENCODE as per RFC 3447.
11340 *
11341 * DigestInfo ::= SEQUENCE {
11342 *   digestAlgorithm DigestAlgorithmIdentifier,
11343 *   digest Digest
11344 * }
11345 *
11346 * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
11347 * Digest ::= OCTET STRING
11348 *
11349 * @param md the message digest object with the hash to sign.
11350 *
11351 * @return the encoded message (ready for RSA encrytion)
11352 */
11353var emsaPkcs1v15encode = function(md) {
11354  // get the oid for the algorithm
11355  var oid;
11356  if(md.algorithm in pki.oids) {
11357    oid = pki.oids[md.algorithm];
11358  } else {
11359    var error = new Error('Unknown message digest algorithm.');
11360    error.algorithm = md.algorithm;
11361    throw error;
11362  }
11363  var oidBytes = asn1.oidToDer(oid).getBytes();
11364
11365  // create the digest info
11366  var digestInfo = asn1.create(
11367    asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, []);
11368  var digestAlgorithm = asn1.create(
11369    asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, []);
11370  digestAlgorithm.value.push(asn1.create(
11371    asn1.Class.UNIVERSAL, asn1.Type.OID, false, oidBytes));
11372  digestAlgorithm.value.push(asn1.create(
11373    asn1.Class.UNIVERSAL, asn1.Type.NULL, false, ''));
11374  var digest = asn1.create(
11375    asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING,
11376    false, md.digest().getBytes());
11377  digestInfo.value.push(digestAlgorithm);
11378  digestInfo.value.push(digest);
11379
11380  // encode digest info
11381  return asn1.toDer(digestInfo).getBytes();
11382};
11383
11384/**
11385 * Performs x^c mod n (RSA encryption or decryption operation).
11386 *
11387 * @param x the number to raise and mod.
11388 * @param key the key to use.
11389 * @param pub true if the key is public, false if private.
11390 *
11391 * @return the result of x^c mod n.
11392 */
11393var _modPow = function(x, key, pub) {
11394  if(pub) {
11395    return x.modPow(key.e, key.n);
11396  }
11397
11398  if(!key.p || !key.q) {
11399    // allow calculation without CRT params (slow)
11400    return x.modPow(key.d, key.n);
11401  }
11402
11403  // pre-compute dP, dQ, and qInv if necessary
11404  if(!key.dP) {
11405    key.dP = key.d.mod(key.p.subtract(BigInteger.ONE));
11406  }
11407  if(!key.dQ) {
11408    key.dQ = key.d.mod(key.q.subtract(BigInteger.ONE));
11409  }
11410  if(!key.qInv) {
11411    key.qInv = key.q.modInverse(key.p);
11412  }
11413
11414  /* Chinese remainder theorem (CRT) states:
11415
11416    Suppose n1, n2, ..., nk are positive integers which are pairwise
11417    coprime (n1 and n2 have no common factors other than 1). For any
11418    integers x1, x2, ..., xk there exists an integer x solving the
11419    system of simultaneous congruences (where ~= means modularly
11420    congruent so a ~= b mod n means a mod n = b mod n):
11421
11422    x ~= x1 mod n1
11423    x ~= x2 mod n2
11424    ...
11425    x ~= xk mod nk
11426
11427    This system of congruences has a single simultaneous solution x
11428    between 0 and n - 1. Furthermore, each xk solution and x itself
11429    is congruent modulo the product n = n1*n2*...*nk.
11430    So x1 mod n = x2 mod n = xk mod n = x mod n.
11431
11432    The single simultaneous solution x can be solved with the following
11433    equation:
11434
11435    x = sum(xi*ri*si) mod n where ri = n/ni and si = ri^-1 mod ni.
11436
11437    Where x is less than n, xi = x mod ni.
11438
11439    For RSA we are only concerned with k = 2. The modulus n = pq, where
11440    p and q are coprime. The RSA decryption algorithm is:
11441
11442    y = x^d mod n
11443
11444    Given the above:
11445
11446    x1 = x^d mod p
11447    r1 = n/p = q
11448    s1 = q^-1 mod p
11449    x2 = x^d mod q
11450    r2 = n/q = p
11451    s2 = p^-1 mod q
11452
11453    So y = (x1r1s1 + x2r2s2) mod n
11454         = ((x^d mod p)q(q^-1 mod p) + (x^d mod q)p(p^-1 mod q)) mod n
11455
11456    According to Fermat's Little Theorem, if the modulus P is prime,
11457    for any integer A not evenly divisible by P, A^(P-1) ~= 1 mod P.
11458    Since A is not divisible by P it follows that if:
11459    N ~= M mod (P - 1), then A^N mod P = A^M mod P. Therefore:
11460
11461    A^N mod P = A^(M mod (P - 1)) mod P. (The latter takes less effort
11462    to calculate). In order to calculate x^d mod p more quickly the
11463    exponent d mod (p - 1) is stored in the RSA private key (the same
11464    is done for x^d mod q). These values are referred to as dP and dQ
11465    respectively. Therefore we now have:
11466
11467    y = ((x^dP mod p)q(q^-1 mod p) + (x^dQ mod q)p(p^-1 mod q)) mod n
11468
11469    Since we'll be reducing x^dP by modulo p (same for q) we can also
11470    reduce x by p (and q respectively) before hand. Therefore, let
11471
11472    xp = ((x mod p)^dP mod p), and
11473    xq = ((x mod q)^dQ mod q), yielding:
11474
11475    y = (xp*q*(q^-1 mod p) + xq*p*(p^-1 mod q)) mod n
11476
11477    This can be further reduced to a simple algorithm that only
11478    requires 1 inverse (the q inverse is used) to be used and stored.
11479    The algorithm is called Garner's algorithm. If qInv is the
11480    inverse of q, we simply calculate:
11481
11482    y = (qInv*(xp - xq) mod p) * q + xq
11483
11484    However, there are two further complications. First, we need to
11485    ensure that xp > xq to prevent signed BigIntegers from being used
11486    so we add p until this is true (since we will be mod'ing with
11487    p anyway). Then, there is a known timing attack on algorithms
11488    using the CRT. To mitigate this risk, "cryptographic blinding"
11489    should be used. This requires simply generating a random number r
11490    between 0 and n-1 and its inverse and multiplying x by r^e before
11491    calculating y and then multiplying y by r^-1 afterwards. Note that
11492    r must be coprime with n (gcd(r, n) === 1) in order to have an
11493    inverse.
11494  */
11495
11496  // cryptographic blinding
11497  var r;
11498  do {
11499    r = new BigInteger(
11500      forge.util.bytesToHex(forge.random.getBytes(key.n.bitLength() / 8)),
11501      16);
11502  } while(r.compareTo(key.n) >= 0 || !r.gcd(key.n).equals(BigInteger.ONE));
11503  x = x.multiply(r.modPow(key.e, key.n)).mod(key.n);
11504
11505  // calculate xp and xq
11506  var xp = x.mod(key.p).modPow(key.dP, key.p);
11507  var xq = x.mod(key.q).modPow(key.dQ, key.q);
11508
11509  // xp must be larger than xq to avoid signed bit usage
11510  while(xp.compareTo(xq) < 0) {
11511    xp = xp.add(key.p);
11512  }
11513
11514  // do last step
11515  var y = xp.subtract(xq)
11516    .multiply(key.qInv).mod(key.p)
11517    .multiply(key.q).add(xq);
11518
11519  // remove effect of random for cryptographic blinding
11520  y = y.multiply(r.modInverse(key.n)).mod(key.n);
11521
11522  return y;
11523};
11524
11525/**
11526 * NOTE: THIS METHOD IS DEPRECATED, use 'sign' on a private key object or
11527 * 'encrypt' on a public key object instead.
11528 *
11529 * Performs RSA encryption.
11530 *
11531 * The parameter bt controls whether to put padding bytes before the
11532 * message passed in. Set bt to either true or false to disable padding
11533 * completely (in order to handle e.g. EMSA-PSS encoding seperately before),
11534 * signaling whether the encryption operation is a public key operation
11535 * (i.e. encrypting data) or not, i.e. private key operation (data signing).
11536 *
11537 * For PKCS#1 v1.5 padding pass in the block type to use, i.e. either 0x01
11538 * (for signing) or 0x02 (for encryption). The key operation mode (private
11539 * or public) is derived from this flag in that case).
11540 *
11541 * @param m the message to encrypt as a byte string.
11542 * @param key the RSA key to use.
11543 * @param bt for PKCS#1 v1.5 padding, the block type to use
11544 *   (0x01 for private key, 0x02 for public),
11545 *   to disable padding: true = public key, false = private key.
11546 *
11547 * @return the encrypted bytes as a string.
11548 */
11549pki.rsa.encrypt = function(m, key, bt) {
11550  var pub = bt;
11551  var eb;
11552
11553  // get the length of the modulus in bytes
11554  var k = Math.ceil(key.n.bitLength() / 8);
11555
11556  if(bt !== false && bt !== true) {
11557    // legacy, default to PKCS#1 v1.5 padding
11558    pub = (bt === 0x02);
11559    eb = _encodePkcs1_v1_5(m, key, bt);
11560  } else {
11561    eb = forge.util.createBuffer();
11562    eb.putBytes(m);
11563  }
11564
11565  // load encryption block as big integer 'x'
11566  // FIXME: hex conversion inefficient, get BigInteger w/byte strings
11567  var x = new BigInteger(eb.toHex(), 16);
11568
11569  // do RSA encryption
11570  var y = _modPow(x, key, pub);
11571
11572  // convert y into the encrypted data byte string, if y is shorter in
11573  // bytes than k, then prepend zero bytes to fill up ed
11574  // FIXME: hex conversion inefficient, get BigInteger w/byte strings
11575  var yhex = y.toString(16);
11576  var ed = forge.util.createBuffer();
11577  var zeros = k - Math.ceil(yhex.length / 2);
11578  while(zeros > 0) {
11579    ed.putByte(0x00);
11580    --zeros;
11581  }
11582  ed.putBytes(forge.util.hexToBytes(yhex));
11583  return ed.getBytes();
11584};
11585
11586/**
11587 * NOTE: THIS METHOD IS DEPRECATED, use 'decrypt' on a private key object or
11588 * 'verify' on a public key object instead.
11589 *
11590 * Performs RSA decryption.
11591 *
11592 * The parameter ml controls whether to apply PKCS#1 v1.5 padding
11593 * or not.  Set ml = false to disable padding removal completely
11594 * (in order to handle e.g. EMSA-PSS later on) and simply pass back
11595 * the RSA encryption block.
11596 *
11597 * @param ed the encrypted data to decrypt in as a byte string.
11598 * @param key the RSA key to use.
11599 * @param pub true for a public key operation, false for private.
11600 * @param ml the message length, if known, false to disable padding.
11601 *
11602 * @return the decrypted message as a byte string.
11603 */
11604pki.rsa.decrypt = function(ed, key, pub, ml) {
11605  // get the length of the modulus in bytes
11606  var k = Math.ceil(key.n.bitLength() / 8);
11607
11608  // error if the length of the encrypted data ED is not k
11609  if(ed.length !== k) {
11610    var error = new Error('Encrypted message length is invalid.');
11611    error.length = ed.length;
11612    error.expected = k;
11613    throw error;
11614  }
11615
11616  // convert encrypted data into a big integer
11617  // FIXME: hex conversion inefficient, get BigInteger w/byte strings
11618  var y = new BigInteger(forge.util.createBuffer(ed).toHex(), 16);
11619
11620  // y must be less than the modulus or it wasn't the result of
11621  // a previous mod operation (encryption) using that modulus
11622  if(y.compareTo(key.n) >= 0) {
11623    throw new Error('Encrypted message is invalid.');
11624  }
11625
11626  // do RSA decryption
11627  var x = _modPow(y, key, pub);
11628
11629  // create the encryption block, if x is shorter in bytes than k, then
11630  // prepend zero bytes to fill up eb
11631  // FIXME: hex conversion inefficient, get BigInteger w/byte strings
11632  var xhex = x.toString(16);
11633  var eb = forge.util.createBuffer();
11634  var zeros = k - Math.ceil(xhex.length / 2);
11635  while(zeros > 0) {
11636    eb.putByte(0x00);
11637    --zeros;
11638  }
11639  eb.putBytes(forge.util.hexToBytes(xhex));
11640
11641  if(ml !== false) {
11642    // legacy, default to PKCS#1 v1.5 padding
11643    return _decodePkcs1_v1_5(eb.getBytes(), key, pub);
11644  }
11645
11646  // return message
11647  return eb.getBytes();
11648};
11649
11650/**
11651 * Creates an RSA key-pair generation state object. It is used to allow
11652 * key-generation to be performed in steps. It also allows for a UI to
11653 * display progress updates.
11654 *
11655 * @param bits the size for the private key in bits, defaults to 2048.
11656 * @param e the public exponent to use, defaults to 65537 (0x10001).
11657 * @param [options] the options to use.
11658 *          prng a custom crypto-secure pseudo-random number generator to use,
11659 *            that must define "getBytesSync".
11660 *          algorithm the algorithm to use (default: 'PRIMEINC').
11661 *
11662 * @return the state object to use to generate the key-pair.
11663 */
11664pki.rsa.createKeyPairGenerationState = function(bits, e, options) {
11665  // TODO: migrate step-based prime generation code to forge.prime
11666
11667  // set default bits
11668  if(typeof(bits) === 'string') {
11669    bits = parseInt(bits, 10);
11670  }
11671  bits = bits || 2048;
11672
11673  // create prng with api that matches BigInteger secure random
11674  options = options || {};
11675  var prng = options.prng || forge.random;
11676  var rng = {
11677    // x is an array to fill with bytes
11678    nextBytes: function(x) {
11679      var b = prng.getBytesSync(x.length);
11680      for(var i = 0; i < x.length; ++i) {
11681        x[i] = b.charCodeAt(i);
11682      }
11683    }
11684  };
11685
11686  var algorithm = options.algorithm || 'PRIMEINC';
11687
11688  // create PRIMEINC algorithm state
11689  var rval;
11690  if(algorithm === 'PRIMEINC') {
11691    rval = {
11692      algorithm: algorithm,
11693      state: 0,
11694      bits: bits,
11695      rng: rng,
11696      eInt: e || 65537,
11697      e: new BigInteger(null),
11698      p: null,
11699      q: null,
11700      qBits: bits >> 1,
11701      pBits: bits - (bits >> 1),
11702      pqState: 0,
11703      num: null,
11704      keys: null
11705    };
11706    rval.e.fromInt(rval.eInt);
11707  } else {
11708    throw new Error('Invalid key generation algorithm: ' + algorithm);
11709  }
11710
11711  return rval;
11712};
11713
11714/**
11715 * Attempts to runs the key-generation algorithm for at most n seconds
11716 * (approximately) using the given state. When key-generation has completed,
11717 * the keys will be stored in state.keys.
11718 *
11719 * To use this function to update a UI while generating a key or to prevent
11720 * causing browser lockups/warnings, set "n" to a value other than 0. A
11721 * simple pattern for generating a key and showing a progress indicator is:
11722 *
11723 * var state = pki.rsa.createKeyPairGenerationState(2048);
11724 * var step = function() {
11725 *   // step key-generation, run algorithm for 100 ms, repeat
11726 *   if(!forge.pki.rsa.stepKeyPairGenerationState(state, 100)) {
11727 *     setTimeout(step, 1);
11728 *   } else {
11729 *     // key-generation complete
11730 *     // TODO: turn off progress indicator here
11731 *     // TODO: use the generated key-pair in "state.keys"
11732 *   }
11733 * };
11734 * // TODO: turn on progress indicator here
11735 * setTimeout(step, 0);
11736 *
11737 * @param state the state to use.
11738 * @param n the maximum number of milliseconds to run the algorithm for, 0
11739 *          to run the algorithm to completion.
11740 *
11741 * @return true if the key-generation completed, false if not.
11742 */
11743pki.rsa.stepKeyPairGenerationState = function(state, n) {
11744  // set default algorithm if not set
11745  if(!('algorithm' in state)) {
11746    state.algorithm = 'PRIMEINC';
11747  }
11748
11749  // TODO: migrate step-based prime generation code to forge.prime
11750  // TODO: abstract as PRIMEINC algorithm
11751
11752  // do key generation (based on Tom Wu's rsa.js, see jsbn.js license)
11753  // with some minor optimizations and designed to run in steps
11754
11755  // local state vars
11756  var THIRTY = new BigInteger(null);
11757  THIRTY.fromInt(30);
11758  var deltaIdx = 0;
11759  var op_or = function(x,y) { return x|y; };
11760
11761  // keep stepping until time limit is reached or done
11762  var t1 = +new Date();
11763  var t2;
11764  var total = 0;
11765  while(state.keys === null && (n <= 0 || total < n)) {
11766    // generate p or q
11767    if(state.state === 0) {
11768      /* Note: All primes are of the form:
11769
11770        30k+i, for i < 30 and gcd(30, i)=1, where there are 8 values for i
11771
11772        When we generate a random number, we always align it at 30k + 1. Each
11773        time the number is determined not to be prime we add to get to the
11774        next 'i', eg: if the number was at 30k + 1 we add 6. */
11775      var bits = (state.p === null) ? state.pBits : state.qBits;
11776      var bits1 = bits - 1;
11777
11778      // get a random number
11779      if(state.pqState === 0) {
11780        state.num = new BigInteger(bits, state.rng);
11781        // force MSB set
11782        if(!state.num.testBit(bits1)) {
11783          state.num.bitwiseTo(
11784            BigInteger.ONE.shiftLeft(bits1), op_or, state.num);
11785        }
11786        // align number on 30k+1 boundary
11787        state.num.dAddOffset(31 - state.num.mod(THIRTY).byteValue(), 0);
11788        deltaIdx = 0;
11789
11790        ++state.pqState;
11791      } else if(state.pqState === 1) {
11792        // try to make the number a prime
11793        if(state.num.bitLength() > bits) {
11794          // overflow, try again
11795          state.pqState = 0;
11796          // do primality test
11797        } else if(state.num.isProbablePrime(
11798          _getMillerRabinTests(state.num.bitLength()))) {
11799          ++state.pqState;
11800        } else {
11801          // get next potential prime
11802          state.num.dAddOffset(GCD_30_DELTA[deltaIdx++ % 8], 0);
11803        }
11804      } else if(state.pqState === 2) {
11805        // ensure number is coprime with e
11806        state.pqState =
11807          (state.num.subtract(BigInteger.ONE).gcd(state.e)
11808          .compareTo(BigInteger.ONE) === 0) ? 3 : 0;
11809      } else if(state.pqState === 3) {
11810        // store p or q
11811        state.pqState = 0;
11812        if(state.p === null) {
11813          state.p = state.num;
11814        } else {
11815          state.q = state.num;
11816        }
11817
11818        // advance state if both p and q are ready
11819        if(state.p !== null && state.q !== null) {
11820          ++state.state;
11821        }
11822        state.num = null;
11823      }
11824    } else if(state.state === 1) {
11825      // ensure p is larger than q (swap them if not)
11826      if(state.p.compareTo(state.q) < 0) {
11827        state.num = state.p;
11828        state.p = state.q;
11829        state.q = state.num;
11830      }
11831      ++state.state;
11832    } else if(state.state === 2) {
11833      // compute phi: (p - 1)(q - 1) (Euler's totient function)
11834      state.p1 = state.p.subtract(BigInteger.ONE);
11835      state.q1 = state.q.subtract(BigInteger.ONE);
11836      state.phi = state.p1.multiply(state.q1);
11837      ++state.state;
11838    } else if(state.state === 3) {
11839      // ensure e and phi are coprime
11840      if(state.phi.gcd(state.e).compareTo(BigInteger.ONE) === 0) {
11841        // phi and e are coprime, advance
11842        ++state.state;
11843      } else {
11844        // phi and e aren't coprime, so generate a new p and q
11845        state.p = null;
11846        state.q = null;
11847        state.state = 0;
11848      }
11849    } else if(state.state === 4) {
11850      // create n, ensure n is has the right number of bits
11851      state.n = state.p.multiply(state.q);
11852
11853      // ensure n is right number of bits
11854      if(state.n.bitLength() === state.bits) {
11855        // success, advance
11856        ++state.state;
11857      } else {
11858        // failed, get new q
11859        state.q = null;
11860        state.state = 0;
11861      }
11862    } else if(state.state === 5) {
11863      // set keys
11864      var d = state.e.modInverse(state.phi);
11865      state.keys = {
11866        privateKey: pki.rsa.setPrivateKey(
11867          state.n, state.e, d, state.p, state.q,
11868          d.mod(state.p1), d.mod(state.q1),
11869          state.q.modInverse(state.p)),
11870        publicKey: pki.rsa.setPublicKey(state.n, state.e)
11871      };
11872    }
11873
11874    // update timing
11875    t2 = +new Date();
11876    total += t2 - t1;
11877    t1 = t2;
11878  }
11879
11880  return state.keys !== null;
11881};
11882
11883/**
11884 * Generates an RSA public-private key pair in a single call.
11885 *
11886 * To generate a key-pair in steps (to allow for progress updates and to
11887 * prevent blocking or warnings in slow browsers) then use the key-pair
11888 * generation state functions.
11889 *
11890 * To generate a key-pair asynchronously (either through web-workers, if
11891 * available, or by breaking up the work on the main thread), pass a
11892 * callback function.
11893 *
11894 * @param [bits] the size for the private key in bits, defaults to 2048.
11895 * @param [e] the public exponent to use, defaults to 65537.
11896 * @param [options] options for key-pair generation, if given then 'bits'
11897 *          and 'e' must *not* be given:
11898 *          bits the size for the private key in bits, (default: 2048).
11899 *          e the public exponent to use, (default: 65537 (0x10001)).
11900 *          workerScript the worker script URL.
11901 *          workers the number of web workers (if supported) to use,
11902 *            (default: 2).
11903 *          workLoad the size of the work load, ie: number of possible prime
11904 *            numbers for each web worker to check per work assignment,
11905 *            (default: 100).
11906 *          prng a custom crypto-secure pseudo-random number generator to use,
11907 *            that must define "getBytesSync".
11908 *          algorithm the algorithm to use (default: 'PRIMEINC').
11909 * @param [callback(err, keypair)] called once the operation completes.
11910 *
11911 * @return an object with privateKey and publicKey properties.
11912 */
11913pki.rsa.generateKeyPair = function(bits, e, options, callback) {
11914  // (bits), (options), (callback)
11915  if(arguments.length === 1) {
11916    if(typeof bits === 'object') {
11917      options = bits;
11918      bits = undefined;
11919    } else if(typeof bits === 'function') {
11920      callback = bits;
11921      bits = undefined;
11922    }
11923  } else if(arguments.length === 2) {
11924    // (bits, e), (bits, options), (bits, callback), (options, callback)
11925    if(typeof bits === 'number') {
11926      if(typeof e === 'function') {
11927        callback = e;
11928        e = undefined;
11929      } else if(typeof e !== 'number') {
11930        options = e;
11931        e = undefined;
11932      }
11933    } else {
11934      options = bits;
11935      callback = e;
11936      bits = undefined;
11937      e = undefined;
11938    }
11939  } else if(arguments.length === 3) {
11940    // (bits, e, options), (bits, e, callback), (bits, options, callback)
11941    if(typeof e === 'number') {
11942      if(typeof options === 'function') {
11943        callback = options;
11944        options = undefined;
11945      }
11946    } else {
11947      callback = options;
11948      options = e;
11949      e = undefined;
11950    }
11951  }
11952  options = options || {};
11953  if(bits === undefined) {
11954    bits = options.bits || 2048;
11955  }
11956  if(e === undefined) {
11957    e = options.e || 0x10001;
11958  }
11959
11960  // if native code is permitted and a callback is given, use native
11961  // key generation code if available and if parameters are acceptable
11962  if(!forge.disableNativeCode && callback &&
11963    bits >= 256 && bits <= 16384 && (e === 0x10001 || e === 3)) {
11964    if(_detectSubtleCrypto('generateKey') && _detectSubtleCrypto('export
11964Key')) {
11965      // use standard native generateKey
11966      return window.crypto.subtle.generateKey({
11967        name: 'RSASSA-PKCS1-v1_5',
11968        modulusLength: bits,
11969        publicExponent: _intToUint8Array(e),
11970        hash: {name: 'SHA-256'}
11971      }, true /* key can be exported*/, ['sign', 'verify'])
11972      .then(function(pair) {
11973        return window.crypto.subtle.exportKey('pkcs8', pair.privateKey);
11974      }).catch(function(err) {
11975        callback(err);
11976      }).then(function(pkcs8) {
11977        if(pkcs8) {
11978          var privateKey = pki.privateKeyFromAsn1(
11979            asn1.fromDer(forge.util.createBuffer(pkcs8)));
11980          callback(null, {
11981            privateKey: privateKey,
11982            publicKey: pki.setRsaPublicKey(privateKey.n, privateKey.e)
11983          });
11984        }
11985      });
11986    }
11987    if(_detectSubtleMsCrypto('generateKey') &&
11988      _detectSubtleMsCrypto('exportKey')) {
11989      var genOp = window.msCrypto.subtle.generateKey({
11990        name: 'RSASSA-PKCS1-v1_5',
11991        modulusLength: bits,
11992        publicExponent: _intToUint8Array(e),
11993        hash: {name: 'SHA-256'}
11994      }, true /* key can be exported*/, ['sign', 'verify']);
11995      genOp.oncomplete = function(e) {
11996        var pair = e.target.result;
11997        var exportOp = window.msCrypto.subtle.exportKey(
11998          'pkcs8', pair.privateKey);
11999        exportOp.oncomplete = function(e) {
12000          var pkcs8 = e.target.result;
12001          var privateKey = pki.privateKeyFromAsn1(
12002            asn1.fromDer(forge.util.createBuffer(pkcs8)));
12003          callback(null, {
12004            privateKey: privateKey,
12005            publicKey: pki.setRsaPublicKey(privateKey.n, privateKey.e)
12006          });
12007        };
12008        exportOp.onerror = function(err) {
12009          callback(err);
12010        };
12011      };
12012      genOp.onerror = function(err) {
12013        callback(err);
12014      };
12015      return;
12016    }
12017  }
12018
12019  // use JavaScript implementation
12020  var state = pki.rsa.createKeyPairGenerationState(bits, e, options);
12021  if(!callback) {
12022    pki.rsa.stepKeyPairGenerationState(state, 0);
12023    return state.keys;
12024  }
12025  _generateKeyPair(state, options, callback);
12026};
12027
12028/**
12029 * Sets an RSA public key from BigIntegers modulus and exponent.
12030 *
12031 * @param n the modulus.
12032 * @param e the exponent.
12033 *
12034 * @return the public key.
12035 */
12036pki.setRsaPublicKey = pki.rsa.setPublicKey = function(n, e) {
12037  var key = {
12038    n: n,
12039    e: e
12040  };
12041
12042  /**
12043   * Encrypts the given data with this public key. Newer applications
12044   * should use the 'RSA-OAEP' decryption scheme, 'RSAES-PKCS1-V1_5' is for
12045   * legacy applications.
12046   *
12047   * @param data the byte string to encrypt.
12048   * @param scheme the encryption scheme to use:
12049   *          'RSAES-PKCS1-V1_5' (default),
12050   *          'RSA-OAEP',
12051   *          'RAW', 'NONE', or null to perform raw RSA encryption,
12052   *          an object with an 'encode' property set to a function
12053   *          with the signature 'function(data, key)' that returns
12054   *          a binary-encoded string representing the encoded data.
12055   * @param schemeOptions any scheme-specific options.
12056   *
12057   * @return the encrypted byte string.
12058   */
12059  key.encrypt = function(data, scheme, schemeOptions) {
12060    if(typeof scheme === 'string') {
12061      scheme = scheme.toUpperCase();
12062    } else if(scheme === undefined) {
12063      scheme = 'RSAES-PKCS1-V1_5';
12064    }
12065
12066    if(scheme === 'RSAES-PKCS1-V1_5') {
12067      scheme = {
12068        encode: function(m, key, pub) {
12069          return _encodePkcs1_v1_5(m, key, 0x02).getBytes();
12070        }
12071      };
12072    } else if(scheme === 'RSA-OAEP' || scheme === 'RSAES-OAEP') {
12073      scheme = {
12074        encode: function(m, key) {
12075          return forge.pkcs1.encode_rsa_oaep(key, m, schemeOptions);
12076        }
12077      };
12078    } else if(['RAW', 'NONE', 'NULL', null].indexOf(scheme) !== -1) {
12079      scheme = { encode: function(e) { return e; } };
12080    } else if(typeof scheme === 'string') {
12081      throw new Error('Unsupported encryption scheme: "' + scheme + '".');
12082    }
12083
12084    // do scheme-based encoding then rsa encryption
12085    var e = scheme.encode(data, key, true);
12086    return pki.rsa.encrypt(e, key, true);
12087  };
12088
12089  /**
12090   * Verifies the given signature against the given digest.
12091   *
12092   * PKCS#1 supports multiple (currently two) signature schemes:
12093   * RSASSA-PKCS1-V1_5 and RSASSA-PSS.
12094   *
12095   * By default this implementation uses the "old scheme", i.e.
12096   * RSASSA-PKCS1-V1_5, in which case once RSA-decrypted, the
12097   * signature is an OCTET STRING that holds a DigestInfo.
12098   *
12099   * DigestInfo ::= SEQUENCE {
12100   *   digestAlgorithm DigestAlgorithmIdentifier,
12101   *   digest Digest
12102   * }
12103   * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
12104   * Digest ::= OCTET STRING
12105   *
12106   * To perform PSS signature verification, provide an instance
12107   * of Forge PSS object as the scheme parameter.
12108   *
12109   * @param digest the message digest hash to compare against the signature,
12110   *          as a binary-encoded string.
12111   * @param signature the signature to verify, as a binary-encoded string.
12112   * @param scheme signature verification scheme to use:
12113   *          'RSASSA-PKCS1-V1_5' or undefined for RSASSA PKCS#1 v1.5,
12114   *          a Forge PSS object for RSASSA-PSS,
12115   *          'NONE' or null for none, DigestInfo will not be expected, but
12116   *            PKCS#1 v1.5 padding will still be used.
12117   *
12118   * @return true if the signature was verified, false if not.
12119   */
12120   key.verify = function(digest, signature, scheme) {
12121     if(typeof scheme === 'string') {
12122       scheme = scheme.toUpperCase();
12123     } else if(scheme === undefined) {
12124       scheme = 'RSASSA-PKCS1-V1_5';
12125     }
12126
12127     if(scheme === 'RSASSA-PKCS1-V1_5') {
12128       scheme = {
12129         verify: function(digest, d) {
12130           // remove padding
12131           d = _decodePkcs1_v1_5(d, key, true);
12132           // d is ASN.1 BER-encoded DigestInfo
12133           var obj = asn1.fromDer(d);
12134           // compare the given digest to the decrypted one
12135           return digest === obj.value[1].value;
12136         }
12137       };
12138     } else if(scheme === 'NONE' || scheme === 'NULL' || scheme === null) {
12139       scheme = {
12140         verify: function(digest, d) {
12141           // remove padding
12142           d = _decodePkcs1_v1_5(d, key, true);
12143           return digest === d;
12144         }
12145       };
12146     }
12147
12148     // do rsa decryption w/o any decoding, then verify -- which does decoding
12149     var d = pki.rsa.decrypt(signature, key, true, false);
12150     return scheme.verify(digest, d, key.n.bitLength());
12151  };
12152
12153  return key;
12154};
12155
12156/**
12157 * Sets an RSA private key from BigIntegers modulus, exponent, primes,
12158 * prime exponents, and modular multiplicative inverse.
12159 *
12160 * @param n the modulus.
12161 * @param e the public exponent.
12162 * @param d the private exponent ((inverse of e) mod n).
12163 * @param p the first prime.
12164 * @param q the second prime.
12165 * @param dP exponent1 (d mod (p-1)).
12166 * @param dQ exponent2 (d mod (q-1)).
12167 * @param qInv ((inverse of q) mod p)
12168 *
12169 * @return the private key.
12170 */
12171pki.setRsaPrivateKey = pki.rsa.setPrivateKey = function(
12172  n, e, d, p, q, dP, dQ, qInv) {
12173  var key = {
12174    n: n,
12175    e: e,
12176    d: d,
12177    p: p,
12178    q: q,
12179    dP: dP,
12180    dQ: dQ,
12181    qInv: qInv
12182  };
12183
12184  /**
12185   * Decrypts the given data with this private key. The decryption scheme
12186   * must match the one used to encrypt the data.
12187   *
12188   * @param data the byte string to decrypt.
12189   * @param scheme the decryption scheme to use:
12190   *          'RSAES-PKCS1-V1_5' (default),
12191   *          'RSA-OAEP',
12192   *          'RAW', 'NONE', or null to perform raw RSA decryption.
12193   * @param schemeOptions any scheme-specific options.
12194   *
12195   * @return the decrypted byte string.
12196   */
12197  key.decrypt = function(data, scheme, schemeOptions) {
12198    if(typeof scheme === 'string') {
12199      scheme = scheme.toUpperCase();
12200    } else if(scheme === undefined) {
12201      scheme = 'RSAES-PKCS1-V1_5';
12202    }
12203
12204    // do rsa decryption w/o any decoding
12205    var d = pki.rsa.decrypt(data, key, false, false);
12206
12207    if(scheme === 'RSAES-PKCS1-V1_5') {
12208      scheme = { decode: _decodePkcs1_v1_5 };
12209    } else if(scheme === 'RSA-OAEP' || scheme === 'RSAES-OAEP') {
12210      scheme = {
12211        decode: function(d, key) {
12212          return forge.pkcs1.decode_rsa_oaep(key, d, schemeOptions);
12213        }
12214      };
12215    } else if(['RAW', 'NONE', 'NULL', null].indexOf(scheme) !== -1) {
12216      scheme = { decode: function(d) { return d; } };
12217    } else {
12218      throw new Error('Unsupported encryption scheme: "' + scheme + '".');
12219    }
12220
12221    // decode according to scheme
12222    return scheme.decode(d, key, false);
12223  };
12224
12225  /**
12226   * Signs the given digest, producing a signature.
12227   *
12228   * PKCS#1 supports multiple (currently two) signature schemes:
12229   * RSASSA-PKCS1-V1_5 and RSASSA-PSS.
12230   *
12231   * By default this implementation uses the "old scheme", i.e.
12232   * RSASSA-PKCS1-V1_5. In order to generate a PSS signature, provide
12233   * an instance of Forge PSS object as the scheme parameter.
12234   *
12235   * @param md the message digest object with the hash to sign.
12236   * @param scheme the signature scheme to use:
12237   *          'RSASSA-PKCS1-V1_5' or undefined for RSASSA PKCS#1 v1.5,
12238   *          a Forge PSS object for RSASSA-PSS,
12239   *          'NONE' or null for none, DigestInfo will not be used but
12240   *            PKCS#1 v1.5 padding will still be used.
12241   *
12242   * @return the signature as a byte string.
12243   */
12244  key.sign = function(md, scheme) {
12245    /* Note: The internal implementation of RSA operations is being
12246      transitioned away from a PKCS#1 v1.5 hard-coded scheme. Some legacy
12247      code like the use of an encoding block identifier 'bt' will eventually
12248      be removed. */
12249
12250    // private key operation
12251    var bt = false;
12252
12253    if(typeof scheme === 'string') {
12254      scheme = scheme.toUpperCase();
12255    }
12256
12257    if(scheme === undefined || scheme === 'RSASSA-PKCS1-V1_5') {
12258      scheme = { encode: emsaPkcs1v15encode };
12259      bt = 0x01;
12260    } else if(scheme === 'NONE' || scheme === 'NULL' || scheme === null) {
12261      scheme = { encode: function() { return md; } };
12262      bt = 0x01;
12263    }
12264
12265    // encode and then encrypt
12266    var d = scheme.encode(md, key.n.bitLength());
12267    return pki.rsa.encrypt(d, key, bt);
12268  };
12269
12270  return key;
12271};
12272
12273/**
12274 * Wraps an RSAPrivateKey ASN.1 object in an ASN.1 PrivateKeyInfo object.
12275 *
12276 * @param rsaKey the ASN.1 RSAPrivateKey.
12277 *
12278 * @return the ASN.1 PrivateKeyInfo.
12279 */
12280pki.wrapRsaPrivateKey = function(rsaKey) {
12281  // PrivateKeyInfo
12282  return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
12283    // version (0)
12284    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false,
12285      asn1.integerToDer(0).getBytes()),
12286    // privateKeyAlgorithm
12287    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
12288      asn1.create(
12289        asn1.Class.UNIVERSAL, asn1.Type.OID, false,
12290        asn1.oidToDer(pki.oids.rsaEncryption).getBytes()),
12291      asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, '')
12292    ]),
12293    // PrivateKey
12294    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false,
12295      asn1.toDer(rsaKey).getBytes())
12296    ]);
12297};
12298
12299/**
12300 * Converts a private key from an ASN.1 object.
12301 *
12302 * @param obj the ASN.1 representation of a PrivateKeyInfo containing an
12303 *          RSAPrivateKey or an RSAPrivateKey.
12304 *
12305 * @return the private key.
12306 */
12307pki.privateKeyFromAsn1 = function(obj) {
12308  // get PrivateKeyInfo
12309  var capture = {};
12310  var errors = [];
12311  if(asn1.validate(obj, privateKeyValidator, capture, errors)) {
12312    obj = asn1.fromDer(forge.util.createBuffer(capture.privateKey));
12313  }
12314
12315  // get RSAPrivateKey
12316  capture = {};
12317  errors = [];
12318  if(!asn1.validate(obj, rsaPrivateKeyValidator, capture, errors)) {
12319    var error = new Error('Cannot read private key. ' +
12320      'ASN.1 object does not contain an RSAPrivateKey.');
12321    error.errors = errors;
12322    throw error;
12323  }
12324
12325  // Note: Version is currently ignored.
12326  // capture.privateKeyVersion
12327  // FIXME: inefficient, get a BigInteger that uses byte strings
12328  var n, e, d, p, q, dP, dQ, qInv;
12329  n = forge.util.createBuffer(capture.privateKeyModulus).toHex();
12330  e = forge.util.createBuffer(capture.privateKeyPublicExponent).toHex();
12331  d = forge.util.createBuffer(capture.privateKeyPrivateExponent).toHex();
12332  p = forge.util.createBuffer(capture.privateKeyPrime1).toHex();
12333  q = forge.util.createBuffer(capture.privateKeyPrime2).toHex();
12334  dP = forge.util.createBuffer(capture.privateKeyExponent1).toHex();
12335  dQ = forge.util.createBuffer(capture.privateKeyExponent2).toHex();
12336  qInv = forge.util.createBuffer(capture.privateKeyCoefficient).toHex();
12337
12338  // set private key
12339  return pki.setRsaPrivateKey(
12340    new BigInteger(n, 16),
12341    new BigInteger(e, 16),
12342    new BigInteger(d, 16),
12343    new BigInteger(p, 16),
12344    new BigInteger(q, 16),
12345    new BigInteger(dP, 16),
12346    new BigInteger(dQ, 16),
12347    new BigInteger(qInv, 16));
12348};
12349
12350/**
12351 * Converts a private key to an ASN.1 RSAPrivateKey.
12352 *
12353 * @param key the private key.
12354 *
12355 * @return the ASN.1 representation of an RSAPrivateKey.
12356 */
12357pki.privateKeyToAsn1 = pki.privateKeyToRSAPrivateKey = function(key) {
12358  // RSAPrivateKey
12359  return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
12360    // version (0 = only 2 primes, 1 multiple primes)
12361    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false,
12362      asn1.integerToDer(0).getBytes()),
12363    // modulus (n)
12364    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false,
12365      _bnToBytes(key.n)),
12366    // publicExponent (e)
12367    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false,
12368      _bnToBytes(key.e)),
12369    // privateExponent (d)
12370    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false,
12371      _bnToBytes(key.d)),
12372    // privateKeyPrime1 (p)
12373    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false,
12374      _bnToBytes(key.p)),
12375    // privateKeyPrime2 (q)
12376    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false,
12377      _bnToBytes(key.q)),
12378    // privateKeyExponent1 (dP)
12379    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false,
12380      _bnToBytes(key.dP)),
12381    // privateKeyExponent2 (dQ)
12382    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false,
12383      _bnToBytes(key.dQ)),
12384    // coefficient (qInv)
12385    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false,
12386      _bnToBytes(key.qInv))
12387  ]);
12388};
12389
12390/**
12391 * Converts a public key from an ASN.1 SubjectPublicKeyInfo or RSAPublicKey.
12392 *
12393 * @param obj the asn1 representation of a SubjectPublicKeyInfo or RSAPublicKey.
12394 *
12395 * @return the public key.
12396 */
12397pki.publicKeyFromAsn1 = function(obj) {
12398  // get SubjectPublicKeyInfo
12399  var capture = {};
12400  var errors = [];
12401  if(asn1.validate(obj, publicKeyValidator, capture, errors)) {
12402    // get oid
12403    var oid = asn1.derToOid(capture.publicKeyOid);
12404    if(oid !== pki.oids.rsaEncryption) {
12405      var error = new Error('Cannot read public key. Unknown OID.');
12406      error.oid = oid;
12407      throw error;
12408    }
12409    obj = capture.rsaPublicKey;
12410  }
12411
12412  // get RSA params
12413  errors = [];
12414  if(!asn1.validate(obj, rsaPublicKeyValidator, capture, errors)) {
12415    var error = new Error('Cannot read public key. ' +
12416      'ASN.1 object does not contain an RSAPublicKey.');
12417    error.errors = errors;
12418    throw error;
12419  }
12420
12421  // FIXME: inefficient, get a BigInteger that uses byte strings
12422  var n = forge.util.createBuffer(capture.publicKeyModulus).toHex();
12423  var e = forge.util.createBuffer(capture.publicKeyExponent).toHex();
12424
12425  // set public key
12426  return pki.setRsaPublicKey(
12427    new BigInteger(n, 16),
12428    new BigInteger(e, 16));
12429};
12430
12431/**
12432 * Converts a public key to an ASN.1 SubjectPublicKeyInfo.
12433 *
12434 * @param key the public key.
12435 *
12436 * @return the asn1 representation of a SubjectPublicKeyInfo.
12437 */
12438pki.publicKeyToAsn1 = pki.publicKeyToSubjectPublicKeyInfo = function(key) {
12439  // SubjectPublicKeyInfo
12440  return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
12441    // AlgorithmIdentifier
12442    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
12443      // algorithm
12444      asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
12445        asn1.oidToDer(pki.oids.rsaEncryption).getBytes()),
12446      // parameters (null)
12447      asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, '')
12448    ]),
12449    // subjectPublicKey
12450    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.BITSTRING, false, [
12451      pki.publicKeyToRSAPublicKey(key)
12452    ])
12453  ]);
12454};
12455
12456/**
12457 * Converts a public key to an ASN.1 RSAPublicKey.
12458 *
12459 * @param key the public key.
12460 *
12461 * @return the asn1 representation of a RSAPublicKey.
12462 */
12463pki.publicKeyToRSAPublicKey = function(key) {
12464  // RSAPublicKey
12465  return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
12466    // modulus (n)
12467    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false,
12468      _bnToBytes(key.n)),
12469    // publicExponent (e)
12470    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false,
12471      _bnToBytes(key.e))
12472  ]);
12473};
12474
12475/**
12476 * Encodes a message using PKCS#1 v1.5 padding.
12477 *
12478 * @param m the message to encode.
12479 * @param key the RSA key to use.
12480 * @param bt the block type to use, i.e. either 0x01 (for signing) or 0x02
12481 *          (for encryption).
12482 *
12483 * @return the padded byte buffer.
12484 */
12485function _encodePkcs1_v1_5(m, key, bt) {
12486  var eb = forge.util.createBuffer();
12487
12488  // get the length of the modulus in bytes
12489  var k = Math.ceil(key.n.bitLength() / 8);
12490
12491  /* use PKCS#1 v1.5 padding */
12492  if(m.length > (k - 11)) {
12493    var error = new Error('Message is too long for PKCS#1 v1.5 padding.');
12494    error.length = m.length;
12495    error.max = k - 11;
12496    throw error;
12497  }
12498
12499  /* A block type BT, a padding string PS, and the data D shall be
12500    formatted into an octet string EB, the encryption block:
12501
12502    EB = 00 || BT || PS || 00 || D
12503
12504    The block type BT shall be a single octet indicating the structure of
12505    the encryption block. For this version of the document it shall have
12506    value 00, 01, or 02. For a private-key operation, the block type
12507    shall be 00 or 01. For a public-key operation, it shall be 02.
12508
12509    The padding string PS shall consist of k-3-||D|| octets. For block
12510    type 00, the octets shall have value 00; for block type 01, they
12511    shall have value FF; and for block type 02, they shall be
12512    pseudorandomly generated and nonzero. This makes the length of the
12513    encryption block EB equal to k. */
12514
12515  // build the encryption block
12516  eb.putByte(0x00);
12517  eb.putByte(bt);
12518
12519  // create the padding
12520  var padNum = k - 3 - m.length;
12521  var padByte;
12522  // private key op
12523  if(bt === 0x00 || bt === 0x01) {
12524    padByte = (bt === 0x00) ? 0x00 : 0xFF;
12525    for(var i = 0; i < padNum; ++i) {
12526      eb.putByte(padByte);
12527    }
12528  } else {
12529    // public key op
12530    // pad with random non-zero values
12531    while(padNum > 0) {
12532      var numZeros = 0;
12533      var padBytes = forge.random.getBytes(padNum);
12534      for(var i = 0; i < padNum; ++i) {
12535        padByte = padBytes.charCodeAt(i);
12536        if(padByte === 0) {
12537          ++numZeros;
12538        } else {
12539          eb.putByte(padByte);
12540        }
12541      }
12542      padNum = numZeros;
12543    }
12544  }
12545
12546  // zero followed by message
12547  eb.putByte(0x00);
12548  eb.putBytes(m);
12549
12550  return eb;
12551}
12552
12553/**
12554 * Decodes a message using PKCS#1 v1.5 padding.
12555 *
12556 * @param em the message to decode.
12557 * @param key the RSA key to use.
12558 * @param pub true if the key is a public key, false if it is private.
12559 * @param ml the message length, if specified.
12560 *
12561 * @return the decoded bytes.
12562 */
12563function _decodePkcs1_v1_5(em, key, pub, ml) {
12564  // get the length of the modulus in bytes
12565  var k = Math.ceil(key.n.bitLength() / 8);
12566
12567  /* It is an error if any of the following conditions occurs:
12568
12569    1. The encryption block EB cannot be parsed unambiguously.
12570    2. The padding string PS consists of fewer than eight octets
12571      or is inconsisent with the block type BT.
12572    3. The decryption process is a public-key operation and the block
12573      type BT is not 00 or 01, or the decryption process is a
12574      private-key operation and the block type is not 02.
12575   */
12576
12577  // parse the encryption block
12578  var eb = forge.util.createBuffer(em);
12579  var first = eb.getByte();
12580  var bt = eb.getByte();
12581  if(first !== 0x00 ||
12582    (pub && bt !== 0x00 && bt !== 0x01) ||
12583    (!pub && bt != 0x02) ||
12584    (pub && bt === 0x00 && typeof(ml) === 'undefined')) {
12585    throw new Error('Encryption block is invalid.');
12586  }
12587
12588  var padNum = 0;
12589  if(bt === 0x00) {
12590    // check all padding bytes for 0x00
12591    padNum = k - 3 - ml;
12592    for(var i = 0; i < padNum; ++i) {
12593      if(eb.getByte() !== 0x00) {
12594        throw new Error('Encryption block is invalid.');
12595      }
12596    }
12597  } else if(bt === 0x01) {
12598    // find the first byte that isn't 0xFF, should be after all padding
12599    padNum = 0;
12600    while(eb.length() > 1) {
12601      if(eb.getByte() !== 0xFF) {
12602        --eb.read;
12603        break;
12604      }
12605      ++padNum;
12606    }
12607  } else if(bt === 0x02) {
12608    // look for 0x00 byte
12609    padNum = 0;
12610    while(eb.length() > 1) {
12611      if(eb.getByte() === 0x00) {
12612        --eb.read;
12613        break;
12614      }
12615      ++padNum;
12616    }
12617  }
12618
12619  // zero must be 0x00 and padNum must be (k - 3 - message length)
12620  var zero = eb.getByte();
12621  if(zero !== 0x00 || padNum !== (k - 3 - eb.length())) {
12622    throw new Error('Encryption block is invalid.');
12623  }
12624
12625  return eb.getBytes();
12626}
12627
12628/**
12629 * Runs the key-generation algorithm asynchronously, either in the background
12630 * via Web Workers, or using the main thread and setImmediate.
12631 *
12632 * @param state the key-pair generation state.
12633 * @param [options] options for key-pair generation:
12634 *          workerScript the worker script URL.
12635 *          workers the number of web workers (if supported) to use,
12636 *            (default: 2, -1 to use estimated cores minus one).
12637 *          workLoad the size of the work load, ie: number of possible prime
12638 *            numbers for each web worker to check per work assignment,
12639 *            (default: 100).
12640 * @param callback(err, keypair) called once the operation completes.
12641 */
12642function _generateKeyPair(state, options, callback) {
12643  if(typeof options === 'function') {
12644    callback = options;
12645    options = {};
12646  }
12647  options = options || {};
12648
12649  var opts = {
12650    algorithm: {
12651      name: options.algorithm || 'PRIMEINC',
12652      options: {
12653        workers: options.workers || 2,
12654        workLoad: options.workLoad || 100,
12655        workerScript: options.workerScript
12656      }
12657    }
12658  };
12659  if('prng' in options) {
12660    opts.prng = options.prng;
12661  }
12662
12663  generate();
12664
12665  function generate() {
12666    // find p and then q (done in series to simplify)
12667    getPrime(state.pBits, function(err, num) {
12668      if(err) {
12669        return callback(err);
12670      }
12671      state.p = num;
12672      if(state.q !== null) {
12673        return finish(err, state.q);
12674      }
12675      getPrime(state.qBits, finish);
12676    });
12677  }
12678
12679  function getPrime(bits, callback) {
12680    forge.prime.generateProbablePrime(bits, opts, callback);
12681  }
12682
12683  function finish(err, num) {
12684    if(err) {
12685      return callback(err);
12686    }
12687
12688    // set q
12689    state.q = num;
12690
12691    // ensure p is larger than q (swap them if not)
12692    if(state.p.compareTo(state.q) < 0) {
12693      var tmp = state.p;
12694      state.p = state.q;
12695      state.q = tmp;
12696    }
12697
12698    // ensure p is coprime with e
12699    if(state.p.subtract(BigInteger.ONE).gcd(state.e)
12700      .compareTo(BigInteger.ONE) !== 0) {
12701      state.p = null;
12702      generate();
12703      return;
12704    }
12705
12706    // ensure q is coprime with e
12707    if(state.q.subtract(BigInteger.ONE).gcd(state.e)
12708      .compareTo(BigInteger.ONE) !== 0) {
12709      state.q = null;
12710      getPrime(state.qBits, finish);
12711      return;
12712    }
12713
12714    // compute phi: (p - 1)(q - 1) (Euler's totient function)
12715    state.p1 = state.p.subtract(BigInteger.ONE);
12716    state.q1 = state.q.subtract(BigInteger.ONE);
12717    state.phi = state.p1.multiply(state.q1);
12718
12719    // ensure e and phi are coprime
12720    if(state.phi.gcd(state.e).compareTo(BigInteger.ONE) !== 0) {
12721      // phi and e aren't coprime, so generate a new p and q
12722      state.p = state.q = null;
12723      generate();
12724      return;
12725    }
12726
12727    // create n, ensure n is has the right number of bits
12728    state.n = state.p.multiply(state.q);
12729    if(state.n.bitLength() !== state.bits) {
12730      // failed, get new q
12731      state.q = null;
12732      getPrime(state.qBits, finish);
12733      return;
12734    }
12735
12736    // set keys
12737    var d = state.e.modInverse(state.phi);
12738    state.keys = {
12739      privateKey: pki.rsa.setPrivateKey(
12740        state.n, state.e, d, state.p, state.q,
12741        d.mod(state.p1), d.mod(state.q1),
12742        state.q.modInverse(state.p)),
12743      publicKey: pki.rsa.setPublicKey(state.n, state.e)
12744    };
12745
12746    callback(null, state.keys);
12747  }
12748}
12749
12750/**
12751 * Converts a positive BigInteger into 2's-complement big-endian bytes.
12752 *
12753 * @param b the big integer to convert.
12754 *
12755 * @return the bytes.
12756 */
12757function _bnToBytes(b) {
12758  // prepend 0x00 if first byte >= 0x80
12759  var hex = b.toString(16);
12760  if(hex[0] >= '8') {
12761    hex = '00' + hex;
12762  }
12763  var bytes = forge.util.hexToBytes(hex);
12764
12765  // ensure integer is minimally-encoded
12766  if(bytes.length > 1 &&
12767    // leading 0x00 for positive integer
12768    ((bytes.charCodeAt(0) === 0 &&
12769    (bytes.charCodeAt(1) & 0x80) === 0) ||
12770    // leading 0xFF for negative integer
12771    (bytes.charCodeAt(0) === 0xFF &&
12772    (bytes.charCodeAt(1) & 0x80) === 0x80))) {
12773    return bytes.substr(1);
12774  }
12775  return bytes;
12776}
12777
12778/**
12779 * Returns the required number of Miller-Rabin tests to generate a
12780 * prime with an error probability of (1/2)^80.
12781 *
12782 * See Handbook of Applied Cryptography Chapter 4, Table 4.4.
12783 *
12784 * @param bits the bit size.
12785 *
12786 * @return the required number of iterations.
12787 */
12788function _getMillerRabinTests(bits) {
12789  if(bits <= 100) return 27;
12790  if(bits <= 150) return 18;
12791  if(bits <= 200) return 15;
12792  if(bits <= 250) return 12;
12793  if(bits <= 300) return 9;
12794  if(bits <= 350) return 8;
12795  if(bits <= 400) return 7;
12796  if(bits <= 500) return 6;
12797  if(bits <= 600) return 5;
12798  if(bits <= 800) return 4;
12799  if(bits <= 1250) return 3;
12800  return 2;
12801}
12802
12803/**
12804 * Performs feature detection on the SubtleCrypto interface.
12805 *
12806 * @param fn the feature (function) to detect.
12807 *
12808 * @return true if detected, false if not.
12809 */
12810function _detectSubtleCrypto(fn) {
12811  return (typeof window !== 'undefined' &&
12812    typeof window.crypto === 'object' &&
12813    typeof window.crypto.subtle === 'object' &&
12814    typeof window.crypto.subtle[fn] === 'function');
12815}
12816
12817/**
12818 * Performs feature detection on the deprecated Microsoft Internet Explorer
12819 * outdated SubtleCrypto interface. This function should only be used after
12820 * checking for the modern, standard SubtleCrypto interface.
12821 *
12822 * @param fn the feature (function) to detect.
12823 *
12824 * @return true if detected, false if not.
12825 */
12826function _detectSubtleMsCrypto(fn) {
12827  return (typeof window !== 'undefined' &&
12828    typeof window.msCrypto === 'object' &&
12829    typeof window.msCrypto.subtle === 'object' &&
12830    typeof window.msCrypto.subtle[fn] === 'function');
12831}
12832
12833function _intToUint8Array(x) {
12834  var bytes = forge.util.hexToBytes(x.toString(16));
12835  var buffer = new Uint8Array(bytes.length);
12836  for(var i = 0; i < bytes.length; ++i) {
12837    buffer[i] = bytes.charCodeAt(i);
12838  }
12839  return buffer;
12840}
12841
12842function _privateKeyFromJwk(jwk) {
12843  if(jwk.kty !== 'RSA') {
12844    throw new Error(
12845      'Unsupported key algorithm "' + jwk.kty + '"; algorithm must be "RSA".');
12846  }
12847  return pki.setRsaPrivateKey(
12848    _base64ToBigInt(jwk.n),
12849    _base64ToBigInt(jwk.e),
12850    _base64ToBigInt(jwk.d),
12851    _base64ToBigInt(jwk.p),
12852    _base64ToBigInt(jwk.q),
12853    _base64ToBigInt(jwk.dp),
12854    _base64ToBigInt(jwk.dq),
12855    _base64ToBigInt(jwk.qi));
12856}
12857
12858function _publicKeyFromJwk(jwk) {
12859  if(jwk.kty !== 'RSA') {
12860    throw new Error('Key algorithm must be "RSA".');
12861  }
12862  return pki.setRsaPublicKey(
12863    _base64ToBigInt(jwk.n),
12864    _base64ToBigInt(jwk.e));
12865}
12866
12867function _base64ToBigInt(b64) {
12868  return new BigInteger(forge.util.bytesToHex(forge.util.decode64(b64)), 16);
12869}
12870
12871} // end module implementation
12872
12873/* ########## Begin module wrapper ########## */
12874var name = 'rsa';
12875if(typeof define !== 'function') {
12876  // NodeJS -> AMD
12877  if(typeof module === 'object' && module.exports) {
12878    var nodeJS = true;
12879    define = function(ids, factory) {
12880      factory(require, module);
12881    };
12882  } else {
12883    // <script>
12884    if(typeof forge === 'undefined') {
12885      forge = {};
12886    }
12887    return initModule(forge);
12888  }
12889}
12890// AMD
12891var deps;
12892var defineFunc = function(require, module) {
12893  module.exports = function(forge) {
12894    var mods = deps.map(function(dep) {
12895      return require(dep);
12896    }).concat(initModule);
12897    // handle circular dependencies
12898    forge = forge || {};
12899    forge.defined = forge.defined || {};
12900    if(forge.defined[name]) {
12901      return forge[name];
12902    }
12903    forge.defined[name] = true;
12904    for(var i = 0; i < mods.length; ++i) {
12905      mods[i](forge);
12906    }
12907    return forge[name];
12908  };
12909};
12910var tmpDefine = define;
12911define = function(ids, factory) {
12912  deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2);
12913  if(nodeJS) {
12914    delete define;
12915    return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0));
12916  }
12917  define = tmpDefine;
12918  return define.apply(null, Array.prototype.slice.call(arguments, 0));
12919};
12920define([
12921  'require',
12922  'module',
12923  './asn1',
12924  './jsbn',
12925  './oids',
12926  './pkcs1',
12927  './prime',
12928  './random',
12929  './util'
12930], function() {
12931  defineFunc.apply(null, Array.prototype.slice.call(arguments, 0));
12932});
12933})();
12934
12935/**
12936 * Javascript implementation of a basic Public Key Infrastructure, including
12937 * support for RSA public and private keys.
12938 *
12939 * @author Dave Longley
12940 *
12941 * Copyright (c) 2010-2013 Digital Bazaar, Inc.
12942 */
12943(function() {
12944/* ########## Begin module implementation ########## */
12945function initModule(forge) {
12946
12947// shortcut for asn.1 API
12948var asn1 = forge.asn1;
12949
12950/* Public Key Infrastructure (PKI) implementation. */
12951var pki = forge.pki = forge.pki || {};
12952
12953/**
12954 * NOTE: THIS METHOD IS DEPRECATED. Use pem.decode() instead.
12955 *
12956 * Converts PEM-formatted data to DER.
12957 *
12958 * @param pem the PEM-formatted data.
12959 *
12960 * @return the DER-formatted data.
12961 */
12962pki.pemToDer = function(pem) {
12963  var msg = forge.pem.decode(pem)[0];
12964  if(msg.procType && msg.procType.type === 'ENCRYPTED') {
12965    throw new Error('Could not convert PEM to DER; PEM is encrypted.');
12966  }
12967  return forge.util.createBuffer(msg.body);
12968};
12969
12970/**
12971 * Converts an RSA private key from PEM format.
12972 *
12973 * @param pem the PEM-formatted private key.
12974 *
12975 * @return the private key.
12976 */
12977pki.privateKeyFromPem = function(pem) {
12978  var msg = forge.pem.decode(pem)[0];
12979
12980  if(msg.type !== 'PRIVATE KEY' && msg.type !== 'RSA PRIVATE KEY') {
12981    var error = new Error('Could not convert private key from PEM; PEM ' +
12982      'header type is not "PRIVATE KEY" or "RSA PRIVATE KEY".');
12983    error.headerType = msg.type;
12984    throw error;
12985  }
12986  if(msg.procType && msg.procType.type === 'ENCRYPTED') {
12987    throw new Error('Could not convert private key from PEM; PEM is encrypted.');
12988  }
12989
12990  // convert DER to ASN.1 object
12991  var obj = asn1.fromDer(msg.body);
12992
12993  return pki.privateKeyFromAsn1(obj);
12994};
12995
12996/**
12997 * Converts an RSA private key to PEM format.
12998 *
12999 * @param key the private key.
13000 * @param maxline the maximum characters per line, defaults to 64.
13001 *
13002 * @return the PEM-formatted private key.
13003 */
13004pki.privateKeyToPem = function(key, maxline) {
13005  // convert to ASN.1, then DER, then PEM-encode
13006  var msg = {
13007    type: 'RSA PRIVATE KEY',
13008    body: asn1.toDer(pki.privateKeyToAsn1(key)).getBytes()
13009  };
13010  return forge.pem.encode(msg, {maxline: maxline});
13011};
13012
13013/**
13014 * Converts a PrivateKeyInfo to PEM format.
13015 *
13016 * @param pki the PrivateKeyInfo.
13017 * @param maxline the maximum characters per line, defaults to 64.
13018 *
13019 * @return the PEM-formatted private key.
13020 */
13021pki.privateKeyInfoToPem = function(pki, maxline) {
13022  // convert to DER, then PEM-encode
13023  var msg = {
13024    type: 'PRIVATE KEY',
13025    body: asn1.toDer(pki).getBytes()
13026  };
13027  return forge.pem.encode(msg, {maxline: maxline});
13028};
13029
13030} // end module implementation
13031
13032/* ########## Begin module wrapper ########## */
13033var name = 'pki';
13034if(typeof define !== 'function') {
13035  // NodeJS -> AMD
13036  if(typeof module === 'object' && module.exports) {
13037    var nodeJS = true;
13038    define = function(ids, factory) {
13039      factory(require, module);
13040    };
13041  } else {
13042    // <script>
13043    if(typeof forge === 'undefined') {
13044      forge = {};
13045    }
13046    return initModule(forge);
13047  }
13048}
13049// AMD
13050var deps;
13051var defineFunc = function(require, module) {
13052  module.exports = function(forge) {
13053    var mods = deps.map(function(dep) {
13054      return require(dep);
13055    }).concat(initModule);
13056    // handle circular dependencies
13057    forge = forge || {};
13058    forge.defined = forge.defined || {};
13059    if(forge.defined[name]) {
13060      return forge[name];
13061    }
13062    forge.defined[name] = true;
13063    for(var i = 0; i < mods.length; ++i) {
13064      mods[i](forge);
13065    }
13066    return forge[name];
13067  };
13068};
13069var tmpDefine = define;
13070define = function(ids, factory) {
13071  deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2);
13072  if(nodeJS) {
13073    delete define;
13074    return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0));
13075  }
13076  define = tmpDefine;
13077  return define.apply(null, Array.prototype.slice.call(arguments, 0));
13078};
13079define([
13080  'require',
13081  'module',
13082  './asn1',
13083  './oids',
13084  './pbe',
13085  './pem',
13086  './pbkdf2',
13087  './pkcs12',
13088  './pss',
13089  './rsa',
13090  './util',
13091  './x509'
13092], function() {
13093  defineFunc.apply(null, Array.prototype.slice.call(arguments, 0));
13094});
13095})();
13096
13097/**
13098 * Object IDs for ASN.1.
13099 *
13100 * @author Dave Longley
13101 *
13102 * Copyright (c) 2010-2013 Digital Bazaar, Inc.
13103 */
13104(function() {
13105/* ########## Begin module implementation ########## */
13106function initModule(forge) {
13107
13108forge.pki = forge.pki || {};
13109var oids = forge.pki.oids = forge.oids = forge.oids || {};
13110
13111// algorithm OIDs
13112oids['1.2.840.113549.1.1.1'] = 'rsaEncryption';
13113oids['rsaEncryption'] = '1.2.840.113549.1.1.1';
13114// Note: md2 & md4 not implemented
13115//oids['1.2.840.113549.1.1.2'] = 'md2WithRSAEncryption';
13116//oids['md2WithRSAEncryption'] = '1.2.840.113549.1.1.2';
13117//oids['1.2.840.113549.1.1.3'] = 'md4WithRSAEncryption';
13118//oids['md4WithRSAEncryption'] = '1.2.840.113549.1.1.3';
13119oids['1.2.840.113549.1.1.4'] = 'md5WithRSAEncryption';
13120oids['md5WithRSAEncryption'] = '1.2.840.113549.1.1.4';
13121oids['1.2.840.113549.1.1.5'] = 'sha1WithRSAEncryption';
13122oids['sha1WithRSAEncryption'] = '1.2.840.113549.1.1.5';
13123oids['1.2.840.113549.1.1.7'] = 'RSAES-OAEP';
13124oids['RSAES-OAEP'] = '1.2.840.113549.1.1.7';
13125oids['1.2.840.113549.1.1.8'] = 'mgf1';
13126oids['mgf1'] = '1.2.840.113549.1.1.8';
13127oids['1.2.840.113549.1.1.9'] = 'pSpecified';
13128oids['pSpecified'] = '1.2.840.113549.1.1.9';
13129oids['1.2.840.113549.1.1.10'] = 'RSASSA-PSS';
13130oids['RSASSA-PSS'] = '1.2.840.113549.1.1.10';
13131oids['1.2.840.113549.1.1.11'] = 'sha256WithRSAEncryption';
13132oids['sha256WithRSAEncryption'] = '1.2.840.113549.1.1.11';
13133oids['1.2.840.113549.1.1.12'] = 'sha384WithRSAEncryption';
13134oids['sha384WithRSAEncryption'] = '1.2.840.113549.1.1.12';
13135oids['1.2.840.113549.1.1.13'] = 'sha512WithRSAEncryption';
13136oids['sha512WithRSAEncryption'] = '1.2.840.113549.1.1.13';
13137
13138oids['1.3.14.3.2.7'] = 'desCBC';
13139oids['desCBC'] = '1.3.14.3.2.7';
13140
13141oids['1.3.14.3.2.26'] = 'sha1';
13142oids['sha1'] = '1.3.14.3.2.26';
13143oids['2.16.840.1.101.3.4.2.1'] = 'sha256';
13144oids['sha256'] = '2.16.840.1.101.3.4.2.1';
13145oids['2.16.840.1.101.3.4.2.2'] = 'sha384';
13146oids['sha384'] = '2.16.840.1.101.3.4.2.2';
13147oids['2.16.840.1.101.3.4.2.3'] = 'sha512';
13148oids['sha512'] = '2.16.840.1.101.3.4.2.3';
13149oids['1.2.840.113549.2.5'] = 'md5';
13150oids['md5'] = '1.2.840.113549.2.5';
13151
13152// pkcs#7 content types
13153oids['1.2.840.113549.1.7.1'] = 'data';
13154oids['data'] = '1.2.840.113549.1.7.1';
13155oids['1.2.840.113549.1.7.2'] = 'signedData';
13156oids['signedData'] = '1.2.840.113549.1.7.2';
13157oids['1.2.840.113549.1.7.3'] = 'envelopedData';
13158oids['envelopedData'] = '1.2.840.113549.1.7.3';
13159oids['1.2.840.113549.1.7.4'] = 'signedAndEnvelopedData';
13160oids['signedAndEnvelopedData'] = '1.2.840.113549.1.7.4';
13161oids['1.2.840.113549.1.7.5'] = 'digestedData';
13162oids['digestedData'] = '1.2.840.113549.1.7.5';
13163oids['1.2.840.113549.1.7.6'] = 'encryptedData';
13164oids['encryptedData'] = '1.2.840.113549.1.7.6';
13165
13166// pkcs#9 oids
13167oids['1.2.840.113549.1.9.1'] = 'emailAddress';
13168oids['emailAddress'] = '1.2.840.113549.1.9.1';
13169oids['1.2.840.113549.1.9.2'] = 'unstructuredName';
13170oids['unstructuredName'] = '1.2.840.113549.1.9.2';
13171oids['1.2.840.113549.1.9.3'] = 'contentType';
13172oids['contentType'] = '1.2.840.113549.1.9.3';
13173oids['1.2.840.113549.1.9.4'] = 'messageDigest';
13174oids['messageDigest'] = '1.2.840.113549.1.9.4';
13175oids['1.2.840.113549.1.9.5'] = 'signingTime';
13176oids['signingTime'] = '1.2.840.113549.1.9.5';
13177oids['1.2.840.113549.1.9.6'] = 'counterSignature';
13178oids['counterSignature'] = '1.2.840.113549.1.9.6';
13179oids['1.2.840.113549.1.9.7'] = 'challengePassword';
13180oids['challengePassword'] = '1.2.840.113549.1.9.7';
13181oids['1.2.840.113549.1.9.8'] = 'unstructuredAddress';
13182oids['unstructuredAddress'] = '1.2.840.113549.1.9.8';
13183oids['1.2.840.113549.1.9.14'] = 'extensionRequest';
13184oids['extensionRequest'] = '1.2.840.113549.1.9.14';
13185
13186oids['1.2.840.113549.1.9.20'] = 'friendlyName';
13187oids['friendlyName'] = '1.2.840.113549.1.9.20';
13188oids['1.2.840.113549.1.9.21'] = 'localKeyId';
13189oids['localKeyId'] = '1.2.840.113549.1.9.21';
13190oids['1.2.840.113549.1.9.22.1'] = 'x509Certificate';
13191oids['x509Certificate'] = '1.2.840.113549.1.9.22.1';
13192
13193// pkcs#12 safe bags
13194oids['1.2.840.113549.1.12.10.1.1'] = 'keyBag';
13195oids['keyBag'] = '1.2.840.113549.1.12.10.1.1';
13196oids['1.2.840.113549.1.12.10.1.2'] = 'pkcs8ShroudedKeyBag';
13197oids['pkcs8ShroudedKeyBag'] = '1.2.840.113549.1.12.10.1.2';
13198oids['1.2.840.113549.1.12.10.1.3'] = 'certBag';
13199oids['certBag'] = '1.2.840.113549.1.12.10.1.3';
13200oids['1.2.840.113549.1.12.10.1.4'] = 'crlBag';
13201oids['crlBag'] = '1.2.840.113549.1.12.10.1.4';
13202oids['1.2.840.113549.1.12.10.1.5'] = 'secretBag';
13203oids['secretBag'] = '1.2.840.113549.1.12.10.1.5';
13204oids['1.2.840.113549.1.12.10.1.6'] = 'safeContentsBag';
13205oids['safeContentsBag'] = '1.2.840.113549.1.12.10.1.6';
13206
13207// password-based-encryption for pkcs#12
13208oids['1.2.840.113549.1.5.13'] = 'pkcs5PBES2';
13209oids['pkcs5PBES2'] = '1.2.840.113549.1.5.13';
13210oids['1.2.840.113549.1.5.12'] = 'pkcs5PBKDF2';
13211oids['pkcs5PBKDF2'] = '1.2.840.113549.1.5.12';
13212
13213oids['1.2.840.113549.1.12.1.1'] = 'pbeWithSHAAnd128BitRC4';
13214oids['pbeWithSHAAnd128BitRC4'] = '1.2.840.113549.1.12.1.1';
13215oids['1.2.840.113549.1.12.1.2'] = 'pbeWithSHAAnd40BitRC4';
13216oids['pbeWithSHAAnd40BitRC4'] = '1.2.840.113549.1.12.1.2';
13217oids['1.2.840.113549.1.12.1.3'] = 'pbeWithSHAAnd3-KeyTripleDES-CBC';
13218oids['pbeWithSHAAnd3-KeyTripleDES-CBC'] = '1.2.840.113549.1.12.1.3';
13219oids['1.2.840.113549.1.12.1.4'] = 'pbeWithSHAAnd2-KeyTripleDES-CBC';
13220oids['pbeWithSHAAnd2-KeyTripleDES-CBC'] = '1.2.840.113549.1.12.1.4';
13221oids['1.2.840.113549.1.12.1.5'] = 'pbeWithSHAAnd128BitRC2-CBC';
13222oids['pbeWithSHAAnd128BitRC2-CBC'] = '1.2.840.113549.1.12.1.5';
13223oids['1.2.840.113549.1.12.1.6'] = 'pbewithSHAAnd40BitRC2-CBC';
13224oids['pbewithSHAAnd40BitRC2-CBC'] = '1.2.840.113549.1.12.1.6';
13225
13226// hmac OIDs
13227oids['1.2.840.113549.2.7'] = 'hmacWithSHA1';
13228oids['hmacWithSHA1'] = '1.2.840.113549.2.7';
13229oids['1.2.840.113549.2.8'] = 'hmacWithSHA224';
13230oids['hmacWithSHA224'] = '1.2.840.113549.2.8';
13231oids['1.2.840.113549.2.9'] = 'hmacWithSHA256';
13232oids['hmacWithSHA256'] = '1.2.840.113549.2.9';
13233oids['1.2.840.113549.2.10'] = 'hmacWithSHA384';
13234oids['hmacWithSHA384'] = '1.2.840.113549.2.10';
13235oids['1.2.840.113549.2.11'] = 'hmacWithSHA512';
13236oids['hmacWithSHA512'] = '1.2.840.113549.2.11';
13237
13238// symmetric key algorithm oids
13239oids['1.2.840.113549.3.7'] = 'des-EDE3-CBC';
13240oids['des-EDE3-CBC'] = '1.2.840.113549.3.7';
13241oids['2.16.840.1.101.3.4.1.2'] = 'aes128-CBC';
13242oids['aes128-CBC'] = '2.16.840.1.101.3.4.1.2';
13243oids['2.16.840.1.101.3.4.1.22'] = 'aes192-CBC';
13244oids['aes192-CBC'] = '2.16.840.1.101.3.4.1.22';
13245oids['2.16.840.1.101.3.4.1.42'] = 'aes256-CBC';
13246oids['aes256-CBC'] = '2.16.840.1.101.3.4.1.42';
13247
13248// certificate issuer/subject OIDs
13249oids['2.5.4.3'] = 'commonName';
13250oids['commonName'] = '2.5.4.3';
13251oids['2.5.4.5'] = 'serialName';
13252oids['serialName'] = '2.5.4.5';
13253oids['2.5.4.6'] = 'countryName';
13254oids['countryName'] = '2.5.4.6';
13255oids['2.5.4.7'] = 'localityName';
13256oids['localityName'] = '2.5.4.7';
13257oids['2.5.4.8'] = 'stateOrProvinceName';
13258oids['stateOrProvinceName'] = '2.5.4.8';
13259oids['2.5.4.10'] = 'organizationName';
13260oids['organizationName'] = '2.5.4.10';
13261oids['2.5.4.11'] = 'organizationalUnitName';
13262oids['organizationalUnitName'] = '2.5.4.11';
13263
13264// X.509 extension OIDs
13265oids['2.16.840.1.113730.1.1'] = 'nsCertType';
13266oids['nsCertType'] = '2.16.840.1.113730.1.1';
13267oids['2.5.29.1'] = 'authorityKeyIdentifier'; // deprecated, use .35
13268oids['2.5.29.2'] = 'keyAttributes'; // obsolete use .37 or .15
13269oids['2.5.29.3'] = 'certificatePolicies'; // deprecated, use .32
13270oids['2.5.29.4'] = 'keyUsageRestriction'; // obsolete use .37 or .15
13271oids['2.5.29.5'] = 'policyMapping'; // deprecated use .33
13272oids['2.5.29.6'] = 'subtreesConstraint'; // obsolete use .30
13273oids['2.5.29.7'] = 'subjectAltName'; // deprecated use .17
13274oids['2.5.29.8'] = 'issuerAltName'; // deprecated use .18
13275oids['2.5.29.9'] = 'subjectDirectoryAttributes';
13276oids['2.5.29.10'] = 'basicConstraints'; // deprecated use .19
13277oids['2.5.29.11'] = 'nameConstraints'; // deprecated use .30
13278oids['2.5.29.12'] = 'policyConstraints'; // deprecated use .36
13279oids['2.5.29.13'] = 'basicConstraints'; // deprecated use .19
13280oids['2.5.29.14'] = 'subjectKeyIdentifier';
13281oids['subjectKeyIdentifier'] = '2.5.29.14';
13282oids['2.5.29.15'] = 'keyUsage';
13283oids['keyUsage'] = '2.5.29.15';
13284oids['2.5.29.16'] = 'privateKeyUsagePeriod';
13285oids['2.5.29.17'] = 'subjectAltName';
13286oids['subjectAltName'] = '2.5.29.17';
13287oids['2.5.29.18'] = 'issuerAltName';
13288oids['issuerAltName'] = '2.5.29.18';
13289oids['2.5.29.19'] = 'basicConstraints';
13290oids['basicConstraints'] = '2.5.29.19';
13291oids['2.5.29.20'] = 'cRLNumber';
13292oids['2.5.29.21'] = 'cRLReason';
13293oids['2.5.29.22'] = 'expirationDate';
13294oids['2.5.29.23'] = 'instructionCode';
13295oids['2.5.29.24'] = 'invalidityDate';
13296oids['2.5.29.25'] = 'cRLDistributionPoints'; // deprecated use .31
13297oids['2.5.29.26'] = 'issuingDistributionPoint'; // deprecated use .28
13298oids['2.5.29.27'] = 'deltaCRLIndicator';
13299oids['2.5.29.28'] = 'issuingDistributionPoint';
13300oids['2.5.29.29'] = 'certificateIssuer';
13301oids['2.5.29.30'] = 'nameConstraints';
13302oids['2.5.29.31'] = 'cRLDistributionPoints';
13303oids['cRLDistributionPoints'] = '2.5.29.31';
13304oids['2.5.29.32'] = 'certificatePolicies';
13305oids['certificatePolicies'] = '2.5.29.32';
13306oids['2.5.29.33'] = 'policyMappings';
13307oids['2.5.29.34'] = 'policyConstraints'; // deprecated use .36
13308oids['2.5.29.35'] = 'authorityKeyIdentifier';
13309oids['authorityKeyIdentifier'] = '2.5.29.35';
13310oids['2.5.29.36'] = 'policyConstraints';
13311oids['2.5.29.37'] = 'extKeyUsage';
13312oids['extKeyUsage'] = '2.5.29.37';
13313oids['2.5.29.46'] = 'freshestCRL';
13314oids['2.5.29.54'] = 'inhibitAnyPolicy';
13315
13316// extKeyUsage purposes
13317oids['1.3.6.1.4.1.11129.2.4.2'] = 'timestampList';
13318oids['timestampList'] = '1.3.6.1.4.1.11129.2.4.2';
13319oids['1.3.6.1.5.5.7.1.1'] = 'authorityInfoAccess';
13320oids['authorityInfoAccess'] = '1.3.6.1.5.5.7.1.1';
13321oids['1.3.6.1.5.5.7.3.1'] = 'serverAuth';
13322oids['serverAuth'] = '1.3.6.1.5.5.7.3.1';
13323oids['1.3.6.1.5.5.7.3.2'] = 'clientAuth';
13324oids['clientAuth'] = '1.3.6.1.5.5.7.3.2';
13325oids['1.3.6.1.5.5.7.3.3'] = 'codeSigning';
13326oids['codeSigning'] = '1.3.6.1.5.5.7.3.3';
13327oids['1.3.6.1.5.5.7.3.4'] = 'emailProtection';
13328oids['emailProtection'] = '1.3.6.1.5.5.7.3.4';
13329oids['1.3.6.1.5.5.7.3.8'] = 'timeStamping';
13330oids['timeStamping'] = '1.3.6.1.5.5.7.3.8';
13331
13332} // end module implementation
13333
13334/* ########## Begin module wrapper ########## */
13335var name = 'oids';
13336if(typeof define !== 'function') {
13337  // NodeJS -> AMD
13338  if(typeof module === 'object' && module.exports) {
13339    var nodeJS = true;
13340    define = function(ids, factory) {
13341      factory(require, module);
13342    };
13343  } else {
13344    // <script>
13345    if(typeof forge === 'undefined') {
13346      forge = {};
13347    }
13348    return initModule(forge);
13349  }
13350}
13351// AMD
13352var deps;
13353var defineFunc = function(require, module) {
13354  module.exports = function(forge) {
13355    var mods = deps.map(function(dep) {
13356      return require(dep);
13357    }).concat(initModule);
13358    // handle circular dependencies
13359    forge = forge || {};
13360    forge.defined = forge.defined || {};
13361    if(forge.defined[name]) {
13362      return forge[name];
13363    }
13364    forge.defined[name] = true;
13365    for(var i = 0; i < mods.length; ++i) {
13366      mods[i](forge);
13367    }
13368    return forge[name];
13369  };
13370};
13371var tmpDefine = define;
13372define = function(ids, factory) {
13373  deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2);
13374  if(nodeJS) {
13375    delete define;
13376    return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0));
13377  }
13378  define = tmpDefine;
13379  return define.apply(null, Array.prototype.slice.call(arguments, 0));
13380};
13381define(['require', 'module'], function() {
13382  defineFunc.apply(null, Array.prototype.slice.call(arguments, 0));
13383});
13384})();
13385
13386/**
13387 * Javascript implementation of X.509 and related components (such as
13388 * Certification Signing Requests) of a Public Key Infrastructure.
13389 *
13390 * @author Dave Longley
13391 *
13392 * Copyright (c) 2010-2014 Digital Bazaar, Inc.
13393 *
13394 * The ASN.1 representation of an X.509v3 certificate is as follows
13395 * (see RFC 2459):
13396 *
13397 * Certificate ::= SEQUENCE {
13398 *   tbsCertificate       TBSCertificate,
13399 *   signatureAlgorithm   AlgorithmIdentifier,
13400 *   signatureValue       BIT STRING
13401 * }
13402 *
13403 * TBSCertificate ::= SEQUENCE {
13404 *   version         [0]  EXPLICIT Version DEFAULT v1,
13405 *   serialNumber         CertificateSerialNumber,
13406 *   signature            AlgorithmIdentifier,
13407 *   issuer               Name,
13408 *   validity             Validity,
13409 *   subject              Name,
13410 *   subjectPublicKeyInfo SubjectPublicKeyInfo,
13411 *   issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
13412 *                        -- If present, version shall be v2 or v3
13413 *   subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
13414 *                        -- If present, version shall be v2 or v3
13415 *   extensions      [3]  EXPLICIT Extensions OPTIONAL
13416 *                        -- If present, version shall be v3
13417 * }
13418 *
13419 * Version ::= INTEGER  { v1(0), v2(1), v3(2) }
13420 *
13421 * CertificateSerialNumber ::= INTEGER
13422 *
13423 * Name ::= CHOICE {
13424 *   // only one possible choice for now
13425 *   RDNSequence
13426 * }
13427 *
13428 * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
13429 *
13430 * RelativeDistinguishedName ::= SET OF AttributeTypeAndValue
13431 *
13432 * AttributeTypeAndValue ::= SEQUENCE {
13433 *   type     AttributeType,
13434 *   value    AttributeValue
13435 * }
13436 * AttributeType ::= OBJECT IDENTIFIER
13437 * AttributeValue ::= ANY DEFINED BY AttributeType
13438 *
13439 * Validity ::= SEQUENCE {
13440 *   notBefore      Time,
13441 *   notAfter       Time
13442 * }
13443 *
13444 * Time ::= CHOICE {
13445 *   utcTime        UTCTime,
13446 *   generalTime    GeneralizedTime
13447 * }
13448 *
13449 * UniqueIdentifier ::= BIT STRING
13450 *
13451 * SubjectPublicKeyInfo ::= SEQUENCE {
13452 *   algorithm            AlgorithmIdentifier,
13453 *   subjectPublicKey     BIT STRING
13454 * }
13455 *
13456 * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
13457 *
13458 * Extension ::= SEQUENCE {
13459 *   extnID      OBJECT IDENTIFIER,
13460 *   critical    BOOLEAN DEFAULT FALSE,
13461 *   extnValue   OCTET STRING
13462 * }
13463 *
13464 * The only key algorithm currently supported for PKI is RSA.
13465 *
13466 * RSASSA-PSS signatures are described in RFC 3447 and RFC 4055.
13467 *
13468 * PKCS#10 v1.7 describes certificate signing requests:
13469 *
13470 * CertificationRequestInfo:
13471 *
13472 * CertificationRequestInfo ::= SEQUENCE {
13473 *   version       INTEGER { v1(0) } (v1,...),
13474 *   subject       Name,
13475 *   subjectPKInfo SubjectPublicKeyInfo{{ PKInfoAlgorithms }},
13476 *   attributes    [0] Attributes{{ CRIAttributes }}
13477 * }
13478 *
13479 * Attributes { ATTRIBUTE:IOSet } ::= SET OF Attribute{{ IOSet }}
13480 *
13481 * CRIAttributes  ATTRIBUTE  ::= {
13482 *   ... -- add any locally defined attributes here -- }
13483 *
13484 * Attribute { ATTRIBUTE:IOSet } ::= SEQUENCE {
13485 *   type   ATTRIBUTE.&id({IOSet}),
13486 *   values SET SIZE(1..MAX) OF ATTRIBUTE.&Type({IOSet}{@type})
13487 * }
13488 *
13489 * CertificationRequest ::= SEQUENCE {
13490 *   certificationRequestInfo CertificationRequestInfo,
13491 *   signatureAlgorithm AlgorithmIdentifier{{ SignatureAlgorithms }},
13492 *   signature          BIT STRING
13493 * }
13494 */
13495(function() {
13496/* ########## Begin module implementation ########## */
13497function initModule(forge) {
13498
13499// shortcut for asn.1 API
13500var asn1 = forge.asn1;
13501
13502/* Public Key Infrastructure (PKI) implementation. */
13503var pki = forge.pki = forge.pki || {};
13504var oids = pki.oids;
13505
13506// short name OID mappings
13507var _shortNames = {};
13508_shortNames['CN'] = oids['commonName'];
13509_shortNames['commonName'] = 'CN';
13510_shortNames['C'] = oids['countryName'];
13511_shortNames['countryName'] = 'C';
13512_shortNames['L'] = oids['localityName'];
13513_shortNames['localityName'] = 'L';
13514_shortNames['ST'] = oids['stateOrProvinceName'];
13515_shortNames['stateOrProvinceName'] = 'ST';
13516_shortNames['O'] = oids['organizationName'];
13517_shortNames['organizationName'] = 'O';
13518_shortNames['OU'] = oids['organizationalUnitName'];
13519_shortNames['organizationalUnitName'] = 'OU';
13520_shortNames['E'] = oids['emailAddress'];
13521_shortNames['emailAddress'] = 'E';
13522
13523// validator for an SubjectPublicKeyInfo structure
13524// Note: Currently only works with an RSA public key
13525var publicKeyValidator = forge.pki.rsa.publicKeyValidator;
13526
13527// validator for an X.509v3 certificate
13528var x509CertificateValidator = {
13529  name: 'Certificate',
13530  tagClass: asn1.Class.UNIVERSAL,
13531  type: asn1.Type.SEQUENCE,
13532  constructed: true,
13533  value: [{
13534    name: 'Certificate.TBSCertificate',
13535    tagClass: asn1.Class.UNIVERSAL,
13536    type: asn1.Type.SEQUENCE,
13537    constructed: true,
13538    captureAsn1: 'tbsCertificate',
13539    value: [{
13540      name: 'Certificate.TBSCertificate.version',
13541      tagClass: asn1.Class.CONTEXT_SPECIFIC,
13542      type: 0,
13543      constructed: true,
13544      optional: true,
13545      value: [{
13546        name: 'Certificate.TBSCertificate.version.integer',
13547        tagClass: asn1.Class.UNIVERSAL,
13548        type: asn1.Type.INTEGER,
13549        constructed: false,
13550        capture: 'certVersion'
13551      }]
13552    }, {
13553      name: 'Certificate.TBSCertificate.serialNumber',
13554      tagClass: asn1.Class.UNIVERSAL,
13555      type: asn1.Type.INTEGER,
13556      constructed: false,
13557      capture: 'certSerialNumber'
13558    }, {
13559      name: 'Certificate.TBSCertificate.signature',
13560      tagClass: asn1.Class.UNIVERSAL,
13561      type: asn1.Type.SEQUENCE,
13562      constructed: true,
13563      value: [{
13564        name: 'Certificate.TBSCertificate.signature.algorithm',
13565        tagClass: asn1.Class.UNIVERSAL,
13566        type: asn1.Type.OID,
13567        constructed: false,
13568        capture: 'certinfoSignatureOid'
13569      }, {
13570        name: 'Certificate.TBSCertificate.signature.parameters',
13571        tagClass: asn1.Class.UNIVERSAL,
13572        optional: true,
13573        captureAsn1: 'certinfoSignatureParams'
13574      }]
13575    }, {
13576      name: 'Certificate.TBSCertificate.issuer',
13577      tagClass: asn1.Class.UNIVERSAL,
13578      type: asn1.Type.SEQUENCE,
13579      constructed: true,
13580      captureAsn1: 'certIssuer'
13581    }, {
13582      name: 'Certificate.TBSCertificate.validity',
13583      tagClass: asn1.Class.UNIVERSAL,
13584      type: asn1.Type.SEQUENCE,
13585      constructed: true,
13586      // Note: UTC and generalized times may both appear so the capture
13587      // names are based on their detected order, the names used below
13588      // are only for the common case, which validity time really means
13589      // "notBefore" and which means "notAfter" will be determined by order
13590      value: [{
13591        // notBefore (Time) (UTC time case)
13592        name: 'Certificate.TBSCertificate.validity.notBefore (utc)',
13593        tagClass: asn1.Class.UNIVERSAL,
13594        type: asn1.Type.UTCTIME,
13595        constructed: false,
13596        optional: true,
13597        capture: 'certValidity1UTCTime'
13598      }, {
13599        // notBefore (Time) (generalized time case)
13600        name: 'Certificate.TBSCertificate.validity.notBefore (generalized)',
13601        tagClass: asn1.Class.UNIVERSAL,
13602        type: asn1.Type.GENERALIZEDTIME,
13603        constructed: false,
13604        optional: true,
13605        capture: 'certValidity2GeneralizedTime'
13606      }, {
13607        // notAfter (Time) (only UTC time is supported)
13608        name: 'Certificate.TBSCertificate.validity.notAfter (utc)',
13609        tagClass: asn1.Class.UNIVERSAL,
13610        type: asn1.Type.UTCTIME,
13611        constructed: false,
13612        optional: true,
13613        capture: 'certValidity3UTCTime'
13614      }, {
13615        // notAfter (Time) (only UTC time is supported)
13616        name: 'Certificate.TBSCertificate.validity.notAfter (generalized)',
13617        tagClass: asn1.Class.UNIVERSAL,
13618        type: asn1.Type.GENERALIZEDTIME,
13619        constructed: false,
13620        optional: true,
13621        capture: 'certValidity4GeneralizedTime'
13622      }]
13623    }, {
13624      // Name (subject) (RDNSequence)
13625      name: 'Certificate.TBSCertificate.subject',
13626      tagClass: asn1.Class.UNIVERSAL,
13627      type: asn1.Type.SEQUENCE,
13628      constructed: true,
13629      captureAsn1: 'certSubject'
13630    },
13631      // SubjectPublicKeyInfo
13632      publicKeyValidator,
13633    {
13634      // issuerUniqueID (optional)
13635      name: 'Certificate.TBSCertificate.issuerUniqueID',
13636      tagClass: asn1.Class.CONTEXT_SPECIFIC,
13637      type: 1,
13638      constructed: true,
13639      optional: true,
13640      value: [{
13641        name: 'Certificate.TBSCertificate.issuerUniqueID.id',
13642        tagClass: asn1.Class.UNIVERSAL,
13643        type: asn1.Type.BITSTRING,
13644        constructed: false,
13645        capture: 'certIssuerUniqueId'
13646      }]
13647    }, {
13648      // subjectUniqueID (optional)
13649      name: 'Certificate.TBSCertificate.subjectUniqueID',
13650      tagClass: asn1.Class.CONTEXT_SPECIFIC,
13651      type: 2,
13652      constructed: true,
13653      optional: true,
13654      value: [{
13655        name: 'Certificate.TBSCertificate.subjectUniqueID.id',
13656        tagClass: asn1.Class.UNIVERSAL,
13657        type: asn1.Type.BITSTRING,
13658        constructed: false,
13659        capture: 'certSubjectUniqueId'
13660      }]
13661    }, {
13662      // Extensions (optional)
13663      name: 'Certificate.TBSCertificate.extensions',
13664      tagClass: asn1.Class.CONTEXT_SPECIFIC,
13665      type: 3,
13666      constructed: true,
13667      captureAsn1: 'certExtensions',
13668      optional: true
13669    }]
13670  }, {
13671    // AlgorithmIdentifier (signature algorithm)
13672    name: 'Certificate.signatureAlgorithm',
13673    tagClass: asn1.Class.UNIVERSAL,
13674    type: asn1.Type.SEQUENCE,
13675    constructed: true,
13676    value: [{
13677      // algorithm
13678      name: 'Certificate.signatureAlgorithm.algorithm',
13679      tagClass: asn1.Class.UNIVERSAL,
13680      type: asn1.Type.OID,
13681      constructed: false,
13682      capture: 'certSignatureOid'
13683    }, {
13684      name: 'Certificate.TBSCertificate.signature.parameters',
13685      tagClass: asn1.Class.UNIVERSAL,
13686      optional: true,
13687      captureAsn1: 'certSignatureParams'
13688    }]
13689  }, {
13690    // SignatureValue
13691    name: 'Certificate.signatureValue',
13692    tagClass: asn1.Class.UNIVERSAL,
13693    type: asn1.Type.BITSTRING,
13694    constructed: false,
13695    capture: 'certSignature'
13696  }]
13697};
13698
13699var rsassaPssParameterValidator = {
13700  name: 'rsapss',
13701  tagClass: asn1.Class.UNIVERSAL,
13702  type: asn1.Type.SEQUENCE,
13703  constructed: true,
13704  value: [{
13705    name: 'rsapss.hashAlgorithm',
13706    tagClass: asn1.Class.CONTEXT_SPECIFIC,
13707    type: 0,
13708    constructed: true,
13709    value: [{
13710      name: 'rsapss.hashAlgorithm.AlgorithmIdentifier',
13711      tagClass: asn1.Class.UNIVERSAL,
13712      type: asn1.Class.SEQUENCE,
13713      constructed: true,
13714      optional: true,
13715      value: [{
13716        name: 'rsapss.hashAlgorithm.AlgorithmIdentifier.algorithm',
13717        tagClass: asn1.Class.UNIVERSAL,
13718        type: asn1.Type.OID,
13719        constructed: false,
13720        capture: 'hashOid'
13721        /* parameter block omitted, for SHA1 NULL anyhow. */
13722      }]
13723    }]
13724  }, {
13725    name: 'rsapss.maskGenAlgorithm',
13726    tagClass: asn1.Class.CONTEXT_SPECIFIC,
13727    type: 1,
13728    constructed: true,
13729    value: [{
13730      name: 'rsapss.maskGenAlgorithm.AlgorithmIdentifier',
13731      tagClass: asn1.Class.UNIVERSAL,
13732      type: asn1.Class.SEQUENCE,
13733      constructed: true,
13734      optional: true,
13735      value: [{
13736        name: 'rsapss.maskGenAlgorithm.AlgorithmIdentifier.algorithm',
13737        tagClass: asn1.Class.UNIVERSAL,
13738        type: asn1.Type.OID,
13739        constructed: false,
13740        capture: 'maskGenOid'
13741      }, {
13742        name: 'rsapss.maskGenAlgorithm.AlgorithmIdentifier.params',
13743        tagClass: asn1.Class.UNIVERSAL,
13744        type: asn1.Type.SEQUENCE,
13745        constructed: true,
13746        value: [{
13747          name: 'rsapss.maskGenAlgorithm.AlgorithmIdentifier.params.algorithm',
13748          tagClass: asn1.Class.UNIVERSAL,
13749          type: asn1.Type.OID,
13750          constructed: false,
13751          capture: 'maskGenHashOid'
13752          /* parameter block omitted, for SHA1 NULL anyhow. */
13753        }]
13754      }]
13755    }]
13756  }, {
13757    name: 'rsapss.saltLength',
13758    tagClass: asn1.Class.CONTEXT_SPECIFIC,
13759    type: 2,
13760    optional: true,
13761    value: [{
13762      name: 'rsapss.saltLength.saltLength',
13763      tagClass: asn1.Class.UNIVERSAL,
13764      type: asn1.Class.INTEGER,
13765      constructed: false,
13766      capture: 'saltLength'
13767    }]
13768  }, {
13769    name: 'rsapss.trailerField',
13770    tagClass: asn1.Class.CONTEXT_SPECIFIC,
13771    type: 3,
13772    optional: true,
13773    value: [{
13774      name: 'rsapss.trailer.trailer',
13775      tagClass: asn1.Class.UNIVERSAL,
13776      type: asn1.Class.INTEGER,
13777      constructed: false,
13778      capture: 'trailer'
13779    }]
13780  }]
13781};
13782
13783// validator for a CertificationRequestInfo structure
13784var certificationRequestInfoValidator = {
13785  name: 'CertificationRequestInfo',
13786  tagClass: asn1.Class.UNIVERSAL,
13787  type: asn1.Type.SEQUENCE,
13788  constructed: true,
13789  captureAsn1: 'certificationRequestInfo',
13790  value: [{
13791    name: 'CertificationRequestInfo.integer',
13792    tagClass: asn1.Class.UNIVERSAL,
13793    type: asn1.Type.INTEGER,
13794    constructed: false,
13795    capture: 'certificationRequestInfoVersion'
13796  }, {
13797    // Name (subject) (RDNSequence)
13798    name: 'CertificationRequestInfo.subject',
13799    tagClass: asn1.Class.UNIVERSAL,
13800    type: asn1.Type.SEQUENCE,
13801    constructed: true,
13802    captureAsn1: 'certificationRequestInfoSubject'
13803  },
13804  // SubjectPublicKeyInfo
13805  publicKeyValidator,
13806  {
13807    name: 'CertificationRequestInfo.attributes',
13808    tagClass: asn1.Class.CONTEXT_SPECIFIC,
13809    type: 0,
13810    constructed: true,
13811    optional: true,
13812    capture: 'certificationRequestInfoAttributes',
13813    value: [{
13814      name: 'CertificationRequestInfo.attributes',
13815      tagClass: asn1.Class.UNIVERSAL,
13816      type: asn1.Type.SEQUENCE,
13817      constructed: true,
13818      value: [{
13819        name: 'CertificationRequestInfo.attributes.type',
13820        tagClass: asn1.Class.UNIVERSAL,
13821        type: asn1.Type.OID,
13822        constructed: false
13823      }, {
13824        name: 'CertificationRequestInfo.attributes.value',
13825        tagClass: asn1.Class.UNIVERSAL,
13826        type: asn1.Type.SET,
13827        constructed: true
13828      }]
13829    }]
13830  }]
13831};
13832
13833// validator for a CertificationRequest structure
13834var certificationRequestValidator = {
13835  name: 'CertificationRequest',
13836  tagClass: asn1.Class.UNIVERSAL,
13837  type: asn1.Type.SEQUENCE,
13838  constructed: true,
13839  captureAsn1: 'csr',
13840  value: [
13841    certificationRequestInfoValidator, {
13842    // AlgorithmIdentifier (signature algorithm)
13843    name: 'CertificationRequest.signatureAlgorithm',
13844    tagClass: asn1.Class.UNIVERSAL,
13845    type: asn1.Type.SEQUENCE,
13846    constructed: true,
13847    value: [{
13848      // algorithm
13849      name: 'CertificationRequest.signatureAlgorithm.algorithm',
13850      tagClass: asn1.Class.UNIVERSAL,
13851      type: asn1.Type.OID,
13852      constructed: false,
13853      capture: 'csrSignatureOid'
13854    }, {
13855      name: 'CertificationRequest.signatureAlgorithm.parameters',
13856      tagClass: asn1.Class.UNIVERSAL,
13857      optional: true,
13858      captureAsn1: 'csrSignatureParams'
13859    }]
13860  }, {
13861    // signature
13862    name: 'CertificationRequest.signature',
13863    tagClass: asn1.Class.UNIVERSAL,
13864    type: asn1.Type.BITSTRING,
13865    constructed: false,
13866    capture: 'csrSignature'
13867  }]
13868};
13869
13870/**
13871 * Converts an RDNSequence of ASN.1 DER-encoded RelativeDistinguishedName
13872 * sets into an array with objects that have type and value properties.
13873 *
13874 * @param rdn the RDNSequence to convert.
13875 * @param md a message digest to append type and value to if provided.
13876 */
13877pki.RDNAttributesAsArray = function(rdn, md) {
13878  var rval = [];
13879
13880  // each value in 'rdn' in is a SET of RelativeDistinguishedName
13881  var set, attr, obj;
13882  for(var si = 0; si < rdn.value.length; ++si) {
13883    // get the RelativeDistinguishedName set
13884    set = rdn.value[si];
13885
13886    // each value in the SET is an AttributeTypeAndValue sequence
13887    // containing first a type (an OID) and second a value (defined by
13888    // the OID)
13889    for(var i = 0; i < set.value.length; ++i) {
13890      obj = {};
13891      attr = set.value[i];
13892      obj.type = asn1.derToOid(attr.value[0].value);
13893      obj.value = attr.value[1].value;
13894      obj.valueTagClass = attr.value[1].type;
13895      // if the OID is known, get its name and short name
13896      if(obj.type in oids) {
13897        obj.name = oids[obj.type];
13898        if(obj.name in _shortNames) {
13899          obj.shortName = _shortNames[obj.name];
13900        }
13901      }
13902      if(md) {
13903        md.update(obj.type);
13904        md.update(obj.value);
13905      }
13906      rval.push(obj);
13907    }
13908  }
13909
13910  return rval;
13911};
13912
13913/**
13914 * Converts ASN.1 CRIAttributes into an array with objects that have type and
13915 * value properties.
13916 *
13917 * @param attributes the CRIAttributes to convert.
13918 */
13919pki.CRIAttributesAsArray = function(attributes) {
13920  var rval = [];
13921
13922  // each value in 'attributes' in is a SEQUENCE with an OID and a SET
13923  for(var si = 0; si < attributes.length; ++si) {
13924    // get the attribute sequence
13925    var seq = attributes[si];
13926
13927    // each value in the SEQUENCE containing first a type (an OID) and
13928    // second a set of values (defined by the OID)
13929    var type = asn1.derToOid(seq.value[0].value);
13930    var values = seq.value[1].value;
13931    for(var vi = 0; vi < values.length; ++vi) {
13932      var obj = {};
13933      obj.type = type;
13934      obj.value = values[vi].value;
13935      obj.valueTagClass = values[vi].type;
13936      // if the OID is known, get its name and short name
13937      if(obj.type in oids) {
13938        obj.name = oids[obj.type];
13939        if(obj.name in _shortNames) {
13940          obj.shortName = _shortNames[obj.name];
13941        }
13942      }
13943      // parse extensions
13944      if(obj.type === oids.extensionRequest) {
13945        obj.extensions = [];
13946        for(var ei = 0; ei < obj.value.length; ++ei) {
13947          obj.extensions.push(pki.certificateExtensionFromAsn1(obj.value[ei]));
13948        }
13949      }
13950      rval.push(obj);
13951    }
13952  }
13953
13954  return rval;
13955};
13956
13957/**
13958 * Gets an issuer or subject attribute from its name, type, or short name.
13959 *
13960 * @param obj the issuer or subject object.
13961 * @param options a short name string or an object with:
13962 *          shortName the short name for the attribute.
13963 *          name the name for the attribute.
13964 *          type the type for the attribute.
13965 *
13966 * @return the attribute.
13967 */
13968function _getAttribute(obj, options) {
13969  if(typeof options === 'string') {
13970    options = {shortName: options};
13971  }
13972
13973  var rval = null;
13974  var attr;
13975  for(var i = 0; rval === null && i < obj.attributes.length; ++i) {
13976    attr = obj.attributes[i];
13977    if(options.type && options.type === attr.type) {
13978      rval = attr;
13979    } else if(options.name && options.name === attr.name) {
13980      rval = attr;
13981    } else if(options.shortName && options.shortName === attr.shortName) {
13982      rval = attr;
13983    }
13984  }
13985  return rval;
13986}
13987
13988/**
13989 * Converts signature parameters from ASN.1 structure.
13990 *
13991 * Currently only RSASSA-PSS supported.  The PKCS#1 v1.5 signature scheme had
13992 * no parameters.
13993 *
13994 * RSASSA-PSS-params  ::=  SEQUENCE  {
13995 *   hashAlgorithm      [0] HashAlgorithm DEFAULT
13996 *                             sha1Identifier,
13997 *   maskGenAlgorithm   [1] MaskGenAlgorithm DEFAULT
13998 *                             mgf1SHA1Identifier,
13999 *   saltLength         [2] INTEGER DEFAULT 20,
14000 *   trailerField       [3] INTEGER DEFAULT 1
14001 * }
14002 *
14003 * HashAlgorithm  ::=  AlgorithmIdentifier
14004 *
14005 * MaskGenAlgorithm  ::=  AlgorithmIdentifier
14006 *
14007 * AlgorithmIdentifer ::= SEQUENCE {
14008 *   algorithm OBJECT IDENTIFIER,
14009 *   parameters ANY DEFINED BY algorithm OPTIONAL
14010 * }
14011 *
14012 * @param oid The OID specifying the signature algorithm
14013 * @param obj The ASN.1 structure holding the parameters
14014 * @param fillDefaults Whether to use return default values where omitted
14015 * @return signature parameter object
14016 */
14017var _readSignatureParameters = function(oid, obj, fillDefaults) {
14018  var params = {};
14019
14020  if(oid !== oids['RSASSA-PSS']) {
14021    return params;
14022  }
14023
14024  if(fillDefaults) {
14025    params = {
14026      hash: {
14027        algorithmOid: oids['sha1']
14028      },
14029      mgf: {
14030        algorithmOid: oids['mgf1'],
14031        hash: {
14032          algorithmOid: oids['sha1']
14033        }
14034      },
14035      saltLength: 20
14036    };
14037  }
14038
14039  var capture = {};
14040  var errors = [];
14041  if(!asn1.validate(obj, rsassaPssParameterValidator, capture, errors)) {
14042    var error = new Error('Cannot read RSASSA-PSS parameter block.');
14043    error.errors = errors;
14044    throw error;
14045  }
14046
14047  if(capture.hashOid !== undefined) {
14048    params.hash = params.hash || {};
14049    params.hash.algorithmOid = asn1.derToOid(capture.hashOid);
14050  }
14051
14052  if(capture.maskGenOid !== undefined) {
14053    params.mgf = params.mgf || {};
14054    params.mgf.algorithmOid = asn1.derToOid(capture.maskGenOid);
14055    params.mgf.hash = params.mgf.hash || {};
14056    params.mgf.hash.algorithmOid = asn1.derToOid(capture.maskGenHashOid);
14057  }
14058
14059  if(capture.saltLength !== undefined) {
14060    params.saltLength = capture.saltLength.charCodeAt(0);
14061  }
14062
14063  return params;
14064};
14065
14066/**
14067 * Converts an X.509 certificate from PEM format.
14068 *
14069 * Note: If the certificate is to be verified then compute hash should
14070 * be set to true. This will scan the TBSCertificate part of the ASN.1
14071 * object while it is converted so it doesn't need to be converted back
14072 * to ASN.1-DER-encoding later.
14073 *
14074 * @param pem the PEM-formatted certificate.
14075 * @param computeHash true to compute the hash for verification.
14076 * @param strict true to be strict when checking ASN.1 value lengths, false to
14077 *          allow truncated values (default: true).
14078 *
14079 * @return the certificate.
14080 */
14081pki.certificateFromPem = function(pem, computeHash, strict) {
14082  var msg = forge.pem.decode(pem)[0];
14083
14084  if(msg.type !== 'CERTIFICATE' &&
14085    msg.type !== 'X509 CERTIFICATE' &&
14086    msg.type !== 'TRUSTED CERTIFICATE') {
14087    var error = new Error('Could not convert certificate from PEM; PEM header type ' +
14088      'is not "CERTIFICATE", "X509 CERTIFICATE", or "TRUSTED CERTIFICATE".');
14089    error.headerType = msg.type;
14090    throw error;
14091  }
14092  if(msg.procType && msg.procType.type === 'ENCRYPTED') {
14093    throw new Error('Could not convert certificate from PEM; PEM is encrypted.');
14094  }
14095
14096  // convert DER to ASN.1 object
14097  var obj = asn1.fromDer(msg.body, strict);
14098
14099  return pki.certificateFromAsn1(obj, computeHash);
14100};
14101
14102/**
14103 * Converts an X.509 certificate to PEM format.
14104 *
14105 * @param cert the certificate.
14106 * @param maxline the maximum characters per line, defaults to 64.
14107 *
14108 * @return the PEM-formatted certificate.
14109 */
14110pki.certificateToPem = function(cert, maxline) {
14111  // convert to ASN.1, then DER, then PEM-encode
14112  var msg = {
14113    type: 'CERTIFICATE',
14114    body: asn1.toDer(pki.certificateToAsn1(cert)).getBytes()
14115  };
14116  return forge.pem.encode(msg, {maxline: maxline});
14117};
14118
14119/**
14120 * Converts an RSA public key from PEM format.
14121 *
14122 * @param pem the PEM-formatted public key.
14123 *
14124 * @return the public key.
14125 */
14126pki.publicKeyFromPem = function(pem) {
14127  var msg = forge.pem.decode(pem)[0];
14128
14129  if(msg.type !== 'PUBLIC KEY' && msg.type !== 'RSA PUBLIC KEY') {
14130    var error = new Error('Could not convert public key from PEM; PEM header ' +
14131      'type is not "PUBLIC KEY" or "RSA PUBLIC KEY".');
14132    error.headerType = msg.type;
14133    throw error;
14134  }
14135  if(msg.procType && msg.procType.type === 'ENCRYPTED') {
14136    throw new Error('Could not convert public key from PEM; PEM is encrypted.');
14137  }
14138
14139  // convert DER to ASN.1 object
14140  var obj = asn1.fromDer(msg.body);
14141
14142  return pki.publicKeyFromAsn1(obj);
14143};
14144
14145/**
14146 * Converts an RSA public key to PEM format (using a SubjectPublicKeyInfo).
14147 *
14148 * @param key the public key.
14149 * @param maxline the maximum characters per line, defaults to 64.
14150 *
14151 * @return the PEM-formatted public key.
14152 */
14153pki.publicKeyToPem = function(key, maxline) {
14154  // convert to ASN.1, then DER, then PEM-encode
14155  var msg = {
14156    type: 'PUBLIC KEY',
14157    body: asn1.toDer(pki.publicKeyToAsn1(key)).getBytes()
14158  };
14159  return forge.pem.encode(msg, {maxline: maxline});
14160};
14161
14162/**
14163 * Converts an RSA public key to PEM format (using an RSAPublicKey).
14164 *
14165 * @param key the public key.
14166 * @param maxline the maximum characters per line, defaults to 64.
14167 *
14168 * @return the PEM-formatted public key.
14169 */
14170pki.publicKeyToRSAPublicKeyPem = function(key, maxline) {
14171  // convert to ASN.1, then DER, then PEM-encode
14172  var msg = {
14173    type: 'RSA PUBLIC KEY',
14174    body: asn1.toDer(pki.publicKeyToRSAPublicKey(key)).getBytes()
14175  };
14176  return forge.pem.encode(msg, {maxline: maxline});
14177};
14178
14179/**
14180 * Gets a fingerprint for the given public key.
14181 *
14182 * @param options the options to use.
14183 *          [md] the message digest object to use (defaults to forge.md.sha1).
14184 *          [type] the type of fingerprint, such as 'RSAPublicKey',
14185 *            'SubjectPublicKeyInfo' (defaults to 'RSAPublicKey').
14186 *          [encoding] an alternative output encoding, such as 'hex'
14187 *            (defaults to none, outputs a byte buffer).
14188 *          [delimiter] the delimiter to use between bytes for 'hex' encoded
14189 *            output, eg: ':' (defaults to none).
14190 *
14191 * @return the fingerprint as a byte buffer or other encoding based on options.
14192 */
14193pki.getPublicKeyFingerprint = function(key, options) {
14194  options = options || {};
14195  var md = options.md || forge.md.sha1.create();
14196  var type = options.type || 'RSAPublicKey';
14197
14198  var bytes;
14199  switch(type) {
14200  case 'RSAPublicKey':
14201    bytes = asn1.toDer(pki.publicKeyToRSAPublicKey(key)).getBytes();
14202    break;
14203  case 'SubjectPublicKeyInfo':
14204    bytes = asn1.toDer(pki.publicKeyToAsn1(key)).getBytes();
14205    break;
14206  default:
14207    throw new Error('Unknown fingerprint type "' + options.type + '".');
14208  }
14209
14210  // hash public key bytes
14211  md.start();
14212  md.update(bytes);
14213  var digest = md.digest();
14214  if(options.encoding === 'hex') {
14215    var hex = digest.toHex();
14216    if(options.delimiter) {
14217      return hex.match(/.{2}/g).join(options.delimiter);
14218    }
14219    return hex;
14220  } else if(options.encoding === 'binary') {
14221    return digest.getBytes();
14222  } else if(options.encoding) {
14223    throw new Error('Unknown encoding "' + options.encoding + '".');
14224  }
14225  return digest;
14226};
14227
14228/**
14229 * Converts a PKCS#10 certification request (CSR) from PEM format.
14230 *
14231 * Note: If the certification request is to be verified then compute hash
14232 * should be set to true. This will scan the CertificationRequestInfo part of
14233 * the ASN.1 object while it is converted so it doesn't need to be converted
14234 * back to ASN.1-DER-encoding later.
14235 *
14236 * @param pem the PEM-formatted certificate.
14237 * @param computeHash true to compute the hash for verification.
14238 * @param strict true to be strict when checking ASN.1 value lengths, false to
14239 *          allow truncated values (default: true).
14240 *
14241 * @return the certification request (CSR).
14242 */
14243pki.certificationRequestFromPem = function(pem, computeHash, strict) {
14244  var msg = forge.pem.decode(pem)[0];
14245
14246  if(msg.type !== 'CERTIFICATE REQUEST') {
14247    var error = new Error('Could not convert certification request from PEM; ' +
14248      'PEM header type is not "CERTIFICATE REQUEST".');
14249    error.headerType = msg.type;
14250    throw error;
14251  }
14252  if(msg.procType && msg.procType.type === 'ENCRYPTED') {
14253    throw new Error('Could not convert certification request from PEM; ' +
14254      'PEM is encrypted.');
14255  }
14256
14257  // convert DER to ASN.1 object
14258  var obj = asn1.fromDer(msg.body, strict);
14259
14260  return pki.certificationRequestFromAsn1(obj, computeHash);
14261};
14262
14263/**
14264 * Converts a PKCS#10 certification request (CSR) to PEM format.
14265 *
14266 * @param csr the certification request.
14267 * @param maxline the maximum characters per line, defaults to 64.
14268 *
14269 * @return the PEM-formatted certification request.
14270 */
14271pki.certificationRequestToPem = function(csr, maxline) {
14272  // convert to ASN.1, then DER, then PEM-encode
14273  var msg = {
14274    type: 'CERTIFICATE REQUEST',
14275    body: asn1.toDer(pki.certificationRequestToAsn1(csr)).getBytes()
14276  };
14277  return forge.pem.encode(msg, {maxline: maxline});
14278};
14279
14280/**
14281 * Creates an empty X.509v3 RSA certificate.
14282 *
14283 * @return the certificate.
14284 */
14285pki.createCertificate = function() {
14286  var cert = {};
14287  cert.version = 0x02;
14288  cert.serialNumber = '00';
14289  cert.signatureOid = null;
14290  cert.signature = null;
14291  cert.siginfo = {};
14292  cert.siginfo.algorithmOid = null;
14293  cert.validity = {};
14294  cert.validity.notBefore = new Date();
14295  cert.validity.notAfter = new Date();
14296
14297  cert.issuer = {};
14298  cert.issuer.getField = function(sn) {
14299    return _getAttribute(cert.issuer, sn);
14300  };
14301  cert.issuer.addField = function(attr) {
14302    _fillMissingFields([attr]);
14303    cert.issuer.attributes.push(attr);
14304  };
14305  cert.issuer.attributes = [];
14306  cert.issuer.hash = null;
14307
14308  cert.subject = {};
14309  cert.subject.getField = function(sn) {
14310    return _getAttribute(cert.subject, sn);
14311  };
14312  cert.subject.addField = function(attr) {
14313    _fillMissingFields([attr]);
14314    cert.subject.attributes.push(attr);
14315  };
14316  cert.subject.attributes = [];
14317  cert.subject.hash = null;
14318
14319  cert.extensions = [];
14320  cert.publicKey = null;
14321  cert.md = null;
14322
14323  /**
14324   * Sets the subject of this certificate.
14325   *
14326   * @param attrs the array of subject attributes to use.
14327   * @param uniqueId an optional a unique ID to use.
14328   */
14329  cert.setSubject = function(attrs, uniqueId) {
14330    // set new attributes, clear hash
14331    _fillMissingFields(attrs);
14332    cert.subject.attributes = attrs;
14333    delete cert.subject.uniqueId;
14334    if(uniqueId) {
14335      cert.subject.uniqueId = uniqueId;
14336    }
14337    cert.subject.hash = null;
14338  };
14339
14340  /**
14341   * Sets the issuer of this certificate.
14342   *
14343   * @param attrs the array of issuer attributes to use.
14344   * @param uniqueId an optional a unique ID to use.
14345   */
14346  cert.setIssuer = function(attrs, uniqueId) {
14347    // set new attributes, clear hash
14348    _fillMissingFields(attrs);
14349    cert.issuer.attributes = attrs;
14350    delete cert.issuer.uniqueId;
14351    if(uniqueId) {
14352      cert.issuer.uniqueId = uniqueId;
14353    }
14354    cert.issuer.hash = null;
14355  };
14356
14357  /**
14358   * Sets the extensions of this certificate.
14359   *
14360   * @param exts the array of extensions to use.
14361   */
14362  cert.setExtensions = function(exts) {
14363    for(var i = 0; i < exts.length; ++i) {
14364      _fillMissingExtensionFields(exts[i], {cert: cert});
14365    }
14366    // set new extensions
14367    cert.extensions = exts;
14368  };
14369
14370  /**
14371   * Gets an extension by its name or id.
14372   *
14373   * @param options the name to use or an object with:
14374   *          name the name to use.
14375   *          id the id to use.
14376   *
14377   * @return the extension or null if not found.
14378   */
14379  cert.getExtension = function(options) {
14380    if(typeof options === 'string') {
14381      options = {name: options};
14382    }
14383
14384    var rval = null;
14385    var ext;
14386    for(var i = 0; rval === null && i < cert.extensions.length; ++i) {
14387      ext = cert.extensions[i];
14388      if(options.id && ext.id === options.id) {
14389        rval = ext;
14390      } else if(options.name && ext.name === options.name) {
14391        rval = ext;
14392      }
14393    }
14394    return rval;
14395  };
14396
14397  /**
14398   * Signs this certificate using the given private key.
14399   *
14400   * @param key the private key to sign with.
14401   * @param md the message digest object to use (defaults to forge.md.sha1).
14402   */
14403  cert.sign = function(key, md) {
14404    // TODO: get signature OID from private key
14405    cert.md = md || forge.md.sha1.create();
14406    var algorithmOid = oids[cert.md.algorithm + 'WithRSAEncryption'];
14407    if(!algorithmOid) {
14408      var error = new Error('Could not compute certificate digest. ' +
14409        'Unknown message digest algorithm OID.');
14410      error.algorithm = cert.md.algorithm;
14411      throw error;
14412    }
14413    cert.signatureOid = cert.siginfo.algorithmOid = algorithmOid;
14414
14415    // get TBSCertificate, convert to DER
14416    cert.tbsCertificate = pki.getTBSCertificate(cert);
14417    var bytes = asn1.toDer(cert.tbsCertificate);
14418
14419    // digest and sign
14420    cert.md.update(bytes.getBytes());
14421    cert.signature = key.sign(cert.md);
14422  };
14423
14424  /**
14425   * Attempts verify the signature on the passed certificate using this
14426   * certificate's public key.
14427   *
14428   * @param child the certificate to verify.
14429   *
14430   * @return true if verified, false if not.
14431   */
14432  cert.verify = function(child) {
14433    var rval = false;
14434
14435    if(!cert.issued(child)) {
14436      var issuer = child.issuer;
14437      var subject = cert.subject;
14438      var error = new Error('The parent certificate did not issue the given child ' +
14439        'certificate; the child certificate\'s issuer does not match the ' +
14440        'parent\'s subject.');
14441      error.expectedIssuer = issuer.attributes;
14442      error.actualIssuer = subject.attributes;
14443      throw error;
14444    }
14445
14446    var md = child.md;
14447    if(md === null) {
14448      // check signature OID for supported signature types
14449      if(child.signatureOid in oids) {
14450        var oid = oids[child.signatureOid];
14451        switch(oid) {
14452        case 'sha1WithRSAEncryption':
14453          md = forge.md.sha1.create();
14454          break;
14455        case 'md5WithRSAEncryption':
14456          md = forge.md.md5.create();
14457          break;
14458        case 'sha256WithRSAEncryption':
14459          md = forge.md.sha256.create();
14460          break;
14461        case 'sha512WithRSAEncryption':
14462          md = forge.md.sha512.create();
14463          break;
14464        case 'RSASSA-PSS':
14465          md = forge.md.sha256.create();
14466          break;
14467        }
14468      }
14469      if(md === null) {
14470        var error = new Error('Could not compute certificate digest. ' +
14471          'Unknown signature OID.');
14472        error.signatureOid = child.signatureOid;
14473        throw error;
14474      }
14475
14476      // produce DER formatted TBSCertificate and digest it
14477      var tbsCertificate = child.tbsCertificate || pki.getTBSCertificate(child);
14478      var bytes = asn1.toDer(tbsCertificate);
14479      md.update(bytes.getBytes());
14480    }
14481
14482    if(md !== null) {
14483      var scheme;
14484
14485      switch(child.signatureOid) {
14486      case oids.sha1WithRSAEncryption:
14487        scheme = undefined;  /* use PKCS#1 v1.5 padding scheme */
14488        break;
14489      case oids['RSASSA-PSS']:
14490        var hash, mgf;
14491
14492        /* initialize mgf */
14493        hash = oids[child.signatureParameters.mgf.hash.algorithmOid];
14494        if(hash === undefined || forge.md[hash] === undefined) {
14495          var error = new Error('Unsupported MGF hash function.');
14496          error.oid = child.signatureParameters.mgf.hash.algorithmOid;
14497          error.name = hash;
14498          throw error;
14499        }
14500
14501        mgf = oids[child.signatureParameters.mgf.algorithmOid];
14502        if(mgf === undefined || forge.mgf[mgf] === undefined) {
14503          var error = new Error('Unsupported MGF function.');
14504          error.oid = child.signatureParameters.mgf.algorithmOid;
14505          error.name = mgf;
14506          throw error;
14507        }
14508
14509        mgf = forge.mgf[mgf].create(forge.md[hash].create());
14510
14511        /* initialize hash function */
14512        hash = oids[child.signatureParameters.hash.algorithmOid];
14513        if(hash === undefined || forge.md[hash] === undefined) {
14514          throw {
14515            message: 'Unsupported RSASSA-PSS hash function.',
14516            oid: child.signatureParameters.hash.algorithmOid,
14517            name: hash
14518          };
14519        }
14520
14521        scheme = forge.pss.create(forge.md[hash].create(), mgf,
14522          child.signatureParameters.saltLength);
14523        break;
14524      }
14525
14526      // verify signature on cert using public key
14527      rval = cert.publicKey.verify(
14528        md.digest().getBytes(), child.signature, scheme);
14529    }
14530
14531    return rval;
14532  };
14533
14534  /**
14535   * Returns true if this certificate's issuer matches the passed
14536   * certificate's subject. Note that no signature check is performed.
14537   *
14538   * @param parent the certificate to check.
14539   *
14540   * @return true if this certificate's issuer matches the passed certificate's
14541   *         subject.
14542   */
14543  cert.isIssuer = function(parent) {
14544    var rval = false;
14545
14546    var i = cert.issuer;
14547    var s = parent.subject;
14548
14549    // compare hashes if present
14550    if(i.hash && s.hash) {
14551      rval = (i.hash === s.hash);
14552    } else if(i.attributes.length === s.attributes.length) {
14553      // all attributes are the same so issuer matches subject
14554      rval = true;
14555      var iattr, sattr;
14556      for(var n = 0; rval && n < i.attributes.length; ++n) {
14557        iattr = i.attributes[n];
14558        sattr = s.attributes[n];
14559        if(iattr.type !== sattr.type || iattr.value !== sattr.value) {
14560          // attribute mismatch
14561          rval = false;
14562        }
14563      }
14564    }
14565
14566    return rval;
14567  };
14568
14569  /**
14570   * Returns true if this certificate's subject matches the issuer of the
14571   * given certificate). Note that not signature check is performed.
14572   *
14573   * @param child the certificate to check.
14574   *
14575   * @return true if this certificate's subject matches the passed
14576   *         certificate's issuer.
14577   */
14578  cert.issued = function(child) {
14579    return child.isIssuer(cert);
14580  };
14581
14582  /**
14583   * Generates the subjectKeyIdentifier for this certificate as byte buffer.
14584   *
14585   * @return the subjectKeyIdentifier for this certificate as byte buffer.
14586   */
14587  cert.generateSubjectKeyIdentifier = function() {
14588    /* See: 4.2.1.2 section of the the RFC3280, keyIdentifier is either:
14589
14590      (1) The keyIdentifier is composed of the 160-bit SHA-1 hash of the
14591        value of the BIT STRING subjectPublicKey (excluding the tag,
14592        length, and number of unused bits).
14593
14594      (2) The keyIdentifier is composed of a four bit type field with
14595        the value 0100 followed by the least significant 60 bits of the
14596        SHA-1 hash of the value of the BIT STRING subjectPublicKey
14597        (excluding the tag, length, and number of unused bit string bits).
14598    */
14599
14600    // skipping the tag, length, and number of unused bits is the same
14601    // as just using the RSAPublicKey (for RSA keys, which are the
14602    // only ones supported)
14603    return pki.getPublicKeyFingerprint(cert.publicKey, {type: 'RSAPublicKey'});
14604  };
14605
14606  /**
14607   * Verifies the subjectKeyIdentifier extension value for this certificate
14608   * against its public key. If no extension is found, false will be
14609   * returned.
14610   *
14611   * @return true if verified, false if not.
14612   */
14613  cert.verifySubjectKeyIdentifier = function() {
14614    var oid = oids['subjectKeyIdentifier'];
14615    for(var i = 0; i < cert.extensions.length; ++i) {
14616      var ext = cert.extensions[i];
14617      if(ext.id === oid) {
14618        var ski = cert.generateSubjectKeyIdentifier().getBytes();
14619        return (forge.util.hexToBytes(ext.subjectKeyIdentifier) === ski);
14620      }
14621    }
14622    return false;
14623  };
14624
14625  return cert;
14626};
14627
14628/**
14629 * Converts an X.509v3 RSA certificate from an ASN.1 object.
14630 *
14631 * Note: If the certificate is to be verified then compute hash should
14632 * be set to true. There is currently no implementation for converting
14633 * a certificate back to ASN.1 so the TBSCertificate part of the ASN.1
14634 * object needs to be scanned before the cert object is created.
14635 *
14636 * @param obj the asn1 representation of an X.509v3 RSA certificate.
14637 * @param computeHash true to compute the hash for verification.
14638 *
14639 * @return the certificate.
14640 */
14641pki.certificateFromAsn1 = function(obj, computeHash) {
14642  // validate certificate and capture data
14643  var capture = {};
14644  var errors = [];
14645  if(!asn1.validate(obj, x509CertificateValidator, capture, errors)) {
14646    var error = new Error('Cannot read X.509 certificate. ' +
14647      'ASN.1 object is not an X509v3 Certificate.');
14648    error.errors = errors;
14649    throw error;
14650  }
14651
14652  // ensure signature is not interpreted as an embedded ASN.1 object
14653  if(typeof capture.certSignature !== 'string') {
14654    var certSignature = '\x00';
14655    for(var i = 0; i < capture.certSignature.length; ++i) {
14656      certSignature += asn1.toDer(capture.certSignature[i]).getBytes();
14657    }
14658    capture.certSignature = certSignature;
14659  }
14660
14661  // get oid
14662  var oid = asn1.derToOid(capture.publicKeyOid);
14663  if(oid !== pki.oids['rsaEncryption']) {
14664    throw new Error('Cannot read public key. OID is not RSA.');
14665  }
14666
14667  // create certificate
14668  var cert = pki.createCertificate();
14669  cert.version = capture.certVersion ?
14670    capture.certVersion.charCodeAt(0) : 0;
14671  var serial = forge.util.createBuffer(capture.certSerialNumber);
14672  cert.serialNumber = serial.toHex();
14673  cert.signatureOid = forge.asn1.derToOid(capture.certSignatureOid);
14674  cert.signatureParameters = _readSignatureParameters(
14675    cert.signatureOid, capture.certSignatureParams, true);
14676  cert.siginfo.algorithmOid = forge.asn1.derToOid(capture.certinfoSignatureOid);
14677  cert.siginfo.parameters = _readSignatureParameters(cert.siginfo.algorithmOid,
14678    capture.certinfoSignatureParams, false);
14679  // skip "unused bits" in signature value BITSTRING
14680  var signature = forge.util.createBuffer(capture.certSignature);
14681  ++signature.read;
14682  cert.signature = signature.getBytes();
14683
14684  var validity = [];
14685  if(capture.certValidity1UTCTime !== undefined) {
14686    validity.push(asn1.utcTimeToDate(capture.certValidity1UTCTime));
14687  }
14688  if(capture.certValidity2GeneralizedTime !== undefined) {
14689    validity.push(asn1.generalizedTimeToDate(
14690      capture.certValidity2GeneralizedTime));
14691  }
14692  if(capture.certValidity3UTCTime !== undefined) {
14693    validity.push(asn1.utcTimeToDate(capture.certValidity3UTCTime));
14694  }
14695  if(capture.certValidity4GeneralizedTime !== undefined) {
14696    validity.push(asn1.generalizedTimeToDate(
14697      capture.certValidity4GeneralizedTime));
14698  }
14699  if(validity.length > 2) {
14700    throw new Error('Cannot read notBefore/notAfter validity times; more ' +
14701      'than two times were provided in the certificate.');
14702  }
14703  if(validity.length < 2) {
14704    throw new Error('Cannot read notBefore/notAfter validity times; they ' +
14705      'were not provided as either UTCTime or GeneralizedTime.');
14706  }
14707  cert.validity.notBefore = validity[0];
14708  cert.validity.notAfter = validity[1];
14709
14710  // keep TBSCertificate to preserve signature when exporting
14711  cert.tbsCertificate = capture.tbsCertificate;
14712
14713  if(computeHash) {
14714    // check signature OID for supported signature types
14715    cert.md = null;
14716    if(cert.signatureOid in oids) {
14717      var oid = oids[cert.signatureOid];
14718      switch(oid) {
14719      case 'sha1WithRSAEncryption':
14720        cert.md = forge.md.sha1.create();
14721        break;
14722      case 'md5WithRSAEncryption':
14723        cert.md = forge.md.md5.create();
14724        break;
14725      case 'sha256WithRSAEncryption':
14726        cert.md = forge.md.sha256.create();
14727        break;
14728      case 'sha512WithRSAEncryption':
14729        cert.md = forge.md.sha512.create();
14730        break;
14731      case 'RSASSA-PSS':
14732        cert.md = forge.md.sha256.create();
14733        break;
14734      }
14735    }
14736    if(cert.md === null) {
14737      var error = new Error('Could not compute certificate digest. ' +
14738        'Unknown signature OID.');
14739      error.signatureOid = cert.signatureOid;
14740      throw error;
14741    }
14742
14743    // produce DER formatted TBSCertificate and digest it
14744    var bytes = asn1.toDer(cert.tbsCertificate);
14745    cert.md.update(bytes.getBytes());
14746  }
14747
14748  // handle issuer, build issuer message digest
14749  var imd = forge.md.sha1.create();
14750  cert.issuer.getField = function(sn) {
14751    return _getAttribute(cert.issuer, sn);
14752  };
14753  cert.issuer.addField = function(attr) {
14754    _fillMissingFields([attr]);
14755    cert.issuer.attributes.push(attr);
14756  };
14757  cert.issuer.attributes = pki.RDNAttributesAsArray(capture.certIssuer, imd);
14758  if(capture.certIssuerUniqueId) {
14759    cert.issuer.uniqueId = capture.certIssuerUniqueId;
14760  }
14761  cert.issuer.hash = imd.digest().toHex();
14762
14763  // handle subject, build subject message digest
14764  var smd = forge.md.sha1.create();
14765  cert.subject.getField = function(sn) {
14766    return _getAttribute(cert.subject, sn);
14767  };
14768  cert.subject.addField = function(attr) {
14769    _fillMissingFields([attr]);
14770    cert.subject.attributes.push(attr);
14771  };
14772  cert.subject.attributes = pki.RDNAttributesAsArray(capture.certSubject, smd);
14773  if(capture.certSubjectUniqueId) {
14774    cert.subject.uniqueId = capture.certSubjectUniqueId;
14775  }
14776  cert.subject.hash = smd.digest().toHex();
14777
14778  // handle extensions
14779  if(capture.certExtensions) {
14780    cert.extensions = pki.certificateExtensionsFromAsn1(capture.certExtensions);
14781  } else {
14782    cert.extensions = [];
14783  }
14784
14785  // convert RSA public key from ASN.1
14786  cert.publicKey = pki.publicKeyFromAsn1(capture.subjectPublicKeyInfo);
14787
14788  return cert;
14789};
14790
14791/**
14792 * Converts an ASN.1 extensions object (with extension sequences as its
14793 * values) into an array of extension objects with types and values.
14794 *
14795 * Supported extensions:
14796 *
14797 * id-ce-keyUsage OBJECT IDENTIFIER ::=  { id-ce 15 }
14798 * KeyUsage ::= BIT STRING {
14799 *   digitalSignature        (0),
14800 *   nonRepudiation          (1),
14801 *   keyEncipherment         (2),
14802 *   dataEncipherment        (3),
14803 *   keyAgreement            (4),
14804 *   keyCertSign             (5),
14805 *   cRLSign                 (6),
14806 *   encipherOnly            (7),
14807 *   decipherOnly            (8)
14808 * }
14809 *
14810 * id-ce-basicConstraints OBJECT IDENTIFIER ::=  { id-ce 19 }
14811 * BasicConstraints ::= SEQUENCE {
14812 *   cA                      BOOLEAN DEFAULT FALSE,
14813 *   pathLenConstraint       INTEGER (0..MAX) OPTIONAL
14814 * }
14815 *
14816 * subjectAltName EXTENSION ::= {
14817 *   SYNTAX GeneralNames
14818 *   IDENTIFIED BY id-ce-subjectAltName
14819 * }
14820 *
14821 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
14822 *
14823 * GeneralName ::= CHOICE {
14824 *   otherName      [0] INSTANCE OF OTHER-NAME,
14825 *   rfc822Name     [1] IA5String,
14826 *   dNSName        [2] IA5String,
14827 *   x400Address    [3] ORAddress,
14828 *   directoryName  [4] Name,
14829 *   ediPartyName   [5] EDIPartyName,
14830 *   uniformResourceIdentifier [6] IA5String,
14831 *   IPAddress      [7] OCTET STRING,
14832 *   registeredID   [8] OBJECT IDENTIFIER
14833 * }
14834 *
14835 * OTHER-NAME ::= TYPE-IDENTIFIER
14836 *
14837 * EDIPartyName ::= SEQUENCE {
14838 *   nameAssigner [0] DirectoryString {ub-name} OPTIONAL,
14839 *   partyName    [1] DirectoryString {ub-name}
14840 * }
14841 *
14842 * @param exts the extensions ASN.1 with extension sequences to parse.
14843 *
14844 * @return the array.
14845 */
14846pki.certificateExtensionsFromAsn1 = function(exts) {
14847  var rval = [];
14848  for(var i = 0; i < exts.value.length; ++i) {
14849    // get extension sequence
14850    var extseq = exts.value[i];
14851    for(var ei = 0; ei < extseq.value.length; ++ei) {
14852      rval.push(pki.certificateExtensionFromAsn1(extseq.value[ei])
14852);
14853    }
14854  }
14855
14856  return rval;
14857};
14858
14859/**
14860 * Parses a single certificate extension from ASN.1.
14861 *
14862 * @param ext the extension in ASN.1 format.
14863 *
14864 * @return the parsed extension as an object.
14865 */
14866pki.certificateExtensionFromAsn1 = function(ext) {
14867  // an extension has:
14868  // [0] extnID      OBJECT IDENTIFIER
14869  // [1] critical    BOOLEAN DEFAULT FALSE
14870  // [2] extnValue   OCTET STRING
14871  var e = {};
14872  e.id = asn1.derToOid(ext.value[0].value);
14873  e.critical = false;
14874  if(ext.value[1].type === asn1.Type.BOOLEAN) {
14875    e.critical = (ext.value[1].value.charCodeAt(0) !== 0x00);
14876    e.value = ext.value[2].value;
14877  } else {
14878    e.value = ext.value[1].value;
14879  }
14880  // if the oid is known, get its name
14881  if(e.id in oids) {
14882    e.name = oids[e.id];
14883
14884    // handle key usage
14885    if(e.name === 'keyUsage') {
14886      // get value as BIT STRING
14887      var ev = asn1.fromDer(e.value);
14888      var b2 = 0x00;
14889      var b3 = 0x00;
14890      if(ev.value.length > 1) {
14891        // skip first byte, just indicates unused bits which
14892        // will be padded with 0s anyway
14893        // get bytes with flag bits
14894        b2 = ev.value.charCodeAt(1);
14895        b3 = ev.value.length > 2 ? ev.value.charCodeAt(2) : 0;
14896      }
14897      // set flags
14898      e.digitalSignature = (b2 & 0x80) === 0x80;
14899      e.nonRepudiation = (b2 & 0x40) === 0x40;
14900      e.keyEncipherment = (b2 & 0x20) === 0x20;
14901      e.dataEncipherment = (b2 & 0x10) === 0x10;
14902      e.keyAgreement = (b2 & 0x08) === 0x08;
14903      e.keyCertSign = (b2 & 0x04) === 0x04;
14904      e.cRLSign = (b2 & 0x02) === 0x02;
14905      e.encipherOnly = (b2 & 0x01) === 0x01;
14906      e.decipherOnly = (b3 & 0x80) === 0x80;
14907    } else if(e.name === 'basicConstraints') {
14908      // handle basic constraints
14909      // get value as SEQUENCE
14910      var ev = asn1.fromDer(e.value);
14911      // get cA BOOLEAN flag (defaults to false)
14912      if(ev.value.length > 0 && ev.value[0].type === asn1.Type.BOOLEAN) {
14913        e.cA = (ev.value[0].value.charCodeAt(0) !== 0x00);
14914      } else {
14915        e.cA = false;
14916      }
14917      // get path length constraint
14918      var value = null;
14919      if(ev.value.length > 0 && ev.value[0].type === asn1.Type.INTEGER) {
14920        value = ev.value[0].value;
14921      } else if(ev.value.length > 1) {
14922        value = ev.value[1].value;
14923      }
14924      if(value !== null) {
14925        e.pathLenConstraint = asn1.derToInteger(value);
14926      }
14927    } else if(e.name === 'extKeyUsage') {
14928      // handle extKeyUsage
14929      // value is a SEQUENCE of OIDs
14930      var ev = asn1.fromDer(e.value);
14931      for(var vi = 0; vi < ev.value.length; ++vi) {
14932        var oid = asn1.derToOid(ev.value[vi].value);
14933        if(oid in oids) {
14934          e[oids[oid]] = true;
14935        } else {
14936          e[oid] = true;
14937        }
14938      }
14939    } else if(e.name === 'nsCertType') {
14940      // handle nsCertType
14941      // get value as BIT STRING
14942      var ev = asn1.fromDer(e.value);
14943      var b2 = 0x00;
14944      if(ev.value.length > 1) {
14945        // skip first byte, just indicates unused bits which
14946        // will be padded with 0s anyway
14947        // get bytes with flag bits
14948        b2 = ev.value.charCodeAt(1);
14949      }
14950      // set flags
14951      e.client = (b2 & 0x80) === 0x80;
14952      e.server = (b2 & 0x40) === 0x40;
14953      e.email = (b2 & 0x20) === 0x20;
14954      e.objsign = (b2 & 0x10) === 0x10;
14955      e.reserved = (b2 & 0x08) === 0x08;
14956      e.sslCA = (b2 & 0x04) === 0x04;
14957      e.emailCA = (b2 & 0x02) === 0x02;
14958      e.objCA = (b2 & 0x01) === 0x01;
14959    } else if(
14960      e.name === 'subjectAltName' ||
14961      e.name === 'issuerAltName') {
14962      // handle subjectAltName/issuerAltName
14963      e.altNames = [];
14964
14965      // ev is a SYNTAX SEQUENCE
14966      var gn;
14967      var ev = asn1.fromDer(e.value);
14968      for(var n = 0; n < ev.value.length; ++n) {
14969        // get GeneralName
14970        gn = ev.value[n];
14971
14972        var altName = {
14973          type: gn.type,
14974          value: gn.value
14975        };
14976        e.altNames.push(altName);
14977
14978        // Note: Support for types 1,2,6,7,8
14979        switch(gn.type) {
14980        // rfc822Name
14981        case 1:
14982        // dNSName
14983        case 2:
14984        // uniformResourceIdentifier (URI)
14985        case 6:
14986          break;
14987        // IPAddress
14988        case 7:
14989          // convert to IPv4/IPv6 string representation
14990          altName.ip = forge.util.bytesToIP(gn.value);
14991          break;
14992        // registeredID
14993        case 8:
14994          altName.oid = asn1.derToOid(gn.value);
14995          break;
14996        default:
14997          // unsupported
14998        }
14999      }
15000    } else if(e.name === 'subjectKeyIdentifier') {
15001      // value is an OCTETSTRING w/the hash of the key-type specific
15002      // public key structure (eg: RSAPublicKey)
15003      var ev = asn1.fromDer(e.value);
15004      e.subjectKeyIdentifier = forge.util.bytesToHex(ev.value);
15005    }
15006  }
15007  return e;
15008};
15009
15010/**
15011 * Converts a PKCS#10 certification request (CSR) from an ASN.1 object.
15012 *
15013 * Note: If the certification request is to be verified then compute hash
15014 * should be set to true. There is currently no implementation for converting
15015 * a certificate back to ASN.1 so the CertificationRequestInfo part of the
15016 * ASN.1 object needs to be scanned before the csr object is created.
15017 *
15018 * @param obj the asn1 representation of a PKCS#10 certification request (CSR).
15019 * @param computeHash true to compute the hash for verification.
15020 *
15021 * @return the certification request (CSR).
15022 */
15023pki.certificationRequestFromAsn1 = function(obj, computeHash) {
15024  // validate certification request and capture data
15025  var capture = {};
15026  var errors = [];
15027  if(!asn1.validate(obj, certificationRequestValidator, capture, errors)) {
15028    var error = new Error('Cannot read PKCS#10 certificate request. ' +
15029      'ASN.1 object is not a PKCS#10 CertificationRequest.');
15030    error.errors = errors;
15031    throw error;
15032  }
15033
15034  // ensure signature is not interpreted as an embedded ASN.1 object
15035  if(typeof capture.csrSignature !== 'string') {
15036    var csrSignature = '\x00';
15037    for(var i = 0; i < capture.csrSignature.length; ++i) {
15038      csrSignature += asn1.toDer(capture.csrSignature[i]).getBytes();
15039    }
15040    capture.csrSignature = csrSignature;
15041  }
15042
15043  // get oid
15044  var oid = asn1.derToOid(capture.publicKeyOid);
15045  if(oid !== pki.oids.rsaEncryption) {
15046    throw new Error('Cannot read public key. OID is not RSA.');
15047  }
15048
15049  // create certification request
15050  var csr = pki.createCertificationRequest();
15051  csr.version = capture.csrVersion ? capture.csrVersion.charCodeAt(0) : 0;
15052  csr.signatureOid = forge.asn1.derToOid(capture.csrSignatureOid);
15053  csr.signatureParameters = _readSignatureParameters(
15054    csr.signatureOid, capture.csrSignatureParams, true);
15055  csr.siginfo.algorithmOid = forge.asn1.derToOid(capture.csrSignatureOid);
15056  csr.siginfo.parameters = _readSignatureParameters(
15057    csr.siginfo.algorithmOid, capture.csrSignatureParams, false);
15058  // skip "unused bits" in signature value BITSTRING
15059  var signature = forge.util.createBuffer(capture.csrSignature);
15060  ++signature.read;
15061  csr.signature = signature.getBytes();
15062
15063  // keep CertificationRequestInfo to preserve signature when exp
15063orting
15064  csr.certificationRequestInfo = capture.certificationRequestInfo;
15065
15066  if(computeHash) {
15067    // check signature OID for supported signature types
15068    csr.md = null;
15069    if(csr.signatureOid in oids) {
15070      var oid = oids[csr.signatureOid];
15071      switch(oid) {
15072      case 'sha1WithRSAEncryption':
15073        csr.md = forge.md.sha1.create();
15074        break;
15075      case 'md5WithRSAEncryption':
15076        csr.md = forge.md.md5.create();
15077        break;
15078      case 'sha256WithRSAEncryption':
15079        csr.md = forge.md.sha256.create();
15080        break;
15081      case 'sha512WithRSAEncryption':
15082        csr.md = forge.md.sha512.create();
15083        break;
15084      case 'RSASSA-PSS':
15085        csr.md = forge.md.sha256.create();
15086        break;
15087      }
15088    }
15089    if(csr.md === null) {
15090      var error = new Error('Could not compute certification request digest. ' +
15091        'Unknown signature OID.');
15092      error.signatureOid = csr.signatureOid;
15093      throw error;
15094    }
15095
15096    // produce DER formatted CertificationRequestInfo and digest it
15097    var bytes = asn1.toDer(csr.certificationRequestInfo);
15098    csr.md.update(bytes.getBytes());
15099  }
15100
15101  // handle subject, build subject message digest
15102  var smd = forge.md.sha1.create();
15103  csr.subject.getField = function(sn) {
15104    return _getAttribute(csr.subject, sn);
15105  };
15106  csr.subject.addField = function(attr) {
15107    _fillMissingFields([attr]);
15108    csr.subject.attributes.push(attr);
15109  };
15110  csr.subject.attributes = pki.RDNAttributesAsArray(
15111    capture.certificationRequestInfoSubject, smd);
15112  csr.subject.hash = smd.digest().toHex();
15113
15114  // convert RSA public key from ASN.1
15115  csr.publicKey = pki.publicKeyFromAsn1(capture.subjectPublicKeyInfo);
15116
15117  // convert attributes from ASN.1
15118  csr.getAttribute = function(sn) {
15119    return _getAttribute(csr, sn);
15120  };
15121  csr.addAttribute = function(attr) {
15122    _fillMissingFields([attr]);
15123    csr.attributes.push(attr);
15124  };
15125  csr.attributes = pki.CRIAttributesAsArray(
15126    capture.certificationRequestInfoAttributes || []);
15127
15128  return csr;
15129};
15130
15131/**
15132 * Creates an empty certification request (a CSR or certificate signing
15133 * request). Once created, its public key and attributes can be set and then
15134 * it can be signed.
15135 *
15136 * @return the empty certification request.
15137 */
15138pki.createCertificationRequest = function() {
15139  var csr = {};
15140  csr.version = 0x00;
15141  csr.signatureOid = null;
15142  csr.signature = null;
15143  csr.siginfo = {};
15144  csr.siginfo.algorithmOid = null;
15145
15146  csr.subject = {};
15147  csr.subject.getField = function(sn) {
15148    return _getAttribute(csr.subject, sn);
15149  };
15150  csr.subject.addField = function(attr) {
15151    _fillMissingFields([attr]);
15152    csr.subject.attributes.push(attr);
15153  };
15154  csr.subject.attributes = [];
15155  csr.subject.hash = null;
15156
15157  csr.publicKey = null;
15158  csr.attributes = [];
15159  csr.getAttribute = function(sn) {
15160    return _getAttribute(csr, sn);
15161  };
15162  csr.addAttribute = function(attr) {
15163    _fillMissingFields([attr]);
15164    csr.attributes.push(attr);
15165  };
15166  csr.md = null;
15167
15168  /**
15169   * Sets the subject of this certification request.
15170   *
15171   * @param attrs the array of subject attributes to use.
15172   */
15173  csr.setSubject = function(attrs) {
15174    // set new attributes
15175    _fillMissingFields(attrs);
15176    csr.subject.attributes = attrs;
15177    csr.subject.hash = null;
15178  };
15179
15180  /**
15181   * Sets the attributes of this certification request.
15182   *
15183   * @param attrs the array of attributes to use.
15184   */
15185  csr.setAttributes = function(attrs) {
15186    // set new attributes
15187    _fillMissingFields(attrs);
15188    csr.attributes = attrs;
15189  };
15190
15191  /**
15192   * Signs this certification request using the given private key.
15193   *
15194   * @param key the private key to sign with.
15195   * @param md the message digest object to use (defaults to forge.md.sha1).
15196   */
15197  csr.sign = function(key, md) {
15198    // TODO: get signature OID from private key
15199    csr.md = md || forge.md.sha1.create();
15200    var algorithmOid = oids[csr.md.algorithm + 'WithRSAEncryption'];
15201    if(!algorithmOid) {
15202      var error = new Error('Could not compute certification request digest. ' +
15203        'Unknown message digest algorithm OID.');
15204      error.algorithm = csr.md.algorithm;
15205      throw error;
15206    }
15207    csr.signatureOid = csr.siginfo.algorithmOid = algorithmOid;
15208
15209    // get CertificationRequestInfo, convert to DER
15210    csr.certificationRequestInfo = pki.getCertificationRequestInfo(csr);
15211    var bytes = asn1.toDer(csr.certificationRequestInfo);
15212
15213    // digest and sign
15214    csr.md.update(bytes.getBytes());
15215    csr.signature = key.sign(csr.md);
15216  };
15217
15218  /**
15219   * Attempts verify the signature on the passed certification request using
15220   * its public key.
15221   *
15222   * A CSR that has been exported to a file in PEM format can be verified using
15223   * OpenSSL using this command:
15224   *
15225   * openssl req -in <the-csr-pem-file> -verify -noout -text
15226   *
15227   * @return true if verified, false if not.
15228   */
15229  csr.verify = function() {
15230    var rval = false;
15231
15232    var md = csr.md;
15233    if(md === null) {
15234      // check signature OID for supported signature types
15235      if(csr.signatureOid in oids) {
15236        // TODO: create DRY `OID to md` function
15237        var oid = oids[csr.signatureOid];
15238        switch(oid) {
15239        case 'sha1WithRSAEncryption':
15240          md = forge.md.sha1.create();
15241          break;
15242        case 'md5WithRSAEncryption':
15243          md = forge.md.md5.create();
15244          break;
15245        case 'sha256WithRSAEncryption':
15246          md = forge.md.sha256.create();
15247          break;
15248        case 'sha512WithRSAEncryption':
15249          md = forge.md.sha512.create();
15250          break;
15251        case 'RSASSA-PSS':
15252          md = forge.md.sha256.create();
15253          break;
15254        }
15255      }
15256      if(md === null) {
15257        var error = new Error('Could not compute certification request digest. ' +
15258          'Unknown signature OID.');
15259        error.signatureOid = csr.signatureOid;
15260        throw error;
15261      }
15262
15263      // produce DER formatted CertificationRequestInfo and digest it
15264      var cri = csr.certificationRequestInfo ||
15265        pki.getCertificationRequestInfo(csr);
15266      var bytes = asn1.toDer(cri);
15267      md.update(bytes.getBytes());
15268    }
15269
15270    if(md !== null) {
15271      var scheme;
15272
15273      switch(csr.signatureOid) {
15274      case oids.sha1WithRSAEncryption:
15275        /* use PKCS#1 v1.5 padding scheme */
15276        break;
15277      case oids['RSASSA-PSS']:
15278        var hash, mgf;
15279
15280        /* initialize mgf */
15281        hash = oids[csr.signatureParameters.mgf.hash.algorithmOid];
15282        if(hash === undefined || forge.md[hash] === undefined) {
15283          var error = new Error('Unsupported MGF hash function.');
15284          error.oid = csr.signatureParameters.mgf.hash.algorithmOid;
15285          error.name = hash;
15286          throw error;
15287        }
15288
15289        mgf = oids[csr.signatureParameters.mgf.algorithmOid];
15290        if(mgf === undefined || forge.mgf[mgf] === undefined) {
15291          var error = new Error('Unsupported MGF function.');
15292          error.oid = csr.signatureParameters.mgf.algorithmOid;
15293          error.name = mgf;
15294          throw error;
15295        }
15296
15297        mgf = forge.mgf[mgf].create(forge.md[hash].create());
15298
15299        /* initialize hash function */
15300        hash = oids[csr.signatureParameters.hash.algorithmOid];
15301        if(hash === undefined || forge.md[hash] === undefined) {
15302          var error = new Error('Unsupported RSASSA-PSS hash function.');
15303          error.oid = csr.signatureParameters.hash.algorithmOid;
15304          error.name = hash;
15305          throw error;
15306        }
15307
15308        scheme = forge.pss.create(forge.md[hash].create(), mgf,
15309          csr.signatureParameters.saltLength);
15310        break;
15311      }
15312
15313      // verify signature on csr using its public key
15314      rval = csr.publicKey.verify(
15315        md.digest().getBytes(), csr.signature, scheme);
15316    }
15317
15318    return rval;
15319  };
15320
15321  return csr;
15322};
15323
15324/**
15325 * Converts an X.509 subject or issuer to an ASN.1 RDNSequence.
15326 *
15327 * @param obj the subject or issuer (distinguished name).
15328 *
15329 * @return the ASN.1 RDNSequence.
15330 */
15331function _dnToAsn1(obj) {
15332  // create an empty RDNSequence
15333  var rval = asn1.create(
15334    asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, []);
15335
15336  // iterate over attributes
15337  var attr, set;
15338  var attrs = obj.attributes;
15339  for(var i = 0; i < attrs.length; ++i) {
15340    attr = attrs[i];
15341    var value = attr.value;
15342
15343    // reuse tag class for attribute value if available
15344    var valueTagClass = asn1.Type.PRINTABLESTRING;
15345    if('valueTagClass' in attr) {
15346      valueTagClass = attr.valueTagClass;
15347
15348      if(valueTagClass === asn1.Type.UTF8) {
15349        value = forge.util.encodeUtf8(value);
15350      }
15351      // FIXME: handle more encodings
15352    }
15353
15354    // create a RelativeDistinguishedName set
15355    // each value in the set is an AttributeTypeAndValue first
15356    // containing the type (an OID) and second the value
15357    set = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SET, true, [
15358      asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
15359        // AttributeType
15360        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
15361          asn1.oidToDer(attr.type).getBytes()),
15362        // AttributeValue
15363        asn1.create(asn1.Class.UNIVERSAL, valueTagClass, false, value)
15364      ])
15365    ]);
15366    rval.value.push(set);
15367  }
15368
15369  return rval;
15370}
15371
15372/**
15373 * Gets all printable attributes (typically of an issuer or subject) in a
15374 * simplified JSON format for display.
15375 *
15376 * @param attrs the attributes.
15377 *
15378 * @return the JSON for display.
15379 */
15380function _getAttributesAsJson(attrs) {
15381  var rval = {};
15382  for(var i = 0; i < attrs.length; ++i) {
15383    var attr = attrs[i];
15384    if(attr.shortName && (
15385      attr.valueTagClass === asn1.Type.UTF8 ||
15386      attr.valueTagClass === asn1.Type.PRINTABLESTRING ||
15387      attr.valueTagClass === asn1.Type.IA5STRING)) {
15388      var value = attr.value;
15389      if(attr.valueTagClass === asn1.Type.UTF8) {
15390        value = forge.util.encodeUtf8(attr.value);
15391      }
15392      if(!(attr.shortName in rval)) {
15393        rval[attr.shortName] = value;
15394      } else if(forge.util.isArray(rval[attr.shortName])) {
15395        rval[attr.shortName].push(value);
15396      } else {
15397        rval[attr.shortName] = [rval[attr.shortName], value];
15398      }
15399    }
15400  }
15401  return rval;
15402}
15403
15404/**
15405 * Fills in missing fields in attributes.
15406 *
15407 * @param attrs the attributes to fill missing fields in.
15408 */
15409function _fillMissingFields(attrs) {
15410  var attr;
15411  for(var i = 0; i < attrs.length; ++i) {
15412    attr = attrs[i];
15413
15414    // populate missing name
15415    if(typeof attr.name === 'undefined') {
15416      if(attr.type && attr.type in pki.oids) {
15417        attr.name = pki.oids[attr.type];
15418      }
15418 else if(attr.shortName && attr.shortName in _shortNames) {
15419        attr.name = pki.oids[_shortNames[attr.shortName]];
15420      }
15421    }
15422
15423    // populate missing type (OID)
15424    if(typeof attr.type === 'undefined') {
15425      if(attr.name && attr.name in pki.oids) {
15426        attr.type = pki.oids[attr.name];
15427      } else {
15428        var error = new Error('Attribute type not specified.');
15429        error.attribute = attr;
15430        throw error;
15431      }
15432    }
15433
15434    // populate missing shortname
15435    if(typeof attr.shortName === 'undefined') {
15436      if(attr.name && attr.name in _shortNames) {
15437        attr.shortName = _shortNames[attr.name];
15438      }
15439    }
15440
15441    // convert extensions to value
15442    if(attr.type === oids.extensionRequest) {
15443      attr.valueConstructed = true;
15444      attr.valueTagClass = asn1.Type.SEQUENCE;
15445      if(!attr.value && attr.extensions) {
15446        attr.value = [];
15447        for(var ei = 0; ei < attr.extensions.length; ++ei) {
15448          attr.value.push(pki.certificateExtensionToAsn1(
15449            _fillMissingExtensionFields(attr.extensions[ei])));
15450        }
15451      }
15452    }
15453
15454    if(typeof attr.value === 'undefined') {
15455      var error = new Error('Attribute value not specified.');
15456      error.attribute = attr;
15457      throw error;
15458    }
15459  }
15460}
15461
15462/**
15463 * Fills in missing fields in certificate extensions.
15464 *
15465 * @param e the extension.
15466 * @param [options] the options to use.
15467 *          [cert] the certificate the extensions are for.
15468 *
15469 * @return the extension.
15470 */
15471function _fillMissingExtensionFields(e, options) {
15472  options = options || {};
15473
15474  // populate missing name
15475  if(typeof e.name === 'undefined') {
15476    if(e.id && e.id in pki.oids) {
15477      e.name = pki.oids[e.id];
15478    }
15479  }
15480
15481  // populate missing id
15482  if(typeof e.id === 'undefined') {
15483    if(e.name && e.name in pki.oids) {
15484      e.id = pki.oids[e.name];
15485    } else {
15486      var error = new Error('Extension ID not specified.');
15487      error.extension = e;
15488      throw error;
15489    }
15490  }
15491
15492  if(typeof e.value !== 'undefined') {
15493    return e;
15494  }
15495
15496  // handle missing value:
15497
15498  // value is a BIT STRING
15499  if(e.name === 'keyUsage') {
15500    // build flags
15501    var unused = 0;
15502    var b2 = 0x00;
15503    var b3 = 0x00;
15504    if(e.digitalSignature) {
15505      b2 |= 0x80;
15506      unused = 7;
15507    }
15508    if(e.nonRepudiation) {
15509      b2 |= 0x40;
15510      unused = 6;
15511    }
15512    if(e.keyEncipherment) {
15513      b2 |= 0x20;
15514      unused = 5;
15515    }
15516    if(e.dataEncipherment) {
15517      b2 |= 0x10;
15518      unused = 4;
15519    }
15520    if(e.keyAgreement) {
15521      b2 |= 0x08;
15522      unused = 3;
15523    }
15524    if(e.keyCertSign) {
15525      b2 |= 0x04;
15526      unused = 2;
15527    }
15528    if(e.cRLSign) {
15529      b2 |= 0x02;
15530      unused = 1;
15531    }
15532    if(e.encipherOnly) {
15533      b2 |= 0x01;
15534      unused = 0;
15535    }
15536    if(e.decipherOnly) {
15537      b3 |= 0x80;
15538      unused = 7;
15539    }
15540
15541    // create bit string
15542    var value = String.fromCharCode(unused);
15543    if(b3 !== 0) {
15544      value += String.fromCharCode(b2) + String.fromCharCode(b3);
15545    } else if(b2 !== 0) {
15546      value += String.fromCharCode(b2);
15547    }
15548    e.value = asn1.create(
15549      asn1.Class.UNIVERSAL, asn1.Type.BITSTRING, false, value);
15550  } else if(e.name === 'basicConstraints') {
15551    // basicConstraints is a SEQUENCE
15552    e.value = asn1.create(
15553      asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, []);
15554    // cA BOOLEAN flag defaults to false
15555    if(e.cA) {
15556      e.value.value.push(asn1.create(
15557        asn1.Class.UNIVERSAL, asn1.Type.BOOLEAN, false,
15558        String.fromCharCode(0xFF)));
15559    }
15560    if('pathLenConstraint' in e) {
15561      e.value.value.push(asn1.create(
15562        asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false,
15563        asn1.integerToDer(e.pathLenConstraint).getBytes()));
15564    }
15565  } else if(e.name === 'extKeyUsage') {
15566    // extKeyUsage is a SEQUENCE of OIDs
15567    e.value = asn1.create(
15568      asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, []);
15569    var seq = e.value.value;
15570    for(var key in e) {
15571      if(e[key] !== true) {
15572        continue;
15573      }
15574      // key is name in OID map
15575      if(key in oids) {
15576        seq.push(asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID,
15577          false, asn1.oidToDer(oids[key]).getBytes()));
15578      } else if(key.indexOf('.') !== -1) {
15579        // assume key is an OID
15580        seq.push(asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID,
15581          false, asn1.oidToDer(key).getBytes()));
15582      }
15583    }
15584  } else if(e.name === 'nsCertType') {
15585    // nsCertType is a BIT STRING
15586    // build flags
15587    var unused = 0;
15588    var b2 = 0x00;
15589
15590    if(e.client) {
15591      b2 |= 0x80;
15592      unused = 7;
15593    }
15594    if(e.server) {
15595      b2 |= 0x40;
15596      unused = 6;
15597    }
15598    if(e.email) {
15599      b2 |= 0x20;
15600      unused = 5;
15601    }
15602    if(e.objsign) {
15603      b2 |= 0x10;
15604      unused = 4;
15605    }
15606    if(e.reserved) {
15607      b2 |= 0x08;
15608      unused = 3;
15609    }
15610    if(e.sslCA) {
15611      b2 |= 0x04;
15612      unused = 2;
15613    }
15614    if(e.emailCA) {
15615      b2 |= 0x02;
15616      unused = 1;
15617    }
15618    if(e.objCA) {
15619      b2 |= 0x01;
15620      unused = 0;
15621    }
15622
15623    // create bit string
15624    var value = String.fromCharCode(unused);
15625    if(b2 !== 0) {
15626      value += String.fromCharCode(b2);
15627    }
15628    e.value = asn1.create(
15629      asn1.Class.UNIVERSAL, asn1.Type.BITSTRING, false, value);
15630  } else if(e.name === 'subjectAltName' || e.name === 'issuerAltName') {
15631    // SYNTAX SEQUENCE
15632    e.value = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, []);
15633
15634    var altName;
15635    for(var n = 0; n < e.altNames.length; ++n) {
15636      altName = e.altNames[n];
15637      var value = altName.value;
15638      // handle IP
15639      if(altName.type === 7 && altName.ip) {
15640        value = forge.util.bytesFromIP(altName.ip);
15641        if(value === null) {
15642          var error = new Error(
15643            'Extension "ip" value is not a valid IPv4 or IPv6 address.');
15644          error.extension = e;
15645          throw error;
15646        }
15647      } else if(altName.type === 8) {
15648        // handle OID
15649        if(altName.oid) {
15650          value = asn1.oidToDer(asn1.oidToDer(altName.oid));
15651        } else {
15652          // deprecated ... convert value to OID
15653          value = asn1.oidToDer(value);
15654        }
15655      }
15656      e.value.value.push(asn1.create(
15657        asn1.Class.CONTEXT_SPECIFIC, altName.type, false,
15658        value));
15659    }
15660  } else if(e.name === 'subjectKeyIdentifier' && options.cert) {
15661    var ski = options.cert.generateSubjectKeyIdentifier();
15662    e.subjectKeyIdentifier = ski.toHex();
15663    // OCTETSTRING w/digest
15664    e.value = asn1.create(
15665      asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, ski.getBytes());
15666  } else if(e.name === 'authorityKeyIdentifier' && options.cert) {
15667    // SYNTAX SEQUENCE
15668    e.value = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, []);
15669    var seq = e.value.value;
15670
15671    if(e.keyIdentifier) {
15672      var keyIdentifier = (e.keyIdentifier === true ?
15673        options.cert.generateSubjectKeyIdentifier().getBytes() :
15674        e.keyIdentifier);
15675      seq.push(
15676        asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, false, keyIdentifier));
15677    }
15678
15679    if(e.authorityCertIssuer) {
15680      var authorityCertIssuer = [
15681        asn1.create(asn1.Class.CONTEXT_SPECIFIC, 4, true, [
15682          _dnToAsn1(e.authorityCertIssuer === true ?
15683            options.cert.issuer : e.authorityCertIssuer)
15684        ])
15685      ];
15686      seq.push(
15687        asn1.create(asn1.Class.CONTEXT_SPECIFIC, 1, true, authorityCertIssuer));
15688    }
15689
15690    if(e.serialNumber) {
15691      var serialNumber = forge.util.hexToBytes(e.serialNumber === true ?
15692        options.cert.serialNumber : e.serialNumber);
15693      seq.push(
15694        asn1.create(asn1.Class.CONTEXT_SPECIFIC, 2, false, serialNumber));
15695    }
15696  } else if (e.name === 'cRLDistributionPoints') {
15697    e.value = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, []);
15698    var seq = e.value.value;
15699
15700    // Create sub SEQUENCE of DistributionPointName
15701    var subSeq = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, []);
15702
15703    // Create fullName CHOICE
15704    var fullNameGeneralNames = asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, []);
15705    var altName;
15706    for(var n = 0; n < e.altNames.length; ++n) {
15707      altName = e.altNames[n];
15708      var value = altName.value;
15709      // handle IP
15710      if(altName.type === 7 && altName.ip) {
15711        value = forge.util.bytesFromIP(altName.ip);
15712        if(value === null) {
15713          var error = new Error(
15714            'Extension "ip" value is not a valid IPv4 or IPv6 address.');
15715          error.extension = e;
15716          throw error;
15717        }
15718      } else if(altName.type === 8) {
15719        // handle OID
15720        if(altName.oid) {
15721          value = asn1.oidToDer(asn1.oidToDer(altName.oid));
15722        } else {
15723          // deprecated ... convert value to OID
15724          value = asn1.oidToDer(value);
15725        }
15726      }
15727      fullNameGeneralNames.value.push(asn1.create(
15728        asn1.Class.CONTEXT_SPECIFIC, altName.type, false,
15729        value));
15730    }
15731
15732    // Add to the parent SEQUENCE
15733    subSeq.value.push(asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [fullNameGeneralNames]));
15734    seq.push(subSeq);
15735  }
15736
15737  // ensure value has been defined by now
15738  if(typeof e.value === 'undefined') {
15739    var error = new Error('Extension value not specified.');
15740    error.extension = e;
15741    throw error;
15742  }
15743
15744  return e;
15745}
15746
15747/**
15748 * Convert signature parameters object to ASN.1
15749 *
15750 * @param {String} oid Signature algorithm OID
15751 * @param params The signature parametrs object
15752 * @return ASN.1 object representing signature parameters
15753 */
15754function _signatureParametersToAsn1(oid, params) {
15755  switch(oid) {
15756  case oids['RSASSA-PSS']:
15757    var parts = [];
15758
15759    if(params.hash.algorithmOid !== undefined) {
15760      parts.push(asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [
15761        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
15762          asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
15763            asn1.oidToDer(params.hash.algorithmOid).getBytes()),
15764          asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, '')
15765        ])
15766      ]));
15767    }
15768
15769    if(params.mgf.algorithmOid !== undefined) {
15770      parts.push(asn1.create(asn1.Class.CONTEXT_SPECIFIC, 1, true, [
15771        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
15772          asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
15773            asn1.oidToDer(params.mgf.algorithmOid).getBytes()),
15774          asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
15775            asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
15776              asn1.oidToDer(params.mgf.hash.algorithmOid).getBytes()),
15777            asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, '')
15778          ])
15779        ])
15780      ]));
15781    }
15782
15783    if(params.saltLength !== undefined) {
15784      parts.push(asn1.create(asn1.Class.CONTEXT_SPECIFIC, 2, true, [
15785        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false,
15786          asn1.integerToDer(params.saltLength).getBytes())
15787      ]));
15788    }
15789
15790    return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, parts);
15791
15792  default:
15793    return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, '');
15794  }
15795}
15796
15797/**
15798 * Converts a certification request's attributes to an ASN.1 set of
15799 * CRIAttributes.
15800 *
15801 * @param csr certification request.
15802 *
15803 * @return the ASN.1 set of CRIAttributes.
15804 */
15805function _CRIAttributesToAsn1(csr) {
15806  // create an empty context-specific container
15807  var rval = asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, []);
15808
15809  // no attributes, return empty container
15810  if(csr.attributes.length === 0) {
15811    return rval;
15812  }
15813
15814  // each attribute has a sequence with a type and a set of values
15815  var attrs = csr.attributes;
15816  for(var i = 0; i < attrs.length; ++i) {
15817    var attr = attrs[i];
15818    var value = attr.value;
15819
15820    // reuse tag class for attribute value if available
15821    var valueTagClass = asn1.Type.UTF8;
15822    if('valueTagClass' in attr) {
15823      valueTagClass = attr.valueTagClass;
15824    }
15825    if(valueTagClass === asn1.Type.UTF8) {
15826      value = forge.util.encodeUtf8(value);
15827    }
15828    var valueConstructed = false;
15829    if('valueConstructed' in attr) {
15830      valueConstructed = attr.valueConstructed;
15831    }
15832    // FIXME: handle more encodings
15833
15834    // create a RelativeDistinguishedName set
15835    // each value in the set is an AttributeTypeAndValue first
15836    // containing the type (an OID) and second the value
15837    var seq = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
15838      // AttributeType
15839      asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
15840        asn1.oidToDer(attr.type).getBytes()),
15841      asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SET, true, [
15842        // AttributeValue
15843        asn1.create(
15844          asn1.Class.UNIVERSAL, valueTagClass, valueConstructed, value)
15845      ])
15846    ]);
15847    rval.value.push(seq);
15848  }
15849
15850  return rval;
15851}
15852
15853/**
15854 * Gets the ASN.1 TBSCertificate part of an X.509v3 certificate.
15855 *
15856 * @param cert the certificate.
15857 *
15858 * @return the asn1 TBSCertificate.
15859 */
15860pki.getTBSCertificate = function(cert) {
15861  // TBSCertificate
15862  var tbs = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
15863    // version
15864    asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [
15865      // integer
15866      asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false,
15867        asn1.integerToDer(cert.version).getBytes())
15868    ]),
15869    // serialNumber
15870    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false,
15871      forge.util.hexToBytes(cert.serialNumber)),
15872    // signature
15873    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
15874      // algorithm
15875      asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
15876        asn1.oidToDer(cert.siginfo.algorithmOid).getBytes()),
15877      // parameters
15878      _signatureParametersToAsn1(
15879        cert.siginfo.algorithmOid, cert.siginfo.parameters)
15880    ]),
15881    // issuer
15882    _dnToAsn1(cert.issuer),
15883    // validity
15884    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
15885      // notBefore
15886      asn1.create(asn1.Class.UNIVERSAL, asn1.Type.UTCTIME, false,
15887        asn1.dateToUtcTime(cert.validity.notBefore)),
15888      // notAfter
15889      asn1.create(asn1.Class.UNIVERSAL, asn1.Type.UTCTIME, false,
15890        asn1.dateToUtcTime(cert.validity.notAfter))
15891    ]),
15892    // subject
15893    _dnToAsn1(cert.subject),
15894    // SubjectPublicKeyInfo
15895    pki.publicKeyToAsn1(cert.publicKey)
15896  ]);
15897
15898  if(cert.issuer.uniqueId) {
15899    // issuerUniqueID (optional)
15900    tbs.value.push(
15901      asn1.create(asn1.Class.CONTEXT_SPECIFIC, 1, true, [
15902        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.BITSTRING, false,
15903          String.fromCharCode(0x00) +
15904          cert.issuer.uniqueId
15905        )
15906      ])
15907    );
15908  }
15909  if(cert.subject.uniqueId) {
15910    // subjectUniqueID (optional)
15911    tbs.value.push(
15912      asn1.create(asn1.Class.CONTEXT_SPECIFIC, 2, true, [
15913        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.BITSTRING, false,
15914          String.fromCharCode(0x00) +
15915          cert.subject.uniqueId
15916        )
15917      ])
15918    );
15919  }
15920
15921  if(cert.extensions.length > 0) {
15922    // extensions (optional)
15923    tbs.value.push(pki.certificateExtensionsToAsn1(cert.extensions));
15924  }
15925
15926  return tbs;
15927};
15928
15929/**
15930 * Gets the ASN.1 CertificationRequestInfo part of a
15931 * PKCS#10 CertificationRequest.
15932 *
15933 * @param csr the certification request.
15934 *
15935 * @return the asn1 CertificationRequestInfo.
15936 */
15937pki.getCertificationRequestInfo = function(csr) {
15938  // CertificationRequestInfo
15939  var cri = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
15940    // version
15941    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false,
15942      asn1.integerToDer(csr.version).getBytes()),
15943    // subject
15944    _dnToAsn1(csr.subject),
15945    // SubjectPublicKeyInfo
15946    pki.publicKeyToAsn1(csr.publicKey),
15947    // attributes
15948    _CRIAttributesToAsn1(csr)
15949  ]);
15950
15951  return cri;
15952};
15953
15954/**
15955 * Converts a DistinguishedName (subject or issuer) to an ASN.1 object.
15956 *
15957 * @param dn the DistinguishedName.
15958 *
15959 * @return the asn1 representation of a DistinguishedName.
15960 */
15961pki.distinguishedNameToAsn1 = function(dn) {
15962  return _dnToAsn1(dn);
15963};
15964
15965/**
15966 * Converts an X.509v3 RSA certificate to an ASN.1 object.
15967 *
15968 * @param cert the certificate.
15969 *
15970 * @return the asn1 representation of an X.509v3 RSA certificate.
15971 */
15972pki.certificateToAsn1 = function(cert) {
15973  // prefer cached TBSCertificate over generating one
15974  var tbsCertificate = cert.tbsCertificate || pki.getTBSCertificate(cert);
15975
15976  // Certificate
15977  return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
15978    // TBSCertificate
15979    tbsCertificate,
15980    // AlgorithmIdentifier (signature algorithm)
15981    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
15982      // algorithm
15983      asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
15984        asn1.oidToDer(cert.signatureOid).getBytes()),
15985      // parameters
15986      _signatureParametersToAsn1(cert.signatureOid, cert.signatureParameters)
15987    ]),
15988    // SignatureValue
15989    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.BITSTRING, false,
15990      String.fromCharCode(0x00) + cert.signature)
15991  ]);
15992};
15993
15994/**
15995 * Converts X.509v3 certificate extensions to ASN.1.
15996 *
15997 * @param exts the extensions to convert.
15998 *
15999 * @return the extensions in ASN.1 format.
16000 */
16001pki.certificateExtensionsToAsn1 = function(exts) {
16002  // create top-level extension container
16003  var rval = asn1.create(asn1.Class.CONTEXT_SPECIFIC, 3, true, []);
16004
16005  // create extension sequence (stores a sequence for each extension)
16006  var seq = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, []);
16007  rval.value.push(seq);
16008
16009  for(var i = 0; i < exts.length; ++i) {
16010    seq.value.push(pki.certificateExtensionToAsn1(exts[i]));
16011  }
16012
16013  return rval;
16014};
16015
16016/**
16017 * Converts a single certificate extension to ASN.1.
16018 *
16019 * @param ext the extension to convert.
16020 *
16021 * @return the extension in ASN.1 format.
16022 */
16023pki.certificateExtensionToAsn1 = function(ext) {
16024  // create a sequence for each extension
16025  var extseq = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, []);
16026
16027  // extnID (OID)
16028  extseq.value.push(asn1.create(
16029    asn1.Class.UNIVERSAL, asn1.Type.OID, false,
16030    asn1.oidToDer(ext.id).getBytes()));
16031
16032  // critical defaults to false
16033  if(ext.critical) {
16034    // critical BOOLEAN DEFAULT FALSE
16035    extseq.value.push(asn1.create(
16036      asn1.Class.UNIVERSAL, asn1.Type.BOOLEAN, false,
16037      String.fromCharCode(0xFF)));
16038  }
16039
16040  var value = ext.value;
16041  if(typeof ext.value !== 'string') {
16042    // value is asn.1
16043    value = asn1.toDer(value).getBytes();
16044  }
16045
16046  // extnValue (OCTET STRING)
16047  extseq.value.push(asn1.create(
16048    asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, value));
16049
16050  return extseq;
16051};
16052
16053/**
16054 * Converts a PKCS#10 certification request to an ASN.1 object.
16055 *
16056 * @param csr the certification request.
16057 *
16058 * @return the asn1 representation of a certification request.
16059 */
16060pki.certificationRequestToAsn1 = function(csr) {
16061  // prefer cached CertificationRequestInfo over generating one
16062  var cri = csr.certificationRequestInfo ||
16063    pki.getCertificationRequestInfo(csr);
16064
16065  // Certificate
16066  return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
16067    // CertificationRequestInfo
16068    cri,
16069    // AlgorithmIdentifier (signature algorithm)
16070    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
16071      // algorithm
16072      asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
16073        asn1.oidToDer(csr.signatureOid).getBytes()),
16074      // parameters
16075      _signatureParametersToAsn1(csr.signatureOid, csr.signatureParameters)
16076    ]),
16077    // signature
16078    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.BITSTRING, false,
16079      String.fromCharCode(0x00) + csr.signature)
16080  ]);
16081};
16082
16083/**
16084 * Creates a CA store.
16085 *
16086 * @param certs an optional array of certificate objects or PEM-formatted
16087 *          certificate strings to add to the CA store.
16088 *
16089 * @return the CA store.
16090 */
16091pki.createCaStore = function(certs) {
16092  // create CA store
16093  var caStore = {
16094    // stored certificates
16095    certs: {}
16096  };
16097
16098  /**
16099   * Gets the certificate that issued the passed certificate or its
16100   * 'parent'.
16101   *
16102   * @param cert the certificate to get the parent for.
16103   *
16104   * @return the parent certificate or null if none was found.
16105   */
16106  caStore.getIssuer = function(cert) {
16107    var rval = getBySubject(cert.issuer);
16108
16109    // see if there are multiple matches
16110    /*if(forge.util.isArray(rval)) {
16111      // TODO: resolve multiple matches by checking
16112      // authorityKey/subjectKey/issuerUniqueID/other identifiers, etc.
16113      // FIXME: or alternatively do authority key mapping
16114      // if possible (X.509v1 certs can't work?)
16115      throw new Error('Resolving multiple issuer matches not implemented yet.');
16116    }*/
16117
16118    return rval;
16119  };
16120
16121  /**
16122   * Adds a trusted certificate to the store.
16123   *
16124   * @param cert the certificate to add as a trusted certificate (either a
16125   *          pki.certificate object or a PEM-formatted certificate).
16126   */
16127  caStore.addCertificate = function(cert) {
16128    // convert from pem if necessary
16129    if(typeof cert === 'string') {
16130      cert = forge.pki.certificateFromPem(cert);
16131    }
16132
16133    ensureSubjectHasHash(cert.subject);
16134
16135    if(!caStore.hasCertificate(cert)) {  // avoid duplicate certificates in store
16136      if(cert.subject.hash in caStore.certs) {
16137        // subject hash already exists, append to array
16138        var tmp = caStore.certs[cert.subject.hash];
16139        if(!forge.util.isArray(tmp)) {
16140          tmp = [tmp];
16141        }
16142        tmp.push(cert);
16143        caStore.certs[cert.subject.hash] = tmp;
16144      } else {
16145        caStore.certs[cert.subject.hash] = cert;
16146      }
16147    }
16148  };
16149
16150  /**
16151   * Checks to see if the given certificate is in the store.
16152   *
16153   * @param cert the certificate to check (either a pki.certificate or a
16154   *          PEM-formatted certificate).
16155   *
16156   * @return true if the certificate is in the store, false if not.
16157   */
16158  caStore.hasCertificate = function(cert) {
16159    // convert from pem if necessary
16160    if(typeof cert === 'string') {
16161      cert = forge.pki.certificateFromPem(cert);
16162    }
16163
16164    var match = getBySubject(cert.subject);
16165    if(!match) {
16166      return false;
16167    }
16168    if(!forge.util.isArray(match)) {
16169      match = [match];
16170    }
16171    // compare DER-encoding of certificates
16172    var der1 = asn1.toDer(pki.certificateToAsn1(cert)).getBytes();
16173    for(var i = 0; i < match.length; ++i) {
16174      var der2 = asn1.toDer(pki.certificateToAsn1(match[i])).getBytes();
16175      if(der1 === der2) {
16176        return true;
16177      }
16178    }
16179    return false;
16180  };
16181
16182  /**
16183   * Lists all of the certificates kept in the store.
16184   *
16185   * @return an array of all of the pki.certificate objects in the store.
16186   */
16187  caStore.listAllCertificates = function() {
16188    var certList = [];
16189
16190    for(var hash in caStore.certs) {
16191      if(caStore.certs.hasOwnProperty(hash)) {
16192        var value = caStore.certs[hash];
16193        if(!forge.util.isArray(value)) {
16194          certList.push(value);
16195        } else {
16196          for(var i = 0; i < value.length; ++i) {
16197            certList.push(value[i]);
16198          }
16199        }
16200      }
16201    }
16202
16203    return certList;
16204  };
16205
16206  /**
16207   * Removes a certificate from the store.
16208   *
16209   * @param cert the certificate to remove (either a pki.certificate or a
16210   *          PEM-formatted certificate).
16211   *
16212   * @return the certificate that was removed or null if the certificate
16213   *           wasn't in store.
16214   */
16215  caStore.removeCertificate = function(cert) {
16216    var result;
16217
16218    // convert from pem if necessary
16219    if(typeof cert === 'string') {
16220      cert = forge.pki.certificateFromPem(cert);
16221    }
16222    ensureSubjectHasHash(cert.subject);
16223    if(!caStore.hasCertificate(cert)) {
16224      return null;
16225    }
16226
16227    var match = getBySubject(cert.subject);
16228
16229    if(!forge.util.isArray(match)) {
16230      result = caStore.certs[cert.subject.hash];
16231      delete caStore.certs[cert.subject.hash];
16232      return result;
16233    }
16234
16235    // compare DER-encoding of certificates
16236    var der1 = asn1.toDer(pki.certificateToAsn1(cert)).getBytes();
16237    for(var i = 0; i < match.length; ++i) {
16238      var der2 = asn1.toDer(pki.certificateToAsn1(match[i])).getBytes();
16239      if(der1 === der2) {
16240        result = match[i];
16241        match.splice(i, 1);
16242      }
16243    }
16244    if(match.length === 0) {
16245      delete caStore.certs[cert.subject.hash];
16246    }
16247
16248    return result;
16249  };
16250
16251  function getBySubject(subject) {
16252    ensureSubjectHasHash(subject);
16253    return caStore.certs[subject.hash] || null;
16254  }
16255
16256  function ensureSubjectHasHash(subject) {
16257    // produce subject hash if it doesn't exist
16258    if(!subject.hash) {
16259      var md = forge.md.sha1.create();
16260      subject.attributes =  pki.RDNAttributesAsArray(_dnToAsn1(subject), md);
16261      subject.hash = md.digest().toHex();
16262    }
16263  }
16264
16265  // auto-add passed in certs
16266  if(certs) {
16267    // parse PEM-formatted certificates as necessary
16268    for(var i = 0; i < certs.length; ++i) {
16269      var cert = certs[i];
16270      caStore.addCertificate(cert);
16271    }
16272  }
16273
16274  return caStore;
16275};
16276
16277/**
16278 * Certificate verification errors, based on TLS.
16279 */
16280pki.certificateError = {
16281  bad_certificate: 'forge.pki.BadCertificate',
16282  unsupported_certificate: 'forge.pki.UnsupportedCertificate',
16283  certificate_revoked: 'forge.pki.CertificateRevoked',
16284  certificate_expired: 'forge.pki.CertificateExpired',
16285  certificate_unknown: 'forge.pki.CertificateUnknown',
16286  unknown_ca: 'forge.pki.UnknownCertificateAuthority'
16287};
16288
16289/**
16290 * Verifies a certificate chain against the given Certificate Authority store
16291 * with an optional custom verify callback.
16292 *
16293 * @param caStore a certificate store to verify against.
16294 * @param chain the certificate chain to verify, with the root or highest
16295 *          authority at the end (an array of certificates).
16296 * @param verify called for every certificate in the chain.
16297 *
16298 * The verify callback has the following signature:
16299 *
16300 * verified - Set to true if certificate was verified, otherwise the
16301 *   pki.certificateError for why the certificate failed.
16302 * depth - The current index in the chain, where 0 is the end point's cert.
16303 * certs - The certificate chain, *NOTE* an empty chain indicates an anonymous
16304 *   end point.
16305 *
16306 * The function returns true on success and on failure either the appropriate
16307 * pki.certificateError or an object with 'error' set to the appropriate
16308 * pki.certificateError and 'message' set to a custom error message.
16309 *
16310 * @return true if successful, error thrown if not.
16311 */
16312pki.verifyCertificateChain = function(caStore, chain, verify) {
16313  /* From: RFC3280 - Internet X.509 Public Key Infrastructure Certificate
16314    Section 6: Certification Path Validation
16315    See inline parentheticals related to this particular implementation.
16316
16317    The primary goal of path validation is to verify the binding between
16318    a subject distinguished name or a subject alternative name and subject
16319    public key, as represented in the end entity certificate, based on the
16320    public key of the trust anchor. This requires obtaining a sequence of
16321    certificates that support that binding. That sequence should be provided
16322    in the passed 'chain'. The trust anchor should be in the given CA
16323    store. The 'end entity' certificate is the certificate provided by the
16324    end point (typically a server) and is the first in the chain.
16325
16326    To meet this goal, the path validation process verifies, among other
16327    things, that a prospective certification path (a sequence of n
16328    certificates or a 'chain') satisfies the following conditions:
16329
16330    (a) for all x in {1, ..., n-1}, the subject of certificate x is
16331          the issuer of certificate x+1;
16332
16333    (b) certificate 1 is issued by the trust anchor;
16334
16335    (c) certificate n is the certificate to be validated; and
16336
16337    (d) for all x in {1, ..., n}, the certificate was valid at the
16338          time in question.
16339
16340    Note that here 'n' is index 0 in the chain and 1 is the last certificate
16341    in the chain and it must be signed by a certificate in the connection's
16342    CA store.
16343
16344    The path validation process also determines the set of certificate
16345    policies that are valid for this path, based on the certificate policies
16346    extension, policy mapping extension, policy constraints extension, and
16347    inhibit any-policy extension.
16348
16349    Note: Policy mapping extension not supported (Not Required).
16350
16351    Note: If the certificate has an unsupported critical extension, then it
16352    must be rejected.
16353
16354    Note: A certificate is self-issued if the DNs that appear in the subject
16355    and issuer fields are identical and are not empty.
16356
16357    The path validation algorithm assumes the following seven inputs are
16358    provided to the path processing logic. What this specific implementation
16359    will use is provided parenthetically:
16360
16361    (a) a prospective certification path of length n (the 'chain')
16362    (b) the current date/time: ('now').
16363    (c) user-initial-policy-set: A set of certificate policy identifiers
16364          naming the policies that are acceptable to the certificate user.
16365          The user-initial-policy-set contains the special value any-policy
16366          if the user is not concerned about certificate policy
16367          (Not implemented. Any policy is accepted).
16368    (d) trust anchor information, describing a CA that serves as a trust
16369          anchor for the certification path. The trust anchor information
16370          includes:
16371
16372      (1)  the trusted issuer name,
16373      (2)  the trusted public key algorithm,
16374      (3)  the trusted public key, and
16375      (4)  optionally, the trusted public key parameters associated
16376             with the public key.
16377
16378      (Trust anchors are provided via certificates in the CA store).
16379
16380      The trust anchor information may be provided to the path processing
16381      procedure in the form of a self-signed certificate. The trusted anchor
16382      information is trusted because it was delivered to the path processing
16383      procedure by some trustworthy out-of-band procedure. If the trusted
16384      public key algorithm requires parameters, then the parameters are
16385      provided along with the trusted public key (No parameters used in this
16386      implementation).
16387
16388    (e) initial-policy-mapping-inhibit, which indicates if policy mapping is
16389          allowed in the certification path.
16390          (Not implemented, no policy checking)
16391
16392    (f) initial-explicit-policy, which indicates if the path must be valid
16393          for at least one of the certificate policies in the user-initial-
16394          policy-set.
16395          (Not implemented, no policy checking)
16396
16397    (g) initial-any-policy-inhibit, which indicates whether the
16398          anyPolicy OID should be processed if it is included in a
16399          certificate.
16400          (Not implemented, so any policy is valid provided that it is
16401          not marked as critical) */
16402
16403  /* Basic Path Processing:
16404
16405    For each certificate in the 'chain', the following is checked:
16406
16407    1. The certificate validity period includes the current time.
16408    2. The certificate was signed by its parent (where the parent is either
16409       the next in the chain or from the CA store). Allow processing to
16410       continue to the next step if no parent is found but the certificate is
16411       in the CA store.
16412    3. TODO: The certificate has not been revoked.
16413    4. The certificate issuer name matches the parent's subject name.
16414    5. TODO: If the certificate is self-issued and not the final certificate
16415       in the chain, skip this step, otherwise verify that the subject name
16416       is within one of the permitted subtrees of X.500 distinguished names
16417       and that each of the alternative names in the subjectAltName extension
16418       (critical or non-critical) is within one of the permitted subtrees for
16419       that name type.
16420    6. TODO: If the certificate is self-issued and not the final certificate
16421       in the chain, skip this step, otherwise verify that the subject name
16422       is not within one of the excluded subtrees for X.500 distinguished
16423       names and none of the subjectAltName extension names are excluded for
16424       that name type.
16425    7. The other steps in the algorithm for basic path processing involve
16426       handling the policy extension which is not presently supported in this
16427       implementation. Instead, if a critical policy extension is found, the
16428       certificate is rejected as not supported.
16429    8. If the certificate is not the first or if its the only certificate in
16430       the chain (having no parent from the CA store or is self-signed) and it
16431       has a critical key usage extension, verify that the keyCertSign bit is
16432       set. If the key usage extension exists, verify that the basic
16433       constraints extension exists. If the basic constraints extension exists,
16434       verify that the cA flag is set. If pathLenConstraint is set, ensure that
16435       the number of certificates that precede in the chain (come earlier
16436       in the chain as implemented below), excluding the very first in the
16437       chain (typically the end-entity one), isn't greater than the
16438       pathLenConstraint. This constraint limits the number of intermediate
16439       CAs that may appear below a CA before only end-entity certificates
16440       may be issued. */
16441
16442  // copy cert chain references to another array to protect against changes
16443  // in verify callback
16444  chain = chain.slice(0);
16445  var certs = chain.slice(0);
16446
16447  // get current date
16448  var now = new Date();
16449
16450  // verify each cert in the chain using its parent, where the parent
16451  // is either the next in the chain or from the CA store
16452  var first = true;
16453  var error = null;
16454  var depth = 0;
16455  do {
16456    var cert = chain.shift();
16457    var parent = null;
16458    var selfSigned = false;
16459
16460    // 1. check valid time
16461    if(now < cert.validity.notBefore || now > cert.validity.notAfter) {
16462      error = {
16463        message: 'Certificate is not valid yet or has expired.',
16464        error: pki.certificateError.certificate_expired,
16465        notBefore: cert.validity.notBefore,
16466        notAfter: cert.validity.notAfter,
16467        now: now
16468      };
16469    }
16470
16471    // 2. verify with parent from chain or CA store
16472    if(error === null) {
16473      parent = chain[0] || caStore.getIssuer(cert);
16474      if(parent === null) {
16475        // check for self-signed cert
16476        if(cert.isIssuer(cert)) {
16477          selfSigned = true;
16478          parent = cert;
16479        }
16480      }
16481
16482      if(parent) {
16483        // FIXME: current CA store implementation might have multiple
16484        // certificates where the issuer can't be determined from the
16485        // certificate (happens rarely with, eg: old certificates) so normalize
16486        // by always putting parents into an array
16487        // TODO: there's may be an extreme degenerate case currently uncovered
16488        // where an old intermediate certificate seems to have a matching parent
16489        // but none of the parents actually verify ... but the intermediate
16490        // is in the CA and it should pass this check; needs investigation
16491        var parents = parent;
16492        if(!forge.util.isArray(parents)) {
16493          parents = [parents];
16494        }
16495
16496        // try to verify with each possible parent (typically only one)
16497        var verified = false;
16498        while(!verified && parents.length > 0) {
16499          parent = parents.shift();
16500          try {
16501            verified = parent.verify(cert);
16502          } catch(ex) {
16503            // failure to verify, don't care why, try next one
16504          }
16505        }
16506
16507        if(!verified) {
16508          error = {
16509            message: 'Certificate signature is invalid.',
16510            error: pki.certificateError.bad_certificate
16511          };
16512        }
16513      }
16514
16515      if(error === null && (!parent || selfSigned) &&
16516        !caStore.hasCertificate(cert)) {
16517        // no parent issuer and certificate itself is not trusted
16518        error = {
16519          message: 'Certificate is not trusted.',
16520          error: pki.certificateError.unknown_ca
16521        };
16522      }
16523    }
16524
16525    // TODO: 3. check revoked
16526
16527    // 4. check for matching issuer/subject
16528    if(error === null && parent && !cert.isIssuer(parent)) {
16529      // parent is not issuer
16530      error = {
16531        message: 'Certificate issuer is invalid.',
16532        error: pki.certificateError.bad_certificate
16533      };
16534    }
16535
16536    // 5. TODO: check names with permitted names tree
16537
16538    // 6. TODO: check names against excluded names tree
16539
16540    // 7. check for unsupported critical extensions
16541    if(error === null) {
16542      // supported extensions
16543      var se = {
16544        keyUsage: true,
16545        basicConstraints: true
16546      };
16547      for(var i = 0; error === null && i < cert.extensions.length; ++i) {
16548        var ext = cert.extensions[i];
16549        if(ext.critical && !(ext.name in se)) {
16550          error = {
16551            message:
16552              'Certificate has an unsupported critical extension.',
16553            error: pki.certificateError.unsupported_certificate
16554          };
16555        }
16556      }
16557    }
16558
16559    // 8. check for CA if cert is not first or is the only certificate
16560    // remaining in chain with no parent or is self-signed
16561    if(error === null &&
16562      (!first || (chain.length === 0 && (!parent || selfSigned)))) {
16563      // first check keyUsage extension and then basic constraints
16564      var bcExt = cert.getExtension('basicConstraints');
16565      var keyUsageExt = cert.getExtension('keyUsage');
16566      if(keyUsageExt !== null) {
16567        // keyCertSign must be true and there must be a basic
16568        // constraints extension
16569        if(!keyUsageExt.keyCertSign || bcExt === null) {
16570          // bad certificate
16571          error = {
16572            message:
16573              'Certificate keyUsage or basicConstraints conflict ' +
16574              'or indicate that the certificate is not a CA. ' +
16575              'If the certificate is the only one in the chain or ' +
16576              'isn\'t the first then the certificate must be a ' +
16577              'valid CA.',
16578            error: pki.certificateError.bad_certificate
16579          };
16580        }
16581      }
16582      // basic constraints cA flag must be set
16583      if(error === null && bcExt !== null && !bcExt.cA) {
16584        // bad certificate
16585        error = {
16586          message:
16587            'Certificate basicConstraints indicates the certificate ' +
16588            'is not a CA.',
16589          error: pki.certificateError.bad_certificate
16590        };
16591      }
16592      // if error is not null and keyUsage is available, then we know it
16593      // has keyCertSign and there is a basic constraints extension too,
16594      // which means we can check pathLenConstraint (if it exists)
16595      if(error === null && keyUsageExt !== null &&
16596        'pathLenConstraint' in bcExt) {
16597        // pathLen is the maximum # of intermediate CA certs that can be
16598        // found between the current certificate and the end-entity (depth 0)
16599        // certificate; this number does not include the end-entity (depth 0,
16600        // last in the chain) even if it happens to be a CA certificate itself
16601        var pathLen = depth - 1;
16602        if(pathLen > bcExt.pathLenConstraint) {
16603          // pathLenConstraint violated, bad certificate
16604          error = {
16605            message:
16606              'Certificate basicConstraints pathLenConstraint violated.',
16607            error: pki.certificateError.bad_certificate
16608          };
16609        }
16610      }
16611    }
16612
16613    // call application callback
16614    var vfd = (error === null) ? true : error.error;
16615    var ret = verify ? verify(vfd, depth, certs) : vfd;
16616    if(ret === true) {
16617      // clear any set error
16618      error = null;
16619    } else {
16620      // if passed basic tests, set default message and alert
16621      if(vfd === true) {
16622        error = {
16623          message: 'The application rejected the certificate.',
16624          error: pki.certificateError.bad_certificate
16625        };
16626      }
16627
16628      // check for custom error info
16629      if(ret || ret === 0) {
16630        // set custom message and error
16631        if(typeof ret === 'object' && !forge.util.isArray(ret)) {
16632          if(ret.message) {
16633             error.message = ret.message;
16634          }
16635          if(ret.error) {
16636            error.error = ret.error;
16637          }
16638        } else if(typeof ret === 'string') {
16639          // set custom error
16640          error.error = ret;
16641        }
16642      }
16643
16644      // throw error
16645      throw error;
16646    }
16647
16648    // no longer first cert in chain
16649    first = false;
16650    ++depth;
16651  } while(chain.length > 0);
16652
16653  return true;
16654};
16655
16656} // end module implementation
16657
16658/* ########## Begin module wrapper ########## */
16659var name = 'x509';
16660if(typeof define !== 'function') {
16661  // NodeJS -> AMD
16662  if(typeof module === 'object' && module.exports) {
16663    var nodeJS = true;
16664    define = function(ids, factory) {
16665      factory(require, module);
16666    };
16667  } else {
16668    // <script>
16669    if(typeof forge === 'undefined') {
16670      forge = {};
16671    }
16672    return initModule(forge);
16673  }
16674}
16675// AMD
16676var deps;
16677var defineFunc = function(require, module) {
16678  module.exports = function(forge) {
16679    var mods = deps.map(function(dep) {
16680      return require(dep);
16681    }).concat(initModule);
16682    // handle circular dependencies
16683    forge = forge || {};
16684    forge.defined = forge.defined || {};
16685    if(forge.defined[name]) {
16686      return forge[name];
16687    }
16688    forge.defined[name] = true;
16689    for(var i = 0; i < mods.length; ++i) {
16690      mods[i](forge);
16691    }
16692    return forge.pki;
16693  };
16694};
16695var tmpDefine = define;
16696define = function(ids, factory) {
16697  deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2);
16698  if(nodeJS) {
16699    delete define;
16700    return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0));
16701  }
16702  define = tmpDefine;
16703  return define.apply(null, Array.prototype.slice.call(arguments, 0));
16704};
16705define([
16706  'require',
16707  'module',
16708  './aes',
16709  './asn1',
16710  './des',
16711  './md',
16712  './mgf',
16713  './oids',
16714  './pem',
16715  './pss',
16716  './rsa',
16717  './util'
16718], function() {
16719  defineFunc.apply(null, Array.prototype.slice.call(arguments, 0));
16720});
16721})();
16722
16723/**
16724 * Node.js module for Forge message digests.
16725 *
16726 * @author Dave Longley
16727 *
16728 * Copyright 2011-2014 Digital Bazaar, Inc.
16729 */
16730(function() {
16731/* ########## Begin module implementation ########## */
16732function initModule(forge) {
16733
16734forge.md = forge.md || {};
16735forge.md.algorithms = {
16736  md5: forge.md5,
16737  sha1: forge.sha1,
16738  sha256: forge.sha256
16739};
16740forge.md.md5 = forge.md5;
16741forge.md.sha1 = forge.sha1;
16742forge.md.sha256 = forge.sha256;
16743
16744} // end module implementation
16745
16746/* ########## Begin module wrapper ########## */
16747var name = 'md';
16748if(typeof define !== 'function') {
16749  // NodeJS -> AMD
16750  if(typeof module === 'object' && module.exports) {
16751    var nodeJS = true;
16752    define = function(ids, factory) {
16753      factory(require, module);
16754    };
16755  } else {
16756    // <script>
16757    if(typeof forge === 'undefined') {
16758      forge = {};
16759    }
16760    return initModule(forge);
16761  }
16762}
16763// AMD
16764var deps;
16765var defineFunc = function(require, module) {
16766  module.exports = function(forge) {
16767    var mods = deps.map(function(dep) {
16768      return require(dep);
16769    }).concat(initModule);
16770    // handle circular dependencies
16771    forge = forge || {};
16772    forge.defined = forge.defined || {};
16773    if(forge.defined[name]) {
16774      return forge[name];
16775    }
16776    forge.defined[name] = true;
16777    for(var i = 0; i < mods.length; ++i) {
16778      mods[i](forge);
16779    }
16780    return forge[name];
16781  };
16782};
16783var tmpDefine = define;
16784define = function(ids, factory) {
16785  deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2);
16786  if(nodeJS) {
16787    delete define;
16788    return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0));
16789  }
16790  define = tmpDefine;
16791  return define.apply(null, Array.prototype.slice.call(arguments, 0));
16792};
16793define(
16794  ['require', 'module', './md5', './sha1', './sha256', './sha512'], function() {
16795  defineFunc.apply(null, Array.prototype.slice.call(arguments, 0));
16796});
16797})();
16798
16799/**
16800 * Password-based encryption functions.
16801 *
16802 * @author Dave Longley
16803 * @author Stefan Siegl <[email protected]>
16804 *
16805 * Copyright (c) 2010-2013 Digital Bazaar, Inc.
16806 * Copyright (c) 2012 Stefan Siegl <[email protected]>
16807 *
16808 * An EncryptedPrivateKeyInfo:
16809 *
16810 * EncryptedPrivateKeyInfo ::= SEQUENCE {
16811 *   encryptionAlgorithm  EncryptionAlgorithmIdentifier,
16812 *   encryptedData        EncryptedData }
16813 *
16814 * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
16815 *
16816 * EncryptedData ::= OCTET STRING
16817 */
16818(function() {
16819/* ########## Begin module implementation ########## */
16820function initModule(forge) {
16821
16822if(typeof BigInteger === 'undefined') {
16823  var BigInteger = forge.jsbn.BigInteger;
16824}
16825
16826// shortcut for asn.1 API
16827var asn1 = forge.asn1;
16828
16829/* Password-based encryption implementation. */
16830var pki = forge.pki = forge.pki || {};
16831pki.pbe = forge.pbe = forge.pbe || {};
16832var oids = pki.oids;
16833
16834// validator for an EncryptedPrivateKeyInfo structure
16835// Note: Currently only works w/algorithm params
16836var encryptedPrivateKeyValidator = {
16837  name: 'EncryptedPrivateKeyInfo',
16838  tagClass: asn1.Class.UNIVERSAL,
16839  type: asn1.Type.SEQUENCE,
16840  constructed: true,
16841  value: [{
16842    name: 'EncryptedPrivateKeyInfo.encryptionAlgorithm',
16843    tagClass: asn1.Class.UNIVERSAL,
16844    type: asn1.Type.SEQUENCE,
16845    constructed: true,
16846    value: [{
16847      name: 'AlgorithmIdentifier.algorithm',
16848      tagClass: asn1.Class.UNIVERSAL,
16849      type: asn1.Type.OID,
16850      constructed: false,
16851      capture: 'encryptionOid'
16852    }, {
16853      name: 'AlgorithmIdentifier.parameters',
16854      tagClass: asn1.Class.UNIVERSAL,
16855      type: asn1.Type.SEQUENCE,
16856      constructed: true,
16857      captureAsn1: 'encryptionParams'
16858    }]
16859  }, {
16860    // encryptedData
16861    name: 'EncryptedPrivateKeyInfo.encryptedData',
16862    tagClass: asn1.Class.UNIVERSAL,
16863    type: asn1.Type.OCTETSTRING,
16864    constructed: false,
16865    capture: 'encryptedData'
16866  }]
16867};
16868
16869// validator for a PBES2Algorithms structure
16870// Note: Currently only works w/PBKDF2 + AES encryption schemes
16871var PBES2AlgorithmsValidator = {
16872  name: 'PBES2Algorithms',
16873  tagClass: asn1.Class.UNIVERSAL,
16874  type: asn1.Type.SEQUENCE,
16875  constructed: true,
16876  value: [{
16877    name: 'PBES2Algorithms.keyDerivationFunc',
16878    tagClass: asn1.Class.UNIVERSAL,
16879    type: asn1.Type.SEQUENCE,
16880    constructed: true,
16881    value: [{
16882      name: 'PBES2Algorithms.keyDerivationFunc.oid',
16883      tagClass: asn1.Class.UNIVERSAL,
16884      type: asn1.Type.OID,
16885      constructed: false,
16886      capture: 'kdfOid'
16887    }, {
16888      name: 'PBES2Algorithms.params',
16889      tagClass: asn1.Class.UNIVERSAL,
16890      type: asn1.Type.SEQUENCE,
16891      constructed: true,
16892      value: [{
16893        name: 'PBES2Algorithms.params.salt',
16894        tagClass: asn1.Class.UNIVERSAL,
16895        type: asn1.Type.OCTETSTRING,
16896        constructed: false,
16897        capture: 'kdfSalt'
16898      }, {
16899        name: 'PBES2Algorithms.params.iterationCount',
16900        tagClass: asn1.Class.UNIVERSAL,
16901        type: asn1.Type.INTEGER,
16902        constructed: false,
16903        capture: 'kdfIterationCount'
16904      }, {
16905        name: 'PBES2Algorithms.params.keyLength',
16906        tagClass: asn1.Class.UNIVERSAL,
16907        type: asn1.Type.INTEGER,
16908        constructed: false,
16909        optional: true,
16910        capture: 'keyLength'
16911      }, {
16912        // prf
16913        name: 'PBES2Algorithms.params.prf',
16914        tagClass: asn1.Class.UNIVERSAL,
16915        type: asn1.Type.SEQUENCE,
16916        constructed: true,
16917        optional: true,
16918        value: [{
16919          name: 'PBES2Algorithms.params.prf.algorithm',
16920          tagClass: asn1.Class.UNIVERSAL,
16921          type: asn1.Type.OID,
16922          constructed: false,
16923          capture: 'prfOid'
16924        }]
16925      }]
16926    }]
16927  }, {
16928    name: 'PBES2Algorithms.encryptionScheme',
16929    tagClass: asn1.Class.UNIVERSAL,
16930    type: asn1.Type.SEQUENCE,
16931    constructed: true,
16932    value: [{
16933      name: 'PBES2Algorithms.encryptionScheme.oid',
16934      tagClass: asn1.Class.UNIVERSAL,
16935      type: asn1.Type.OID,
16936      constructed: false,
16937      capture: 'encOid'
16938    }, {
16939      name: 'PBES2Algorithms.encryptionScheme.iv',
16940      tagClass: asn1.Class.UNIVERSAL,
16941      type: asn1.Type.OCTETSTRING,
16942      constructed: false,
16943      capture: 'encIv'
16944    }]
16945  }]
16946};
16947
16948var pkcs12PbeParamsValidator = {
16949  name: 'pkcs-12PbeParams',
16950  tagClass: asn1.Class.UNIVERSAL,
16951  type: asn1.Type.SEQUENCE,
16952  constructed: true,
16953  value: [{
16954    name: 'pkcs-12PbeParams.salt',
16955    tagClass: asn1.Class.UNIVERSAL,
16956    type: asn1.Type.OCTETSTRING,
16957    constructed: false,
16958    capture: 'salt'
16959  }, {
16960    name: 'pkcs-12PbeParams.iterations',
16961    tagClass: asn1.Class.UNIVERSAL,
16962    type: asn1.Type.INTEGER,
16963    constructed: false,
16964    capture: 'iterations'
16965  }]
16966};
16967
16968/**
16969 * Encrypts a ASN.1 PrivateKeyInfo object, producing an EncryptedPrivateKeyInfo.
16970 *
16971 * PBES2Algorithms ALGORITHM-IDENTIFIER ::=
16972 *   { {PBES2-params IDENTIFIED BY id-PBES2}, ...}
16973 *
16974 * id-PBES2 OBJECT IDENTIFIER ::= {pkcs-5 13}
16975 *
16976 * PBES2-params ::= SEQUENCE {
16977 *   keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}},
16978 *   encryptionScheme AlgorithmIdentifier {{PBES2-Encs}}
16979 * }
16980 *
16981 * PBES2-KDFs ALGORITHM-IDENTIFIER ::=
16982 *   { {PBKDF2-params IDENTIFIED BY id-PBKDF2}, ... }
16983 *
16984 * PBES2-Encs ALGORITHM-IDENTIFIER ::= { ... }
16985 *
16986 * PBKDF2-params ::= SEQUENCE {
16987 *   salt CHOICE {
16988 *     specified OCTET STRING,
16989 *     otherSource AlgorithmIdentifier {{PBKDF2-SaltSources}}
16990 *   },
16991 *   iterationCount INTEGER (1..MAX),
16992 *   keyLength INTEGER (1..MAX) OPTIONAL,
16993 *   prf AlgorithmIdentifier {{PBKDF2-PRFs}} DEFAULT algid-hmacWithSHA1
16994 * }
16995 *
16996 * @param obj the ASN.1 PrivateKeyInfo object.
16997 * @param password the password to encrypt with.
16998 * @param options:
16999 *          algorithm the encryption algorithm to use
17000 *            ('aes128', 'aes192', 'aes256', '3des'), defaults to 'aes128'.
17001 *          count the iteration count to use.
17002 *          saltSize the salt size to use.
17003 *          prfAlgorithm the PRF message digest algorithm to use
17004 *            ('sha1', 'sha224', 'sha256', 'sha384', 'sha512')
17005 *
17006 * @return the ASN.1 EncryptedPrivateKeyInfo.
17007 */
17008pki.encryptPrivateKeyInfo = function(obj, password, options) {
17009  // set default options
17010  options = options || {};
17011  options.saltSize = options.saltSize || 8;
17012  options.count = options.count || 2048;
17013  options.algorithm = options.algorithm || 'aes128';
17014  options.prfAlgorithm = options.prfAlgorithm || 'sha1';
17015
17016  // generate PBE params
17017  var salt = forge.random.getBytesSync(options.saltSize);
17018  var count = options.count;
17019  var countBytes = asn1.integerToDer(count);
17020  var dkLen;
17021  var encryptionAlgorithm;
17022  var encryptedData;
17023  if(options.algorithm.indexOf('aes') === 0 || options.algorithm === 'des') {
17024    // do PBES2
17025    var ivLen, encOid, cipherFn;
17026    switch(options.algorithm) {
17027    case 'aes128':
17028      dkLen = 16;
17029      ivLen = 16;
17030      encOid = oids['aes128-CBC'];
17031      cipherFn = forge.aes.createEncryptionCipher;
17032      break;
17033    case 'aes192':
17034      dkLen = 24;
17035      ivLen = 16;
17036      encOid = oids['aes192-CBC'];
17037      cipherFn = forge.aes.createEncryptionCipher;
17038      break;
17039    case 'aes256':
17040      dkLen = 32;
17041      ivLen = 16;
17042      encOid = oids['aes256-CBC'];
17043      cipherFn = forge.aes.createEncryptionCipher;
17044      break;
17045    case 'des':
17046      dkLen = 8;
17047      ivLen = 8;
17048      encOid = oids['desCBC'];
17049      cipherFn = forge.des.createEncryptionCipher;
17050      break;
17051    default:
17052      var error = new Error('Cannot encrypt private key. Unknown encryption algorithm.');
17053      error.algorithm = options.algorithm;
17054      throw error;
17055    }
17056
17057    // get PRF message digest
17058    var prfAlgorithm = 'hmacWith' + options.prfAlgorithm.toUpperCase();
17059    var md = prfAlgorithmToMessageDigest(prfAlgorithm);
17060
17061    // encrypt private key using pbe SHA-1 and AES/DES
17062    var dk = forge.pkcs5.pbkdf2(password, salt, count, dkLen, md);
17063    var iv = forge.random.getBytesSync(ivLen);
17064    var cipher = cipherFn(dk);
17065    cipher.start(iv);
17066    cipher.update(asn1.toDer(obj));
17067    cipher.finish();
17068    encryptedData = cipher.output.getBytes();
17069
17070    // get PBKDF2-params
17071    var params = createPbkdf2Params(salt, countBytes, dkLen, prfAlgorithm);
17072
17073    encryptionAlgorithm = asn1.create(
17074      asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
17075      asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
17076        asn1.oidToDer(oids['pkcs5PBES2']).getBytes()),
17077      asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
17078        // keyDerivationFunc
17079        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
17080          asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
17081            asn1.oidToDer(oids['pkcs5PBKDF2']).getBytes()),
17082          // PBKDF2-params
17083          params
17084        ]),
17085        // encryptionScheme
17086        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
17087          asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
17088            asn1.oidToDer(encOid).getBytes()),
17089          // iv
17090          asn1.create(
17091            asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, iv)
17092        ])
17093      ])
17094    ]);
17095  } else if(options.algorithm === '3des') {
17096    // Do PKCS12 PBE
17097    dkLen = 24;
17098
17099    var saltBytes = new forge.util.ByteBuffer(salt);
17100    var dk = pki.pbe.generatePkcs12Key(password, saltBytes, 1, count, dkLen);
17101    var iv = pki.pbe.generatePkcs12Key(password, saltBytes, 2, count, dkLen);
17102    var cipher = forge.des.createEncryptionCipher(dk);
17103    cipher.start(iv);
17104    cipher.update(asn1.toDer(obj));
17105    cipher.finish();
17106    encryptedData = cipher.output.getBytes();
17107
17108    encryptionAlgorithm = asn1.create(
17109      asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
17110      asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
17111        asn1.oidToDer(oids['pbeWithSHAAnd3-KeyTripleDES-CBC']).getBytes()),
17112      // pkcs-12PbeParams
17113      asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
17114        // salt
17115        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, salt),
17116        // iteration count
17117        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false,
17118          countBytes.getBytes())
17119      ])
17120    ]);
17121  } else {
17122    var error = new Error('Cannot encrypt private key. Unknown encryption algorithm.');
17123    error.algorithm = options.algorithm;
17124    throw error;
17125  }
17126
17127  // EncryptedPrivateKeyInfo
17128  var rval = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
17129    // encryptionAlgorithm
17130    encryptionAlgorithm,
17131    // encryptedData
17132    asn1.create(
17133      asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, encryptedData)
17134  ]);
17135  return rval;
17136};
17137
17138/**
17139 * Decrypts a ASN.1 PrivateKeyInfo object.
17140 *
17141 * @param obj the ASN.1 EncryptedPrivateKeyInfo object.
17142 * @param password the password to decrypt with.
17143 *
17144 * @return the ASN.1 PrivateKeyInfo on success, null on failure.
17145 */
17146pki.decryptPrivateKeyInfo = function(obj, password) {
17147  var rval = null;
17148
17149  // get PBE params
17150  var capture = {};
17151  var errors = [];
17152  if(!asn1.validate(obj, encryptedPrivateKeyValidator, capture, errors)) {
17153    var error = new Error('Cannot read encrypted private key. ' +
17154      'ASN.1 object is not a supported EncryptedPrivateKeyInfo.');
17155    error.errors = errors;
17156    throw error;
17157  }
17158
17159  // get cipher
17160  var oid = asn1.derToOid(capture.encryptionOid);
17161  var cipher = pki.pbe.getCipher(oid, capture.encryptionParams, password);
17162
17163  // get encrypted data
17164  var encrypted = forge.util.createBuffer(capture.encryptedData);
17165
17166  cipher.update(encrypted);
17167  if(cipher.finish()) {
17168    rval = asn1.fromDer(cipher.output);
17169  }
17170
17171  return rval;
17172};
17173
17174/**
17175 * Converts a EncryptedPrivateKeyInfo to PEM format.
17176 *
17177 * @param epki the EncryptedPrivateKeyInfo.
17178 * @param maxline the maximum characters per line, defaults to 64.
17179 *
17180 * @return the PEM-formatted encrypted private key.
17181 */
17182pki.encryptedPrivateKeyToPem = function(epki, maxline) {
17183  // convert to DER, then PEM-encode
17184  var msg = {
17185    type: 'ENCRYPTED PRIVATE KEY',
17186    body: asn1.toDer(epki).getBytes()
17187  };
17188  return forge.pem.encode(msg, {maxline: maxline});
17189};
17190
17191/**
17192 * Converts a PEM-encoded EncryptedPrivateKeyInfo to ASN.1 format. Decryption
17193 * is not performed.
17194 *
17195 * @param pem the EncryptedPrivateKeyInfo in PEM-format.
17196 *
17197 * @return the ASN.1 EncryptedPrivateKeyInfo.
17198 */
17199pki.encryptedPrivateKeyFromPem = function(pem) {
17200  var msg = forge.pem.decode(pem)[0];
17201
17202  if(msg.type !== 'ENCRYPTED PRIVATE KEY') {
17203    var error = new Error('Could not convert encrypted private key from PEM; ' +
17204      'PEM header type is "ENCRYPTED PRIVATE KEY".');
17205    error.headerType = msg.type;
17206    throw error;
17207  }
17208  if(msg.procType && msg.procType.type === 'ENCRYPTED') {
17209    throw new Error('Could not convert encrypted private key from PEM; ' +
17210      'PEM is encrypted.');
17211  }
17212
17213  // convert DER to ASN.1 object
17214  return asn1.fromDer(msg.body);
17215};
17216
17217/**
17218 * Encrypts an RSA private key. By default, the key will be wrapped in
17219 * a PrivateKeyInfo and encrypted to produce a PKCS#8 EncryptedPrivateKeyInfo.
17220 * This is the standard, preferred way to encrypt a private key.
17221 *
17222 * To produce a non-standard PEM-encrypted private key that uses encapsulated
17223 * headers to indicate the encryption algorithm (old-style non-PKCS#8 OpenSSL
17224 * private key encryption), set the 'legacy' option to true. Note: Using this
17225 * option will cause the iteration count to be forced to 1.
17226 *
17227 * Note: The 'des' algorithm is supported, but it is not considered to be
17228 * secure because it only uses a single 56-bit key. If possible, it is highly
17229 * recommended that a different algorithm be used.
17230 *
17231 * @param rsaKey the RSA key to encrypt.
17232 * @param password the password to use.
17233 * @param options:
17234 *          algorithm: the encryption algorithm to use
17235 *            ('aes128', 'aes192', 'aes256', '3des', 'des').
17236 *          count: the iteration count to use.
17237 *          saltSize: the salt size to use.
17238 *          legacy: output an old non-PKCS#8 PEM-encrypted+encapsulated
17239 *            headers (DEK-Info) private key.
17240 *
17241 * @return the PEM-encoded ASN.1 EncryptedPrivateKeyInfo.
17242 */
17243pki.encryptRsaPrivateKey = function(rsaKey, password, options) {
17244  // standard PKCS#8
17245  options = options || {};
17246  if(!options.legacy) {
17247    // encrypt PrivateKeyInfo
17248    var rval = pki.wrapRsaPrivateKey(pki.privateKeyToAsn1(rsaKey));
17249    rval = pki.encryptPrivateKeyInfo(rval, password, options);
17250    return pki.encryptedPrivateKeyToPem(rval);
17251  }
17252
17253  // legacy non-PKCS#8
17254  var algorithm;
17255  var iv;
17256  var dkLen;
17257  var cipherFn;
17258  switch(options.algorithm) {
17259  case 'aes128':
17260    algorithm = 'AES-128-CBC';
17261    dkLen = 16;
17262    iv = forge.random.getBytesSync(16);
17263    cipherFn = forge.aes.createEncryptionCipher;
17264    break;
17265  case 'aes192':
17266    algorithm = 'AES-192-CBC';
17267    dkLen = 24;
17268    iv = forge.random.getBytesSync(16);
17269    cipherFn = forge.aes.createEncryptionCipher;
17270    break;
17271  case 'aes256':
17272    algorithm = 'AES-256-CBC';
17273    dkLen = 32;
17274    iv = forge.random.getBytesSync(16);
17275    cipherFn = forge.aes.createEncryptionCipher;
17276    break;
17277  case '3des':
17278    algorithm = 'DES-EDE3-CBC';
17279    dkLen = 24;
17280    iv = forge.random.getBytesSync(8);
17281    cipherFn = forge.des.createEncryptionCipher;
17282    break;
17283  case 'des':
17284    algorithm = 'DES-CBC';
17285    dkLen = 8;
17286    iv = forge.random.getBytesSync(8);
17287    cipherFn = forge.des.createEncryptionCipher;
17288    break;
17289  default:
17290    var error = new Error('Could not encrypt RSA private key; unsupported ' +
17291      'encryption algorithm "' + options.algorithm + '".');
17292    error.algorithm = options.algorithm;
17293    throw error;
17294  }
17295
17296  // encrypt private key using OpenSSL legacy key derivation
17297  var dk = forge.pbe.opensslDeriveBytes(password, iv.substr(0, 8), dkLen);
17298  var cipher = cipherFn(dk);
17299  cipher.start(iv);
17300  cipher.update(asn1.toDer(pki.privateKeyToAsn1(rsaKey)));
17301  cipher.finish();
17302
17303  var msg = {
17304    type: 'RSA PRIVATE KEY',
17305    procType: {
17306      version: '4',
17307      type: 'ENCRYPTED'
17308    },
17309    dekInfo: {
17310      algorithm: algorithm,
17311      parameters: forge.util.bytesToHex(iv).toUpperCase()
17312    },
17313    body: cipher.output.getBytes()
17314  };
17315  return forge.pem.encode(msg);
17316};
17317
17318/**
17319 * Decrypts an RSA private key.
17320 *
17321 * @param pem the PEM-formatted EncryptedPrivateKeyInfo to decrypt.
17322 * @param password the password to use.
17323 *
17324 * @return the RSA key on success, null on failure.
17325 */
17326pki.decryptRsaPrivateKey = function(pem, password) {
17327  var rval = null;
17328
17329  var msg = forge.pem.decode(pem)[0];
17330
17331  if(msg.type !== 'ENCRYPTED PRIVATE KEY' &&
17332    msg.type !== 'PRIVATE KEY' &&
17333    msg.type !== 'RSA PRIVATE KEY') {
17334    var error = new Error('Could not convert private key from PEM; PEM header type ' +
17335      'is not "ENCRYPTED PRIVATE KEY", "PRIVATE KEY", or "RSA PRIVATE KEY".');
17336    error.headerType = error;
17337    throw error;
17338  }
17339
17340  if(msg.procType && msg.procType.type === 'ENCRYPTED') {
17341    var dkLen;
17342    var cipherFn;
17343    switch(msg.dekInfo.algorithm) {
17344    case 'DES-CBC':
17345      dkLen = 8;
17346      cipherFn = forge.des.createDecryptionCipher;
17347      break;
17348    case 'DES-EDE3-CBC':
17349      dkLen = 24;
17350      cipherFn = forge.des.createDecryptionCipher;
17351      break;
17352    case 'AES-128-CBC':
17353      dkLen = 16;
17354      cipherFn = forge.aes.createDecryptionCipher;
17355      break;
17356    case 'AES-192-CBC':
17357      dkLen = 24;
17358      cipherFn = forge.aes.createDecryptionCipher;
17359      break;
17360    case 'AES-256-CBC':
17361      dkLen = 32;
17362      cipherFn = forge.aes.createDecryptionCipher;
17363      break;
17364    case 'RC2-40-CBC':
17365      dkLen = 5;
17366      cipherFn = function(key) {
17367        return forge.rc2.createDecryptionCipher(key, 40);
17368      };
17369      break;
17370    case 'RC2-64-CBC':
17371      dkLen = 8;
17372      cipherFn = function(key) {
17373        return forge.rc2.createDecryptionCipher(key, 64);
17374      };
17375      break;
17376    case 'RC2-128-CBC':
17377      dkLen = 16;
17378      cipherFn = function(key) {
17379        return forge.rc2.createDecryptionCipher(key, 128);
17380      };
17381      break;
17382    default:
17383      var error = new Error('Could not decrypt private key; unsupported ' +
17384        'encryption algorithm "' + msg.dekInfo.algorithm + '".');
17385      error.algorithm = msg.dekInfo.algorithm;
17386      throw error;
17387    }
17388
17389    // use OpenSSL legacy key derivation
17390    var iv = forge.util.hexToBytes(msg.dekInfo.parameters);
17391    var dk = forge.pbe.opensslDeriveBytes(password, iv.substr(0, 8), dkLen);
17392    var cipher = cipherFn(dk);
17393    cipher.start(iv);
17394    cipher.update(forge.util.createBuffer(msg.body));
17395    if(cipher.finish()) {
17396      rval = cipher.output.getBytes();
17397    } else {
17398      return rval;
17399    }
17400  } else {
17401    rval = msg.body;
17402  }
17403
17404  if(msg.type === 'ENCRYPTED PRIVATE KEY') {
17405    rval = pki.decryptPrivateKeyInfo(asn1.fromDer(rval), password);
17406  } else {
17407    // decryption already performed above
17408    rval = asn1.fromDer(rval);
17409  }
17410
17411  if(rval !== null) {
17412    rval = pki.privateKeyFromAsn1(rval);
17413  }
17414
17415  return rval;
17416};
17417
17418/**
17419 * Derives a PKCS#12 key.
17420 *
17421 * @param password the password to derive the key material from, null or
17422 *          undefined for none.
17423 * @param salt the salt, as a ByteBuffer, to use.
17424 * @param id the PKCS#12 ID byte (1 = key material, 2 = IV, 3 = MAC).
17425 * @param iter the iteration count.
17426 * @param n the number of bytes to derive from the password.
17427 * @param md the message digest to use, defaults to SHA-1.
17428 *
17429 * @return a ByteBuffer with the bytes derived from the password.
17430 */
17431pki.pbe.generatePkcs12Key = function(password, salt, id, iter, n, md) {
17432  var j, l;
17433
17434  if(typeof md === 'undefined' || md === null) {
17435    md = forge.md.sha1.create();
17436  }
17437
17438  var u = md.digestLength;
17439  var v = md.blockLength;
17440  var result = new forge.util.ByteBuffer();
17441
17442  /* Convert password to Unicode byte buffer + trailing 0-byte. */
17443  var passBuf = new forge.util.ByteBuffer();
17444  if(password !== null && password !== undefined) {
17445    for(l = 0; l < password.length; l++) {
17446      passBuf.putInt16(password.charCodeAt(l));
17447    }
17448    passBuf.putInt16(0);
17449  }
17450
17451  /* Length of salt and password in BYTES. */
17452  var p = passBuf.length();
17453  var s = salt.length();
17454
17455  /* 1. Construct a string, D (the "diversifier"), by concatenating
17456        v copies of ID. */
17457  var D = new forge.util.ByteBuffer();
17458  D.fillWithByte(id, v);
17459
17460  /* 2. Concatenate copies of the salt together to create a string S of length
17461        v * ceil(s / v) bytes (the final copy of the salt may be trunacted
17462        to create S).
17463        Note that if the salt is the empty string, then so is S. */
17464  var Slen = v * Math.ceil(s / v);
17465  var S = new forge.util.ByteBuffer();
17466  for(l = 0; l < Slen; l ++) {
17467    S.putByte(salt.at(l % s));
17468  }
17469
17470  /* 3. Concatenate copies of the password together to create a string P of
17471        length v * ceil(p / v) bytes (the final copy of the password may be
17472        truncated to create P).
17473        Note that if the password is the empty string, then so is P. */
17474  var Plen = v * Math.ceil(p / v);
17475  var P = new forge.util.ByteBuffer();
17476  for(l = 0; l < Plen; l ++) {
17477    P.putByte(passBuf.at(l % p));
17478  }
17479
17480  /* 4. Set I=S||P to be the concatenation of S and P. */
17481  var I = S;
17482  I.putBuffer(P);
17483
17484  /* 5. Set c=ceil(n / u). */
17485  var c = Math.ceil(n / u);
17486
17487  /* 6. For i=1, 2, ..., c, do the following: */
17488  for(var i = 1; i <= c; i ++) {
17489    /* a) Set Ai=H^r(D||I). (l.e. the rth hash of D||I, H(H(H(...H(D||I)))) */
17490    var buf = new forge.util.ByteBuffer();
17491    buf.putBytes(D.bytes());
17492    buf.putBytes(I.bytes());
17493    for(var round = 0; round < iter; round ++) {
17494      md.start();
17495      md.update(buf.getBytes());
17496      buf = md.digest();
17497    }
17498
17499    /* b) Concatenate copies of Ai to create a string B of length v bytes (the
17500          final copy of Ai may be truncated to create B). */
17501    var B = new forge.util.ByteBuffer();
17502    for(l = 0; l < v; l ++) {
17503      B.putByte(buf.at(l % u));
17504    }
17505
17506    /* c) Treating I as a concatenation I0, I1, ..., Ik-1 of v-byte blocks,
17507          where k=ceil(s / v) + ceil(p / v), modify I by setting
17508          Ij=(Ij+B+1) mod 2v for each j.  */
17509    var k = Math.ceil(s / v) + Math.ceil(p / v);
17510    var Inew = new forge.util.ByteBuffer();
17511    for(j = 0; j < k; j ++) {
17512      var chunk = new forge.util.ByteBuffer(I.getBytes(v));
17513      var x = 0x1ff;
17514      for(l = B.length() - 1; l >= 0; l --) {
17515        x = x >> 8;
17516        x += B.at(l) + chunk.at(l);
17517        chunk.setAt(l, x & 0xff);
17518      }
17519      Inew.putBuffer(chunk);
17520    }
17521    I = Inew;
17522
17523    /* Add Ai to A. */
17524    result.putBuffer(buf);
17525  }
17526
17527  result.truncate(result.length() - n);
17528  return result;
17529};
17530
17531/**
17532 * Get new Forge cipher object instance.
17533 *
17534 * @param oid the OID (in string notation).
17535 * @param params the ASN.1 params object.
17536 * @param password the password to decrypt with.
17537 *
17538 * @return new cipher object instance.
17539 */
17540pki.pbe.getCipher = function(oid, params, password) {
17541  switch(oid) {
17542  case pki.oids['pkcs5PBES2']:
17543    return pki.pbe.getCipherForPBES2(oid, params, password);
17544
17545  case pki.oids['pbeWithSHAAnd3-KeyTripleDES-CBC']:
17546  case pki.oids['pbewithSHAAnd40BitRC2-CBC']:
17547    return pki.pbe.getCipherForPKCS12PBE(oid, params, password);
17548
17549  default:
17550    var error = new Error('Cannot read encrypted PBE data block. Unsupported OID.');
17551    error.oid = oid;
17552    error.supportedOids = [
17553      'pkcs5PBES2',
17554      'pbeWithSHAAnd3-KeyTripleDES-CBC',
17555      'pbewithSHAAnd40BitRC2-CBC'
17556    ];
17557    throw error;
17558  }
17559};
17560
17561/**
17562 * Get new Forge cipher object instance according to PBES2 params block.
17563 *
17564 * The returned cipher instance is already started using the IV
17565 * from PBES2 parameter block.
17566 *
17567 * @param oid the PKCS#5 PBKDF2 OID (in string notation).
17568 * @param params the ASN.1 PBES2-params object.
17569 * @param password the password to decrypt with.
17570 *
17571 * @return new cipher object instance.
17572 */
17573pki.pbe.getCipherForPBES2 = function(oid, params, password) {
17574  // get PBE params
17575  var capture = {};
17576  var errors = [];
17577  if(!asn1.validate(params, PBES2AlgorithmsValidator, capture, errors)) {
17578    var error = new Error('Cannot read password-based-encryption algorithm ' +
17579      'parameters. ASN.1 object is not a supported EncryptedPrivateKeyInfo.');
17580    error.errors = errors;
17581    throw error;
17582  }
17583
17584  // check oids
17585  oid = asn1.derToOid(capture.kdfOid);
17586  if(oid !== pki.oids['pkcs5PBKDF2']) {
17587    var error = new Error('Cannot read encrypted private key. ' +
17588      'Unsupported key derivation function OID.');
17589    error.oid = oid;
17590    error.supportedOids = ['pkcs5PBKDF2'];
17591    throw error;
17592  }
17593  oid = asn1.derToOid(capture.encOid);
17594  if(oid !== pki.oids['aes128-CBC'] &&
17595    oid !== pki.oids['aes192-CBC'] &&
17596    oid !== pki.oids['aes256-CBC'] &&
17597    oid !== pki.oids['des-EDE3-CBC'] &&
17598    oid !== pki.oids['desCBC']) {
17599    var error = new Error('Cannot read encrypted private key. ' +
17600      'Unsupported encryption scheme OID.');
17601    error.oid = oid;
17602    error.supportedOids = [
17603      'aes128-CBC', 'aes192-CBC', 'aes256-CBC', 'des-EDE3-CBC', 'desCBC'];
17604    throw error;
17605  }
17606
17607  // set PBE params
17608  var salt = capture.kdfSalt;
17609  var count = forge.util.createBuffer(capture.kdfIterationCount);
17610  count = count.getInt(count.length() << 3);
17611  var dkLen;
17612  var cipherFn;
17613  switch(pki.oids[oid]) {
17614  case 'aes128-CBC':
17615    dkLen = 16;
17616    cipherFn = forge.aes.createDecryptionCipher;
17617    break;
17618  case 'aes192-CBC':
17619    dkLen = 24;
17620    cipherFn = forge.aes.createDecryptionCipher;
17621    break;
17622  case 'aes256-CBC':
17623    dkLen = 32;
17624    cipherFn = forge.aes.createDecryptionCipher;
17625    break;
17626  case 'des-EDE3-CBC':
17627    dkLen = 24;
17628    cipherFn = forge.des.createDecryptionCipher;
17629    break;
17630  case 'desCBC':
17631    dkLen = 8;
17632    cipherFn = forge.des.createDecryptionCipher;
17633    break;
17634  }
17635
17636  // get PRF message digest
17637  var md = prfOidToMessageDigest(capture.prfOid);
17638
17639  // decrypt private key using pbe with chosen PRF and AES/DES
17640  var dk = forge.pkcs5.pbkdf2(password, salt, count, dkLen, md);
17641  var iv = capture.encIv;
17642  var cipher = cipherFn(dk);
17643  cipher.start(iv);
17644
17645  return cipher;
17646};
17647
17648/**
17649 * Get new Forge cipher object instance for PKCS#12 PBE.
17650 *
17651 * The returned cipher instance is already started using the key & IV
17652 * derived from the provided password and PKCS#12 PBE salt.
17653 *
17654 * @param oid The PKCS#12 PBE OID (in string notation).
17655 * @param params The ASN.1 PKCS#12 PBE-params object.
17656 * @param password The password to decrypt with.
17657 *
17658 * @return the new cipher object instance.
17659 */
17660pki.pbe.getCipherForPKCS12PBE = function(oid, params, password) {
17661  // get PBE params
17662  var capture = {};
17663  var errors = [];
17664  if(!asn1.validate(params, pkcs12PbeParamsValidator, capture, errors)) {
17665    var error = new Error('Cannot read password-based-encryption algorithm ' +
17666      'parameters. ASN.1 object is not a supported EncryptedPrivateKeyInfo.');
17667    error.errors = errors;
17668    throw error;
17669  }
17670
17671  var salt = forge.util.createBuffer(capture.salt);
17672  var count = forge.util.createBuffer(capture.iterations);
17673  count = count.getInt(count.length() << 3);
17674
17675  var dkLen, dIvLen, cipherFn;
17676  switch(oid) {
17677    case pki.oids['pbeWithSHAAnd3-KeyTripleDES-CBC']:
17678      dkLen = 24;
17679      dIvLen = 8;
17680      cipherFn = forge.des.startDecrypting;
17681      break;
17682
17683    case pki.oids['pbewithSHAAnd40BitRC2-CBC']:
17684      dkLen = 5;
17685      dIvLen = 8;
17686      cipherFn = function(key, iv) {
17687        var cipher = forge.rc2.createDecryptionCipher(key, 40);
17688        cipher.start(iv, null);
17689        return cipher;
17690      };
17691      break;
17692
17693    default:
17694      var error = new Error('Cannot read PKCS #12 PBE data block. Unsupported OID.');
17695      error.oid = oid;
17696      throw error;
17697  }
17698
17699  // get PRF message digest
17700  var md = prfOidToMessageDigest(capture.prfOid);
17701  var key = pki.pbe.generatePkcs12Key(password, salt, 1, count, dkLen, md);
17702  md.start();
17703  var iv = pki.pbe.generatePkcs12Key(password, salt, 2, count, dIvLen, md);
17704
17705  return cipherFn(key, iv);
17706};
17707
17708/**
17709 * OpenSSL's legacy key derivation function.
17710 *
17711 * See: http://www.openssl.org/docs/crypto/EVP_BytesToKey.html
17712 *
17713 * @param password the password to derive the key from.
17714 * @param salt the salt to use, null for none.
17715 * @param dkLen the number of bytes needed for the derived key.
17716 * @param [options] the options to use:
17717 *          [md] an optional message digest object to use.
17718 */
17719pki.pbe.opensslDeriveBytes = function(password, salt, dkLen, md) {
17720  if(typeof md === 'undefined' || md === null) {
17721    md = forge.md.md5.create();
17722  }
17723  if(salt === null) {
17724    salt = '';
17725  }
17726  var digests = [hash(md, password + salt)];
17727  for(var length = 16, i = 1; length < dkLen; ++i, length += 16) {
17728    digests.push(hash(md, digests[i - 1] + password + salt));
17729  }
17730  return digests.join('').substr(0, dkLen);
17731};
17732
17733function hash(md, bytes) {
17734  return md.start().update(bytes).digest().getBytes();
17735}
17736
17737function prfOidToMessageDigest(prfOid) {
17738  // get PRF algorithm, default to SHA-1
17739  var prfAlgorithm;
17740  if(!prfOid) {
17741    prfAlgorithm = 'hmacWithSHA1';
17742  } else {
17743    prfAlgorithm = pki.oids[asn1.derToOid(prfOid)];
17744    if(!prfAlgorithm) {
17745      var error = new Error('Unsupported PRF OID.');
17746      error.oid = prfOid;
17747      error.supported = [
17748        'hmacWithSHA1', 'hmacWithSHA224', 'hmacWithSHA256', 'hmacWithSHA384',
17749        'hmacWithSHA512'];
17750      throw error;
17751    }
17752  }
17753  return prfAlgorithmToMessageDigest(prfAlgorithm);
17754}
17755
17756function prfAlgorithmToMessageDigest(prfAlgorithm) {
17757  var factory = forge.md;
17758  switch(prfAlgorithm) {
17759  case 'hmacWithSHA224':
17760    factory = forge.md.sha512;
17761  case 'hmacWithSHA1':
17762  case 'hmacWithSHA256':
17763  case 'hmacWithSHA384':
17764  case 'hmacWithSHA512':
17765    prfAlgorithm = prfAlgorithm.substr(8).toLowerCase();
17766    break;
17767  default:
17768    var error = new Error('Unsupported PRF algorithm.');
17769    error.algorithm = prfAlgorithm;
17770    error.supported = [
17771      'hmacWithSHA1', 'hmacWithSHA224', 'hmacWithSHA256', 'hmacWithSHA384',
17772      'hmacWithSHA512'];
17773    throw error;
17774  }
17775  return factory[prfAlgorithm].create();
17776}
17777
17778function createPbkdf2Params(salt, countBytes, dkLen, prfAlgorithm) {
17779  var params = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
17780    // salt
17781    asn1.create(
17782      asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, salt),
17783    // iteration count
17784    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false,
17785      countBytes.getBytes())
17786  ]);
17787  // when PRF algorithm is not SHA-1 default, add key length and PRF algorithm
17788  if(prfAlgorithm !== 'hmacWithSHA1') {
17789    params.value.push(
17790      // key length
17791      asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false,
17792        forge.util.hexToBytes(dkLen.toString(16))),
17793      // AlgorithmIdentifier
17794      asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
17795        // algorithm
17796        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
17797          asn1.oidToDer(pki.oids[prfAlgorithm]).getBytes()),
17798        // parameters (null)
17799        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, '')
17800      ]));
17801  }
17802  return params;
17803}
17804
17805} // end module implementation
17806
17807/* ########## Begin module wrapper ########## */
17808var name = 'pbe';
17809if(typeof define !== 'function') {
17810  // NodeJS -> AMD
17811  if(typeof module === 'object' && module.exports) {
17812    var nodeJS = true;
17813    define = function(ids, factory) {
17814      factory(require, module);
17815    };
17816  } else {
17817    // <script>
17818    if(typeof forge === 'undefined') {
17819      forge = {};
17820    }
17821    return initModule(forge);
17822  }
17823}
17824// AMD
17825var deps;
17826var defineFunc = function(require, module) {
17827  module.exports = function(forge) {
17828    var mods = deps.map(function(dep) {
17829      return require(dep);
17830    }).concat(initModule);
17831    // handle circular dependencies
17832    forge = forge || {};
17833    forge.defined = forge.defined || {};
17834    if(forge.defined[name]) {
17835      return forge[name];
17836    }
17837    forge.defined[name] = true;
17838    for(var i = 0; i < mods.length; ++i) {
17839      mods[i](forge);
17840    }
17841    return forge[name];
17842  };
17843};
17844var tmpDefine = define;
17845define = function(ids, factory) {
17846  deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2);
17847  if(nodeJS) {
17848    delete define;
17849    return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0));
17850  }
17851  define = tmpDefine;
17852  return define.apply(null, Array.prototype.slice.call(arguments, 0));
17853};
17854define([
17855  'require',
17856  'module',
17857  './aes',
17858  './asn1',
17859  './des',
17860  './md',
17861  './oids',
17862  './pem',
17863  './pbkdf2',
17864  './random',
17865  './rc2',
17866  './rsa',
17867  './util'
17868], function() {
17869  defineFunc.apply(null, Array.prototype.slice.call(arguments, 0));
17870});
17871})();
17872
17873/**
17874 * Hash-based Message Authentication Code implementation. Requires a message
17875 * digest object that can be obtained, for example, from forge.md.sha1 or
17876 * forge.md.md5.
17877 *
17878 * @author Dave Longley
17879 *
17880 * Copyright (c) 2010-2012 Digital Bazaar, Inc. All rights reserved.
17881 */
17882(function() {
17883/* ########## Begin module implementation ########## */
17884function initModule(forge) {
17885
17886/* HMAC API */
17887var hmac = forge.hmac = forge.hmac || {};
17888
17889/**
17890 * Creates an HMAC object that uses the given message digest object.
17891 *
17892 * @return an HMAC object.
17893 */
17894hmac.create = function() {
17895  // the hmac key to use
17896  var _key = null;
17897
17898  // the message digest to use
17899  var _md = null;
17900
17901  // the inner padding
17902  var _ipadding = null;
17903
17904  // the outer padding
17905  var _opadding = null;
17906
17907  // hmac context
17908  var ctx = {};
17909
17910  /**
17911   * Starts or restarts the HMAC with the given key and message digest.
17912   *
17913   * @param md the message digest to use, null to reuse the previous one,
17914   *           a string to use builtin 'sha1', 'md5', 'sha256'.
17915   * @param key the key to use as a string, array of bytes, byte buffer,
17916   *           or null to reuse the previous key.
17917   */
17918  ctx.start = function(md, key) {
17919    if(md !== null) {
17920      if(typeof md === 'string') {
17921        // create builtin message digest
17922        md = md.toLowerCase();
17923        if(md in forge.md.algorithms) {
17924          _md = forge.md.algorithms[md].create();
17925        } else {
17926          throw new Error('Unknown hash algorithm "' + md + '"');
17927        }
17928      } else {
17929        // store message digest
17930        _md = md;
17931      }
17932    }
17933
17934    if(key === null) {
17935      // reuse previous key
17936      key = _key;
17937    } else {
17938      if(typeof key === 'string') {
17939        // convert string into byte buffer
17940        key = forge.util.createBuffer(key);
17941      } else if(forge.util.isArray(key)) {
17942        // convert byte array into byte buffer
17943        var tmp = key;
17944        key = forge.util.createBuffer();
17945        for(var i = 0; i < tmp.length; ++i) {
17946          key.putByte(tmp[i]);
17947        }
17948      }
17949
17950      // if key is longer than blocksize, hash it
17951      var keylen = key.length();
17952      if(keylen > _md.blockLength) {
17953        _md.start();
17954        _md.update(key.bytes());
17955        key = _md.digest();
17956      }
17957
17958      // mix key into inner and outer padding
17959      // ipadding = [0x36 * blocksize] ^ key
17960      // opadding = [0x5C * blocksize] ^ key
17961      _ipadding = forge.util.createBuffer();
17962      _opadding = forge.util.createBuffer();
17963      keylen = key.length();
17964      for(var i = 0; i < keylen; ++i) {
17965        var tmp = key.at(i);
17966        _ipadding.putByte(0x36 ^ tmp);
17967        _opadding.putByte(0x5C ^ tmp);
17968      }
17969
17970      // if key is shorter than blocksize, add additional padding
17971      if(keylen < _md.blockLength) {
17972        var tmp = _md.blockLength - keylen;
17973        for(var i = 0; i < tmp; ++i) {
17974          _ipadding.putByte(0x36);
17975          _opadding.putByte(0x5C);
17976        }
17977      }
17978      _key = key;
17979      _ipadding = _ipadding.bytes();
17980      _opadding = _opadding.bytes();
17981    }
17982
17983    // digest is done like so: hash(opadding | hash(ipadding | message))
17984
17985    // prepare to do inner hash
17986    // hash(ipadding | message)
17987    _md.start();
17988    _md.update(_ipadding);
17989  };
17990
17991  /**
17992   * Updates the HMAC with the given message bytes.
17993   *
17994   * @param bytes the bytes to update with.
17995   */
17996  ctx.update = function(bytes) {
17997    _md.update(bytes);
17998  };
17999
18000  /**
18001   * Produces the Message Authentication Code (MAC).
18002   *
18003   * @return a byte buffer containing the digest value.
18004   */
18005  ctx.getMac = function() {
18006    // digest is done like so: hash(opadding | hash(ipadding | message))
18007    // here we do the outer hashing
18008    var inner = _md.digest().bytes();
18009    _md.start();
18010    _md.update(_opadding);
18011    _md.update(inner);
18012    return _md.digest();
18013  };
18014  // alias for getMac
18015  ctx.digest = ctx.getMac;
18016
18017  return ctx;
18018};
18019
18020} // end module implementation
18021
18022/* ########## Begin module wrapper ########## */
18023var name = 'hmac';
18024if(typeof define !== 'function') {
18025  // NodeJS -> AMD
18026  if(typeof module === 'object' && module.exports) {
18027    var nodeJS = true;
18028    define = function(ids, factory) {
18029      factory(require, module);
18030    };
18031  } else {
18032    // <script>
18033    if(typeof forge === 'undefined') {
18034      forge = {};
18035    }
18036    return initModule(forge);
18037  }
18038}
18039// AMD
18040var deps;
18041var defineFunc = function(require, module) {
18042  module.exports = function(forge) {
18043    var mods = deps.map(function(dep) {
18044      return require(dep);
18045    }).concat(initModule);
18046    // handle circular dependencies
18047    forge = forge || {};
18048    forge.defined = forge.defined || {};
18049    if(forge.defined[name]) {
18050      return forge[name];
18051    }
18052    forge.defined[name] = true;
18053    for(var i = 0; i < mods.length; ++i) {
18054      mods[i](forge);
18055    }
18056    return forge[name];
18057  };
18058};
18059var tmpDefine = define;
18060define = function(ids, factory) {
18061  deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2);
18062  if(nodeJS) {
18063    delete define;
18064    return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0));
18065  }
18066  define = tmpDefine;
18067  return define.apply(null, Array.prototype.slice.call(arguments, 0));
18068};
18069define(['require', 'module', './md', './util'], function() {
18070  defineFunc.apply(null, Array.prototype.slice.call(arguments, 0));
18071});
18072})();
18073
18074/**
18075 * Password-Based Key-Derivation Function #2 implementation.
18076 *
18077 * See RFC 2898 for details.
18078 *
18079 * @author Dave Longley
18080 *
18081 * Copyright (c) 2010-2013 Digital Bazaar, Inc.
18082 */
18083(function() {
18084/* ########## Begin module implementation ########## */
18085function initModule(forge) {
18086
18087var pkcs5 = forge.pkcs5 = forge.pkcs5 || {};
18088
18089var _nodejs = (
18090  typeof process !== 'undefined' && process.versions && process.versions.node);
18091var crypto;
18092if(_nodejs && !forge.disableNativeCode) {
18093  crypto = require('crypto');
18094}
18095
18096/**
18097 * Derives a key from a password.
18098 *
18099 * @param p the password as a binary-encoded string of bytes.
18100 * @param s the salt as a binary-encoded string of bytes.
18101 * @param c the iteration count, a positive integer.
18102 * @param dkLen the intended length, in bytes, of the derived key,
18103 *          (max: 2^32 - 1) * hash length of the PRF.
18104 * @param [md] the message digest (or algorithm identifier as a string) to use
18105 *          in the PRF, defaults to SHA-1.
18106 * @param [callback(err, key)] presence triggers asynchronous version, called
18107 *          once the operation completes.
18108 *
18109 * @return the derived key, as a binary-encoded string of bytes, for the
18110 *           synchronous version (if no callback is specified).
18111 */
18112forge.pbkdf2 = pkcs5.pbkdf2 = function(p, s, c, dkLen, md, callback) {
18113  if(typeof md === 'function') {
18114    callback = md;
18115    md = null;
18116  }
18117
18118  // use native implementation if possible and not disabled, note that
18119  // some node versions only support SHA-1, others allow digest to be changed
18120  if(_nodejs && !forge.disableNativeCode && crypto.pbkdf2 &&
18121    (md === null || typeof md !== 'object') &&
18122    (crypto.pbkdf2Sync.length > 4 || (!md || md === 'sha1'))) {
18123    if(typeof md !== 'string') {
18124      // default prf to SHA-1
18125      md = 'sha1';
18126    }
18127    s = new Buffer(s, 'binary');
18128    if(!callback) {
18129      if(crypto.pbkdf2Sync.length === 4) {
18130        return crypto.pbkdf2Sync(p, s, c, dkLen).toString('binary');
18131      }
18132      return crypto.pbkdf2Sync(p, s, c, dkLen, md).toString('binary');
18133    }
18134    if(crypto.pbkdf2Sync.length === 4) {
18135      return crypto.pbkdf2(p, s, c, dkLen, function(err, key) {
18136        if(err) {
18137          return callback(err);
18138        }
18139        callback(null, key.toString('binary'));
18140      });
18141    }
18142    return crypto.pbkdf2(p, s, c, dkLen, md, function(err, key) {
18143      if(err) {
18144        return callback(err);
18145      }
18146      callback(null, key.toString('binary'));
18147    });
18148  }
18149
18150  if(typeof md === 'undefined' || md === null) {
18151    // default prf to SHA-1
18152    md = forge.md.sha1.create();
18153  }
18154  if(typeof md === 'string') {
18155    if(!(md in forge.md.algorithms)) {
18156      throw new Error('Unknown hash algorithm: ' + md);
18157    }
18158    md = forge.md[md].create();
18159  }
18160
18161  var hLen = md.digestLength;
18162
18163  /* 1. If dkLen > (2^32 - 1) * hLen, output "derived key too long" and
18164    stop. */
18165  if(dkLen > (0xFFFFFFFF * hLen)) {
18166    var err = new Error('Derived key is too long.');
18167    if(callback) {
18168      return callback(err);
18169    }
18170    throw err;
18171  }
18172
18173  /* 2. Let len be the number of hLen-octet blocks in the derived key,
18174    rounding up, and let r be the number of octets in the last
18175    block:
18176
18177    len = CEIL(dkLen / hLen),
18178    r = dkLen - (len - 1) * hLen. */
18179  var len = Math.ceil(dkLen / hLen);
18180  var r = dkLen - (len - 1) * hLen;
18181
18182  /* 3. For each block of the derived key apply the function F defined
18183    below to the password P, the salt S, the iteration count c, and
18184    the block index to compute the block:
18185
18186    T_1 = F(P, S, c, 1),
18187    T_2 = F(P, S, c, 2),
18188    ...
18189    T_len = F(P, S, c, len),
18190
18191    where the function F is defined as the exclusive-or sum of the
18192    first c iterates of the underlying pseudorandom function PRF
18193    applied to the password P and the concatenation of the salt S
18194    and the block index i:
18195
18196    F(P, S, c, i) = u_1 XOR u_2 XOR ... XOR u_c
18197
18198    where
18199
18200    u_1 = PRF(P, S || INT(i)),
18201    u_2 = PRF(P, u_1),
18202    ...
18203    u_c = PRF(P, u_{c-1}).
18204
18205    Here, INT(i) is a four-octet encoding of the integer i, most
18206    significant octet first. */
18207  var prf = forge.hmac.create();
18208  prf.start(md, p);
18209  var dk = '';
18210  var xor, u_c, u_c1;
18211
18212  // sync version
18213  if(!callback) {
18214    for(var i = 1; i <= len; ++i) {
18215      // PRF(P, S || INT(i)) (first iteration)
18216      prf.start(null, null);
18217      prf.update(s);
18218      prf.update(forge.util.int32ToBytes(i));
18219      xor = u_c1 = prf.digest().getBytes();
18220
18221      // PRF(P, u_{c-1}) (other iterations)
18222      for(var j = 2; j <= c; ++j) {
18223        prf.start(null, null);
18224        prf.update(u_c1);
18225        u_c = prf.digest().getBytes();
18226        // F(p, s, c, i)
18227        xor = forge.util.xorBytes(xor, u_c, hLen);
18228        u_c1 = u_c;
18229      }
18230
18231      /* 4. Concatenate the blocks and extract the first dkLen octets to
18232        produce a derived key DK:
18233
18234        DK = T_1 || T_2 ||  ...  || T_len<0..r-1> */
18235      dk += (i < len) ? xor : xor.substr(0, r);
18236    }
18237    /* 5. Output the derived key DK. */
18238    return dk;
18239  }
18240
18241  // async version
18242  var i = 1, j;
18243  function outer() {
18244    if(i > len) {
18245      // done
18246      return callback(null, dk);
18247    }
18248
18249    // PRF(P, S || INT(i)) (first iteration)
18250    prf.start(null, null);
18251    prf.update(s);
18252    prf.update(forge.util.int32ToBytes(i));
18253    xor = u_c1 = prf.digest().getBytes();
18254
18255    // PRF(P, u_{c-1}) (other iterations)
18256    j = 2;
18257    inner();
18258  }
18259
18260  function inner() {
18261    if(j <= c) {
18262      prf.start(null, null);
18263      prf.update(u_c1);
18264      u_c = prf.digest().getBytes();
18265      // F(p, s, c, i)
18266      xor = forge.util.xorBytes(xor, u_c, hLen);
18267      u_c1 = u_c;
18268      ++j;
18269      return forge.util.setImmediate(inner);
18270    }
18271
18272    /* 4. Concatenate the blocks and extract the first dkLen octets to
18273      produce a derived key DK:
18274
18275      DK = T_1 || T_2 ||  ...  || T_len<0..r-1> */
18276    dk += (i < len) ? xor : xor.substr(0, r);
18277
18278    ++i;
18279    outer();
18280  }
18281
18282  outer();
18283};
18284
18285} // end module implementation
18286
18287/* ########## Begin module wrapper ########## */
18288var name = 'pbkdf2';
18289if(typeof define !== 'function') {
18290  // NodeJS -> AMD
18291  if(typeof module === 'object' && module.exports) {
18292    var nodeJS = true;
18293    define = function(ids, factory) {
18294      factory(require, module);
18295    };
18296  } else {
18297    // <script>
18298    if(typeof forge === 'undefined') {
18299      forge = {};
18300    }
18301    return initModule(forge);
18302  }
18303}
18304// AMD
18305var deps;
18306var defineFunc = function(require, module) {
18307  module.exports = function(forge) {
18308    var mods = deps.map(function(dep) {
18309      return require(dep);
18310    }).concat(initModule);
18311    // handle circular dependencies
18312    forge = forge || {};
18313    forge.defined = forge.defined || {};
18314    if(forge.defined[name]) {
18315      return forge[name];
18316    }
18317    forge.defined[name] = true;
18318    for(var i = 0; i < mods.length; ++i) {
18319      mods[i](forge);
18320    }
18321    return forge[name];
18322  };
18323};
18324var tmpDefine = define;
18325define = function(ids, factory) {
18326  deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2);
18327  if(nodeJS) {
18328    delete define;
18329    return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0));
18330  }
18331  define = tmpDefine;
18332  return define.apply(null, Array.prototype.slice.call(arguments, 0));
18333};
18334define(['require', 'module', './hmac', './md', './util'], function() {
18335  defineFunc.apply(null, Array.prototype.slice.call(arguments, 0));
18336});
18337})();
18338
18339/**
18340 * Javascript implementation of PKCS#12.
18341 *
18342 * @author Dave Longley
18343 * @author Stefan Siegl <[email protected]>
18344 *
18345 * Copyright (c) 2010-2014 Digital Bazaar, Inc.
18346 * Copyright (c) 2012 Stefan Siegl <[email protected]>
18347 *
18348 * The ASN.1 representation of PKCS#12 is as follows
18349 * (see ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-12/pkcs-12-tc1.pdf for details)
18350 *
18351 * PFX ::= SEQUENCE {
18352 *   version  INTEGER {v3(3)}(v3,...),
18353 *   authSafe ContentInfo,
18354 *   macData  MacData OPTIONAL
18355 * }
18356 *
18357 * MacData ::= SEQUENCE {
18358 *   mac DigestInfo,
18359 *   macSalt OCTET STRING,
18360 *   iterations INTEGER DEFAULT 1
18361 * }
18362 * Note: The iterations default is for historical reasons and its use is
18363 * deprecated. A higher value, like 1024, is recommended.
18364 *
18365 * DigestInfo is defined in PKCS#7 as follows:
18366 *
18367 * DigestInfo ::= SEQUENCE {
18368 *   digestAlgorithm DigestAlgorithmIdentifier,
18369 *   digest Digest
18370 * }
18371 *
18372 * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
18373 *
18374 * The AlgorithmIdentifier contains an Object Identifier (OID) and parameters
18375 * for the algorithm, if any. In the case of SHA1 there is none.
18376 *
18377 * AlgorithmIdentifer ::= SEQUENCE {
18378 *    algorithm OBJECT IDENTIFIER,
18379 *    parameters ANY DEFINED BY algorithm OPTIONAL
18380 * }
18381 *
18382 * Digest ::= OCTET STRING
18383 *
18384 *
18385 * ContentInfo ::= SEQUENCE {
18386 *   contentType ContentType,
18387 *   content     [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL
18388 * }
18389 *
18390 * ContentType ::= OBJECT IDENTIFIER
18391 *
18392 * AuthenticatedSafe ::= SEQUENCE OF ContentInfo
18393 * -- Data if unencrypted
18394 * -- EncryptedData if password-encrypted
18395 * -- EnvelopedData if public key-encrypted
18396 *
18397 *
18398 * SafeContents ::= SEQUENCE OF SafeBag
18399 *
18400 * SafeBag ::= SEQUENCE {
18401 *   bagId     BAG-TYPE.&id ({PKCS12BagSet})
18402 *   bagValue  [0] EXPLICIT BAG-TYPE.&Type({PKCS12BagSet}{@bagId}),
18403 *   bagAttributes SET OF PKCS12Attribute OPTIONAL
18404 * }
18405 *
18406 * PKCS12Attribute ::= SEQUENCE {
18407 *   attrId ATTRIBUTE.&id ({PKCS12AttrSet}),
18408 *   attrValues SET OF ATTRIBUTE.&Type ({PKCS12AttrSet}{@attrId})
18409 * } -- This type is compatible with the X.500 type �Attribute�
18410 *
18411 * PKCS12AttrSet ATTRIBUTE ::= {
18412 *   friendlyName | -- from PKCS #9
18413 *   localKeyId, -- from PKCS #9
18414 *   ... -- Other attributes are allowed
18415 * }
18416 *
18417 * CertBag ::= SEQUENCE {
18418 *   certId    BAG-TYPE.&id   ({CertTypes}),
18419 *   certValue [0] EXPLICIT BAG-TYPE.&Type ({CertTypes}{@certId})
18420 * }
18421 *
18422 * x509Certificate BAG-TYPE ::= {OCTET STRING IDENTIFIED BY {certTypes 1}}
18423 *   -- DER-encoded X.509 certificate stored in OCTET STRING
18424 *
18425 * sdsiCertificate BAG-TYPE ::= {IA5String IDENTIFIED BY {certTypes 2}}
18426 * -- Base64-encoded SDSI certificate stored in IA5String
18427 *
18428 * CertTypes BAG-TYPE ::= {
18429 *   x509Certificate |
18430 *   sdsiCertificate,
18431 *   ... -- For future extensions
18432 * }
18433 */
18434(function() {
18435/* ########## Begin module implementation ########## */
18436function initModule(forge) {
18437
18438// shortcut for asn.1 & PKI API
18439var asn1 = forge.asn1;
18440var pki = forge.pki;
18441
18442// shortcut for PKCS#12 API
18443var p12 = forge.pkcs12 = forge.pkcs12 || {};
18444
18445var contentInfoValidator = {
18446  name: 'ContentInfo',
18447  tagClass: asn1.Class.UNIVERSAL,
18448  type: asn1.Type.SEQUENCE,  // a ContentInfo
18449  constructed: true,
18450  value: [{
18451    name: 'ContentInfo.contentType',
18452    tagClass: asn1.Class.UNIVERSAL,
18453    type: asn1.Type.OID,
18454    constructed: false,
18455    capture: 'contentType'
18456  }, {
18457    name: 'ContentInfo.content',
18458    tagClass: asn1.Class.CONTEXT_SPECIFIC,
18459    constructed: true,
18460    captureAsn1: 'content'
18461  }]
18462};
18463
18464var pfxValidator = {
18465  name: 'PFX',
18466  tagClass: asn1.Class.UNIVERSAL,
18467  type: asn1.Type.SEQUENCE,
18468  constructed: true,
18469  value: [{
18470    name: 'PFX.version',
18471    tagClass: asn1.Class.UNIVERSAL,
18472    type: asn1.Type.INTEGER,
18473    constructed: false,
18474    capture: 'version'
18475  },
18476  contentInfoValidator, {
18477    name: 'PFX.macData',
18478    tagClass: asn1.Class.UNIVERSAL,
18479    type: asn1.Type.SEQUENCE,
18480    constructed: true,
18481    optional: true,
18482    captureAsn1: 'mac',
18483    value: [{
18484      name: 'PFX.macData.mac',
18485      tagClass: asn1.Class.UNIVERSAL,
18486      type: asn1.Type.SEQUENCE,  // DigestInfo
18487      constructed: true,
18488      value: [{
18489        name: 'PFX.macData.mac.digestAlgorithm',
18490        tagClass: asn1.Class.UNIVERSAL,
18491        type: asn1.Type.SEQUENCE,  // DigestAlgorithmIdentifier
18492        constructed: true,
18493        value: [{
18494          name: 'PFX.macData.mac.digestAlgorithm.algorithm',
18495          tagClass: asn1.Class.UNIVERSAL,
18496          type: asn1.Type.OID,
18497          constructed: false,
18498          capture: 'macAlgorithm'
18499        }, {
18500          name: 'PFX.macData.mac.digestAlgorithm.parameters',
18501          tagClass: asn1.Class.UNIVERSAL,
18502          captureAsn1: 'macAlgorithmParameters'
18503        }]
18504      }, {
18505        name: 'PFX.macData.mac.digest',
18506        tagClass: asn1.Class.UNIVERSAL,
18507        type: asn1.Type.OCTETSTRING,
18508        constructed: false,
18509        capture: 'macDigest'
18510      }]
18511    }, {
18512      name: 'PFX.macData.macSalt',
18513      tagClass: asn1.Class.UNIVERSAL,
18514      type: asn1.Type.OCTETSTRING,
18515      constructed: false,
18516      capture: 'macSalt'
18517    }, {
18518      name: 'PFX.macData.iterations',
18519      tagClass: asn1.Class.UNIVERSAL,
18520      type: asn1.Type.INTEGER,
18521      constructed: false,
18522      optional: true,
18523      capture: 'macIterations'
18524    }]
18525  }]
18526};
18527
18528var safeBagValidator = {
18529  name: 'SafeBag',
18530  tagClass: asn1.Class.UNIVERSAL,
18531  type: asn1.Type.SEQUENCE,
18532  constructed: true,
18533  value: [{
18534    name: 'SafeBag.bagId',
18535    tagClass: asn1.Class.UNIVERSAL,
18536    type: asn1.Type.OID,
18537    constructed: false,
18538    capture: 'bagId'
18539  }, {
18540    name: 'SafeBag.bagValue',
18541    tagClass: asn1.Class.CONTEXT_SPECIFIC,
18542    constructed: true,
18543    captureAsn1: 'bagValue'
18544  }, {
18545    name: 'SafeBag.bagAttributes',
18546    tagClass: asn1.Class.UNIVERSAL,
18547    type: asn1.Type.SET,
18548    constructed: true,
18549    optional: true,
18550    capture: 'bagAttributes'
18551  }]
18552};
18553
18554var attributeValidator = {
18555  name: 'Attribute',
18556  tagClass: asn1.Class.UNIVERSAL,
18557  type: asn1.Type.SEQUENCE,
18558  constructed: true,
18559  value: [{
18560    name: 'Attribute.attrId',
18561    tagClass: asn1.Class.UNIVERSAL,
18562    type: asn1.Type.OID,
18563    constructed: false,
18564    capture: 'oid'
18565  }, {
18566    name: 'Attribute.attrValues',
18567    tagClass: asn1.Class.UNIVERSAL,
18568    type: asn1.Type.SET,
18569    constructed: true,
18570    capture: 'values'
18571  }]
18572};
18573
18574var certBagValidator = {
18575  name: 'CertBag',
18576  tagClass: asn1.Class.UNIVERSAL,
18577  type: asn1.Type.SEQUENCE,
18578  constructed: true,
18579  value: [{
18580    name: 'CertBag.certId',
18581    tagClass: asn1.Class.UNIVERSAL,
18582    type: asn1.Type.OID,
18583    constructed: false,
18584    capture: 'certId'
18585  }, {
18586    name: 'CertBag.certValue',
18587    tagClass: asn1.Class.CONTEXT_SPECIFIC,
18588    constructed: true,
18589    /* So far we only support X.509 certificates (which are wrapped in
18590       an OCTET STRING, hence hard code that here). */
18591    value: [{
18592      name: 'CertBag.certValue[0]',
18593      tagClass: asn1.Class.UNIVERSAL,
18594      type: asn1.Class.OCTETSTRING,
18595      constructed: false,
18596      capture: 'cert'
18597    }]
18598  }]
18599};
18600
18601/**
18602 * Search SafeContents structure for bags with matching attributes.
18603 *
18604 * The search can optionally be narrowed by a certain bag type.
18605 *
18606 * @param safeContents the SafeContents structure to search in.
18607 * @param attrName the name of the attribute to compare against.
18608 * @param attrValue the attribute value to search for.
18609 * @param [bagType] bag type to narrow search by.
18610 *
18611 * @return an array of matching bags.
18612 */
18613function _getBagsByAttribute(safeContents, attrName, attrValue, bagType) {
18614  var result = [];
18615
18616  for(var i = 0; i < safeContents.length; i ++) {
18617    for(var j = 0; j < safeContents[i].safeBags.length; j ++) {
18618      var bag = safeContents[i].safeBags[j];
18619      if(bagType !== undefined && bag.type !== bagType) {
18620        continue;
18621      }
18622      // only filter by bag type, no attribute specified
18623      if(attrName === null) {
18624        result.push(bag);
18625        continue;
18626      }
18627      if(bag.attributes[attrName] !== undefined &&
18628        bag.attributes[attrName].indexOf(attrValue) >= 0) {
18629        result.push(bag);
18630      }
18631    }
18632  }
18633
18634  return result;
18635}
18636
18637/**
18638 * Converts a PKCS#12 PFX in ASN.1 notation into a PFX object.
18639 *
18640 * @param obj The PKCS#12 PFX in ASN.1 notation.
18641 * @param strict true to use strict DER decoding, false not to (default: true).
18642 * @param {String} password Password to decrypt with (optional).
18643 *
18644 * @return PKCS#12 PFX object.
18645 */
18646p12.pkcs12FromAsn1 = function(obj, strict, password) {
18647  // handle args
18648  if(typeof strict === 'string') {
18649    password = strict;
18650    strict = true;
18651  } else if(strict === undefined) {
18652    strict = true;
18653  }
18654
18655  // validate PFX and capture data
18656  var capture = {};
18657  var errors = [];
18658  if(!asn1.validate(obj, pfxValidator, capture, errors)) {
18659    var error = new Error('Cannot read PKCS#12 PFX. ' +
18660      'ASN.1 object is not an PKCS#12 PFX.');
18661    error.errors = error;
18662    throw error;
18663  }
18664
18665  var pfx = {
18666    version: capture.version.charCodeAt(0),
18667    safeContents: [],
18668
18669    /**
18670     * Gets bags with matching attributes.
18671     *
18672     * @param filter the attributes to filter by:
18673     *          [localKeyId] the localKeyId to search for.
18674     *          [localKeyIdHex] the localKeyId in hex to search for.
18675     *          [friendlyName] the friendly name to search for.
18676     *          [bagType] bag type to narrow each attribute search by.
18677     *
18678     * @return a map of attribute type to an array of matching bags or, if no
18679     *           attribute was given but a bag type, the map key will be the
18680     *           bag type.
18681     */
18682    getBags: function(filter) {
18683      var rval = {};
18684
18685      var localKeyId;
18686      if('localKeyId' in filter) {
18687        localKeyId = filter.localKeyId;
18688      } else if('localKeyIdHex' in filter) {
18689        localKeyId = forge.util.hexToBytes(filter.localKeyIdHex);
18690      }
18691
18692      // filter on bagType only
18693      if(localKeyId === undefined && !('friendlyName' in filter) &&
18694        'bagType' in filter) {
18695        rval[filter.bagType] = _getBagsByAttribute(
18696          pfx.safeContents, null, null, filter.bagType);
18697      }
18698
18699      if(localKeyId !== undefined) {
18700        rval.localKeyId = _getBagsByAttribute(
18701          pfx.safeContents, 'localKeyId',
18702          localKeyId, filter.bagType);
18703      }
18704      if('friendlyName' in filter) {
18705        rval.friendlyName = _getBagsByAttribute(
18706          pfx.safeContents, 'friendlyName',
18707          filter.friendlyName, filter.bagType);
18708      }
18709
18710      return rval;
18711    },
18712
18713    /**
18714     * DEPRECATED: use getBags() instead.
18715     *
18716     * Get bags with matching friendlyName attribute.
18717     *
18718     * @param friendlyName the friendly name to search for.
18719     * @param [bagType] bag type to narrow search by.
18720     *
18721     * @return an array of bags with matching friendlyName attribute.
18722     */
18723    getBagsByFriendlyName: function(friendlyName, bagType) {
18724      return _getBagsByAttribute(
18725        pfx.safeContents, 'friendlyName', friendlyName, bagType);
18726    },
18727
18728    /**
18729     * DEPRECATED: use getBags() instead.
18730     *
18731     * Get bags with matching localKeyId attribute.
18732     *
18733     * @param localKeyId the localKeyId to search for.
18734     * @param [bagType] bag type to narrow search by.
18735     *
18736     * @return an array of bags with matching localKeyId attribute.
18737     */
18738    getBagsByLocalKeyId: function(localKeyId, bagType) {
18739      return _getBagsByAttribute(
18740        pfx.safeContents, 'localKeyId', localKeyId, bagType);
18741    }
18742  };
18743
18744  if(capture.version.charCodeAt(0) !== 3) {
18745    var error = new Error('PKCS#12 PFX of version other than 3 not supported.');
18746    error.version = capture.version.charCodeAt(0);
18747    throw error;
18748  }
18749
18750  if(asn1.derToOid(capture.contentType) !== pki.oids.data) {
18751    var error = new Error('Only PKCS#12 PFX in password integrity mode supported.');
18752    error.oid = asn1.derToOid(capture.contentType);
18753    throw error;
18754  }
18755
18756  var data = capture.content.value[0];
18757  if(data.tagClass !== asn1.Class.UNIVERSAL ||
18758     data.type !== asn1.Type.OCTETSTRING) {
18759    throw new Error('PKCS#12 authSafe content data is not an OCTET STRING.');
18760  }
18761  data = _decodePkcs7Data(data);
18762
18763  // check for MAC
18764  if(capture.mac) {
18765    var md = null;
18766    var macKeyBytes = 0;
18767    var macAlgorithm = asn1.derToOid(capture.macAlgorithm);
18768    switch(macAlgorithm) {
18769    case pki.oids.sha1:
18770      md = forge.md.sha1.create();
18771      macKeyBytes = 20;
18772      break;
18773    case pki.oids.sha256:
18774      md = forge.md.sha256.create();
18775      macKeyBytes = 32;
18776      break;
18777    case pki.oids.sha384:
18778      md = forge.md.sha384.create();
18779      macKeyBytes = 48;
18780      break;
18781    case pki.oids.sha512:
18782      md = forge.md.sha512.create();
18783      macKeyBytes = 64;
18784      break;
18785    case pki.oids.md5:
18786      md = forge.md.md5.create();
18787      macKeyBytes = 16;
18788      break;
18789    }
18790    if(md === null) {
18791      throw new Error('PKCS#12 uses unsupported MAC algorithm: ' + macAlgorithm);
18792    }
18793
18794    // verify MAC (iterations default to 1)
18795    var macSalt = new forge.util.ByteBuffer(capture.macSalt);
18796    var macIterations = (('macIterations' in capture) ?
18797      parseInt(forge.util.bytesToHex(capture.macIterations), 16) : 1);
18798    var macKey = p12.generateKey(
18799      password, macSalt, 3, macIterations, macKeyBytes, md);
18800    var mac = forge.hmac.create();
18801    mac.start(md, macKey);
18802    mac.update(data.value);
18803    var macValue = mac.getMac();
18804    if(macValue.getBytes() !== capture.macDigest) {
18805      throw new Error('PKCS#12 MAC could not be verified. Invalid password?');
18806    }
18807  }
18808
18809  _decodeAuthenticatedSafe(pfx, data.value, strict, password);
18810  return pfx;
18811};
18812
18813/**
18814 * Decodes PKCS#7 Data. PKCS#7 (RFC 2315) defines "Data" as an OCTET STRING,
18815 * but it is sometimes an OCTET STRING that is composed/constructed of chunks,
18816 * each its own OCTET STRING. This is BER-encoding vs. DER-encoding. This
18817 * function transforms this corner-case into the usual simple,
18818 * non-composed/constructed OCTET STRING.
18819 *
18820 * This function may be moved to ASN.1 at some point to better deal with
18821 * more BER-encoding issues, should they arise.
18822 *
18823 * @param data the ASN.1 Data object to transform.
18824 */
18825function _decodePkcs7Data(data) {
18826  // handle special case of "chunked" data content: an octet string composed
18827  // of other octet strings
18828  if(data.composed || data.constructed) {
18829    var value = forge.util.createBuffer();
18830    for(var i = 0; i < data.value.length; ++i) {
18831      value.putBytes(data.value[i].value);
18832    }
18833    data.composed = data.constructed = false;
18834    data.value = value.getBytes();
18835  }
18836  return data;
18837}
18838
18839/**
18840 * Decode PKCS#12 AuthenticatedSafe (BER encoded) into PFX object.
18841 *
18842 * The AuthenticatedSafe is a BER-encoded SEQUENCE OF ContentInfo.
18843 *
18844 * @param pfx The PKCS#12 PFX object to fill.
18845 * @param {String} authSafe BER-encoded AuthenticatedSafe.
18846 * @param strict true to use strict DER decoding, false not to.
18847 * @param {String} password Password to decrypt with (optional).
18848 */
18849function _decodeAuthenticatedSafe(pfx, authSafe, strict, password) {
18850  authSafe = asn1.fromDer(authSafe, strict);  /* actually it's BER encoded */
18851
18852  if(authSafe.tagClass !== asn1.Class.UNIVERSAL ||
18853     authSafe.type !== asn1.Type.SEQUENCE ||
18854     authSafe.constructed !== true) {
18855    throw new Error('PKCS#12 AuthenticatedSafe expected to be a ' +
18856      'SEQUENCE OF ContentInfo');
18857  }
18858
18859  for(var i = 0; i < authSafe.value.length; i ++) {
18860    var contentInfo = authSafe.value[i];
18861
18862    // validate contentInfo and capture data
18863    var capture = {};
18864    var errors = [];
18865    if(!asn1.validate(contentInfo, contentInfoValidator, capture, errors)) {
18866      var error = new Error('Cannot read ContentInfo.');
18867      error.errors = errors;
18868      throw error;
18869    }
18870
18871    var obj = {
18872      encrypted: false
18873    };
18874    var safeContents = null;
18875    var data = capture.content.value[0];
18876    switch(asn1.derToOid(capture.contentType)) {
18877    case pki.oids.data:
18878      if(data.tagClass !== asn1.Class.UNIVERSAL ||
18879         data.type !== asn1.Type.OCTETSTRING) {
18880        throw new Error('PKCS#12 SafeContents Data is not an OCTET STRING.');
18881      }
18882      safeContents = _decodePkcs7Data(data).value;
18883      break;
18884    case pki.oids.encryptedData:
18885      safeContents = _decryptSafeContents(data, password);
18886      obj.encrypted = true;
18887      break;
18888    default:
18889      var error = new Error('Unsupported PKCS#12 contentType.');
18890      error.contentType = asn1.derToOid(capture.contentType);
18891      throw error;
18892    }
18893
18894    obj.safeBags = _decodeSafeContents(safeContents, strict, password);
18895    pfx.safeContents.push(obj);
18896  }
18897}
18898
18899/**
18900 * Decrypt PKCS#7 EncryptedData structure.
18901 *
18902 * @param data ASN.1 encoded EncryptedContentInfo object.
18903 * @param password The user-provided password.
18904 *
18905 * @return The decrypted SafeContents (ASN.1 object).
18906 */
18907function _decryptSafeContents(data, password) {
18908  var capture = {};
18909  var errors = [];
18910  if(!asn1.validate(
18911    data, forge.pkcs7.asn1.encryptedDataValidator, capture, errors)) {
18912    var error = new Error('Cannot read EncryptedContentInfo.');
18913    error.errors = errors;
18914    throw error;
18915  }
18916
18917  var oid = asn1.derToOid(capture.contentType);
18918  if(oid !== pki.oids.data) {
18919    var error = new Error(
18920      'PKCS#12 EncryptedContentInfo ContentType is not Data.');
18921    error.oid = oid;
18922    throw error;
18923  }
18924
18925  // get cipher
18926  oid = asn1.derToOid(capture.encAlgorithm);
18927  var cipher = pki.pbe.getCipher(oid, capture.encParameter, password);
18928
18929  // get encrypted data
18930  var encryptedContentAsn1 = _decodePkcs7Data(capture.encryptedContentAsn1);
18931  var encrypted = forge.util.createBuffer(encryptedContentAsn1.value);
18932
18933  cipher.update(encrypted);
18934  if(!cipher.finish()) {
18935    throw new Error('Failed to decrypt PKCS#12 SafeContents.');
18936  }
18937
18938  return cipher.output.getBytes();
18939}
18940
18941/**
18942 * Decode PKCS#12 SafeContents (BER-encoded) into array of Bag objects.
18943 *
18944 * The safeContents is a BER-encoded SEQUENCE OF SafeBag.
18945 *
18946 * @param {String} safeContents BER-encoded safeContents.
18947 * @param strict true to use strict DER decoding, false not to.
18948 * @param {String} password Password to decrypt with (optional).
18949 *
18950 * @return {Array} Array of Bag objects.
18951 */
18952function _decodeSafeContents(safeContents, strict, password) {
18953  // if strict and no safe contents, return empty safes
18954  if(!strict && safeContents.length === 0) {
18955    return [];
18956  }
18957
18958  // actually it's BER-encoded
18959  safeContents = asn1.fromDer(safeContents, strict);
18960
18961  if(safeContents.tagClass !== asn1.Class.UNIVERSAL ||
18962    safeContents.type !== asn1.Type.SEQUENCE ||
18963    safeContents.constructed !== true) {
18964    throw new Error(
18965      'PKCS#12 SafeContents expected to be a SEQUENCE OF SafeBag.');
18966  }
18967
18968  var res = [];
18969  for(var i = 0; i < safeContents.value.length; i++) {
18970    var safeBag = safeContents.value[i];
18971
18972    // validate SafeBag and capture data
18973    var capture = {};
18974    var errors = [];
18975    if(!asn1.validate(safeBag, safeBagValidator, capture, errors)) {
18976      var error = new Error('Cannot read SafeBag.');
18977      error.errors = errors;
18978      throw error;
18979    }
18980
18981    /* Create bag object and push to result array. */
18982    var bag = {
18983      type: asn1.derToOid(capture.bagId),
18984      attributes: _decodeBagAttributes(capture.bagAttributes)
18985    };
18986    res.push(bag);
18987
18988    var validator, decoder;
18989    var bagAsn1 = capture.bagValue.value[0];
18990    switch(bag.type) {
18991      case pki.oids.pkcs8ShroudedKeyBag:
18992        /* bagAsn1 has a EncryptedPrivateKeyInfo, which we need to decrypt.
18993           Afterwards we can handle it like a keyBag,
18994           which is a PrivateKeyInfo. */
18995        bagAsn1 = pki.decryptPrivateKeyInfo(bagAsn1, password);
18996        if(bagAsn1 === null) {
18997          throw new Error(
18998            'Unable to decrypt PKCS#8 ShroudedKeyBag, wrong password?');
18999        }
19000
19001        /* fall through */
19002      case pki.oids.keyBag:
19003        /* A PKCS#12 keyBag is a simple PrivateKeyInfo as understood by our
19004           PKI module, hence we don't have to do validation/capturing here,
19005           just pass what we already got. */
19006        try {
19007          bag.key = pki.privateKeyFromAsn1(bagAsn1);
19008        } catch(e) {
19009          // ignore unknown key type, pass asn1 value
19010          bag.key = null;
19011          bag.asn1 = bagAsn1;
19012        }
19013        continue;  /* Nothing more to do. */
19014
19015      case pki.oids.certBag:
19016        /* A PKCS#12 certBag can wrap both X.509 and sdsi certificates.
19017           Therefore put the SafeBag content through another validator to
19018           capture the fields.  Afterwards check & store the results. */
19019        validator = certBagValidator;
19020        decoder = function() {
19021          if(asn1.derToOid(capture.certId) !== pki.oids.x509Certificate) {
19022            var error = new Error(
19023              'Unsupported certificate type, only X.509 supported.');
19024            error.oid = asn1.derToOid(capture.certId);
19025            throw error;
19026          }
19027
19028          // true=produce cert hash
19029          var certAsn1 = asn1.fromDer(capture.cert, strict);
19030          try {
19031            bag.cert = pki.certificateFromAsn1(certAsn1, true);
19032          } catch(e) {
19033            // ignore unknown cert type, pass asn1 value
19034            bag.cert = null;
19035            bag.asn1 = certAsn1;
19036          }
19037        };
19038        break;
19039
19040      default:
19041        var error = new Error('Unsupported PKCS#12 SafeBag type.');
19042        error.oid = bag.type;
19043        throw error;
19044    }
19045
19046    /* Validate SafeBag value (i.e. CertBag, etc.) and capture data if needed. */
19047    if(validator !== undefined &&
19048       !asn1.validate(bagAsn1, validator, capture, errors)) {
19049      var error = new Error('Cannot read PKCS#12 ' + validator.name);
19050      error.errors = errors;
19051      throw error;
19052    }
19053
19054    /* Call decoder function from above to store the results. */
19055    decoder();
19056  }
19057
19058  return res;
19059}
19060
19061/**
19062 * Decode PKCS#12 SET OF PKCS12Attribute into JavaScript object.
19063 *
19064 * @param attributes SET OF PKCS12Attribute (ASN.1 object).
19065 *
19066 * @return the decoded attributes.
19067 */
19068function _decodeBagAttributes(attributes) {
19069  var decodedAttrs = {};
19070
19071  if(attributes !== undefined) {
19072    for(var i = 0; i < attributes.length; ++i) {
19073      var capture = {};
19074      var errors = [];
19075      if(!asn1.validate(attributes[i], attributeValidator, capture, errors)) {
19076        var error = new Error('Cannot read PKCS#12 BagAttribute.');
19077        error.errors = errors;
19078        throw error;
19079      }
19080
19081      var oid = asn1.derToOid(capture.oid);
19082      if(pki.oids[oid] === undefined) {
19083        // unsupported attribute type, ignore.
19084        continue;
19085      }
19086
19087      decodedAttrs[pki.oids[oid]] = [];
19088      for(var j = 0; j < capture.values.length; ++j) {
19089        decodedAttrs[pki.oids[oid]].push(capture.values[j].value);
19090      }
19091    }
19092  }
19093
19094  return decodedAttrs;
19095}
19096
19097/**
19098 * Wraps a private key and certificate in a PKCS#12 PFX wrapper. If a
19099 * password is provided then the private key will be encrypted.
19100 *
19101 * An entire certificate chain may also be included. To do this, pass
19102 * an array for the "cert" parameter where the first certificate is
19103 * the one that is paired with the private key and each subsequent one
19104 * verifies the previous one. The certificates may be in PEM format or
19105 * have been already parsed by Forge.
19106 *
19107 * @todo implement password-based-encryption for the whole package
19108 *
19109 * @param key the private key.
19110 * @param cert the certificate (may be an array of certificates in order
19111 *          to specify a certificate chain).
19112 * @param password the password to use, null for none.
19113 * @param options:
19114 *          algorithm the encryption algorithm to use
19115 *            ('aes128', 'aes192', 'aes256', '3des'), defaults to 'aes128'.
19116 *          count the iteration count to use.
19117 *          saltSize the salt size to use.
19118 *          useMac true to include a MAC, false not to, defaults to true.
19119 *          localKeyId the local key ID to use, in hex.
19120 *          friendlyName the friendly name to use.
19121 *          generateLocalKeyId true to generate a random local key ID,
19122 *            false not to, defaults to true.
19123 *
19124 * @return the PKCS#12 PFX ASN.1 object.
19125 */
19126p12.toPkcs12Asn1 = function(key, cert, password, options) {
19127  // set default options
19128  options = options || {};
19129  options.saltSize = options.saltSize || 8;
19130  options.count = options.count || 2048;
19131  options.algorithm = options.algorithm || options.encAlgorithm || 'aes128';
19132  if(!('useMac' in options)) {
19133    options.useMac = true;
19134  }
19135  if(!('localKeyId' in options)) {
19136    options.localKeyId = null;
19137  }
19138  if(!('generateLocalKeyId' in options)) {
19139    options.generateLocalKeyId = true;
19140  }
19141
19142  var localKeyId = options.localKeyId;
19143  var bagAttrs;
19144  if(localKeyId !== null) {
19145    localKeyId = forge.util.hexToBytes(localKeyId);
19146  } else if(options.generateLocalKeyId) {
19147    // use SHA-1 of paired cert, if available
19148    if(cert) {
19149      var pairedCert = forge.util.isArray(cert) ? cert[0] : cert;
19150      if(typeof pairedCert === 'string') {
19151        pairedCert = pki.certificateFromPem(pairedCert);
19152      }
19153      var sha1 = forge.md.sha1.create();
19154      sha1.update(asn1.toDer(pki.certificateToAsn1(pairedCert)).getBytes());
19155      localKeyId = sha1.digest().getBytes();
19156    } else {
19157      // FIXME: consider using SHA-1 of public key (which can be generated
19158      // from private key components), see: cert.generateSubjectKeyIdentifier
19159      // generate random bytes
19160      localKeyId = forge.random.getBytes(20);
19161    }
19162  }
19163
19164  var attrs = [];
19165  if(localKeyId !== null) {
19166    attrs.push(
19167      // localKeyID
19168      asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
19169        // attrId
19170        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
19171          asn1.oidToDer(pki.oids.localKeyId).getBytes()),
19172        // attrValues
19173        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SET, true, [
19174          asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false,
19175            localKeyId)
19176        ])
19177      ]));
19178  }
19179  if('friendlyName' in options) {
19180    attrs.push(
19181      // friendlyName
19182      asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
19183        // attrId
19184        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
19185          asn1.oidToDer(pki.oids.friendlyName).getBytes()),
19186        // attrValues
19187        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SET, true, [
19188          asn1.create(asn1.Class.UNIVERSAL, asn1.Type.BMPSTRING, false,
19189            options.friendlyName)
19190        ])
19191      ]));
19192  }
19193
19194  if(attrs.length > 0) {
19195    bagAttrs = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SET, true, attrs);
19196  }
19197
19198  // collect contents for AuthenticatedSafe
19199  var contents = [];
19200
19201  // create safe bag(s) for certificate chain
19202  var chain = [];
19203  if(cert !== null) {
19204    if(forge.util.isArray(cert)) {
19205      chain = cert;
19206    } else {
19207      chain = [cert];
19208    }
19209  }
19210
19211  var certSafeBags = [];
19212  for(var i = 0; i < chain.length; ++i) {
19213    // convert cert from PEM as necessary
19214    cert = chain[i];
19215    if(typeof cert === 'string') {
19216      cert = pki.certificateFromPem(cert);
19217    }
19218
19219    // SafeBag
19220    var certBagAttrs = (i === 0) ? bagAttrs : undefined;
19221    var certAsn1 = pki.certificateToAsn1(cert);
19222    var certSafeBag =
19223      asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
19224        // bagId
19225        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
19226          asn1.oidToDer(pki.oids.certBag).getBytes()),
19227        // bagValue
19228        asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [
19229          // CertBag
19230          asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
19231            // certId
19232            asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
19233              asn1.oidToDer(pki.oids.x509Certificate).getBytes()),
19234            // certValue (x509Certificate)
19235            asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [
19236              asn1.create(
19237                asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false,
19238                asn1.toDer(certAsn1).getBytes())
19239            ])])]),
19240        // bagAttributes (OPTIONAL)
19241        certBagAttrs
19242      ]);
19243    certSafeBags.push(certSafeBag);
19244  }
19245
19246  if(certSafeBags.length > 0) {
19247    // SafeContents
19248    var certSafeContents = asn1.create(
19249      asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, certSafeBags);
19250
19251    // ContentInfo
19252    var certCI =
19253      // PKCS#7 ContentInfo
19254      asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
19255        // contentType
19256        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
19257          // OID for the content type is 'data'
19258          asn1.oidToDer(pki.oids.data).getBytes()),
19259        // content
19260        asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [
19261          asn1.create(
19262            asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false,
19263            asn1.toDer(certSafeContents).getBytes())
19264        ])
19265      ]);
19266    contents.push(certCI);
19267  }
19268
19269  // create safe contents for private key
19270  var keyBag = null;
19271  if(key !== null) {
19272    // SafeBag
19273    var pkAsn1 = pki.wrapRsaPrivateKey(pki.privateKeyToAsn1(key));
19274    if(password === null) {
19275      // no encryption
19276      keyBag = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
19277        // bagId
19278        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
19279          asn1.oidToDer(pki.oids.keyBag).getBytes()),
19280        // bagValue
19281        asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [
19282          // PrivateKeyInfo
19283          pkAsn1
19284        ]),
19285        // bagAttributes (OPTIONAL)
19286        bagAttrs
19287      ]);
19288    } else {
19289      // encrypted PrivateKeyInfo
19290      keyBag = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
19291        // bagId
19292        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
19293          asn1.oidToDer(pki.oids.pkcs8ShroudedKeyBag).getBytes()),
19294        // bagValue
19295        asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [
19296          // EncryptedPrivateKeyInfo
19297          pki.encryptPrivateKeyInfo(pkAsn1, password, options)
19298        ]),
19299        // bagAttributes (OPTIONAL)
19300        bagAttrs
19301      ]);
19302    }
19303
19304    // SafeContents
19305    var keySafeContents =
19306      asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [keyBag]);
19307
19308    // ContentInfo
19309    var keyCI =
19310      // PKCS#7 ContentInfo
19311      asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
19312        // contentType
19313        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
19314          // OID for the content type is 'data'
19315          asn1.oidToDer(pki.oids.data).getBytes()),
19316        // content
19317        asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [
19318          asn1.create(
19319            asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false,
19320            asn1.toDer(keySafeContents).getBytes())
19321        ])
19322      ]);
19323    contents.push(keyCI);
19324  }
19325
19326  // create AuthenticatedSafe by stringing together the contents
19327  var safe = asn1.create(
19328    asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, contents);
19329
19330  var macData;
19331  if(options.useMac) {
19332    // MacData
19333    var sha1 = forge.md.sha1.create();
19334    var macSalt = new forge.util.ByteBuffer(
19335      forge.random.getBytes(options.saltSize));
19336    var count = options.count;
19337    // 160-bit key
19338    var key = p12.generateKey(password, macSalt, 3, count, 20);
19339    var mac = forge.hmac.create();
19340    mac.start(sha1, key);
19341    mac.update(asn1.toDer(safe).getBytes());
19342    var macValue = mac.getMac();
19343    macData = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
19344      // mac DigestInfo
19345      asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
19346        // digestAlgorithm
19347        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
19348          // algorithm = SHA-1
19349          asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
19350            asn1.oidToDer(pki.oids.sha1).getBytes()),
19351          // parameters = Null
19352          asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, '')
19353        ]),
19354        // digest
19355        asn1.create(
19356          asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING,
19357          false, macValue.getBytes())
19358      ]),
19359      // macSalt OCTET STRING
19360      asn1.create(
19361        asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, macSalt.getBytes()),
19362      // iterations INTEGER (XXX: Only support count < 65536)
19363      asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false,
19364        asn1.integerToDer(count).getBytes()
19365      )
19366    ]);
19367  }
19368
19369  // PFX
19370  return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
19371    // version (3)
19372    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false,
19373      asn1.integerToDer(3).getBytes()),
19374    // PKCS#7 ContentInfo
19375    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
19376      // contentType
19377      asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
19378        // OID for the content type is 'data'
19379        asn1.oidToDer(pki.oids.data).getBytes()),
19380      // content
19381      asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [
19382        asn1.create(
19383          asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false,
19384          asn1.toDer(safe).getBytes())
19385      ])
19386    ]),
19387    macData
19388  ]);
19389};
19390
19391/**
19392 * Derives a PKCS#12 key.
19393 *
19394 * @param password the password to derive the key material from, null or
19395 *          undefined for none.
19396 * @param salt the salt, as a ByteBuffer, to use.
19397 * @param id the PKCS#12 ID byte (1 = key material, 2 = IV, 3 = MAC).
19398 * @param iter the iteration count.
19399 * @param n the number of bytes to derive from the password.
19400 * @param md the message digest to use, defaults to SHA-1.
19401 *
19402 * @return a ByteBuffer with the bytes derived from the password.
19403 */
19404p12.generateKey = forge.pbe.generatePkcs12Key;
19405
19406} // end module implementation
19407
19408/* ########## Begin module wrapper ########## */
19409var name = 'pkcs12';
19410if(typeof define !== 'function') {
19411  // NodeJS -> AMD
19412  if(typeof module === 'object' && module.exports) {
19413    var nodeJS = true;
19414    define = function(ids, factory) {
19415      factory(require, module);
19416    };
19417  } else {
19418    // <script>
19419    if(typeof forge === 'undefined') {
19420      forge = {};
19421    }
19422    return initModule(forge);
19423  }
19424}
19425// AMD
19426var deps;
19427var defineFunc = function(require, module) {
19428  module.exports = function(forge) {
19429    var mods = deps.map(function(dep) {
19430      return require(dep);
19431    }).concat(initModule);
19432    // handle circular dependencies
19433    forge = forge || {};
19434    forge.defined = forge.defined || {};
19435    if(forge.defined[name]) {
19436      return forge[name];
19437    }
19438    forge.defined[name] = true;
19439    for(var i = 0; i < mods.length; ++i) {
19440      mods[i](forge);
19441    }
19442    return forge[name];
19443  };
19444};
19445var tmpDefine = define;
19446define = function(ids, factory) {
19447  deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2);
19448  if(nodeJS) {
19449    delete define;
19450    return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0));
19451  }
19452  define = tmpDefine;
19453  return define.apply(null, Array.prototype.slice.call(arguments, 0));
19454};
19455define([
19456  'require',
19457  'module',
19458  './asn1',
19459  './hmac',
19460  './oids',
19461  './pkcs7asn1',
19462  './pbe',
19463  './random',
19464  './rsa',
19465  './sha1',
19466  './util',
19467  './x509'
19468], function() {
19469  defineFunc.apply(null, Array.prototype.slice.call(arguments, 0));
19470});
19471})();
19472
19473/**
19474 * Javascript implementation of ASN.1 validators for PKCS#7 v1.5.
19475 *
19476 * @author Dave Longley
19477 * @author Stefan Siegl
19478 *
19479 * Copyright (c) 2012-2015 Digital Bazaar, Inc.
19480 * Copyright (c) 2012 Stefan Siegl <[email protected]>
19481 *
19482 * The ASN.1 representation of PKCS#7 is as follows
19483 * (see RFC #2315 for details, http://www.ietf.org/rfc/rfc2315.txt):
19484 *
19485 * A PKCS#7 message consists of a ContentInfo on root level, which may
19486 * contain any number of further ContentInfo nested into it.
19487 *
19488 * ContentInfo ::= SEQUENCE {
19489 *   contentType                ContentType,
19490 *   content               [0]  EXPLICIT ANY DEFINED BY contentType OPTIONAL
19491 * }
19492 *
19493 * ContentType ::= OBJECT IDENTIFIER
19494 *
19495 * EnvelopedData ::= SEQUENCE {
19496 *   version                    Version,
19497 *   recipientInfos             RecipientInfos,
19498 *   encryptedContentInfo       EncryptedContentInfo
19499 * }
19500 *
19501 * EncryptedData ::= SEQUENCE {
19502 *   version                    Version,
19503 *   encryptedContentInfo       EncryptedContentInfo
19504 * }
19505 *
19506 * id-signedData OBJECT IDENTIFIER ::= { iso(1) member-body(2)
19507 *   us(840) rsadsi(113549) pkcs(1) pkcs7(7) 2 }
19508 *
19509 * SignedData ::= SEQUENCE {
19510 *   version           INTEGER,
19511 *   digestAlgorithms  DigestAlgorithmIdentifiers,
19512 *   contentInfo       ContentInfo,
19513 *   certificates      [0] IMPLICIT Certificates OPTIONAL,
19514 *   crls              [1] IMPLICIT CertificateRevocationLists OPTIONAL,
19515 *   signerInfos       SignerInfos
19516 * }
19517 *
19518 * SignerInfos ::= SET OF SignerInfo
19519 *
19520 * SignerInfo ::= SEQUENCE {
19521 *   version                    Version,
19522 *   issuerAndSerialNumber      IssuerAndSerialNumber,
19523 *   digestAlgorithm            DigestAlgorithmIdentifier,
19524 *   authenticatedAttributes    [0] IMPLICIT Attributes OPTIONAL,
19525 *   digestEncryptionAlgorithm  DigestEncryptionAlgorithmIdentifier,
19526 *   encryptedDigest            EncryptedDigest,
19527 *   unauthenticatedAttributes  [1] IMPLICIT Attributes OPTIONAL
19528 * }
19529 *
19530 * EncryptedDigest ::= OCTET STRING
19531 *
19532 * Attributes ::= SET OF Attribute
19533 *
19534 * Attribute ::= SEQUENCE {
19535 *   attrType    OBJECT IDENTIFIER,
19536 *   attrValues  SET OF AttributeValue
19537 * }
19538 *
19539 * AttributeValue ::= ANY
19540 *
19541 * Version ::= INTEGER
19542 *
19543 * RecipientInfos ::= SET OF RecipientInfo
19544 *
19545 * EncryptedContentInfo ::= SEQUENCE {
19546 *   contentType                 ContentType,
19547 *   contentEncryptionAlgorithm  ContentEncryptionAlgorithmIdentifier,
19548 *   encryptedContent       [0]  IMPLICIT EncryptedContent OPTIONAL
19549 * }
19550 *
19551 * ContentEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
19552 *
19553 * The AlgorithmIdentifier contains an Object Identifier (OID) and parameters
19554 * for the algorithm, if any. In the case of AES and DES3, there is only one,
19555 * the IV.
19556 *
19557 * AlgorithmIdentifer ::= SEQUENCE {
19558 *    algorithm OBJECT IDENTIFIER,
19559 *    parameters ANY DEFINED BY algorithm OPTIONAL
19560 * }
19561 *
19562 * EncryptedContent ::= OCTET STRING
19563 *
19564 * RecipientInfo ::= SEQUENCE {
19565 *   version                     Version,
19566 *   issuerAndSerialNumber       IssuerAndSerialNumber,
19567 *   keyEncryptionAlgorithm      KeyEncryptionAlgorithmIdentifier,
19568 *   encryptedKey                EncryptedKey
19569 * }
19570 *
19571 * IssuerAndSerialNumber ::= SEQUENCE {
19572 *   issuer                      Name,
19573 *   serialNumber                CertificateSerialNumber
19574 * }
19575 *
19576 * CertificateSerialNumber ::= INTEGER
19577 *
19578 * KeyEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
19579 *
19580 * EncryptedKey ::= OCTET STRING
19581 */
19582(function() {
19583/* ########## Begin module implementation ########## */
19584function initModule(forge) {
19585
19586// shortcut for ASN.1 API
19587var asn1 = forge.asn1;
19588
19589// shortcut for PKCS#7 API
19590var p7v = forge.pkcs7asn1 = forge.pkcs7asn1 || {};
19591forge.pkcs7 = forge.pkcs7 || {};
19592forge.pkcs7.asn1 = p7v;
19593
19594var contentInfoValidator = {
19595  name: 'ContentInfo',
19596  tagClass: asn1.Class.UNIVERSAL,
19597  type: asn1.Type.SEQUENCE,
19598  constructed: true,
19599  value: [{
19600    name: 'ContentInfo.ContentType',
19601    tagClass: asn1.Class.UNIVERSAL,
19602    type: asn1.Type.OID,
19603    constructed: false,
19604    capture: 'contentType'
19605  }, {
19606    name: 'ContentInfo.content',
19607    tagClass: asn1.Class.CONTEXT_SPECIFIC,
19608    type: 0,
19609    constructed: true,
19610    optional: true,
19611    captureAsn1: 'content'
19612  }]
19613};
19614p7v.contentInfoValidator = contentInfoValidator;
19615
19616var encryptedContentInfoValidator = {
19617  name: 'EncryptedContentInfo',
19618  tagClass: asn1.Class.UNIVERSAL,
19619  type: asn1.Type.SEQUENCE,
19620  constructed: true,
19621  value: [{
19622    name: 'EncryptedContentInfo.contentType',
19623    tagClass: asn1.Class.UNIVERSAL,
19624    type: asn1.Type.OID,
19625    constructed: false,
19626    capture: 'contentType'
19627  }, {
19628    name: 'EncryptedContentInfo.contentEncryptionAlgorithm',
19629    tagClass: asn1.Class.UNIVERSAL,
19630    type: asn1.Type.SEQUENCE,
19631    constructed: true,
19632    value: [{
19633      name: 'EncryptedContentInfo.contentEncryptionAlgorithm.algorithm',
19634      tagClass: asn1.Class.UNIVERSAL,
19635      type: asn1.Type.OID,
19636      constructed: false,
19637      capture: 'encAlgorithm'
19638    }, {
19639      name: 'EncryptedContentInfo.contentEncryptionAlgorithm.parameter',
19640      tagClass: asn1.Class.UNIVERSAL,
19641      captureAsn1: 'encParameter'
19642    }]
19643  }, {
19644    name: 'EncryptedContentInfo.encryptedContent',
19645    tagClass: asn1.Class.CONTEXT_SPECIFIC,
19646    type: 0,
19647    /* The PKCS#7 structure output by OpenSSL somewhat differs from what
19648     * other implementations do generate.
19649     *
19650     * OpenSSL generates a structure like this:
19651     * SEQUENCE {
19652     *    ...
19653     *    [0]
19654     *       26 DA 67 D2 17 9C 45 3C B1 2A A8 59 2F 29 33 38
19655     *       C3 C3 DF 86 71 74 7A 19 9F 40 D0 29 BE 85 90 45
19656     *       ...
19657     * }
19658     *
19659     * Whereas other implementations (and this PKCS#7 module) generate:
19660     * SEQUENCE {
19661     *    ...
19662     *    [0] {
19663     *       OCTET STRING
19664     *          26 DA 67 D2 17 9C 45 3C B1 2A A8 59 2F 29 33 38
19665     *          C3 C3 DF 86 71 74 7A 19 9F 40 D0 29 BE 85 90 45
19666     *          ...
19667     *    }
19668     * }
19669     *
19670     * In order to support both, we just capture the context specific
19671     * field here.  The OCTET STRING bit is removed below.
19672     */
19673    capture: 'encryptedContent',
19674    captureAsn1: 'encryptedContentAsn1'
19675  }]
19676};
19677
19678p7v.envelopedDataValidator = {
19679  name: 'EnvelopedData',
19680  tagClass: asn1.Class.UNIVERSAL,
19681  type: asn1.Type.SEQUENCE,
19682  constructed: true,
19683  value: [{
19684    name: 'EnvelopedData.Version',
19685    tagClass: asn1.Class.UNIVERSAL,
19686    type: asn1.Type.INTEGER,
19687    constructed: false,
19688    capture: 'version'
19689  }, {
19690    name: 'EnvelopedData.RecipientInfos',
19691    tagClass: asn1.Class.UNIVERSAL,
19692    type: asn1.Type.SET,
19693    constructed: true,
19694    captureAsn1: 'recipientInfos'
19695  }].concat(encryptedContentInfoValidator)
19696};
19697
19698p7v.encryptedDataValidator = {
19699  name: 'EncryptedData',
19700  tagClass: asn1.Class.UNIVERSAL,
19701  type: asn1.Type.SEQUENCE,
19702  constructed: true,
19703  value: [{
19704    name: 'EncryptedData.Version',
19705    tagClass: asn1.Class.UNIVERSAL,
19706    type: asn1.Type.INTEGER,
19707    constructed: false,
19708    capture: 'version'
19709  }].concat(encryptedContentInfoValidator)
19710};
19711
19712var signerValidator = {
19713  name: 'SignerInfo',
19714  tagClass: asn1.Class.UNIVERSAL,
19715  type: asn1.Type.SEQUENCE,
19716  constructed: true,
19717  value: [{
19718    name: 'SignerInfo.version',
19719    tagClass: asn1.Class.UNIVERSAL,
19720    type: asn1.Type.INTEGER,
19721    constructed: false
19722  }, {
19723    name: 'SignerInfo.issuerAndSerialNumber',
19724    tagClass: asn1.Class.UNIVERSAL,
19725    type: asn1.Type.SEQUENCE,
19726    constructed: true,
19727    value: [{
19728      name: 'SignerInfo.issuerAndSerialNumber.issuer',
19729      tagClass: asn1.Class.UNIVERSAL,
19730      type: asn1.Type.SEQUENCE,
19731      constructed: true,
19732      captureAsn1: 'issuer'
19733    }, {
19734      name: 'SignerInfo.issuerAndSerialNumber.serialNumber',
19735      tagClass: asn1.Class.UNIVERSAL,
19736      type: asn1.Type.INTEGER,
19737      constructed: false,
19738      capture: 'serial'
19739    }]
19740  }, {
19741    name: 'SignerInfo.digestAlgorithm',
19742    tagClass: asn1.Class.UNIVERSAL,
19743    type: asn1.Type.SEQUENCE,
19744    constructed: true,
19745    value: [{
19746      name: 'SignerInfo.digestAlgorithm.algorithm',
19747      tagClass: asn1.Class.UNIVERSAL,
19748      type: asn1.Type.OID,
19749      constructed: false,
19750      capture: 'digestAlgorithm'
19751    }, {
19752      name: 'SignerInfo.digestAlgorithm.parameter',
19753      tagClass: asn1.Class.UNIVERSAL,
19754      constructed: false,
19755      captureAsn1: 'digestParameter',
19756      optional: true
19757    }]
19758  }, {
19759    name: 'SignerInfo.authenticatedAttributes',
19760    tagClass: asn1.Class.CONTEXT_SPECIFIC,
19761    type: 0,
19762    constructed: true,
19763    optional: true,
19764    capture: 'authenticatedAttributes'
19765  }, {
19766    name: 'SignerInfo.digestEncryptionAlgorithm',
19767    tagClass: asn1.Class.UNIVERSAL,
19768    type: asn1.Type.SEQUENCE,
19769    constructed: true,
19770    capture: 'signatureAlgorithm'
19771  }, {
19772    name: 'SignerInfo.encryptedDigest',
19773    tagClass: asn1.Class.UNIVERSAL,
19774    type: asn1.Type.OCTETSTRING,
19775    constructed: false,
19776    capture: 'signature'
19777  }, {
19778    name: 'SignerInfo.unauthenticatedAttributes',
19779    tagClass: asn1.Class.CONTEXT_SPECIFIC,
19780    type: 1,
19781    constructed: true,
19782    optional: true,
19783    capture: 'unauthenticatedAttributes'
19784  }]
19785};
19786
19787p7v.signedDataValidator = {
19788  name: 'SignedData',
19789  tagClass: asn1.Class.UNIVERSAL,
19790  type: asn1.Type.SEQUENCE,
19791  constructed: true,
19792  value: [{
19793    name: 'SignedData.Version',
19794    tagClass: asn1.Class.UNIVERSAL,
19795    type: asn1.Type.INTEGER,
19796    constructed: false,
19797    capture: 'version'
19798  }, {
19799    name: 'SignedData.DigestAlgorithms',
19800    tagClass: asn1.Class.UNIVERSAL,
19801    type: asn1.Type.SET,
19802    constructed: true,
19803    captureAsn1: 'digestAlgorithms'
19804  },
19805  contentInfoValidator,
19806  {
19807    name: 'SignedData.Certificates',
19808    tagClass: asn1.Class.CONTEXT_SPECIFIC,
19809    type: 0,
19810    optional: true,
19811    captureAsn1: 'certificates'
19812  }, {
19813    name: 'SignedData.CertificateRevocationLists',
19814    tagClass: asn1.Class.CONTEXT_SPECIFIC,
19815    type: 1,
19816    optional: true,
19817    captureAsn1: 'crls'
19818  }, {
19819    name: 'SignedData.SignerInfos',
19820    tagClass: asn1.Class.UNIVERSAL,
19821    type: asn1.Type.SET,
19822    capture: 'signerInfos',
19823    optional: true,
19824    value: [signerValidator]
19825  }]
19826};
19827
19828p7v.recipientInfoValidator = {
19829  name: 'RecipientInfo',
19830  tagClass: asn1.Class.UNIVERSAL,
19831  type: asn1.Type.SEQUENCE,
19832  constructed: true,
19833  value: [{
19834    name: 'RecipientInfo.version',
19835    tagClass: asn1.Class.UNIVERSAL,
19836    type: asn1.Type.INTEGER,
19837    constructed: false,
19838    capture: 'version'
19839  }, {
19840    name: 'RecipientInfo.issuerAndSerial',
19841    tagClass: asn1.Class.UNIVERSAL,
19842    type: asn1.Type.SEQUENCE,
19843    constructed: true,
19844    value: [{
19845      name: 'RecipientInfo.issuerAndSerial.issuer',
19846      tagClass: asn1.Class.UNIVERSAL,
19847      type: asn1.Type.SEQUENCE,
19848      constructed: true,
19849      captureAsn1: 'issuer'
19850    }, {
19851      name: 'RecipientInfo.issuerAndSerial.serialNumber',
19852      tagClass: asn1.Class.UNIVERSAL,
19853      type: asn1.Type.INTEGER,
19854      constructed: false,
19855      capture: 'serial'
19856    }]
19857  }, {
19858    name: 'RecipientInfo.keyEncryptionAlgorithm',
19859    tagClass: asn1.Class.UNIVERSAL,
19860    type: asn1.Type.SEQUENCE,
19861    constructed: true,
19862    value: [{
19863      name: 'RecipientInfo.keyEncryptionAlgorithm.algorithm',
19864      tagClass: asn1.Class.UNIVERSAL,
19865      type: asn1.Type.OID,
19866      constructed: false,
19867      capture: 'encAlgorithm'
19868    }, {
19869      name: 'RecipientInfo.keyEncryptionAlgorithm.parameter',
19870      tagClass: asn1.Class.UNIVERSAL,
19871      constructed: false,
19872      captureAsn1: 'encParameter'
19873    }]
19874  }, {
19875    name: 'RecipientInfo.encryptedKey',
19876    tagClass: asn1.Class.UNIVERSAL,
19877    type: asn1.Type.OCTETSTRING,
19878    constructed: false,
19879    capture: 'encKey'
19880  }]
19881};
19882
19883} // end module implementation
19884
19885/* ########## Begin module wrapper ########## */
19886var name = 'pkcs7asn1';
19887if(typeof define !== 'function') {
19888  // NodeJS -> AMD
19889  if(typeof module === 'object' && module.exports) {
19890    var nodeJS = true;
19891    define = function(ids, factory) {
19892      factory(require, module);
19893    };
19894  } else {
19895    // <script>
19896    if(typeof forge === 'undefined') {
19897      forge = {};
19898    }
19899    return initModule(forge);
19900  }
19901}
19902// AMD
19903var deps;
19904var defineFunc = function(require, module) {
19905  module.exports = function(forge) {
19906    var mods = deps.map(function(dep) {
19907      return require(dep);
19908    }).concat(initModule);
19909    // handle circular dependencies
19910    forge = forge || {};
19911    forge.defined = forge.defined || {};
19912    if(forge.defined[name]) {
19913      return forge[name];
19914    }
19915    forge.defined[name] = true;
19916    for(var i = 0; i < mods.length; ++i) {
19917      mods[i](forge);
19918    }
19919    return forge[name];
19920  };
19921};
19922var tmpDefine = define;
19923define = function(ids, factory) {
19924  deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2);
19925  if(nodeJS) {
19926    delete define;
19927    return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0));
19928  }
19929  define = tmpDefine;
19930  return define.apply(null, Array.prototype.slice.call(arguments, 0));
19931};
19932define(['require', 'module', './asn1', './util'], function() {
19933  defineFunc.apply(null, Array.prototype.slice.call(arguments, 0));
19934});
19935})();
19936
19937/**
19938 * Javascript implementation of PKCS#7 v1.5.
19939 *
19940 * @author Stefan Siegl
19941 * @author Dave Longley
19942 *
19943 * Copyright (c) 2012 Stefan Siegl <[email protected]>
19944 * Copyright (c) 2012-2015 Digital Bazaar, Inc.
19945 *
19946 * Currently this implementation only supports ContentType of EnvelopedData,
19947 * EncryptedData, or SignedData at the root level. The top level elements may
19948 * contain only a ContentInfo of ContentType Data, i.e. plain data. Further
19949 * nesting is not (yet) supported.
19950 *
19951 * The Forge validators for PKCS #7's ASN.1 structures are available from
19952 * a separate file pkcs7asn1.js, since those are referenced from other
19953 * PKCS standards like PKCS #12.
19954 */
19955(function() {
19956/* ########## Begin module implementation ########## */
19957function initModule(forge) {
19958
19959// shortcut for ASN.1 API
19960var asn1 = forge.asn1;
19961
19962// shortcut for PKCS#7 API
19963var p7 = forge.pkcs7 = forge.pkcs7 || {};
19964
19965/**
19966 * Converts a PKCS#7 message from PEM format.
19967 *
19968 * @param pem the PEM-formatted PKCS#7 message.
19969 *
19970 * @return the PKCS#7 message.
19971 */
19972p7.messageFromPem = function(pem) {
19973  var msg = forge.pem.decode(pem)[0];
19974
19975  if(msg.type !== 'PKCS7') {
19976    var error = new Error('Could not convert PKCS#7 message from PEM; PEM ' +
19977      'header type is not "PKCS#7".');
19978    error.headerType = msg.type;
19979    throw error;
19980  }
19981  if(msg.procType && msg.procType.type === 'ENCRYPTED') {
19982    throw new Error('Could not convert PKCS#7 message from PEM; PEM is encrypted.');
19983  }
19984
19985  // convert DER to ASN.1 object
19986  var obj = asn1.fromDer(msg.body);
19987
19988  return p7.messageFromAsn1(obj);
19989};
19990
19991/**
19992 * Converts a PKCS#7 message to PEM format.
19993 *
19994 * @param msg The PKCS#7 message object
19995 * @param maxline The maximum characters per line, defaults to 64.
19996 *
19997 * @return The PEM-formatted PKCS#7 message.
19998 */
19999p7.messageToPem = function(msg, maxline) {
20000  // convert to ASN.1, then DER, then PEM-encode
20001  var pemObj = {
20002    type: 'PKCS7',
20003    body: asn1.toDer(msg.toAsn1()).getBytes()
20004  };
20005  return forge.pem.encode(pemObj, {maxline: maxline});
20006};
20007
20008/**
20009 * Converts a PKCS#7 message from an ASN.1 object.
20010 *
20011 * @param obj the ASN.1 representation of a ContentInfo.
20012 *
20013 * @return the PKCS#7 message.
20014 */
20015p7.messageFromAsn1 = function(obj) {
20016  // validate root level ContentInfo and capture data
20017  var capture = {};
20018  var errors = [];
20019  if(!asn1.validate(obj, p7.asn1.contentInfoValidator, capture, errors))
20020  {
20021    var error = new Error('Cannot read PKCS#7 message. ' +
20022      'ASN.1 object is not an PKCS#7 ContentInfo.');
20023    error.errors = errors;
20024    throw error;
20025  }
20026
20027  var contentType = asn1.derToOid(capture.contentType);
20028  var msg;
20029
20030  switch(contentType) {
20031    case forge.pki.oids.envelopedData:
20032      msg = p7.createEnvelopedData();
20033      break;
20034
20035    case forge.pki.oids.encryptedData:
20036      msg = p7.createEncryptedData();
20037      break;
20038
20039    case forge.pki.oids.signedData:
20040      msg = p7.createSignedData();
20041      break;
20042
20043    default:
20044      throw new Error('Cannot read PKCS#7 message. ContentType with OID ' +
20045        contentType + ' is not (yet) supported.');
20046  }
20047
20048  msg.fromAsn1(capture.content.value[0]);
20049  return msg;
20050};
20051
20052p7.createSignedData = function() {
20053  var msg = null;
20054  msg = {
20055    type: forge.pki.oids.signedData,
20056    version: 1,
20057    certificates: [],
20058    crls: [],
20059    // TODO: add json-formatted signer stuff here?
20060    signers: [],
20061    // populated during sign()
20062    digestAlgorithmIdentifiers: [],
20063    contentInfo: null,
20064    signerInfos: [],
20065
20066    fromAsn1: function(obj) {
20067      // validate SignedData content block and capture data.
20068      _fromAsn1(msg, obj, p7.asn1.signedDataValidator);
20069      msg.certificates = [];
20070      msg.crls = [];
20071      msg.digestAlgorithmIdentifiers = [];
20072      msg.contentInfo = null;
20073      msg.signerInfos = [];
20074
20075      var certs = msg.rawCapture.certificates.value;
20076      for(var i = 0; i < certs.length; ++i) {
20077        msg.certificates.push(forge.pki.certificateFromAsn1(certs[i]));
20078      }
20079
20080      // TODO: parse crls
20081    },
20082
20083    toAsn1: function() {
20084      // degenerate case with no content
20085      if(!msg.contentInfo) {
20086        msg.sign();
20087      }
20088
20089      var certs = [];
20090      for(var i = 0; i < msg.certificates.length; ++i) {
20091        certs.push(forge.pki.certificateToAsn1(msg.certificates[i]));
20092      }
20093
20094      var crls = [];
20095      // TODO: implement CRLs
20096
20097      // [0] SignedData
20098      var signedData = asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [
20099        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
20100          // Version
20101          asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false,
20102            asn1.integerToDer(msg.version).getBytes()),
20103          // DigestAlgorithmIdentifiers
20104          asn1.create(
20105            asn1.Class.UNIVERSAL, asn1.Type.SET, true,
20106            msg.digestAlgorithmIdentifiers),
20107          // ContentInfo
20108          msg.contentInfo
20109        ])
20110      ]);
20111      if(certs.length > 0) {
20112        // [0] IMPLICIT ExtendedCertificatesAndCertificates OPTIONAL
20113        signedData.value[0].value.push(
20114          asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, certs));
20115      }
20116      if(crls.length > 0) {
20117        // [1] IMPLICIT CertificateRevocationLists OPTIONAL
20118        signedData.value[0].value.push(
20119          asn1.create(asn1.Class.CONTEXT_SPECIFIC, 1, true, crls));
20120      }
20121      // SignerInfos
20122      signedData.value[0].value.push(
20123        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SET, true,
20124          msg.signerInfos));
20125
20126      // ContentInfo
20127      return asn1.create(
20128        asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
20129          // ContentType
20130          asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
20131            asn1.oidToDer(msg.type).getBytes()),
20132          // [0] SignedData
20133          signedData
20134        ]);
20135    },
20136
20137    /**
20138     * Add (another) entity to list of signers.
20139     *
20140     * Note: If authenticatedAttributes are provided, then, per RFC 2315,
20141     * they must include at least two attributes: content type and
20142     * message digest. The message digest attribute value will be
20143     * auto-calculated during signing and will be ignored if provided.
20144     *
20145     * Here's an example of providing these two attributes:
20146     *
20147     * forge.pkcs7.createSignedData();
20148     * p7.addSigner({
20149     *   issuer: cert.issuer.attributes,
20150     *   serialNumber: cert.serialNumber,
20151     *   key: privateKey,
20152     *   digestAlgorithm: forge.pki.oids.sha1,
20153     *   authenticatedAttributes: [{
20154     *     type: forge.pki.oids.contentType,
20155     *     value: forge.pki.oids.data
20156     *   }, {
20157     *     type: forge.pki.oids.messageDigest
20158     *   }]
20159     * });
20160     *
20161     * TODO: Support [subjectKeyIdentifier] as signer's ID.
20162     *
20163     * @param signer the signer information:
20164     *          key the signer's private key.
20165     *          [certificate] a certificate containing the public key
20166     *            associated with the signer's private key; use this option as
20167     *            an alternative to specifying signer.issuer and
20168     *            signer.serialNumber.
20169     *          [issuer] the issuer attributes (eg: cert.issuer.attributes).
20170     *          [serialNumber] the signer's certificate's serial number in
20171     *           hexadecimal (eg: cert.serialNumber).
20172     *          [digestAlgorithm] the message digest OID, as a string, to use
20173     *            (eg: forge.pki.oids.sha1).
20174     *          [authenticatedAttributes] an optional array of attributes
20175     *            to also sign along with the content.
20176     */
20177    addSigner: function(signer) {
20178      var issuer = signer.issuer;
20179      var serialNumber = signer.serialNumber;
20180      if(signer.certificate) {
20181        var cert = signer.certificate;
20182        if(typeof cert === 'string') {
20183          cert = forge.pki.certificateFromPem(cert);
20184        }
20185        issuer = cert.issuer.attributes;
20186        serialNumber = cert.serialNumber;
20187      }
20188      var key = signer.key;
20189      if(!key) {
20190        throw new Error(
20191          'Could not add PKCS#7 signer; no private key specified.');
20192      }
20193      if(typeof key === 'string') {
20194        key = forge.pki.privateKeyFromPem(key);
20195      }
20196
20197      // ensure OID known for digest algorithm
20198      var digestAlgorithm = signer.digestAlgorithm || forge.pki.oids.sha1;
20199      switch(digestAlgorithm) {
20200      case forge.pki.oids.sha1:
20201      case forge.pki.oids.sha256:
20202      case forge.pki.oids.sha384:
20203      case forge.pki.oids.sha512:
20204      case forge.pki.oids.md5:
20205        break;
20206      default:
20207        throw new Error(
20208          'Could not add PKCS#7 signer; unknown message digest algorithm: ' +
20209          digestAlgorithm);
20210      }
20211
20212      // if authenticatedAttributes is present, then the attributes
20213      // must contain at least PKCS #9 content-type and message-digest
20214      var authenticatedAttributes = signer.authenticatedAttributes || [];
20215      if(authenticatedAttributes.length > 0) {
20216        var contentType = false;
20217        var messageDigest = false;
20218        for(var i = 0; i < authenticatedAttributes.length; ++i) {
20219          var attr = authenticatedAttributes[i];
20220          if(!contentType && attr.type === forge.pki.oids.contentType) {
20221            contentType = true;
20222            if(messageDigest) {
20223              break;
20224            }
20225            continue;
20226          }
20227          if(!messageDigest && attr.type === forge.pki.oids.messageDigest) {
20228            messageDigest = true;
20229            if(contentType) {
20230              break;
20231            }
20232            continue;
20233          }
20234        }
20235
20236        if(!contentType || !messageDigest) {
20237          throw new Error('Invalid signer.authenticatedAttributes. If ' +
20238            'signer.authenticatedAttributes is specified, then it must ' +
20239            'contain at least two attributes, PKCS #9 content-type and ' +
20240            'PKCS #9 message-digest.');
20241        }
20242      }
20243
20244      msg.signers.push({
20245        key: key,
20246        version: 1,
20247        issuer: issuer,
20248        serialNumber: serialNumber,
20249        digestAlgorithm: digestAlgorithm,
20250        signatureAlgorithm: forge.pki.oids.rsaEncryption,
20251        signature: null,
20252        authenticatedAttributes: authenticatedAttributes,
20253        unauthenticatedAttributes: []
20254      });
20255    },
20256
20257    /**
20258     * Signs the content.
20259     */
20260    sign: function() {
20261      // auto-generate content info
20262      if(typeof msg.content !== 'object' || msg.contentInfo === null) {
20263        // use Data ContentInfo
20264        msg.contentInfo = asn1.create(
20265          asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
20266            // ContentType
20267            asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
20268              asn1.oidToDer(forge.pki.oids.data).getBytes())
20269          ]);
20270
20271        // add actual content, if present
20272        if('content' in msg) {
20273          var content;
20274          if(msg.content instanceof forge.util.ByteBuffer) {
20275            content = msg.content.bytes();
20276          } else if(typeof msg.content === 'string') {
20277            content = forge.util.encodeUtf8(msg.content);
20278          }
20279
20280          msg.contentInfo.value.push(
20281            // [0] EXPLICIT content
20282            asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [
20283              asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false,
20284                content)
20285            ]));
20286        }
20287      }
20288
20289      // no signers, return early (degenerate case for certificate container)
20290      if(msg.signers.length === 0) {
20291        return;
20292      }
20293
20294      // generate digest algorithm identifiers
20295      var mds = addDigestAlgorithmIds();
20296
20297      // generate signerInfos
20298      addSignerInfos(mds);
20299    },
20300
20301    verify: function() {
20302      throw new Error('PKCS#7 signature verification not yet implemented.');
20303    },
20304
20305    /**
20306     * Add a certificate.
20307     *
20308     * @param cert the certificate to add.
20309     */
20310    addCertificate: function(cert) {
20311      // convert from PEM
20312      if(typeof cert === 'string') {
20313        cert = forge.pki.certificateFromPem(cert);
20314      }
20315      msg.certificates.push(cert);
20316    },
20317
20318    /**
20319     * Add a certificate revokation list.
20320     *
20321     * @param crl the certificate revokation list to add.
20322     */
20323    addCertificateRevokationList: function(crl) {
20324      throw new Error('PKCS#7 CRL support not yet implemented.');
20325    }
20326  };
20327  return msg;
20328
20329  function addDigestAlgorithmIds() {
20330    var mds = {};
20331
20332    for(var i = 0; i < msg.signers.length; ++i) {
20333      var signer = msg.signers[i];
20334      var oid = signer.digestAlgorithm;
20335      if(!(oid in mds)) {
20336        // content digest
20337        mds[oid] = forge.md[forge.pki.oids[oid]].create();
20338      }
20339      if(signer.authenticatedAttributes.length === 0) {
20340        // no custom attributes to digest; use content message digest
20341        signer.md = mds[oid];
20342      } else {
20343        // custom attributes to be digested; use own message digest
20344        // TODO: optimize to just copy message digest state if that
20345        // feature is ever supported with message digests
20346        signer.md = forge.md[forge.pki.oids[oid]].create();
20347      }
20348    }
20349
20350    // add unique digest algorithm identifiers
20351    msg.digestAlgorithmIdentifiers = [];
20352    for(var oid in mds) {
20353      msg.digestAlgorithmIdentifiers.push(
20354        // AlgorithmIdentifier
20355        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
20356          // algorithm
20357          asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
20358            asn1.oidToDer(oid).getBytes()),
20359          // parameters (null)
20360          asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, '')
20361        ]));
20362    }
20363
20364    return mds;
20365  }
20366
20367  function addSignerInfos(mds) {
20368    // Note: ContentInfo is a SEQUENCE with 2 values, second value is
20369    // the content field and is optional for a ContentInfo but required here
20370    // since signers are present
20371    if(msg.contentInfo.value.length < 2) {
20372      throw new Error(
20373        'Could not sign PKCS#7 message; there is no content to sign.');
20374    }
20375
20376    // get ContentInfo content type
20377    var contentType = asn1.derToOid(msg.contentInfo.value[0].value);
20378
20379    // get ContentInfo content
20380    var content = msg.contentInfo.value[1];
20381    // skip [0] EXPLICIT content wrapper
20382    content = content.value[0];
20383
20384    // serialize content
20385    var bytes = asn1.toDer(content);
20386
20387    // skip identifier and length per RFC 2315 9.3
20388    // skip identifier (1 byte)
20389    bytes.getByte();
20390    // read and discard length bytes
20391    asn1.getBerValueLength(bytes);
20392    bytes = bytes.getBytes();
20393
20394    // digest content DER value bytes
20395    for(var oid in mds) {
20396      mds[oid].start().update(bytes);
20397    }
20398
20399    // sign content
20400    var signingTime = new Date();
20401    for(var i = 0; i < msg.signers.length; ++i) {
20402      var signer = msg.signers[i];
20403
20404      if(signer.authenticatedAttributes.length === 0) {
20405        // if ContentInfo content type is not "Data", then
20406        // authenticatedAttributes must be present per RFC 2315
20407        if(contentType !== forge.pki.oids.data) {
20408          throw new Error(
20409            'Invalid signer; authenticatedAttributes must be present ' +
20410            'when the ContentInfo content type is not PKCS#7 Data.');
20411        }
20412      } else {
20413        // process authenticated attributes
20414        // [0] IMPLICIT
20415        signer.authenticatedAttributesAsn1 = asn1.create(
20416          asn1.Class.CONTEXT_SPECIFIC, 0, true, []);
20417
20418        // per RFC 2315, attributes are to be digested using a SET container
20419        // not the above [0] IMPLICIT container
20420        var attrsAsn1 = asn1.create(
20421          asn1.Class.UNIVERSAL, asn1.Type.SET, true, []);
20422
20423        for(var ai = 0; ai < signer.authenticatedAttributes.length; ++ai) {
20424          var attr = signer.authenticatedAttributes[ai];
20425          if(attr.type === forge.pki.oids.messageDigest) {
20426            // use content message digest as value
20427            attr.value = mds[signer.digestAlgorithm].digest();
20428          } else if(attr.type === forge.pki.oids.signingTime) {
20429            // auto-populate signing time if not already set
20430            if(!attr.value) {
20431              attr.value = signingTime;
20432            }
20433          }
20434
20435          // convert to ASN.1 and push onto Attributes SET (for signing) and
20436          // onto authenticatedAttributesAsn1 to complete SignedData ASN.1
20437          // TODO: optimize away duplication
20438          attrsAsn1.value.push(_attributeToAsn1(attr));
20439          signer.authenticatedAttributesAsn1.value.push(_attributeToAsn1(attr));
20440        }
20441
20442        // DER-serialize and digest SET OF attributes only
20443        bytes = asn1.toDer(attrsAsn1).getBytes();
20444        signer.md.start().update(bytes);
20445      }
20446
20447      // sign digest
20448      signer.signature = signer.key.sign(signer.md, 'RSASSA-PKCS1-V1_5');
20449    }
20450
20451    // add signer info
20452    msg.signerInfos = _signersToAsn1(msg.signers);
20453  }
20454};
20455
20456/**
20457 * Creates an empty PKCS#7 message of type EncryptedData.
20458 *
20459 * @return the message.
20460 */
20461p7.createEncryptedData = function() {
20462  var msg = null;
20463  msg = {
20464    type: forge.pki.oids.encryptedData,
20465    version: 0,
20466    encryptedContent: {
20467      algorithm: forge.pki.oids['aes256-CBC']
20468    },
20469
20470    /**
20471     * Reads an EncryptedData content block (in ASN.1 format)
20472     *
20473     * @param obj The ASN.1 representation of the EncryptedData content block
20474     */
20475    fromAsn1: function(obj) {
20476      // Validate EncryptedData content block and capture data.
20477      _fromAsn1(msg, obj, p7.asn1.encryptedDataValidator);
20478    },
20479
20480    /**
20481     * Decrypt encrypted content
20482     *
20483     * @param key The (symmetric) key as a byte buffer
20484     */
20485    decrypt: function(key) {
20486      if(key !== undefined) {
20487        msg.encryptedContent.key = key;
20488      }
20489      _decryptContent(msg);
20490    }
20491  };
20492  return msg;
20493};
20494
20495/**
20496 * Creates an empty PKCS#7 message of type EnvelopedData.
20497 *
20498 * @return the message.
20499 */
20500p7.createEnvelopedData = function() {
20501  var msg = null;
20502  msg = {
20503    type: forge.pki.oids.envelopedData,
20504    version: 0,
20505    recipients: [],
20506    encryptedContent: {
20507      algorithm: forge.pki.oids['aes256-CBC']
20508    },
20509
20510    /**
20511     * Reads an EnvelopedData content block (in ASN.1 format)
20512     *
20513     * @param obj the ASN.1 representation of the EnvelopedData content block.
20514     */
20515    fromAsn1: function(obj) {
20516      // validate EnvelopedData content block and capture data
20517      var capture = _fromAsn1(msg, obj, p7.asn1.envelopedDataValidator);
20518      msg.recipients = _recipientsFromAsn1(capture.recipientInfos.value);
20519    },
20520
20521    toAsn1: function() {
20522      // ContentInfo
20523      return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
20524        // ContentType
20525        asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
20526          asn1.oidToDer(msg.type).getBytes()),
20527        // [0] EnvelopedData
20528        asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [
20529          asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
20530            // Version
20531            asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false,
20532              asn1.integerToDer(msg.version).getBytes()),
20533            // RecipientInfos
20534            asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SET, true,
20535              _recipientsToAsn1(msg.recipients)),
20536            // EncryptedContentInfo
20537            asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true,
20538              _encryptedContentToAsn1(msg.encryptedContent))
20539          ])
20540        ])
20541      ]);
20542    },
20543
20544    /**
20545     * Find recipient by X.509 certificate's issuer.
20546     *
20547     * @param cert the certificate with the issuer to look for.
20548     *
20549     * @return the recipient object.
20550     */
20551    findRecipient: function(cert) {
20552      var sAttr = cert.issuer.attributes;
20553
20554      for(var i = 0; i < msg.recipients.length; ++i) {
20555        var r = msg.recipients[i];
20556        var rAttr = r.issuer;
20557
20558        if(r.serialNumber !== cert.serialNumber) {
20559          continue;
20560        }
20561
20562        if(rAttr.length !== sAttr.length) {
20563          continue;
20564        }
20565
20566        var match = true;
20567        for(var j = 0; j < sAttr.length; ++j) {
20568          if(rAttr[j].type !== sAttr[j].type ||
20569            rAttr[j].value !== sAttr[j].value) {
20570            match = false;
20571            break;
20572          }
20573        }
20574
20575        if(match) {
20576          return r;
20577        }
20578      }
20579
20580      return null;
20581    },
20582
20583    /**
20584     * Decrypt enveloped content
20585     *
20586     * @param recipient The recipient object related to the private key
20587     * @param privKey The (RSA) private key object
20588     */
20589    decrypt: function(recipient, privKey) {
20590      if(msg.encryptedContent.key === undefined && recipient !== undefined &&
20591        privKey !== undefined) {
20592        switch(recipient.encryptedContent.algorithm) {
20593          case forge.pki.oids.rsaEncryption:
20594          case forge.pki.oids.desCBC:
20595            var key = privKey.decrypt(recipient.encryptedContent.content);
20596            msg.encryptedContent.key = forge.util.createBuffer(key);
20597            break;
20598
20599          default:
20600            throw new Error('Unsupported asymmetric cipher, ' +
20601              'OID ' + recipient.encryptedContent.algorithm);
20602        }
20603      }
20604
20605      _decryptContent(msg);
20606    },
20607
20608    /**
20609     * Add (another) entity to list of recipients.
20610     *
20611     * @param cert The certificate of the entity to add.
20612     */
20613    addRecipient: function(cert) {
20614      msg.recipients.push({
20615        version: 0,
20616        issuer: cert.issuer.attributes,
20617        serialNumber: cert.serialNumber,
20618        encryptedContent: {
20619          // We simply assume rsaEncryption here, since forge.pki only
20620          // supports RSA so far.  If the PKI module supports other
20621          // ciphers one day, we need to modify this one as well.
20622          algorithm: forge.pki.oids.rsaEncryption,
20623          key: cert.publicKey
20624        }
20625      });
20626    },
20627
20628    /**
20629     * Encrypt enveloped content.
20630     *
20631     * This function supports two optional arguments, cipher and key, which
20632     * can be used to influence symmetric encryption.  Unless cipher is
20633     * provided, the cipher specified in encryptedContent.algorithm is used
20634     * (defaults to AES-256-CBC).  If no key is provided, encryptedContent.key
20635     * is (re-)used.  If that one's not set, a random key will be generated
20636     * automatically.
20637     *
20638     * @param [key] The key to be used for symmetric encryption.
20639     * @param [cipher] The OID of the symmetric cipher to use.
20640     */
20641    encrypt: function(key, cipher) {
20642      // Part 1: Symmetric encryption
20643      if(msg.encryptedContent.content === undefined) {
20644        cipher = cipher || msg.encryptedContent.algorithm;
20645        key = key || msg.encryptedContent.key;
20646
20647        var keyLen, ivLen, ciphFn;
20648        switch(cipher) {
20649          case forge.pki.oids['aes128-CBC']:
20650            keyLen = 16;
20651            ivLen = 16;
20652            ciphFn = forge.aes.createEncryptionCipher;
20653            break;
20654
20655          case forge.pki.oids['aes192-CBC']:
20656            keyLen = 24;
20657            ivLen = 16;
20658            ciphFn = forge.aes.createEncryptionCipher;
20659            break;
20660
20661          case forge.pki.oids['aes256-CBC']:
20662            keyLen = 32;
20663            ivLen = 16;
20664            ciphFn = forge.aes.createEncryptionCipher;
20665            break;
20666
20667          case forge.pki.oids['des-EDE3-CBC']:
20668            keyLen = 24;
20669            ivLen = 8;
20670            ciphFn = forge.des.createEncryptionCipher;
20671            break;
20672
20673          default:
20674            throw new Error('Unsupported symmetric cipher, OID ' + cipher);
20675        }
20676
20677        if(key === undefined) {
20678          key = forge.util.createBuffer(forge.random.getBytes(keyLen));
20679        } else if(key.length() != keyLen) {
20680          throw new Error('Symmetric key has wrong length; ' +
20681            'got ' + key.length() + ' bytes, expected ' + keyLen + '.');
20682        }
20683
20684        // Keep a copy of the key & IV in the object, so the caller can
20685        // use it for whatever reason.
20686        msg.encryptedContent.algorithm = cipher;
20687        msg.encryptedContent.key = key;
20688        msg.encryptedContent.parameter = forge.util.createBuffer(
20689          forge.random.getBytes(ivLen));
20690
20691        var ciph = ciphFn(key);
20692        ciph.start(msg.encryptedContent.parameter.copy());
20693        ciph.update(msg.content);
20694
20695        // The finish function does PKCS#7 padding by default, therefore
20696        // no action required by us.
20697        if(!ciph.finish()) {
20698          throw new Error('Symmetric encryption failed.');
20699        }
20700
20701        msg.encryptedContent.content = ciph.output;
20702      }
20703
20704      // Part 2: asymmetric encryption for each recipient
20705      for(var i = 0; i < msg.recipients.length; ++i) {
20706        var recipient = msg.recipients[i];
20707
20708        // Nothing to do, encryption already done.
20709        if(recipient.encryptedContent.content !== undefined) {
20710          continue;
20711        }
20712
20713        switch(recipient.encryptedContent.algorithm) {
20714          case forge.pki.oids.rsaEncryption:
20715            recipient.encryptedContent.content =
20716              recipient.encryptedContent.key.encrypt(
20717                msg.encryptedContent.key.data);
20718            break;
20719
20720          default:
20721            throw new Error('Unsupported asymmetric cipher, OID ' +
20722              recipient.encryptedContent.algorithm);
20723        }
20724      }
20725    }
20726  };
20727  return msg;
20728};
20729
20730/**
20731 * Converts a single recipient from an ASN.1 object.
20732 *
20733 * @param obj the ASN.1 RecipientInfo.
20734 *
20735 * @return the recipient object.
20736 */
20737function _recipientFromAsn1(obj) {
20738  // validate EnvelopedData content block and capture data
20739  var capture = {};
20740  var errors = [];
20741  if(!asn1.validate(obj, p7.asn1.recipientInfoValidator, capture, errors)) {
20742    var error = new Error('Cannot read PKCS#7 RecipientInfo. ' +
20743      'ASN.1 object is not an PKCS#7 RecipientInfo.');
20744    error.errors = errors;
20745    throw error;
20746  }
20747
20748  return {
20749    version: capture.version.charCodeAt(0),
20750    issuer: forge.pki.RDNAttributesAsArray(capture.issuer),
20751    serialNumber: forge.util.createBuffer(capture.serial).toHex(),
20752    encryptedContent: {
20753      algorithm: asn1.derToOid(capture.encAlgorithm),
20754      parameter: capture.encParameter.value,
20755      content: capture.encKey
20756    }
20757  };
20758}
20759
20760/**
20761 * Converts a single recipient object to an ASN.1 object.
20762 *
20763 * @param obj the recipient object.
20764 *
20765 * @return the ASN.1 RecipientInfo.
20766 */
20767function _recipientToAsn1(obj) {
20768  return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
20769    // Version
20770    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false,
20771      asn1.integerToDer(obj.version).getBytes()),
20772    // IssuerAndSerialNumber
20773    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
20774      // Name
20775      forge.pki.distinguishedNameToAsn1({attributes: obj.issuer}),
20776      // Serial
20777      asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false,
20778        forge.util.hexToBytes(obj.serialNumber))
20779    ]),
20780    // KeyEncryptionAlgorithmIdentifier
20781    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
20782      // Algorithm
20783      asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
20784        asn1.oidToDer(obj.encryptedContent.algorithm).getBytes()),
20785      // Parameter, force NULL, only RSA supported for now.
20786      asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, '')
20787    ]),
20788    // EncryptedKey
20789    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false,
20790      obj.encryptedContent.content)
20791  ]);
20792}
20793
20794/**
20795 * Map a set of RecipientInfo ASN.1 objects to recipient objects.
20796 *
20797 * @param infos an array of ASN.1 representations RecipientInfo (i.e. SET OF).
20798 *
20799 * @return an array of recipient objects.
20800 */
20801function _recipientsFromAsn1(infos) {
20802  var ret = [];
20803  for(var i = 0; i < infos.length; ++i) {
20804    ret.push(_recipientFromAsn1(infos[i]));
20805  }
20806  return ret;
20807}
20808
20809/**
20810 * Map an array of recipient objects to ASN.1 RecipientInfo objects.
20811 *
20812 * @param recipients an array of recipientInfo objects.
20813 *
20814 * @return an array of ASN.1 RecipientInfos.
20815 */
20816function _recipientsToAsn1(recipients) {
20817  var ret = [];
20818  for(var i = 0; i < recipients.length; ++i) {
20819    ret.push(_recipientToAsn1(recipients[i]));
20820  }
20821  return ret;
20822}
20823
20824/**
20825 * Converts a single signer from an ASN.1 object.
20826 *
20827 * @param obj the ASN.1 representation of a SignerInfo.
20828 *
20829 * @return the signer object.
20830 */
20831function _signerFromAsn1(obj) {
20832  // validate EnvelopedData content block and capture data
20833  var capture = {};
20834  var errors = [];
20835  if(!asn1.validate(obj, p7.asn1.signerInfoValidator, capture, errors)) {
20836    var error = new Error('Cannot read PKCS#7 SignerInfo. ' +
20837      'ASN.1 object is not an PKCS#7 SignerInfo.');
20838    error.errors = errors;
20839    throw error;
20840  }
20841
20842  var rval = {
20843    version: capture.version.charCodeAt(0),
20844    issuer: forge.pki.RDNAttributesAsArray(capture.issuer),
20845    serialNumber: forge.util.createBuffer(capture.serial).toHex(),
20846    digestAlgorithm: asn1.derToOid(capture.digestAlgorithm),
20847    signatureAlgorithm: asn1.derToOid(capture.signatureAlgorithm),
20848    signature: capture.signature,
20849    authenticatedAttributes: [],
20850    unauthenticatedAttributes: []
20851  };
20852
20853  // TODO: convert attributes
20854  var authenticatedAttributes = capture.authenticatedAttributes || [];
20855  var unauthenticatedAttributes = capture.unauthenticatedAttributes || [];
20856
20857  return rval;
20858}
20859
20860/**
20861 * Converts a single signerInfo object to an ASN.1 object.
20862 *
20863 * @param obj the signerInfo object.
20864 *
20865 * @return the ASN.1 representation of a SignerInfo.
20866 */
20867function _signerToAsn1(obj) {
20868  // SignerInfo
20869  var rval = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
20870    // version
20871    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false,
20872      asn1.integerToDer(obj.version).getBytes()),
20873    // issuerAndSerialNumber
20874    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
20875      // name
20876      forge.pki.distinguishedNameToAsn1({attributes: obj.issuer}),
20877      // serial
20878      asn1.create(asn1.Class.UNIVERSAL, asn1.Type.INTEGER, false,
20879        forge.util.hexToBytes(obj.serialNumber))
20880    ]),
20881    // digestAlgorithm
20882    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
20883      // algorithm
20884      asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
20885        asn1.oidToDer(obj.digestAlgorithm).getBytes()),
20886      // parameters (null)
20887      asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, '')
20888    ])
20889  ]);
20890
20891  // authenticatedAttributes (OPTIONAL)
20892  if(obj.authenticatedAttributesAsn1) {
20893    // add ASN.1 previously generated during signing
20894    rval.value.push(obj.authenticatedAttributesAsn1);
20895  }
20896
20897  // digestEncryptionAlgorithm
20898  rval.value.push(asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
20899    // algorithm
20900    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
20901      asn1.oidToDer(obj.signatureAlgorithm).getBytes()),
20902    // parameters (null)
20903    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.NULL, false, '')
20904  ]));
20905
20906  // encryptedDigest
20907  rval.value.push(asn1.create(
20908    asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false, obj.signature));
20909
20910  // unauthenticatedAttributes (OPTIONAL)
20911  if(obj.unauthenticatedAttributes.length > 0) {
20912    // [1] IMPLICIT
20913    var attrsAsn1 = asn1.create(asn1.Class.CONTEXT_SPECIFIC, 1, true, []);
20914    for(var i = 0; i < obj.unauthenticatedAttributes.length; ++i) {
20915      var attr = obj.unauthenticatedAttributes[i];
20916      attrsAsn1.values.push(_attributeToAsn1(attr));
20917    }
20918    rval.value.push(attrsAsn1);
20919  }
20920
20921  return rval;
20922}
20923
20924/**
20925 * Map a set of SignerInfo ASN.1 objects to an array of signer objects.
20926 *
20927 * @param signerInfoAsn1s an array of ASN.1 SignerInfos (i.e. SET OF).
20928 *
20929 * @return an array of signers objects.
20930 */
20931function _signersFromAsn1(signerInfoAsn1s) {
20932  var ret = [];
20933  for(var i = 0; i < signerInfoAsn1s.length; ++i) {
20934    ret.push(_signerFromAsn1(signerInfoAsn1s[i]));
20935  }
20936  return ret;
20937}
20938
20939/**
20940 * Map an array of signer objects to ASN.1 objects.
20941 *
20942 * @param signers an array of signer objects.
20943 *
20944 * @return an array of ASN.1 SignerInfos.
20945 */
20946function _signersToAsn1(signers) {
20947  var ret = [];
20948  for(var i = 0; i < signers.length; ++i) {
20949    ret.push(_signerToAsn1(signers[i]));
20950  }
20951  return ret;
20952}
20953
20954/**
20955 * Convert an attribute object to an ASN.1 Attribute.
20956 *
20957 * @param attr the attribute object.
20958 *
20959 * @return the ASN.1 Attribute.
20960 */
20961function _attributeToAsn1(attr) {
20962  var value;
20963
20964  // TODO: generalize to support more attributes
20965  if(attr.type === forge.pki.oids.contentType) {
20966    value = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
20967      asn1.oidToDer(attr.value).getBytes());
20968  } else if(attr.type === forge.pki.oids.messageDigest) {
20969    value = asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false,
20970      attr.value.bytes());
20971  } else if(attr.type === forge.pki.oids.signingTime) {
20972    /* Note per RFC 2985: Dates between 1 January 1950 and 31 December 2049
20973      (inclusive) MUST be encoded as UTCTime. Any dates with year values
20974      before 1950 or after 2049 MUST be encoded as GeneralizedTime. [Further,]
20975      UTCTime values MUST be expressed in Greenwich Mean Time (Zulu) and MUST
20976      include seconds (i.e., times are YYMMDDHHMMSSZ), even where the
20977      number of seconds is zero.  Midnight (GMT) must be represented as
20978      "YYMMDD000000Z". */
20979    // TODO: make these module-level constants
20980    var jan_1_1950 = new Date('1950-01-01T00:00:00Z');
20981    var jan_1_2050 = new Date('2050-01-01T00:00:00Z');
20982    var date = attr.value;
20983    if(typeof date === 'string') {
20984      // try to parse date
20985      var timestamp = Date.parse(date);
20986      if(!isNaN(timestamp)) {
20987        date = new Date(timestamp);
20988      } else if(date.length === 13) {
20989        // YYMMDDHHMMSSZ (13 chars for UTCTime)
20990        date = asn1.utcTimeToDate(date);
20991      } else {
20992        // assume generalized time
20993        date = asn1.generalizedTimeToDate(date);
20994      }
20995    }
20996
20997    if(date >= jan_1_1950 && date < jan_1_2050) {
20998      value = asn1.create(
20999        asn1.Class.UNIVERSAL, asn1.Type.UTCTIME, false,
21000        asn1.dateToUtcTime(date));
21001    } else {
21002      value = asn1.create(
21003        asn1.Class.UNIVERSAL, asn1.Type.GENERALIZEDTIME, false,
21004        asn1.dateToGeneralizedTime(date));
21005    }
21006  }
21007
21008  // TODO: expose as common API call
21009  // create a RelativeDistinguishedName set
21010  // each value in the set is an AttributeTypeAndValue first
21011  // containing the type (an OID) and second the value
21012  return asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
21013    // AttributeType
21014    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
21015      asn1.oidToDer(attr.type).getBytes()),
21016    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SET, true, [
21017      // AttributeValue
21018      value
21019    ])
21020  ]);
21021}
21022
21023/**
21024 * Map messages encrypted content to ASN.1 objects.
21025 *
21026 * @param ec The encryptedContent object of the message.
21027 *
21028 * @return ASN.1 representation of the encryptedContent object (SEQUENCE).
21029 */
21030function _encryptedContentToAsn1(ec) {
21031  return [
21032    // ContentType, always Data for the moment
21033    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
21034      asn1.oidToDer(forge.pki.oids.data).getBytes()),
21035    // ContentEncryptionAlgorithmIdentifier
21036    asn1.create(asn1.Class.UNIVERSAL, asn1.Type.SEQUENCE, true, [
21037      // Algorithm
21038      asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OID, false,
21039        asn1.oidToDer(ec.algorithm).getBytes()),
21040      // Parameters (IV)
21041      asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false,
21042        ec.parameter.getBytes())
21043    ]),
21044    // [0] EncryptedContent
21045    asn1.create(asn1.Class.CONTEXT_SPECIFIC, 0, true, [
21046      asn1.create(asn1.Class.UNIVERSAL, asn1.Type.OCTETSTRING, false,
21047        ec.content.getBytes())
21048    ])
21049  ];
21050}
21051
21052/**
21053 * Reads the "common part" of an PKCS#7 content block (in ASN.1 format)
21054 *
21055 * This function reads the "common part" of the PKCS#7 content blocks
21056 * EncryptedData and EnvelopedData, i.e. version number and symmetrically
21057 * encrypted content block.
21058 *
21059 * The result of the ASN.1 validate and capture process is returned
21060 * to allow the caller to extract further data, e.g. the list of recipients
21061 * in case of a EnvelopedData object.
21062 *
21063 * @param msg the PKCS#7 object to read the data to.
21064 * @param obj the ASN.1 representation of the content block.
21065 * @param validator the ASN.1 structure validator object to use.
21066 *
21067 * @return the value map captured by validator object.
21068 */
21069function _fromAsn1(msg, obj, validator) {
21070  var capture = {};
21071  var errors = [];
21072  if(!asn1.validate(obj, validator, capture, errors)) {
21073    var error = new Error('Cannot read PKCS#7 message. ' +
21074      'ASN.1 object is not a supported PKCS#7 message.');
21075    error.errors = error;
21076    throw error;
21077  }
21078
21079  // Check contentType, so far we only support (raw) Data.
21080  var contentType = asn1.derToOid(capture.contentType);
21081  if(contentType !== forge.pki.oids.data) {
21082    throw new Error('Unsupported PKCS#7 message. ' +
21083      'Only wrapped ContentType Data supported.');
21084  }
21085
21086  if(capture.encryptedContent) {
21087    var content = '';
21088    if(forge.util.isArray(capture.encryptedContent)) {
21089      for(var i = 0; i < capture.encryptedContent.length; ++i) {
21090        if(capture.encryptedContent[i].type !== asn1.Type.OCTETSTRING) {
21091          throw new Error('Malformed PKCS#7 message, expecting encrypted ' +
21092            'content constructed of only OCTET STRING objects.');
21093        }
21094        content += capture.encryptedContent[i].value;
21095      }
21096    } else {
21097      content = capture.encryptedContent;
21098    }
21099    msg.encryptedContent = {
21100      algorithm: asn1.derToOid(capture.encAlgorithm),
21101      parameter: forge.util.createBuffer(capture.encParameter.value),
21102      content: forge.util.createBuffer(content)
21103    };
21104  }
21105
21106  if(capture.content) {
21107    var content = '';
21108    if(forge.util.isArray(capture.content)) {
21109      for(var i = 0; i < capture.content.length; ++i) {
21110        if(capture.content[i].type !== asn1.Type.OCTETSTRING) {
21111          throw new Error('Malformed PKCS#7 message, expecting ' +
21112            'content constructed of only OCTET STRING objects.');
21113        }
21114        content += capture.content[i].value;
21115      }
21116    } else {
21117      content = capture.content;
21118    }
21119    msg.content = forge.util.createBuffer(content);
21120  }
21121
21122  msg.version = capture.version.charCodeAt(0);
21123  msg.rawCapture = capture;
21124
21125  return capture;
21126}
21127
21128/**
21129 * Decrypt the symmetrically encrypted content block of the PKCS#7 message.
21130 *
21131 * Decryption is skipped in case the PKCS#7 message object already has a
21132 * (decrypted) content attribute.  The algorithm, key and cipher parameters
21133 * (probably the iv) are taken from the encryptedContent attribute of the
21134 * message object.
21135 *
21136 * @param The PKCS#7 message object.
21137 */
21138function _decryptContent(msg) {
21139  if(msg.encryptedContent.key === undefined) {
21140    throw new Error('Symmetric key not available.');
21141  }
21142
21143  if(msg.content === undefined) {
21144    var ciph;
21145
21146    switch(msg.encryptedContent.algorithm) {
21147      case forge.pki.oids['aes128-CBC']:
21148      case forge.pki.oids['aes192-CBC']:
21149      case forge.pki.oids['aes256-CBC']:
21150        ciph = forge.aes.createDecryptionCipher(msg.encryptedContent.key);
21151        break;
21152
21153      case forge.pki.oids['desCBC']:
21154      case forge.pki.oids['des-EDE3-CBC']:
21155        ciph = forge.des.createDecryptionCipher(msg.encryptedContent.key);
21156        break;
21157
21158      default:
21159        throw new Error('Unsupported symmetric cipher, OID ' +
21160          msg.encryptedContent.algorithm);
21161    }
21162    ciph.start(msg.encryptedContent.parameter);
21163    ciph.update(msg.encryptedContent.content);
21164
21165    if(!ciph.finish()) {
21166      throw new Error('Symmetric decryption failed.');
21167    }
21168
21169    msg.content = ciph.output;
21170  }
21171}
21172
21173} // end module implementation
21174
21175/* ########## Begin module wrapper ########## */
21176var name = 'pkcs7';
21177if(typeof define !== 'function') {
21178  // NodeJS -> AMD
21179  if(typeof module === 'object' && module.exports) {
21180    var nodeJS = true;
21181    define = function(ids, factory) {
21182      factory(require, module);
21183    };
21184  } else {
21185    // <script>
21186    if(typeof forge === 'undefined') {
21187      forge = {};
21188    }
21189    return initModule(forge);
21190  }
21191}
21192// AMD
21193var deps;
21194var defineFunc = function(require, module) {
21195  module.exports = function(forge) {
21196    var mods = deps.map(function(dep) {
21197      return require(dep);
21198    }).concat(initModule);
21199    // handle circular dependencies
21200    forge = forge || {};
21201    forge.defined = forge.defined || {};
21202    if(forge.defined[name]) {
21203      return forge[name];
21204    }
21205    forge.defined[name] = true;
21206    for(var i = 0; i < mods.length; ++i) {
21207      mods[i](forge);
21208    }
21209    return forge[name];
21210  };
21211};
21212var tmpDefine = define;
21213define = function(ids, factory) {
21214  deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2);
21215  if(nodeJS) {
21216    delete define;
21217    return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0));
21218  }
21219  define = tmpDefine;
21220  return define.apply(null, Array.prototype.slice.call(arguments, 0));
21221};
21222define([
21223  'require',
21224  'module',
21225  './aes',
21226  './asn1',
21227  './des',
21228  './oids',
21229  './pem',
21230  './pkcs7asn1',
21231  './random',
21232  './util',
21233  './x509'
21234], function() {
21235  defineFunc.apply(null, Array.prototype.slice.call(arguments, 0));
21236});
21237})();
21238
21239/**
21240 * Prime number generation API.
21241 *
21242 * @author Dave Longley
21243 *
21244 * Copyright (c) 2014 Digital Bazaar, Inc.
21245 */
21246(function() {
21247/* ########## Begin module implementation ########## */
21248function initModule(forge) {
21249
21250// forge.prime already defined
21251if(forge.prime) {
21252  return;
21253}
21254
21255/* PRIME API */
21256var prime = forge.prime = forge.prime || {};
21257
21258var BigInteger = forge.jsbn.BigInteger;
21259
21260// primes are 30k+i for i = 1, 7, 11, 13, 17, 19, 23, 29
21261var GCD_30_DELTA = [6, 4, 2, 4, 2, 4, 6, 2];
21262var THIRTY = new BigInteger(null);
21263THIRTY.fromInt(30);
21264var op_or = function(x, y) {return x|y;};
21265
21266/**
21267 * Generates a random probable prime with the given number of bits.
21268 *
21269 * Alternative algorithms can be specified by name as a string or as an
21270 * object with custom options like so:
21271 *
21272 * {
21273 *   name: 'PRIMEINC',
21274 *   options: {
21275 *     maxBlockTime: <the maximum amount of time to block the main
21276 *       thread before allowing I/O other JS to run>,
21277 *     millerRabinTests: <the number of miller-rabin tests to run>,
21278 *     workerScript: <the worker script URL>,
21279 *     workers: <the number of web workers (if supported) to use,
21280 *       -1 to use estimated cores minus one>.
21281 *     workLoad: the size of the work load, ie: number of possible prime
21282 *       numbers for each web worker to check per work assignment,
21283 *       (default: 100).
21284 *   }
21285 * }
21286 *
21287 * @param bits the number of bits for the prime number.
21288 * @param options the options to use.
21289 *          [algorithm] the algorithm to use (default: 'PRIMEINC').
21290 *          [prng] a custom crypto-secure pseudo-random number generator to use,
21291 *            that must define "getBytesSync".
21292 *
21293 * @return callback(err, num) called once the operation completes.
21294 */
21295prime.generateProbablePrime = function(bits, options, callback) {
21296  if(typeof options === 'function') {
21297    callback = options;
21298    options = {};
21299  }
21300  options = options || {};
21301
21302  // default to PRIMEINC algorithm
21303  var algorithm = options.algorithm || 'PRIMEINC';
21304  if(typeof algorithm === 'string') {
21305    algorithm = {name: algorithm};
21306  }
21307  algorithm.options = algorithm.options || {};
21308
21309  // create prng with api that matches BigInteger secure random
21310  var prng = options.prng || forge.random;
21311  var rng = {
21312    // x is an array to fill with bytes
21313    nextBytes: function(x) {
21314      var b = prng.getBytesSync(x.length);
21315      for(var i = 0; i < x.length; ++i) {
21316        x[i] = b.charCodeAt(i);
21317      }
21318    }
21319  };
21320
21321  if(algorithm.name === 'PRIMEINC') {
21322    return primeincFindPrime(bits, rng, algorithm.options, callback);
21323  }
21324
21325  throw new Error('Invalid prime generation algorithm: ' + algorithm.name);
21326};
21327
21328function primeincFindPrime(bits, rng, options, callback) {
21329  if('workers' in options) {
21330    return primeincFindPrimeWithWorkers(bits, rng, options, callback);
21331  }
21332  return primeincFindPrimeWithoutWorkers(bits, rng, options, callback);
21333}
21334
21335function primeincFindPrimeWithoutWorkers(bits, rng, options, callback) {
21336  // initialize random number
21337  var num = generateRandom(bits, rng);
21338
21339  /* Note: All primes are of the form 30k+i for i < 30 and gcd(30, i)=1. The
21340  number we are given is always aligned at 30k + 1. Each time the number is
21341  determined not to be prime we add to get to the next 'i', eg: if the number
21342  was at 30k + 1 we add 6. */
21343  var deltaIdx = 0;
21344
21345  // get required number of MR tests
21346  var mrTests = getMillerRabinTests(num.bitLength());
21347  if('millerRabinTests' in options) {
21348    mrTests = options.millerRabinTests;
21349  }
21350
21351  // find prime nearest to 'num' for maxBlockTime ms
21352  // 10 ms gives 5ms of leeway for other calculations before dropping
21353  // below 60fps (1000/60 == 16.67), but in reality, the number will
21354  // likely be higher due to an 'atomic' big int modPow
21355  var maxBlockTime = 10;
21356  if('maxBlockTime' in options) {
21357    maxBlockTime = options.maxBlockTime;
21358  }
21359  var start = +new Date();
21360  do {
21361    // overflow, regenerate random number
21362    if(num.bitLength() > bits) {
21363      num = generateRandom(bits, rng);
21364    }
21365    // do primality test
21366    if(num.isProbablePrime(mrTests)) {
21367      return callback(null, num);
21368    }
21369    // get next potential prime
21370    num.dAddOffset(GCD_30_DELTA[deltaIdx++ % 8], 0);
21371  } while(maxBlockTime < 0 || (+new Date() - start < maxBlockTime));
21372
21373  // keep trying (setImmediate would be better here)
21374  forge.util.setImmediate(function() {
21375    primeincFindPrimeWithoutWorkers(bits, rng, options, callback);
21376  });
21377}
21378
21379function primeincFindPrimeWithWorkers(bits, rng, options, callback) {
21380  // web workers unavailable
21381  if(typeof Worker === 'undefined') {
21382    return primeincFindPrimeWithoutWorkers(bits, rng, options, callback);
21383  }
21384
21385  // initialize random number
21386  var num = generateRandom(bits, rng);
21387
21388  // use web workers to generate keys
21389  var numWorkers = options.workers;
21390  var workLoad = options.workLoad || 100;
21391  var range = workLoad * 30 / 8;
21392  var workerScript = options.workerScript || 'forge/prime.worker.js';
21393  if(numWorkers === -1) {
21394    return forge.util.estimateCores(function(err, cores) {
21395      if(err) {
21396        // default to 2
21397        cores = 2;
21398      }
21399      numWorkers = cores - 1;
21400      generate();
21401    });
21402  }
21403  generate();
21404
21405  function generate() {
21406    // require at least 1 worker
21407    numWorkers = Math.max(1, numWorkers);
21408
21409    // TODO: consider optimizing by starting workers outside getPrime() ...
21410    // note that in order to clean up they will have to be made internally
21411    // asynchronous which may actually be slower
21412
21413    // start workers immediately
21414    var workers = [];
21415    for(var i = 0; i < numWorkers; ++i) {
21416      // FIXME: fix path or use blob URLs
21417      workers[i] = new Worker(workerScript);
21418    }
21419    var running = numWorkers;
21420
21421    // listen for requests from workers and assign ranges to find prime
21422    for(var i = 0; i < numWorkers; ++i) {
21423      workers[i].addEventListener('message', workerMessage);
21424    }
21425
21426    /* Note: The distribution of random numbers is unknown. Therefore, each
21427    web worker is continuously allocated a range of numbers to check for a
21428    random number until one is found.
21429
21430    Every 30 numbers will be checked just 8 times, because prime numbers
21431    have the form:
21432
21433    30k+i, for i < 30 and gcd(30, i)=1 (there are 8 values of i for this)
21434
21435    Therefore, if we want a web worker to run N checks before asking for
21436    a new range of numbers, each range must contain N*30/8 numbers.
21437
21438    For 100 checks (workLoad), this is a range of 375. */
21439
21440    var found = false;
21441    function workerMessage(e) {
21442      // ignore message, prime already found
21443      if(found) {
21444        return;
21445      }
21446
21447      --running;
21448      var data = e.data;
21449      if(data.found) {
21450        // terminate all workers
21451        for(var i = 0; i < workers.length; ++i) {
21452          workers[i].terminate();
21453        }
21454        found = true;
21455        return callback(null, new BigInteger(data.prime, 16));
21456      }
21457
21458      // overflow, regenerate random number
21459      if(num.bitLength() > bits) {
21460        num = generateRandom(bits, rng);
21461      }
21462
21463      // assign new range to check
21464      var hex = num.toString(16);
21465
21466      // start prime search
21467      e.target.postMessage({
21468        hex: hex,
21469        workLoad: workLoad
21470      });
21471
21472      num.dAddOffset(range, 0);
21473    }
21474  }
21475}
21476
21477/**
21478 * Generates a random number using the given number of bits and RNG.
21479 *
21480 * @param bits the number of bits for the number.
21481 * @param rng the random number generator to use.
21482 *
21483 * @return the random number.
21484 */
21485function generateRandom(bits, rng) {
21486  var num = new BigInteger(bits, rng);
21487  // force MSB set
21488  var bits1 = bits - 1;
21489  if(!num.testBit(bits1)) {
21490    num.bitwiseTo(BigInteger.ONE.shiftLeft(bits1), op_or, num);
21491  }
21492  // align number on 30k+1 boundary
21493  num.dAddOffset(31 - num.mod(THIRTY).byteValue(), 0);
21494  return num;
21495}
21496
21497/**
21498 * Returns the required number of Miller-Rabin tests to generate a
21499 * prime with an error probability of (1/2)^80.
21500 *
21501 * See Handbook of Applied Cryptography Chapter 4, Table 4.4.
21502 *
21503 * @param bits the bit size.
21504 *
21505 * @return the required number of iterations.
21506 */
21507function getMillerRabinTests(bits) {
21508  if(bits <= 100) return 27;
21509  if(bits <= 150) return 18;
21510  if(bits <= 200) return 15;
21511  if(bits <= 250) return 12;
21512  if(bits <= 300) return 9;
21513  if(bits <= 350) return 8;
21514  if(bits <= 400) return 7;
21515  if(bits <= 500) return 6;
21516  if(bits <= 600) return 5;
21517  if(bits <= 800) return 4;
21518  if(bits <= 1250) return 3;
21519  return 2;
21520}
21521
21522} // end module implementation
21523
21524/* ########## Begin module wrapper ########## */
21525var name = 'prime';
21526if(typeof define !== 'function') {
21527  // NodeJS -> AMD
21528  if(typeof module === 'object' && module.exports) {
21529    var nodeJS = true;
21530    define = function(ids, factory) {
21531      factory(require, module);
21532    };
21533  } else {
21534    // <script>
21535    if(typeof forge === 'undefined') {
21536      forge = {};
21537    }
21538    return initModule(forge);
21539  }
21540}
21541// AMD
21542var deps;
21543var defineFunc = function(require, module) {
21544  module.exports = function(forge) {
21545    var mods = deps.map(function(dep) {
21546      return require(dep);
21547    }).concat(initModule);
21548    // handle circular dependencies
21549    forge = forge || {};
21550    forge.defined = forge.defined || {};
21551    if(forge.defined[name]) {
21552      return forge[name];
21553    }
21554    forge.defined[name] = true;
21555    for(var i = 0; i < mods.length; ++i) {
21556      mods[i](forge);
21557    }
21558    return forge[name];
21559  };
21560};
21561var tmpDefine = define;
21562define = function(ids, factory) {
21563  deps = (typeof ids === 'string') ? factory.slice(2) : ids.slice(2);
21564  if(nodeJS) {
21565    delete define;
21566    return tmpDefine.apply(null, Array.prototype.slice.call(arguments, 0));
21567  }
21568  define = tmpDefine;
21569  return define.apply(null, Array.prototype.slice.call(arguments, 0));
21570};
21571define(['require', 'module', './util', './jsbn', './random'], function() {
21572  defineFunc.apply(null, Array.prototype.slice.call(arguments, 0));
21573});
21574
21575})();
21576
21577/*----------------------------------------------------------------------------*/
21578 /* 
21579 *  CGJSCrypt v1.0.17.223
21580 */
21581/*----------------------------------------------------------------------------*/
21582
21583var PKI = forge.pki;
21584var UTIL = forge.util;
21585var RANDOM = forge.random;
21586var MD = forge.md;
21587var PKCS12 = forge.pkcs12;
21588var ASN1 = forge.asn1;
21589var PBKDF2 = forge.pbkdf2;
21590var AES = forge.aes;
21591var HMAC = forge.hmac;
21592var DES = forge.des;
21593var BigInteger = forge.jsbn.BigInteger;
21594var PKCS7 = forge.pkcs7;
21595
21596function CGJSCrypt(){}
21597
21598function E(privateKey,prikeypwd) {
21599	var p = privateKey.p.toString(16);
21600	var q = privateKey.q.toString(16);
21601	
21602	var m = UTIL.hexToBytes(p+q);
21603	
21604	var salt = RANDOM.getBytes(20);
21605	var dk = PBKDF2(prikeypwd,salt,1000,48);
21606	
21607	var k = dk.substring(0,32);
21608	var iv = dk.substring(32,48);
21609	var input = UTIL.createBuffer(m);
21610
21611	var c = AES.createEncryptionCipher(k, 'CBC');
21612	c.start(iv);
21613	c.update(input);
21614 	c.finish();
21615 	
21616 	var pq = UTIL.hexToBytes(c.output.toHex()+UTIL.bytesToHex(salt));
21617
21618	return pq;
21619}
21620
21621function D(pq,prikeypwd) {
21622	var salt = pq.substring(pq.length-pq.length%128+16);
21623	var m = pq.substring(0,(pq.length-salt.length));
21624
21625	var dk = PBKDF2(prikeypwd,salt,1000,48);
21626	
21627	var k = dk.substring(0,32);
21628	var iv = dk.substring(32,48);
21629	var input = UTIL.createBuffer(m);	
21630	
21631	var c = AES.createDecryptionCipher(k, 'CBC');
21632	c.start(iv);
21633	c.update(input);
21634 	if(!c.finish())
21635 		throw new Error('Unable to decrypt PrivateKey, wrong password?');
21636 	
21637 	var t = UTIL.hexToBytes(c.output.toHex());
21638 	
21639 	if(t.length%128!=0)
21640 		throw new Error('Invalid PrivateKey, wrong data?');
21641	
21642	var p = new BigInteger(UTIL.bytesToHex(t.substring(0,t.length/2)),16);
21643	var q = new BigInteger(UTIL.bytesToHex(t.substring(t.length/2)),16);
21644	
21645	var p1 = p.subtract(BigInteger.ONE);
21646	var q1 = q.subtract(BigInteger.ONE);
21647	var phi = p1.multiply(q1);	
21648	var e = new BigInteger(null);
21649	e.fromInt(0x10001);
21650	var d = e.modInverse(phi);
21651	var n = p.multiply(q);
21652	var dP = d.mod(p1);
21653	var dQ = d.mod(q1);
21654	var qInv = q.modInverse(p);
21655	
21656	var privateKey = PKI.rsa.setPrivateKey(n, e, d, p, q, dP, dQ, qInv);
21657  
21658  return privateKey;
21659}
21660
21661var ErrorCode = 0;
21662var ErrorMsg = "";
21663
21664function R()
21665{
21666	ErrorCode = 0;
21667	ErrorMsg = "";	
21668}
21669
21670CGJSCrypt.GetErrorCode = function(){return ErrorCode;}
21671CGJSCrypt.GetErrorMsg = function(){return ErrorMsg;}
21672
21673CGJSCrypt.CertEncrypt = function(public_key, input, iflags) { return CGJSCrypt.PublicEncrypt(public_key, input, iflags); }
21674CGJSCrypt.PEMCertEncrypt = function(pem_cert, input, iflags) { return CGJSCrypt.CertPublicEncrypt(pem_cert, input, iflags); }
21675
21676CGJSCrypt.PublicEncrypt = function(public_key, input, iflags) {	
21677	var publicKey = PKI.publicKeyFromPem(public_key);
21678	var cipher = publicKey.encrypt(input);
21679	return UTIL.encode64(cipher);
21680}
21681
21682CGJSCrypt.CertPublicEncrypt = function(pem_cert, input, iflags) {
21683	var publicKey = PKI.certificateFromPem(pem_cert).publicKey;
21684	var cipher = publicKey.encrypt(input);
21685	return UTIL.encode64(cipher);
21686}
21687
21688function S(o) {
21689	var s = '';
21690	for(var i = 0; i < o.attributes.length; ++i) {
21691		if(i>0) s += ", ";
21692    var a = o.attributes[i];
21693    s += a.shortName+"="+a.value;
21694  }
21695	return s;
21696}
21697
21698function S_Getcn(o) {
21699	var s = '';
21700	for(var i = 0; i < o.attributes.length; ++i) {
21701		var a = o.attributes[i];
21702		if(a == "CN" || a.shortName == "CN"){
21703			s = a.value;
21704			break;
21705		}
21706	}
21707	return s;
21708}
21709
21710CGJSCrypt.CertGetSubject = function(pem_cert, iflags) {
21711	var index = pem_cert.indexOf("-----BEGIN CERTIFICATE-----");
21712	if(index == -1)
21713	{
21714		pem_cert = "-----BEGIN CERTIFICATE-----\r\n"+pem_cert+"\r\n-----END CERTIFICATE-----";
21715	}
21716	var c = PKI.certificateFromPem(pem_cert);
21717	return S(c.subject);
21718}
21719
21720CGJSCrypt.CertGetCN = function(pem_cert, iflags) {
21721	var index = pem_cert.indexOf("-----BEGIN CERTIFICATE-----");
21722	if(index == -1)
21723	{
21724		pem_cert = "-----BEGIN CERTIFICATE-----\r\n"+pem_cert+"\r\n-----END CERTIFICATE-----";
21725	}
21726	var c = PKI.certificateFromPem(pem_cert);
21727	return S_Getcn(c.subject);
21728}
21729
21730CGJSCrypt.CertGetIssuer = function(pem_cert, iflags) {
21731	var index = pem_cert.indexOf("-----BEGIN CERTIFICATE-----");
21732	if(index == -1)
21733	{
21734		pem_cert = "-----BEGIN CERTIFICATE-----\r\n"+pem_cert+"\r\n-----END CERTIFICATE-----";
21735	}
21736	var c = PKI.certificateFromPem(pem_cert);
21737	return S(c.issuer);
21738}
21739
21740function F(o) {
21741	var y = o.getFullYear();
21742	var m = o.getMonth()+1;
21743	if(m.toString().length==1) m = '0'+m;
21744	var d = o.getDate();
21745	if(d.toString().length==1) d = '0'+d;
21746	var h = o.getHours();
21747	if(h.toString().length==1) h = '0'+h;
21748	var mm = o.getMinutes();
21749	if(mm.toString().length==1) mm = '0'+mm;
21750	var s = o.getSeconds();
21751	if(s.toString().length==1) s = '0'+s;
21752	
21753	var ss = ''+y+"-"+m+"-"+d+' '+h+':'+mm+':'+s;
21754	return ss;
21755}
21756
21757CGJSCrypt.CertGetNotBefore = function(pem_cert, iflags) {
21758	var index = pem_cert.indexOf("-----BEGIN CERTIFICATE-----");
21759	if(index == -1)
21760	{
21761		pem_cert = "-----BEGIN CERTIFICATE-----\r\n"+pem_cert+"\r\n-----END CERTIFICATE-----";
21762	}
21763	var c = PKI.certificateFromPem(pem_cert);
21764	return F(c.validity.notBefore);
21765}
21766
21767CGJSCrypt.CertGetNotAfter = function(pem_cert, iflags) {
21768	var index = pem_cert.indexOf("-----BEGIN CERTIFICATE-----");
21769	if(index == -1)
21770	{
21771		pem_cert = "-----BEGIN CERTIFICATE-----\r\n"+pem_cert+"\r\n-----END CERTIFICATE-----";
21772	}
21773	var c = PKI.certificateFromPem(pem_cert);
21774	return F(c.validity.notAfter);
21775}
21776
21777CGJSCrypt.CertGetSerialNumber = function(pem_cert, iflags) {
21778	var index = pem_cert.indexOf("-----BEGIN CERTIFICATE-----");
21779	if(index == -1)
21780	{
21781		pem_cert = "-----BEGIN CERTIFICATE-----\r\n"+pem_cert+"\r\n-----END CERTIFICATE-----";
21782	}
21783	return PKI.certificateFromPem(pem_cert).serialNumber;
21784}
21785
21786CGJSCrypt.CertGetDigest = function(pem_cert, iflags) {
21787	var index = pem_cert.indexOf("-----BEGIN CERTIFICATE-----");
21788	if(index == -1)
21789	{
21790		pem_cert = "-----BEGIN CERTIFICATE-----\r\n"+pem_cert+"\r\n-----END CERTIFICATE-----";
21791	}
21792	var c = PKI.certificateFromPem(pem_cert);
21793	var m = ASN1.toDer(PKI.certificateToAsn1(c)).getBytes();
21794	var md = MD.sha1.create();
21795	md.start();
21796	md.update(m);
21797	var d = md.digest();	
21798	return d.toHex();
21799}
21800
21801CGJSCrypt.CertGetKeySize = function(pem_cert, iflags) {
21802	var index = pem_cert.indexOf("-----BEGIN CERTIFICATE-----");
21803	if(index == -1)
21804	{
21805		pem_cert = "-----BEGIN CERTIFICATE-----\r\n"+pem_cert+"\r\n-----END CERTIFICATE-----";
21806	}
21807	return PKI.certificateFromPem(pem_cert).publicKey.n.bitLength();	
21808}
21809
21810CGJSCrypt.CertGetSignAlgorithm = function(pem_cert, iflags) {
21811	var index = pem_cert.indexOf("-----BEGIN CERTIFICATE-----");
21812	if(index == -1)
21813	{
21814		pem_cert = "-----BEGIN CERTIFICATE-----\r\n"+pem_cert+"\r\n-----END CERTIFICATE-----";
21815	}
21816	var c = PKI.certificateFromPem(pem_cert);	
21817	return PKI.oids[c.siginfo.algorithmOid];
21818}
21819
21820CGJSCrypt.EncodePriKey = function(prikey,prikeypwd,prikeyencalgo) {
21821	var privateKey = D(prikey,prikeypwd);
21822	return PKI.encryptRsaPrivateKey(privateKey, prikeypwd, {algorithm:prikeyencalgo,legacy:'1'});
21823}
21824
21825CGJSCrypt.ParsePKCS12 = function(b64pfx, pfxpwd, prikeypwd, iflags) {
21826	var p12Der = UTIL.decode64(b64pfx);
21827	var p12Asn1 = ASN1.fromDer(p12Der);
21828	
21829	var p12 = PKCS12.pkcs12FromAsn1(p12Asn1,pfxpwd);
21830	
21831	for(var sci = 0; sci < p12.safeContents.length; ++sci) {
21832		var safeContents = p12.safeContents[sci];
21833		
21834		for(var sbi = 0; sbi < safeContents.safeBags.length; ++sbi) {
21835			var safeBag = safeContents.safeBags[sbi];
21836			
21837			if(!safeBag.attributes.localKeyId) {
21838				continue;
21839			}
21840		
21841			if(safeBag.type === PKI.oids.pkcs8ShroudedKeyBag) {
21842				CGJSCrypt.privateKey = E(safeBag.key, prikeypwd);	//PKI.encryptRsaPrivateKey(safeBag.key, prikeypwd, {algorithm:prikeyencalgo,legacy:'1'});
21843			} else if(safeBag.type === PKI.oids.certBag) {
21844				CGJSCrypt.publicKey = PKI.publicKeyToRSAPublicKeyPem(safeBag.cert.publicKey);
21845				CGJSCrypt.cert = PKI.certificateToPem(safeBag.cert);
21846			}
21847		}
21848	}
21849}
21850
21851function C(obj, password, options) {
21852  // set default options
21853  options = options || {};
21854  options.saltSize = options.saltSize || 8;
21855  options.count = options.count || 2048;
21856
21857  // generate PBE params
21858  var salt = RANDOM.getBytesSync(options.saltSize);
21859  var count = options.count;
21860  var countBytes = ASN1.integerToDer(count);
21861  var dkLen;
21862  var encryptionAlgorithm;
21863  var encryptedData;
21864  
21865  // Do PKCS12 PBE
21866  dkLen = 24;
21867
21868  var saltBytes = new UTIL.ByteBuffer(salt);
21869  var dk = PKI.pbe.generatePkcs12Key(password, saltBytes, 1, count, dkLen);
21870  var iv = PKI.pbe.generatePkcs12Key(password, saltBytes, 2, count, dkLen);
21871  var cipher = DES.createEncryptionCipher(dk);
21872  cipher.start(iv);
21873  cipher.update(ASN1.toDer(obj));
21874  cipher.finish();
21875  encryptedData = cipher.output.getBytes();
21876
21877  encryptionAlgorithm = ASN1.create(
21878    ASN1.Class.UNIVERSAL, ASN1.Type.SEQUENCE, true, [
21879    ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.OID, false,
21880      ASN1.oidToDer(PKI.oids['pbeWithSHAAnd3-KeyTripleDES-CBC']).getBytes()),
21881    // pkcs-12PbeParams
21882    ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.SEQUENCE, true, [
21883      // salt
21884      ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.OCTETSTRING, false, salt),
21885      // iteration count
21886      ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.INTEGER, false,
21887        countBytes.getBytes())
21888    ])
21889  ]);
21890
21891  var rval = 
21892  ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.SEQUENCE, true, [
21893  ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.OID, false,ASN1.oidToDer(PKI.oids.data).getBytes()),
21894  encryptionAlgorithm,
21895  ASN1.create(ASN1.Class.CONTEXT_SPECIFIC, 0, false, encryptedData)]);
21896  return rval;
21897};
21898
21899function P(key, cert, password, options) {
21900  // set default options
21901  options = options || {};
21902  options.saltSize = options.saltSize || 8;
21903  options.count = options.count || 2048;
21904  options.algorithm = options.algorithm || options.encAlgorithm || 'aes128';
21905  if(!('useMac' in options)) {
21906    options.useMac = true;
21907  }
21908  if(!('localKeyId' in options)) {
21909    options.localKeyId = null;
21910  }
21911  if(!('generateLocalKeyId' in options)) {
21912    options.generateLocalKeyId = true;
21913  }
21914
21915  var localKeyId = options.localKeyId;
21916  var keyAttrs, certAttrs;
21917  if(localKeyId !== null) {
21918    localKeyId = UTIL.hexToBytes(localKeyId);
21919  } else if(options.generateLocalKeyId) {
21920    // use SHA-1 of paired cert, if available
21921    if(cert) {
21922      var pairedCert = UTIL.isArray(cert) ? cert[0] : cert;
21923      if(typeof pairedCert === 'string') {
21924        pairedCert = PKI.certificateFromPem(pairedCert);
21925      }
21926      var sha1 = MD.sha1.create();
21927      sha1.update(ASN1.toDer(PKI.certificateToAsn1(pairedCert)).getBytes());
21928      localKeyId = sha1.digest().getBytes();
21929    } else {
21930      // FIXME: consider using SHA-1 of public key (which can be generated
21931      // from private key components), see: cert.generateSubjectKeyIdentifier
21932      // generate random bytes
21933      localKeyId = RANDOM.getBytes(20);
21934    }
21935  }
21936
21937  var attrs = [], certattrs = [];
21938  if(localKeyId !== null) {
21939    attrs.push(
21940      // localKeyID
21941      ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.SEQUENCE, true, [
21942        // attrId
21943        ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.OID, false,
21944          ASN1.oidToDer(PKI.oids.localKeyId).getBytes()),
21945        // attrValues
21946        ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.SET, true, [
21947          ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.OCTETSTRING, false,
21948            localKeyId)
21949        ])
21950      ]));
21951     certattrs.push(
21952      // localKeyID
21953      ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.SEQUENCE, true, [
21954        // attrId
21955        ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.OID, false,
21956          ASN1.oidToDer(PKI.oids.localKeyId).getBytes()),
21957        // attrValues
21958        ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.SET, true, [
21959          ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.OCTETSTRING, false,
21960            localKeyId)
21961        ])
21962      ]));
21963  }
21964
21965  if(attrs.length > 0) {
21966    keyAttrs = ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.SET, true, attrs);
21967    certAttrs = ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.SET, true, certattrs);
21968  }
21969
21970  // collect contents for AuthenticatedSafe
21971  var contents = [];
21972
21973  // create safe contents for private key
21974  var keyBag = null;
21975  if(key !== null) {
21976    // SafeBag
21977    var pkAsn1 = PKI.wrapRsaPrivateKey(PKI.privateKeyToAsn1(key));
21978    if(password === null) {
21979      // no encryption
21980      keyBag = ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.SEQUENCE, true, [
21981        // bagId
21982        ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.OID, false,
21983          ASN1.oidToDer(PKI.oids.keyBag).getBytes()),
21984        // bagValue
21985        ASN1.create(ASN1.Class.CONTEXT_SPECIFIC, 0, true, [
21986          // PrivateKeyInfo
21987          pkAsn1
21988        ]),
21989        // bagAttributes (OPTIONAL)
21990        bagAttrs
21991      ]);
21992    } else {
21993      // encrypted PrivateKeyInfo
21994      keyBag = ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.SEQUENCE, true, [
21995        // bagId
21996        ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.OID, false,
21997          ASN1.oidToDer(PKI.oids.pkcs8ShroudedKeyBag).getBytes()),
21998        // bagValue
21999        ASN1.create(ASN1.Class.CONTEXT_SPECIFIC, 0, true, [
22000          // EncryptedPrivateKeyInfo
22001          PKI.encryptPrivateKeyInfo(pkAsn1, password, options)
22002        ]),
22003        // bagAttributes (OPTIONAL)
22004        keyAttrs
22005      ]);
22006    }
22007
22008    // SafeContents
22009    var keySafeContents =
22010      ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.SEQUENCE, true, [keyBag]);
22011
22012    // ContentInfo
22013    var keyCI =
22014      // PKCS#7 ContentInfo
22015      ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.SEQUENCE, true, [
22016        // contentType
22017        ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.OID, false,
22018          // OID for the content type is 'data'
22019          ASN1.oidToDer(PKI.oids.data).getBytes()),
22020        // content
22021        ASN1.create(ASN1.Class.CONTEXT_SPECIFIC, 0, true, [
22022          ASN1.create(
22023            ASN1.Class.UNIVERSAL, ASN1.Type.OCTETSTRING, false,
22024            ASN1.toDer(keySafeContents).getBytes())
22025        ])
22026      ]);
22027    contents.push(keyCI);
22028  }
22029
22030  // create safe bag(s) for certificate chain
22031  var chain = [];
22032  if(cert !== null) {
22033    if(UTIL.isArray(cert)) {
22034      chain = cert;
22035    } else {
22036      chain = [cert];
22037    }
22038  }
22039
22040  var certSafeBags = [];
22041  for(var i = 0; i < chain.length; ++i) {
22042    // convert cert from PEM as necessary
22043    cert = chain[i];
22044    if(typeof cert === 'string') {
22045      cert = PKI.certificateFromPem(cert);
22046    }
22047
22048    // SafeBag
22049    var certBagAttrs = (i === 0) ? certAttrs : undefined;
22050    var certAsn1 = PKI.certificateToAsn1(cert);
22051    var certSafeBag =
22052      ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.SEQUENCE, true, [
22053        // bagId
22054        ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.OID, false,
22055          ASN1.oidToDer(PKI.oids.certBag).getBytes()),
22056        // bagValue
22057        ASN1.create(ASN1.Class.CONTEXT_SPECIFIC, 0, true, [
22058          // CertBag
22059          ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.SEQUENCE, true, [
22060            // certId
22061            ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.OID, false,
22062              ASN1.oidToDer(PKI.oids.x509Certificate).getBytes()),
22063            // certValue (x509Certificate)
22064            ASN1.create(ASN1.Class.CONTEXT_SPECIFIC, 0, true, [
22065              ASN1.create(
22066                ASN1.Class.UNIVERSAL, ASN1.Type.OCTETSTRING, false,
22067                ASN1.toDer(certAsn1).getBytes())
22068            ])])]),
22069        // bagAttributes (OPTIONAL)
22070        certBagAttrs
22071      ]);
22072    certSafeBags.push(certSafeBag);
22073  }
22074
22075  if(certSafeBags.length > 0) {  	
22076  	
22077    // SafeContents
22078    var certSafeContents = ASN1.create(
22079      ASN1.Class.UNIVERSAL, ASN1.Type.SEQUENCE, true, certSafeBags);
22080      
22081    var certBag = C(certSafeContents, password, options);
22082      
22083    // ContentInfo
22084    var certCI =
22085      // PKCS#7 ContentInfo
22086      ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.SEQUENCE, true, [
22087        // contentType
22088        ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.OID, false,
22089          ASN1.oidToDer(PKI.oids.encryptedData).getBytes()),
22090        // content
22091        ASN1.create(ASN1.Class.CONTEXT_SPECIFIC, 0, true, [
22092          ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.SEQUENCE, true, [
22093         		ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.INTEGER, false, ASN1.integerToDer(0).getBytes()),
22094							certBag])
22095        ])
22096      ]);
22097    contents.push(certCI);
22098  }
22099
22100  // create AuthenticatedSafe by stringing together the contents
22101  var safe = ASN1.create(
22102    ASN1.Class.UNIVERSAL, ASN1.Type.SEQUENCE, true, contents);
22103
22104  var macData;
22105  if(options.useMac) {
22106    // MacData
22107    var sha1 = MD.sha1.create();
22108    var macSalt = new UTIL.ByteBuffer(
22109      RANDOM.getBytes(options.saltSize));
22110    var count = options.count;
22111    // 160-bit key
22112    var key = PKCS12.generateKey(password, macSalt, 3, count, 20);
22113    var mac = HMAC.create();
22114    mac.start(sha1, key);
22115    mac.update(ASN1.toDer(safe).getBytes());
22116    var macValue = mac.getMac();
22117    macData = ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.SEQUENCE, true, [
22118      // mac DigestInfo
22119      ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.SEQUENCE, true, [
22120        // digestAlgorithm
22121        ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.SEQUENCE, true, [
22122          // algorithm = SHA-1
22123          ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.OID, false,
22124            ASN1.oidToDer(PKI.oids.sha1).getBytes()),
22125          // parameters = Null
22126          ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.NULL, false, '')
22127        ]),
22128        // digest
22129        ASN1.create(
22130          ASN1.Class.UNIVERSAL, ASN1.Type.OCTETSTRING,
22131          false, macValue.getBytes())
22132      ]),
22133      // macSalt OCTET STRING
22134      ASN1.create(
22135        ASN1.Class.UNIVERSAL, ASN1.Type.OCTETSTRING, false, macSalt.getBytes()),
22136      // iterations INTEGER (XXX: Only support count < 65536)
22137      ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.INTEGER, false,
22138        ASN1.integerToDer(count).getBytes()
22139      )
22140    ]);
22141  }
22142
22143  // PFX
22144  return ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.SEQUENCE, true, [
22145    // version (3)
22146    ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.INTEGER, false,
22147      ASN1.integerToDer(3).getBytes()),
22148    // PKCS#7 ContentInfo
22149    ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.SEQUENCE, true, [
22150      // contentType
22151      ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.OID, false,
22152        // OID for the content type is 'data'
22153        ASN1.oidToDer(PKI.oids.data).getBytes()),
22154      // content
22155      ASN1.create(ASN1.Class.CONTEXT_SPECIFIC, 0, true, [
22156        ASN1.create(
22157          ASN1.Class.UNIVERSAL, ASN1.Type.OCTETSTRING, false,
22158          ASN1.toDer(safe).getBytes())
22159      ])
22160    ]),
22161    macData
22162  ]);
22163};
22164
22165CGJSCrypt.ComposePKCS12 = function(prikey,prikeypwd,cert,pfxpwd,iflags) {
22166	var privateKey = D(prikey,prikeypwd);
22167	var newPkcs12Asn1 = P(privateKey, [cert], pfxpwd, {algorithm:'3des'});
22168	return ASN1.toDer(newPkcs12Asn1).getBytes();
22169}
22170
22171CGJSCrypt.GenerateKeyPair = function(keyLength, prikeypwd) {
22172	var keypair = PKI.rsa.generateKeyPair(keyLength);
22173	
22174	CGJSCrypt.privateKey = E(keypair.privateKey, prikeypwd);
22175	CGJSCrypt.publicKey = PKI.publicKeyToRSAPublicKeyPem(keypair.publicKey);		
22176}
22177
22178CGJSCrypt.CreatePKCS10 = function(keyLength, prikeypwd, hashalgo, strSubject, attrs, callbackFun) {
22179	
22180	if (typeof callbackFun === 'function') {
22181		if(location.protocol != 'https:')
22182			forge.disableNativeCode=true;
22183		PKI.rsa.generateKeyPair( {bits: keyLength, workerScript: "../cgjscrypt/prime.worker.js"}, function(err, keypair) {
22184			CGJSCrypt.privateKey = E(keypair.privateKey, prikeypwd);	//PKI.encryptRsaPrivateKey(keypair.privateKey, prikeypwd, {algorithm:prikeyencalgo,legacy:'1'});
22185			CGJSCrypt.publicKey = PKI.publicKeyToRSAPublicKeyPem(keypair.publicKey);	
22186			var csr = PKI.createCertificationRequest();
22187			csr.publicKey = keypair.publicKey;
22188			
22189			if(strSubject) {
22190				var a = strSubject.split(",");
22191				var subject = new Array(a.length);
22192				for(var i=0;i<a.length;i++) {
22193					var b = a[i].split("=");
22194					subject[i] = {shortName: b[0],value: b[1]};
22195				}
22196				csr.setSubject(subject);
22197			}
22198			if(attrs) csr.setAttributes(attrs);
22199			
22200			if(!hashalgo || hashalgo=="") hashalgo = 'sha1';
22201			
22202			var md = MD[hashalgo].create();
22203			csr.sign(keypair.privateKey,md);
22204			callbackFun(PKI.certificationRequestToPem(csr));
22205			
22206		});
22207	}
22208	
22209	else{
22210		var keypair = PKI.rsa.generateKeyPair(keyLength);
22211		CGJSCrypt.privateKey = E(keypair.privateKey, prikeypwd);	//PKI.encryptRsaPrivateKey(keypair.privateKey, prikeypwd, {algorithm:prikeyencalgo,legacy:'1'});
22212		CGJSCrypt.publicKey = PKI.publicKeyToRSAPublicKeyPem(keypair.publicKey);	
22213		
22214		var csr = PKI.createCertificationRequest();
22215		csr.publicKey = keypair.publicKey;
22216		
22217		if(strSubject) {
22218			var a = strSubject.split(",");
22219			var subject = new Array(a.length);
22220			for(var i=0;i<a.length;i++) {
22221				var b = a[i].split("=");
22222				subject[i] = {shortName: b[0],value: b[1]};
22223			}
22224			csr.setSubject(subject);
22225		}
22226		if(attrs) csr.setAttributes(attrs);
22227		
22228		if(!hashalgo || hashalgo=="") hashalgo = 'sha1';
22229		
22230		var md = MD[hashalgo].create();
22231		csr.sign(keypair.privateKey,md);
22232		
22233		return PKI.certificationRequestToPem(csr);	
22234	}
22235		
22236}
22237
22238CGJSCrypt.PrivateDecrypt = function(prikey,prikeypwd,cipher) {
22239	var privateKey = D(prikey,prikeypwd);
22240	return privateKey.decrypt(UTIL.decode64(cipher));
22241}
22242
22243/*
22244CGJSCrypt.PrivateSign = function(prikey,prikeypwd,data,encoding,hashalgo) {
22245	if( (typeof hashalgo === "undefined") )
22246		return PrivateSign2(prikey,prikeypwd,data,encoding);
22247	
22248	try{
22249		R();
22250		var privateKey = D(prikey,prikeypwd);
22251		if(!hashalgo || hashalgo=="") hashalgo = 'sha1';
22252		var md = MD[hashalgo].create();
22253		md.update(data, encoding);
22254		var signature = privateKey.sign(md);  
22255		return UTIL.encode64(signature);
22256	}catch(e){
22257		ErrorMsg=e.message;
22258		(ErrorMsg == "Unable to decrypt PrivateKey, wrong password?")?ErrorCode=5003:ErrorCode=5005;
22259	}
22260	return "";
22261}
22262*/
22263
22264CGJSCrypt.PrivateSign = function(prikey,prikeypwd,data,encoding,hashalgo,ext1,ext2) {
22265	if( (typeof hashalgo === "undefined") )
22266		return PrivateSign2(prikey,prikeypwd,data,encoding);
22267	else if( (typeof hashalgo === "function") )
22268		return PrivateSign2(prikey,prikeypwd,data,encoding,hashalgo,ext1,ext2);
22269	
22270	try{
22271		R();
22272		var privateKey = D(prikey,prikeypwd);
22273		if(!hashalgo || hashalgo=="") hashalgo = 'sha1';
22274		var md = MD[hashalgo].create();
22275		md.update(data, encoding);
22276		var signature = privateKey.sign(md);  
22277		return UTIL.encode64(signature);
22278	}catch(e){
22279		ErrorMsg=e.message;
22280		(ErrorMsg == "Unable to decrypt PrivateKey, wrong password?")?ErrorCode=5003:ErrorCode=5005;
22281	}
22282	return "";
22283}
22284
22285/*
22286CGJSCrypt.ComposePKCS7 = function(prikey,prikeypwd,cert,data,encoding,hashalgo) {
22287	if( (typeof encoding === "undefined") || (typeof hashalgo === "undefined") )
22288		return ComposePKCS72(prikey,prikeypwd,cert,data);
22289		
22290	try{
22291		var pem_privatekey = D(prikey,prikeypwd);
22292		var oidhash = PKI.oids.sha1;
22293		
22294		if(!hashalgo || hashalgo=="") 
22295			oidhash = PKI.oids.sha1;	
22296		else{
22297			switch (hashalgo) {
22298			case "sha1":
22299				oidhash = PKI.oids.sha1;	
22300				break;
22301			case "sha256":	
22302				oidhash = PKI.oids.sha256;	
22303				break;
22304			case "md5":
22305				oidhash = PKI.oids.md5;	
22306				break;
22307			default:
22308				oidhash = PKI.oids.sha1;	
22309			}
22310			
22311		}
22312		
22313		var p7 = PKCS7.createSignedData();
22314		p7.content = UTIL.createBuffer(data, encoding);
22315		p7.addCertificate(cert);
22316		p7.addSigner({
22317		  key: pem_privatekey,
22318		  certificate: cert,
22319		  digestAlgorithm: oidhash
22320		});
22321		p7.sign();
22322		
22323		var p7pem = PKCS7.messageToPem(p7);	
22324		
22325		return p7pem.substring(p7pem.indexOf("\r\n")+2, p7pem.indexOf("-----END"));
22326	}catch(e){
22327		ErrorMsg=e.message;
22328		(ErrorMsg == "Unable to decrypt PrivateKey, wrong password?")?ErrorCode=5003:ErrorCode=5005;
22329	}
22330	return "";
22331}
22332*/
22333
22334CGJSCrypt.ComposePKCS7 = function(prikey,prikeypwd,cert,data,encoding,hashalgo,ext1) {
22335	
22336	if( (typeof encoding === "undefined") )
22337		return ComposePKCS72(prikey,prikeypwd,cert,data);
22338	else if( (typeof encoding === "function") )
22339		return ComposePKCS72(prikey,prikeypwd,cert,data,encoding,hashalgo,ext1);
22340		
22341	try{
22342		var pem_privatekey = D(prikey,prikeypwd);
22343		var oidhash = PKI.oids.sha1;
22344		
22345		if(!hashalgo || hashalgo=="") 
22346			oidhash = PKI.oids.sha1;	
22347		else{
22348			switch (hashalgo) {
22349			case "sha1":
22350				oidhash = PKI.oids.sha1;	
22351				break;
22352			case "sha256":	
22353				oidhash = PKI.oids.sha256;	
22354				break;
22355			case "md5":
22356				oidhash = PKI.oids.md5;	
22357				break;
22358			default:
22359				oidhash = PKI.oids.sha1;	
22360			}
22361			
22362		}
22363		
22364		var p7 = PKCS7.createSignedData();
22365		p7.content = UTIL.createBuffer(data, encoding);
22366		p7.addCertificate(cert);
22367		p7.addSigner({
22368		  key: pem_privatekey,
22369		  certificate: cert,
22370		  digestAlgorithm: oidhash
22371		});
22372		p7.sign();
22373		
22374		var p7pem = PKCS7.messageToPem(p7);	
22375		
22376		return p7pem.substring(p7pem.indexOf("\r\n")+2, p7pem.indexOf("-----END"));
22377	}catch(e){
22378		ErrorMsg=e.message;
22379		(ErrorMsg == "Unable to decrypt PrivateKey, wrong password?")?ErrorCode=5003:ErrorCode=5005;
22380	}
22381	return "";
22382}
22383
22384
22385CGJSCrypt.EncodeBase64 = function(data) {
22386	try{
22387		return UTIL.encode64(data);
22388	}catch(e){ErrorMsg=e.message;ErrorCode=5005;}
22389	return "";
22390}
22391
22392CGJSCrypt.DecodeBase64 = function(data) {
22393	try{
22394		return UTIL.decode64(data);
22395	}catch(e){ErrorMsg=e.message;ErrorCode=5005;}
22396	return "";
22397}
22398
22399CGJSCrypt.SavePrivatekey = function(privateKey,cn,pid){
22400	ErrorCode = -1;
22401	
22402	if(privateKey == null || privateKey.length <= 0){
22403		ErrorCode = 5005;
22404	}	
22405	else{
22406		if(typeof(Storage) !== "undefined") {
22407			if(typeof cn === "undefined" || cn===null)
22408				localStorage.setItem("Prikey_"+Company+"_"+pid, UTIL.encode64(privateKey));
22409			else
22410				localStorage.setItem("Prikey_"+Company+"_"+pid,  UTIL.encode64(privateKey) + ">_<" + cn);
22411			
22412			ErrorCode = 0;
22413		}
22414		else
22415			ErrorCode = 5002;
22416	}		
22417	//return ErrorCode;
22418}
22419
22420CGJSCrypt.SavePublickey = function(publicKey,pid){
22421	ErrorCode = -1;
22422	
22423	if(publicKey == null || publicKey.length <= 0){
22424		ErrorCode = 5005;
22425	}	
22426	else{
22427		if(typeof(Storage) !== "undefined") {
22428			
22429			localStorage.setItem("Pubkey_"+Company+"_"+pid, publicKey);			
22430			ErrorCode = 0;
22431		}
22432		else
22433			ErrorCode = 5002;
22434	}		
22435	//return ErrorCode;
22436}
22437
22438CGJSCrypt.DeleteWebstorage = function(pid){
22439	ErrorCode = -1;
22440		
22441	if(typeof(Storage) !== "undefined") {
22442		if(localStorage.getItem("Prikey_"+Company+"_"+pid))
22443			localStorage.removeItem("Prikey_"+Company+"_"+pid);
22444		if(localStorage.getItem("Pubkey_"+Company+"_"+pid))
22445			localStorage.removeItem("Pubkey_"+Company+"_"+pid);
22446		if(localStorage.getItem("Cert_"+Company+"_"+pid))
22447			localStorage.removeItem("Cert_"+Company+"_"+pid);
22448		ErrorCode = 0;
22449	}
22450	else
22451		ErrorCode = 5002;		
22452	
22453	//return ErrorCode;
22454	
22455}
22456
22457CGJSCrypt.ImportCert = function(cert,pid){
22458	ErrorCode = -1;
22459	
22460	if(cert == null || cert.length <= 0){
22461		ErrorCode = 5005;
22462	}	
22463	else{
22464
22465		var index = cert.indexOf("-----BEGIN CERTIFICATE-----");
22466		if(index == -1)
22467		{
22468			cert = "-----BEGIN CERTIFICATE-----\r\n"+cert.replace(/ /g,'')+"\r\n-----END CERTIFICATE-----";
22469		}
22470		
22471		if(typeof(Storage) !== "undefined") {
22472			localStorage.setItem("Cert_"+Company+"_"+pid, cert);
22473			ErrorCode = 0;
22474		}
22475		else
22476			ErrorCode = 5002;
22477	}		
22478	//return ErrorCode;
22479}
22480
22481CGJSCrypt.GetCert = function(pid){
22482	ErrorCode = -1;
22483	var certValue = "";
22484	if(typeof(Storage) !== "undefined") {
22485		var cert = localStorage.getItem("Cert_"+Company+"_"+pid);
22486		if(cert == null)
22487			ErrorCode = 5003;
22488		else
22489		{
22490			certValue = cert;
22491			ErrorCode = 0;
22492		}
22493	}
22494	else
22495		ErrorCode = 5002;
22496	
22497	return certValue;
22498		
22499	//return ErrorCode;
22500}
22501
22502CGJSCrypt.GetPublicKey = function(pid){
22503	ErrorCode = -1;
22504	var pubValue = "";
22505	if(typeof(Storage) !== "undefined") {
22506		var pub = localStorage.getItem("Pubkey_"+Company+"_"+pid);
22507		if(pub == null)
22508			ErrorCode = 5003;
22509		else
22510		{
22511			pubValue = pub;
22512			ErrorCode = 0;
22513		}
22514	}
22515	else
22516		ErrorCode = 5002;
22517	
22518	return pubValue;
22519		
22520	//return ErrorCode;
22521}
22522
22523CGJSCrypt.GetPrivateKey = function(pid){
22524	ErrorCode = -1;
22525	var priValue = "";
22526	if(typeof(Storage) !== "undefined") {
22527		var pri = localStorage.getItem("Prikey_"+Company+"_"+pid);
22528		if(pri == null)
22529			ErrorCode = 5003;
22530		else
22531		{
22532			var valuecount = pri.indexOf(">_<");
22533			if(valuecount > -1) {
22534				priValue = UTIL.decode64(pri.substring(0, valuecount));
22535			}
22536			else {
22537				priValue = UTIL.decode64(pri);
22538			}
22539			ErrorCode = 0;
22540		}
22541	}
22542	else
22543		ErrorCode = 5002;
22544	
22545	return priValue;
22546		
22547	//return ErrorCode;
22548}
22549
22550CGJSCrypt.GetCN = function(pid){
22551	ErrorCode = -1;
22552	var cnValue = "";
22553	if(typeof(Storage) !== "undefined") {
22554		var cn = localStorage.getItem("Prikey_"+Company+"_"+pid);
22555		if(cn == null)
22556			ErrorCode = 5003;
22557		else
22558		{
22559			var valuecount = cn.indexOf(">_<");
22560			if(valuecount > -1) {
22561				cnValue = cn.substring(valuecount+3);
22562				ErrorCode = 0;
22563			}
22564			else {
22565				ErrorCode = 5003;
22566			}
22567
22568		}
22569	}
22570	else
22571		ErrorCode = 5002;
22572	
22573	return cnValue;
22574		
22575	//return ErrorCode;
22576}
22577
22578/*
22579function PrivateSign2(data,encoding,hashalgo,pid) {
22580	try{
22581		var prikey = CGJSCrypt.GetPrivateKey(pid);
22582		if(ErrorCode != 0)
22583			return "";
22584		var prikeypwd = DecodePrikeyPass(pid);
22585		if(ErrorCode != 0)
22586		{
22587			var pass = prompt("???????");
22588			if (pass == null) {
22589				return "";
22590			}
22591			
22592			prikeypwd = pass;
22593		}		
22594		R();
22595		var privateKey = D(prikey,prikeypwd);
22596		if(!hashalgo || hashalgo=="") hashalgo = 'sha1';
22597		var md = MD[hashalgo].create();
22598		md.update(data, encoding);
22599		var signature = privateKey.sign(md);  
22600		
22601		if(typeof(pass) !== "undefined")
22602			SavePriKeyPass(pass,pid);
22603		
22604		if(ErrorCode != 0)
22605		{
22606			ErrorMsg == "Unable to store password";
22607			return "";
22608		}
22609		return UTIL.encode64(signature);
22610	}catch(e){
22611		ErrorMsg=e.message;
22612		(ErrorMsg == "Unable to decrypt PrivateKey, wrong password?")?ErrorCode=5003:ErrorCode=5005;
22613	}
22614	return "";
22615}
22616*/
22617
22618CGJSCrypt.PromptComputeCallback = function(pass){};
22619CGJSCrypt.PromptCancelCallback = function() {
22620	CGJSCrypt.PromptComputeCallback = function(pass){};
22621}
22622
22623function PrivateSign2(data,encoding,hashalgo,pid,open_modal_func,success_func,fail_func) {
22624	var usemodal = (typeof(open_modal_func) === "function");
22625	
22626	try{
22627		var prikey = CGJSCrypt.GetPrivateKey(pid);
22628		if(ErrorCode != 0)
22629			return "";
22630		var prikeypwd = DecodePrikeyPass(pid);
22631		if(ErrorCode != 0)
22632		{
22633			if(!usemodal) {
22634				var pass = prompt("???????");
22635				if (pass == null) {
22636					return "";
22637				}
22638				
22639				prikeypwd = pass;
22640			} else {
22641				var f_openmodal = open_modal_func;
22642				var f_success = (typeof(success_func) === "function") ? success_func : function(result){};
22643				var f_fail = (typeof(fail_func) === "function") ? fail_func : function(errorCode){};
22644	
22645				CGJSCrypt.PromptComputeCallback = function(pass){
22646					//alert("prikey: " + prikey + ", pass: " + pass);
22647					if (pass == null || typeof pass === "undefined") {
22648						CGJSCrypt.PromptComputeCallback = function(pass){};
22649						return;
22650					}
22651					
22652					try {
22653						prikeypwd = pass;
22654						
22655						R();
22656						var privateKey = D(prikey,prikeypwd);
22657						if(!hashalgo || hashalgo=="") hashalgo = 'sha1';
22658						var md = MD[hashalgo].create();
22659						md.update(data, encoding);
22660						var signature = privateKey.sign(md);  
22661						
22662						if(typeof(pass) !== "undefined")
22663							SavePriKeyPass(pass,pid);
22664						
22665						if(ErrorCode != 0)
22666						{
22667							ErrorMsg == "Unable to store password";
22668							CGJSCrypt.PromptComputeCallback = function(pass){};
22669							f_fail(ErrorCode);
22670							return;
22671						}
22672						CGJSCrypt.PromptComputeCallback = function(pass){};
22673						f_success(UTIL.encode64(signature));
22674					}catch(e){
22675						ErrorMsg=e.message;
22676						(ErrorMsg == "Unable to decrypt PrivateKey, wrong password?")?ErrorCode=5003:ErrorCode=5005;
22677						CGJSCrypt.PromptComputeCallback = function(pass){};
22678						f_fail(ErrorCode);
22679					}
22680				}
22681
22682				f_openmodal();
22683				
22684				return "USE_MODAL";
22685			}
22686		}		
22687		R();
22688		var privateKey = D(prikey,prikeypwd);
22689		if(!hashalgo || hashalgo=="") hashalgo = 'sha1';
22690		var md = MD[hashalgo].create();
22691		md.update(data, encoding);
22692		var signature = privateKey.sign(md);  
22693		
22694		if(typeof(pass) !== "undefined")
22695			SavePriKeyPass(pass,pid);
22696		
22697		if(ErrorCode != 0)
22698		{
22699			ErrorMsg == "Unable to store password";
22700			return "";
22701		}
22702		return UTIL.encode64(signature);
22703	}catch(e){
22704		ErrorMsg=e.message;
22705		(ErrorMsg == "Unable to decrypt PrivateKey, wrong password?")?ErrorCode=5003:ErrorCode=5005;
22706	}
22707	return "";
22708}
22709
22710/*
22711function ComposePKCS72(data,encoding,hashalgo,pid) {
22712	try{
22713		var cert = CGJSCrypt.GetCert(pid);
22714		if(ErrorCode != 0)
22715			return "";
22716		var prikey = CGJSCrypt.GetPrivateKey(pid);
22717		if(ErrorCode != 0)
22718			return "";
22719		var prikeypwd = DecodePrikeyPass(pid);
22720		if(ErrorCode != 0)
22721		{
22722			var pass = prompt("???????");
22723			if (pass == null) {
22724				return "";
22725			}
22726			
22727			prikeypwd = pass;
22728		}	
22729		
22730		var pem_privatekey = D(prikey,prikeypwd);
22731		var oidhash = PKI.oids.sha1;
22732		
22733		if(!hashalgo || hashalgo=="") 
22734			oidhash = PKI.oids.sha1;	
22735		else{
22736			switch (hashalgo) {
22737			case "sha1":
22738				oidhash = PKI.oids.sha1;	
22739				break;
22740			case "sha256":	
22741				oidhash = PKI.oids.sha256;	
22742				break;
22743			case "md5":
22744				oidhash = PKI.oids.md5;	
22745				break;
22746			default:
22747				oidhash = PKI.oids.sha1;	
22748			}
22749			
22750		}
22751		
22752		var p7 = PKCS7.createSignedData();
22753		p7.content = UTIL.createBuffer(data, encoding);
22754		p7.addCertificate(cert);
22755		p7.addSigner({
22756		  key: pem_privatekey,
22757		  certificate: cert,
22758		  digestAlgorithm: oidhash
22759		});
22760		p7.sign();
22761		
22762		var p7pem = PKCS7.messageToPem(p7);
22763		
22764		if(typeof(pass) !== "undefined")
22765			SavePriKeyPass(pass,pid);
22766		
22767		if(ErrorCode != 0)
22768		{
22769			ErrorMsg == "Unable to store password";
22770			return "";
22771		}
22772			
22773		return p7pem.substring(p7pem.indexOf("\r\n")+2, p7pem.indexOf("-----END"));
22774	}catch(e){
22775		ErrorMsg=e.message;
22776		(ErrorMsg == "Unable to decrypt PrivateKey, wrong password?")?ErrorCode=5003:ErrorCode=5005;
22777	}
22778	return "";
22779}
22780*/
22781
22782function ComposePKCS72(data,encoding,hashalgo,pid,open_modal_func,success_func,fail_func) {
22783	var usemodal = (typeof(open_modal_func) === "function");
22784	
22785	try{
22786		var cert = CGJSCrypt.GetCert(pid);
22787		if(ErrorCode != 0)
22788			return "";
22789		var prikey = CGJSCrypt.GetPrivateKey(pid);
22790		if(ErrorCode != 0)
22791			return "";
22792		var prikeypwd = DecodePrikeyPass(pid);
22793		if(ErrorCode != 0)
22794		{
22795			if(!usemodal) {
22796				var pass = prompt("???????");
22797				if (pass == null) {
22798					return "";
22799				}
22800				
22801				prikeypwd = pass;
22802			} else {
22803				var f_openmodal = open_modal_func;
22804				var f_success = (typeof(success_func) === "function") ? success_func : function(result){};
22805				var f_fail = (typeof(fail_func) === "function") ? fail_func : function(errorCode){};
22806	
22807				CGJSCrypt.PromptComputeCallback = function(pass){
22808					//alert("cert: " + cert + ", prikey: " + prikey + ", pass: " + pass);
22809					if (pass == null || typeof pass === "undefined") {
22810						CGJSCrypt.PromptComputeCallback = function(pass){};
22811						return;
22812					}
22813					
22814					try {
22815						prikeypwd = pass;
22816						
22817						var pem_privatekey = D(prikey,prikeypwd);
22818						var oidhash = PKI.oids.sha1;
22819						
22820						if(!hashalgo || hashalgo=="") 
22821							oidhash = PKI.oids.sha1;	
22822						else{
22823							switch (hashalgo) {
22824							case "sha1":
22825								oidhash = PKI.oids.sha1;	
22826								break;
22827							case "sha256":	
22828								oidhash = PKI.oids.sha256;	
22829								break;
22830							case "md5":
22831								oidhash = PKI.oids.md5;	
22832								break;
22833							default:
22834								oidhash = PKI.oids.sha1;	
22835							}
22836							
22837						}
22838						
22839						var p7 = PKCS7.createSignedData();
22840						p7.content = UTIL.createBuffer(data, encoding);
22841						p7.addCertificate(cert);
22842						p7.addSigner({
22843						  key: pem_privatekey,
22844						  certificate: cert,
22845						  digestAlgorithm: oidhash
22846						});
22847						p7.sign();
22848						
22849						var p7pem = PKCS7.messageToPem(p7);
22850						
22851						if(typeof(pass) !== "undefined")
22852							SavePriKeyPass(pass,pid);
22853						
22854						if(ErrorCode != 0)
22855						{
22856							ErrorMsg == "Unable to store password";
22857							CGJSCrypt.PromptComputeCallback = function(pass){};
22858							f_fail(ErrorCode);
22859							return;
22860						}
22861							
22862						CGJSCrypt.PromptComputeCallback = function(pass){};
22863						f_success(p7pem.substring(p7pem.indexOf("\r\n")+2, p7pem.indexOf("-----END")));
22864					}catch(e){
22865						ErrorMsg=e.message;
22866						(ErrorMsg == "Unable to decrypt PrivateKey, wrong password?")?ErrorCode=5003:ErrorCode=5005;
22867						CGJSCrypt.PromptComputeCallback = function(pass){};
22868						f_fail(ErrorCode);
22869					}
22870				}
22871				
22872				f_openmodal();
22873				
22874				return "USE_MODAL";
22875			}
22876		}	
22877		
22878		var pem_privatekey = D(prikey,prikeypwd);
22879		var oidhash = PKI.oids.sha1;
22880		
22881		if(!hashalgo || hashalgo=="") 
22882			oidhash = PKI.oids.sha1;	
22883		else{
22884			switch (hashalgo) {
22885			case "sha1":
22886				oidhash = PKI.oids.sha1;	
22887				break;
22888			case "sha256":	
22889				oidhash = PKI.oids.sha256;	
22890				break;
22891			case "md5":
22892				oidhash = PKI.oids.md5;	
22893				break;
22894			default:
22895				oidhash = PKI.oids.sha1;	
22896			}
22897			
22898		}
22899		
22900		var p7 = PKCS7.createSignedData();
22901		p7.content = UTIL.createBuffer(data, encoding);
22902		p7.addCertificate(cert);
22903		p7.addSigner({
22904		  key: pem_privatekey,
22905		  certificate: cert,
22906		  digestAlgorithm: oidhash
22907		});
22908		p7.sign();
22909		
22910		var p7pem = PKCS7.messageToPem(p7);
22911		
22912		if(typeof(pass) !== "undefined")
22913			SavePriKeyPass(pass,pid);
22914		
22915		if(ErrorCode != 0)
22916		{
22917			ErrorMsg == "Unable to store password";
22918			return "";
22919		}
22920			
22921		return p7pem.substring(p7pem.indexOf("\r\n")+2, p7pem.indexOf("-----END"));
22922	}catch(e){
22923		ErrorMsg=e.message;
22924		(ErrorMsg == "Unable to decrypt PrivateKey, wrong password?")?ErrorCode=5003:ErrorCode=5005;
22925	}
22926	return "";
22927}
22928
22929
22930function SavePriKeyPass(prikeypwd,pid){
22931	ErrorCode=0;
22932	var encryptedpwd = null;
22933	
22934	if(typeof(Storage) !== "undefined") {
22935		var d = new Date();
22936		var data_str = "";
22937		data_str  = d.getFullYear().toString();
22938		data_str = ((d.getMonth()+1) < 10)?data_str.concat("0",d.getMonth()+1):data_str.concat(d.getMonth()+1);
22939		data_str = ((d.getDate()) < 10)?data_str.concat("0",d.getDate()):data_str.concat(d.getDate());
22940		
22941		var it = 1500;
22942		
22943		var salt = RANDOM.getBytes(50);
22944		var dk = PBKDF2(data_str,salt,it,48);
22945		
22946		var k = dk.substring(0,32);
22947		var iv = dk.substring(32,48);
22948		var input = UTIL.createBuffer(prikeypwd);
22949
22950		var c = AES.createEncryptionCipher(k, 'CBC');
22951		c.start(iv);
22952		c.update(input);
22953		c.finish();
22954		
22955		encryptedpwd = UTIL.encode64(UTIL.hexToBytes(c.output.toHex()+UTIL.bytesToHex(salt)+it.toString()));
22956		
22957		sessionStorage.setItem("PrikeyPass_"+Company+"_"+pid, encryptedpwd);
22958		
22959	}
22960	else	
22961		ErrorCode=5002;
22962}
22963
22964function DecodePrikeyPass(pid)
22965{
22966	ErrorCode=0;
22967	var encryptdata = null;
22968	var t="";
22969	
22970	if(typeof(Storage) !== "undefined") {
22971		encryptdata = sessionStorage.getItem("PrikeyPass_"+Company+"_"+pid);
22972		if(encryptdata != null)
22973		{
22974			encryptdata = UTIL.decode64(encryptdata);
22975			var salt = encryptdata.substring(encryptdata.length-50-2,encryptdata.length-2);
22976			var m = encryptdata.substring(0,(encryptdata.length-salt.length-2));
22977			var it = parseInt(UTIL.bytesToHex(encryptdata.substring(encryptdata.length-2)));
22978			
22979			//alert(UTIL.bytesToHex(encryptdata.substring(encryptdata.length-2)));
22980			//ALL.SaltB.value=UTIL.bytesToHex(salt);
22981			//ALL.SaltB.value=ALL.SaltB.value+=it;
22982			
22983			var d = new Date();
22984			var data_str = "";
22985			data_str  = d.getFullYear().toString();
22986			data_str = ((d.getMonth()+1) < 10)?data_str.concat("0",d.getMonth()+1):data_str.concat(d.getMonth()+1);
22987			data_str = ((d.getDate()) < 10)?data_str.concat("0",d.getDate()):data_str.concat(d.getDate());
22988			
22989
22990			var dk = PBKDF2(data_str,salt,it,48);
22991			
22992			var k = dk.substring(0,32);
22993			var iv = dk.substring(32,48);
22994			var input = UTIL.createBuffer(m);	
22995			
22996			var c = AES.createDecryptionCipher(k, 'CBC');
22997			c.start(iv);
22998			c.update(input);
22999			if(!c.finish())
23000				ErrorCode = 5003;
23001				//throw new Error('Unable to decrypt PrivateKeypass');
23002			else
23003			{	
23004				t = c.output;
23005			}
23006		}
23007		else
23008		{
23009			ErrorCode=5003;
23010		}
23011	}
23012	else
23013		ErrorCode=5002;
23014	
23015	return t;	
23016}
23017
23018CGJSCrypt.ChangeCertPass = function(oldpass,newpass,pid) {
23019	ErrorCode=0;
23020	var cn = CGJSCrypt.GetCN(pid);
23021	var prikey = CGJSCrypt.GetPrivateKey(pid); 
23022	
23023	try{	
23024		R();
23025		var o_prikey = D(prikey,oldpass);
23026		
23027		var newprikey = E(o_prikey, newpass);
23028		
23029		CGJSCrypt.SavePrivatekey(newprikey,cn,pid);
23030		
23031		return true;
23032
23033	}catch(e){
23034		ErrorMsg=e.message;
23035		(ErrorMsg == "Unable to decrypt PrivateKey, wrong password?")?ErrorCode=5003:ErrorCode=5005;
23036	}
23037	
23038	return false;
23039}
23040
23041
23042CGJSCrypt.CheckCert = function(pid){
23043	
23044	var cert = CGJSCrypt.GetCert(pid);
23045	if(CGJSCrypt.GetErrorCode()!=0){
23046	    
23047		return 5010;
23048	}else{
23049		var arr = CGJSCrypt.CertGetNotAfter(cert).split(/[- :]/);
23050		var noafter = new Date(arr[0], arr[1]-1, arr[2], arr[3], arr[4], arr[5]);
23051		var today = new Date();
23052		if(today<noafter){
23053			return 0;
23054		}else{
23055			CGJSCrypt.DeleteWebstorage(pid);
23056			
23057			return 5010;
23058		}
23059	}
23060	
23061}
23062
23063CGJSCrypt.GetPublicFromCert = function(pem_cert,iflags) {
23064	var index = pem_cert.indexOf("-----BEGIN CERTIFICATE-----");
23065	if(index == -1)
23066	{
23067		pem_cert = "-----BEGIN CERTIFICATE-----\r\n"+pem_cert+"\r\n-----END CERTIFICATE-----";
23068	}
23069	var publicKey = PKI.certificateFromPem(pem_cert).publicKey;
23070	
23071	publicKey = PKI.publicKeyToRSAPublicKeyPem(publicKey);
23072	
23073	return publicKey;
23074}
23075
23076CGJSCrypt.CertPassCheck = function(oldpass,prikey) {
23077	ErrorCode=0;
23078	
23079	try{	
23080		R();
23081		var o_prikey = D(prikey,oldpass);
23082		
23083		return (o_prikey != null);
23084
23085	}catch(e){
23086		ErrorMsg=e.message;
23087		(ErrorMsg == "Unable to decrypt PrivateKey, wrong password?")?ErrorCode=5003:ErrorCode=5005;
23088	}
23089	
23090	return false;
23091}
23092
23093
23094p7addRH = function(msg,strPuKey){
23095	msg.recipients.push({
23096		version: 2,
23097		subjectKeyIdentifier: PKI.getPublicKeyFingerprint(strPuKey,{type: 'SubjectPublicKeyInfo', encoding: 'binary'}),
23098		encryptedContent: {
23099	        // We simply assume rsaEncryption here, since forge.pki only
23100	        // supports RSA so far.  If the PKI module supports other
23101	        // ciphers one day, we need to modify this one as well.
23102	        algorithm: forge.pki.oids.rsaEncryption,
23103	        key: strPuKey
23104	      }
23105	});
23106	return msg;
23107}
23108
23109CGJSCrypt.PKCS7PublicEncrypt = function(strPuKey,data,iFlags){
23110	var p7 = PKCS7.createEnvelopedData();
23111	p7.content = UTIL.createBuffer(data, "utf8");
23112	var publickey = PKI.publicKeyFromPem(strPuKey);
23113	p7 = p7addRH(p7,publickey);
23114//	p7.addRecipient2(publickey);
23115	p7.encrypt();
23116	var p7pem = p7MtoP(p7);	
23117	return p7pem.substring(p7pem.indexOf("\r\n")+2, p7pem.indexOf("-----END"));
23118}
23119
23120CGJSCrypt.PKCS7Encrypt = function(pem_cert,data,iFlags){
23121	var p7 = PKCS7.createEnvelopedData();
23122	p7.content = UTIL.createBuffer(data, "utf8");
23123	var cert = PKI.certificateFromPem(pem_cert);
23124	p7.addRecipient(cert);
23125	p7.encrypt();
23126	var p7pem = PKCS7.messageToPem(p7);	
23127	return p7pem.substring(p7pem.indexOf("\r\n")+2, p7pem.indexOf("-----END"));
23128}
23129
23130p7RtoA = function(obj) {
23131	  return ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.SEQUENCE, true, [
23132	    // Version
23133	    ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.INTEGER, false,
23134	      ASN1.integerToDer(obj.version).getBytes()),
23135	    // SubjectKeyIdentifier 
23136	    ASN1.create(ASN1.Class.CONTEXT_SPECIFIC, 0, false, obj.subjectKeyIdentifier
23137		),
23138	    // KeyEncryptionAlgorithmIdentifier
23139	    ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.SEQUENCE, true, [
23140	      // Algorithm
23141	      ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.OID, false,
23142	        ASN1.oidToDer(obj.encryptedContent.algorithm).getBytes()),
23143	      // Parameter, force NULL, only RSA supported for now.
23144	      ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.NULL, false, '')
23145	    ]),
23146	    // EncryptedKey
23147	    ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.OCTETSTRING, false,
23148	      obj.encryptedContent.content)
23149	  ]);
23150	}
23151
23152p7MtoP = function(msg, maxline) {
23153	  // convert to ASN.1, then DER, then PEM-encode
23154	  var pemObj = {
23155	    type: 'PKCS7',
23156	    body: ASN1.toDer(p7toA(msg)).getBytes()
23157	  };
23158	  return forge.pem.encode(pemObj, {maxline: maxline});
23159	}
23160	
23161p7toA = function(msg) {
23162	// ContentInfo
23163	return ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.SEQUENCE, true, [
23164	    // ContentType
23165		ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.OID, false,ASN1.oidToDer(msg.type).getBytes()),
23166	        // [0] EnvelopedData
23167	    ASN1.create(ASN1.Class.CONTEXT_SPECIFIC, 0, true, [
23168	          ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.SEQUENCE, true, [
23169	            // Version
23170	            ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.INTEGER, false, ASN1.integerToDer(msg.version).getBytes()),
23171	            // RecipientInfos
23172	            ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.SET, true,p7RstoA(msg.recipients)),
23173	            // EncryptedContentInfo
23174	            ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.SEQUENCE, true,
23175	              _encryptedContentToAsn1(msg.encryptedContent))
23176	          ])
23177	        ])
23178	      ]);
23179	    }
23180	
23181p7RstoA = function(recipients) {
23182	var ret = [];
23183	for(var i = 0; i < recipients.length; ++i) {
23184		ret.push(p7RtoA(recipients[i]));
23185	}
23186	return ret;
23187}
23188
23189function _encryptedContentToAsn1(ec) {
23190  return [
23191    // ContentType, always Data for the moment
23192    ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.OID, false,
23193      ASN1.oidToDer(forge.pki.oids.data).getBytes()),
23194    // ContentEncryptionAlgorithmIdentifier
23195    ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.SEQUENCE, true, [
23196      // Algorithm
23197      ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.OID, false,
23198        ASN1.oidToDer(ec.algorithm).getBytes()),
23199      // Parameters (IV)
23200      ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.OCTETSTRING, false,
23201        ec.parameter.getBytes())
23202    ]),
23203    // [0] EncryptedContent
23204    ASN1.create(ASN1.Class.CONTEXT_SPECIFIC, 0, true, [
23205      ASN1.create(ASN1.Class.UNIVERSAL, ASN1.Type.OCTETSTRING, false,
23206        ec.content.getBytes())
23207    ])
23208  ];
23209}
23210
23211CGJSCrypt.Hash = function(data, encoding, hashalgo, iflags) {
23212	try {
23213		if(!hashalgo || hashalgo=="") hashalgo = 'sha1';
23214		var md = MD[hashalgo].create();
23215		md.update(data, encoding);
23216		var d = md.digest();	
23217		return d.toHex();
23218	} catch(e) {
23219		ErrorMsg=e.message;
23220		ErrorCode=5005;
23221	}
23222	return "";
23223}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.