1 /*! asn1tsp-1.0.1.js (c) 2014 Kenji Urushima | kjur.github.com/jsrsasign/license
  2  */
  3 /*
  4  * asn1tsp.js - ASN.1 DER encoder classes for RFC 3161 Time Stamp Protocol
  5  *
  6  * Copyright (c) 2014 Kenji Urushima (kenji.urushima@gmail.com)
  7  *
  8  * This software is licensed under the terms of the MIT License.
  9  * http://kjur.github.com/jsrsasign/license
 10  *
 11  * The above copyright and license notice shall be 
 12  * included in all copies or substantial portions of the Software.
 13  */
 14 
 15 /**
 16  * @fileOverview
 17  * @name asn1tsp-1.0.js
 18  * @author Kenji Urushima kenji.urushima@gmail.com
 19  * @version 1.0.1 (2014-Jun-07)
 20  * @since jsrsasign 4.5.1
 21  * @license <a href="http://kjur.github.io/jsrsasign/license/">MIT License</a>
 22  */
 23 
 24 /* 
 25  * kjur's class library name space
 26  * // already documented in asn1-1.0.js
 27  * @name KJUR
 28  * @namespace kjur's class library name space
 29  */
 30 if (typeof KJUR == "undefined" || !KJUR) KJUR = {};
 31 
 32 /*
 33  * kjur's ASN.1 class library name space
 34  * // already documented in asn1-1.0.js
 35  * @name KJUR.asn1
 36  * @namespace
 37  */
 38 if (typeof KJUR.asn1 == "undefined" || !KJUR.asn1) KJUR.asn1 = {};
 39 
 40 /**
 41  * kjur's ASN.1 class for RFC 3161 Time Stamp Protocol
 42  * <p>
 43  * This name space provides 
 44  * <a href="https://tools.ietf.org/html/rfc3161">RFC 3161
 45  * Time-Stamp Protocol(TSP)</a> data generator.
 46  *
 47  * <h4>FEATURES</h4>
 48  * <ul>
 49  * <li>easily generate CMS SignedData</li>
 50  * <li>APIs are very similar to BouncyCastle library ASN.1 classes. So easy to learn.</li>
 51  * </ul>
 52  * 
 53  * <h4>PROVIDED CLASSES</h4>
 54  * <ul>
 55  * </ul>
 56  * NOTE: Please ignore method summary and document of this namespace. This caused by a bug of jsdoc2.
 57  * </p>
 58  * @name KJUR.asn1.tsp
 59  * @namespace
 60  */
 61 if (typeof KJUR.asn1.tsp == "undefined" || !KJUR.asn1.tsp) KJUR.asn1.tsp = {};
 62 
 63 /**
 64  * class for TSP Accuracy ASN.1 object
 65  * @name KJUR.asn1.tsp.Accuracy
 66  * @class class for TSP Accuracy ASN.1 object
 67  * @param {Array} params associative array of parameters
 68  * @extends KJUR.asn1.ASN1Object
 69  * @since jsrsasign 4.6.0 asn1tsp 1.0.0
 70  * @description
 71  * <pre>
 72  * Accuracy ::= SEQUENCE {
 73  *       seconds        INTEGER              OPTIONAL,
 74  *       millis     [0] INTEGER  (1..999)    OPTIONAL,
 75  *       micros     [1] INTEGER  (1..999)    OPTIONAL  }
 76  * </pre>
 77  * @example
 78  * o = new KJUR.asn1.tsp.Accuracy({seconds: 1,
 79  *                                 millis: 500,
 80  *                                 micros: 500});
 81  */
 82 KJUR.asn1.tsp.Accuracy = function(params) {
 83     KJUR.asn1.tsp.Accuracy.superclass.constructor.call(this);
 84     var nA = KJUR.asn1;
 85     this.seconds = null;
 86     this.millis = null;
 87     this.micros = null;
 88 
 89     this.getEncodedHex = function() {
 90         var dSeconds = null;
 91         var dTagMillis = null;
 92         var dTagMicros = null;
 93         
 94         var a = [];
 95         if (this.seconds != null) {
 96             dSeconds = new nA.DERInteger({'int': this.seconds});
 97             a.push(dSeconds);
 98         }
 99         if (this.millis != null) {
100             var dMillis = new nA.DERInteger({'int': this.millis});
101             dTagMillis = new nA.DERTaggedObject({obj: dMillis,
102                                                  tag: '80',
103                                                  explicit: false});
104             a.push(dTagMillis);
105         }
106         if (this.micros != null) {
107             var dMicros = new nA.DERInteger({'int': this.micros});
108             dTagMicros = new nA.DERTaggedObject({obj: dMicros,
109                                                  tag: '81',
110                                                  explicit: false});
111             a.push(dTagMicros);
112         }
113         var seq = new nA.DERSequence({array: a});
114         this.hTLV = seq.getEncodedHex();
115         return this.hTLV;
116     };
117 
118     if (typeof params != "undefined") {
119         if (typeof params.seconds == "number") this.seconds = params.seconds;
120         if (typeof params.millis == "number") this.millis = params.millis;
121         if (typeof params.micros == "number") this.micros = params.micros;
122     }
123 };
124 YAHOO.lang.extend(KJUR.asn1.tsp.Accuracy, KJUR.asn1.ASN1Object);
125 
126 /**
127  * class for TSP MessageImprint ASN.1 object
128  * @name KJUR.asn1.tsp.MessageImprint
129  * @class class for TSP MessageImprint ASN.1 object
130  * @param {Array} params associative array of parameters
131  * @extends KJUR.asn1.ASN1Object
132  * @since jsrsasign 4.6.0 asn1tsp 1.0.0
133  * @description
134  * <pre>
135  * MessageImprint ::= SEQUENCE  {
136  *      hashAlgorithm                AlgorithmIdentifier,
137  *      hashedMessage                OCTET STRING  }
138  * </pre>
139  * @example
140  * o = new KJUR.asn1.tsp.MessageImprint({hashAlg: 'sha1',
141  *                                       hashValue: '1f3dea...'});
142  */
143 KJUR.asn1.tsp.MessageImprint = function(params) {
144     KJUR.asn1.tsp.MessageImprint.superclass.constructor.call(this);
145     var nA = KJUR.asn1;
146     var nX = KJUR.asn1.x509;
147     this.dHashAlg = null;
148     this.dHashValue = null;
149 
150     this.getEncodedHex = function() {
151         if (typeof this.hTLV == "string") return this.hTLV;
152         var seq = 
153             new nA.DERSequence({array: [this.dHashAlg, this.dHashValue]});
154         return seq.getEncodedHex();
155     };
156 
157     if (typeof params != "undefined") {
158         if (typeof params.hashAlg == "string") {
159             this.dHashAlg = new nX.AlgorithmIdentifier({name: params.hashAlg});
160         } 
161         if (typeof params.hashValue == "string") {
162             this.dHashValue = new nA.DEROctetString({hex: params.hashValue});
163         }
164     }
165 };
166 YAHOO.lang.extend(KJUR.asn1.tsp.MessageImprint, KJUR.asn1.ASN1Object);
167 
168 /**
169  * class for TSP TimeStampReq ASN.1 object
170  * @name KJUR.asn1.tsp.TimeStampReq
171  * @class class for TSP TimeStampReq ASN.1 object
172  * @param {Array} params associative array of parameters
173  * @extends KJUR.asn1.ASN1Object
174  * @since jsrsasign 4.6.0 asn1tsp 1.0.0
175  * @description
176  * <pre>
177  * TimeStampReq ::= SEQUENCE  {
178  *    version          INTEGER  { v1(1) },
179  *    messageImprint   MessageImprint,
180  *    reqPolicy        TSAPolicyId               OPTIONAL,
181  *    nonce            INTEGER                   OPTIONAL,
182  *    certReq          BOOLEAN                   DEFAULT FALSE,
183  *    extensions       [0] IMPLICIT Extensions   OPTIONAL  }
184  * </pre>
185  */
186 KJUR.asn1.tsp.TimeStampReq = function(params) {
187     KJUR.asn1.tsp.TimeStampReq.superclass.constructor.call(this);
188     var nA = KJUR.asn1;
189     var nT = KJUR.asn1.tsp;
190     this.dVersion = new nA.DERInteger({'int': 1});
191     this.dMessageImprint = null;
192     this.dPolicy = null;
193     this.dNonce = null;
194     this.certReq = true;
195 
196     this.setMessageImprint = function(params) {
197         if (params instanceof KJUR.asn1.tsp.MessageImprint) {
198             this.dMessageImprint = params;
199             return;
200         }
201         if (typeof params == "object") {
202             this.dMessageImprint = new nT.MessageImprint(params);
203         }
204     };
205 
206     this.getEncodedHex = function() {
207         if (this.dMessageImprint == null)
208             throw "messageImprint shall be specified";
209 
210         var a = [this.dVersion, this.dMessageImprint];
211         if (this.dPolicy != null) a.push(this.dPolicy);
212         if (this.dNonce != null)  a.push(this.dNonce);
213         if (this.certReq)         a.push(new nA.DERBoolean());
214 
215         var seq = new nA.DERSequence({array: a});
216         this.hTLV = seq.getEncodedHex();
217         return this.hTLV;
218     };
219 
220     if (typeof params != "undefined") {
221         if (typeof params.mi == "object") {
222             this.setMessageImprint(params.mi);
223         }
224         if (typeof params.policy == "object") {
225             this.dPolicy = new nA.DERObjectIdentifier(params.policy);
226         }
227         if (typeof params.nonce == "object") {
228             this.dNonce = new nA.DERInteger(params.nonce);
229         }
230         if (typeof params.certreq == "boolean") {
231             this.certReq = params.certreq;
232         }
233     }
234 };
235 YAHOO.lang.extend(KJUR.asn1.tsp.TimeStampReq, KJUR.asn1.ASN1Object);
236 
237 /**
238  * class for TSP TSTInfo ASN.1 object
239  * @name KJUR.asn1.tsp.TSTInfo
240  * @class class for TSP TSTInfo ASN.1 object
241  * @param {Array} params associative array of parameters
242  * @extends KJUR.asn1.ASN1Object
243  * @since jsrsasign 4.6.0 asn1tsp 1.0.0
244  * @description
245  * <pre>
246  * TSTInfo ::= SEQUENCE  {
247  *    version         INTEGER  { v1(1) },
248  *    policy          TSAPolicyId,
249  *    messageImprint  MessageImprint,
250  *    serialNumber    INTEGER, -- up to 160bit
251  *    genTime         GeneralizedTime,
252  *    accuracy        Accuracy                 OPTIONAL,
253  *    ordering        BOOLEAN                  DEFAULT FALSE,
254  *    nonce           INTEGER                  OPTIONAL,
255  *    tsa             [0] GeneralName          OPTIONAL,
256  *    extensions      [1] IMPLICIT Extensions  OPTIONAL   }
257  * </pre>
258  * @example
259  * o = new KJUR.asn1.tsp.TSTInfo({
260  *     policy:    '1.2.3.4.5',
261  *     messageImprint: {hashAlg: 'sha256', hashMsgHex: '1abc...'},
262  *     genTime:   {withMillis: true},     // OPTION
263  *     accuracy:  {micros: 500},          // OPTION
264  *     ordering:  true,                   // OPITON
265  *     nonce:     {hex: '52fab1...'},     // OPTION
266  *     tsa:       {str: '/C=US/O=TSA1'}   // OPITON
267  * });
268  */
269 KJUR.asn1.tsp.TSTInfo = function(params) {
270     KJUR.asn1.tsp.TSTInfo.superclass.constructor.call(this);
271     var nA = KJUR.asn1;
272     var nX = KJUR.asn1.x509;
273     var nT = KJUR.asn1.tsp;
274 
275     this.dVersion = new nA.DERInteger({'int': 1});
276     this.dPolicy = null;
277     this.dMessageImprint = null;
278     this.dSerialNumber = null;
279     this.dGenTime = null;
280     this.dAccuracy = null;
281     this.dOrdering = null;
282     this.dNonce = null;
283     this.dTsa = null;
284 
285     this.getEncodedHex = function() {
286         var a = [this.dVersion];
287 
288         if (this.dPolicy == null) throw "policy shall be specified.";
289         a.push(this.dPolicy);
290 
291         if (this.dMessageImprint == null)
292             throw "messageImprint shall be specified.";
293         a.push(this.dMessageImprint);
294 
295         if (this.dSerialNumber == null)
296             throw "serialNumber shall be specified.";
297         a.push(this.dSerialNumber);
298 
299         if (this.dGenTime == null)
300             throw "genTime shall be specified.";
301         a.push(this.dGenTime);
302 
303         if (this.dAccuracy != null) a.push(this.dAccuracy);
304         if (this.dOrdering != null) a.push(this.dOrdering);
305         if (this.dNonce != null) a.push(this.dNonce);
306         if (this.dTsa != null) a.push(this.dTsa);
307 
308         var seq = new nA.DERSequence({array: a});
309         this.hTLV = seq.getEncodedHex();
310         return this.hTLV;
311     };
312 
313     if (typeof params != "undefined") {
314         if (typeof params.policy == "string") {
315             if (! params.policy.match(/^[0-9.]+$/))
316                 throw "policy shall be oid like 0.1.4.134";
317             this.dPolicy = new nA.DERObjectIdentifier({oid: params.policy});
318         }
319         if (typeof params.messageImprint != "undefined") {
320             this.dMessageImprint = new nT.MessageImprint(params.messageImprint);
321         }
322         if (typeof params.serialNumber != "undefined") {
323             this.dSerialNumber = new nA.DERInteger(params.serialNumber);
324         }
325         if (typeof params.genTime != "undefined") {
326             this.dGenTime = new nA.DERGeneralizedTime(params.genTime);
327         }
328         if (typeof params.accuracy != "undefind") {
329             this.dAccuracy = new nT.Accuracy(params.accuracy);
330         }
331         if (typeof params.ordering != "undefined" &&
332             params.ordering == true) {
333             this.dOrdering = new nA.DERBoolean();
334         }
335         if (typeof params.nonce != "undefined") {
336             this.dNonce = new nA.DERInteger(params.nonce);
337         }
338         if (typeof params.tsa != "undefined") {
339             this.dTsa = new nX.X500Name(params.tsa);
340         }
341     }
342 };
343 YAHOO.lang.extend(KJUR.asn1.tsp.TSTInfo, KJUR.asn1.ASN1Object);
344 
345 /**
346  * class for TSP TimeStampResp ASN.1 object
347  * @name KJUR.asn1.tsp.TimeStampResp
348  * @class class for TSP TimeStampResp ASN.1 object
349  * @param {Array} params associative array of parameters
350  * @extends KJUR.asn1.ASN1Object
351  * @since jsrsasign 4.6.0 asn1tsp 1.0.0
352  * @description
353  * <pre>
354  * TimeStampResp ::= SEQUENCE  {
355  *    status                  PKIStatusInfo,
356  *    timeStampToken          TimeStampToken     OPTIONAL  }
357  * </pre>
358  */
359 KJUR.asn1.tsp.TimeStampResp = function(params) {
360     KJUR.asn1.tsp.TimeStampResp.superclass.constructor.call(this);
361     var nA = KJUR.asn1;
362     var nT = KJUR.asn1.tsp;
363     this.dStatus = null;
364     this.dTST = null;
365 
366     this.getEncodedHex = function() {
367         if (this.dStatus == null)
368             throw "status shall be specified";
369         var a = [this.dStatus];
370         if (this.dTST != null) a.push(this.dTST);
371         var seq = new nA.DERSequence({array: a});
372         this.hTLV = seq.getEncodedHex();
373         return this.hTLV;
374     };
375 
376     if (typeof params != "undefined") {
377         if (typeof params.status == "object") {
378             this.dStatus = new nT.PKIStatusInfo(params.status);
379         }
380         if (typeof params.tst != "undefined" &&
381             params.tst instanceof KJUR.asn1.ASN1Object) {
382             this.dTST = params.tst.getContentInfo();
383         }
384     }
385 };
386 YAHOO.lang.extend(KJUR.asn1.tsp.TimeStampResp, KJUR.asn1.ASN1Object);
387 
388 // --- BEGIN OF RFC 2510 CMP -----------------------------------------------
389 
390 /**
391  * class for TSP PKIStatusInfo ASN.1 object
392  * @name KJUR.asn1.tsp.PKIStatusInfo
393  * @class class for TSP PKIStatusInfo ASN.1 object
394  * @param {Array} params associative array of parameters
395  * @extends KJUR.asn1.ASN1Object
396  * @since jsrsasign 4.6.0 asn1tsp 1.0.0
397  * @description
398  * <pre>
399  * PKIStatusInfo ::= SEQUENCE {
400  *    status                  PKIStatus,
401  *    statusString            PKIFreeText     OPTIONAL,
402  *    failInfo                PKIFailureInfo  OPTIONAL  }
403  * </pre>
404  */
405 KJUR.asn1.tsp.PKIStatusInfo = function(params) {
406     KJUR.asn1.tsp.PKIStatusInfo.superclass.constructor.call(this);
407     var nA = KJUR.asn1;
408     var nT = KJUR.asn1.tsp;
409     this.dStatus = null;
410     this.dStatusString = null;
411     this.dFailureInfo = null;
412 
413     this.getEncodedHex = function() {
414         if (this.dStatus == null)
415             throw "status shall be specified";
416         var a = [this.dStatus];
417         if (this.dStatusString != null) a.push(this.dStatusString);
418         if (this.dFailureInfo != null) a.push(this.dFailureInfo);
419         var seq = new nA.DERSequence({array: a});
420         this.hTLV = seq.getEncodedHex();
421         return this.hTLV;
422     };
423 
424     if (typeof params != "undefined") {
425         if (typeof params.status == "object") { // param for int
426             this.dStatus = new nT.PKIStatus(params.status);
427         }
428         if (typeof params.statstr == "object") { // array of str
429             this.dStatusString = 
430                 new nT.PKIFreeText({array: params.statstr});
431         }
432         if (typeof params.failinfo == "object") {
433             this.dFailureInfo = 
434                 new nT.PKIFailureInfo(params.failinfo); // param for bitstr
435         }
436     };
437 };
438 YAHOO.lang.extend(KJUR.asn1.tsp.PKIStatusInfo, KJUR.asn1.ASN1Object);
439 
440 /**
441  * class for TSP PKIStatus ASN.1 object
442  * @name KJUR.asn1.tsp.PKIStatus
443  * @class class for TSP PKIStatus ASN.1 object
444  * @param {Array} params associative array of parameters
445  * @extends KJUR.asn1.ASN1Object
446  * @since jsrsasign 4.6.0 asn1tsp 1.0.0
447  * @description
448  * <pre>
449  * PKIStatus ::= INTEGER {
450  *    granted                (0),
451  *    grantedWithMods        (1),
452  *    rejection              (2),
453  *    waiting                (3),
454  *    revocationWarning      (4),
455  *    revocationNotification (5) }
456  * </pre>
457  */
458 KJUR.asn1.tsp.PKIStatus = function(params) {
459     KJUR.asn1.tsp.PKIStatus.superclass.constructor.call(this);
460     var nA = KJUR.asn1;
461     var nT = KJUR.asn1.tsp;
462     var dStatus = null;
463 
464     this.getEncodedHex = function() {
465         this.hTLV = this.dStatus.getEncodedHex();
466         return this.hTLV;
467     };
468 
469     if (typeof params != "undefined") {
470         if (typeof params.name != "undefined") {
471             var list = nT.PKIStatus.valueList;
472             if (typeof list[params.name] == "undefined")
473                 throw "name undefined: " + params.name;
474             this.dStatus = 
475                 new nA.DERInteger({'int': list[params.name]});
476         } else {
477             this.dStatus = new nA.DERInteger(params);
478         }
479     }
480 };
481 YAHOO.lang.extend(KJUR.asn1.tsp.PKIStatus, KJUR.asn1.ASN1Object);
482 
483 KJUR.asn1.tsp.PKIStatus.valueList = {
484     granted:                0,
485     grantedWithMods:        1,
486     rejection:              2,
487     waiting:                3,
488     revocationWarning:      4,
489     revocationNotification: 5
490 };
491 
492 /**
493  * class for TSP PKIFreeText ASN.1 object
494  * @name KJUR.asn1.tsp.PKIFreeText
495  * @class class for TSP PKIFreeText ASN.1 object
496  * @param {Array} params associative array of parameters
497  * @extends KJUR.asn1.ASN1Object
498  * @since jsrsasign 4.6.0 asn1tsp 1.0.0
499  * @description
500  * <pre>
501  * PKIFreeText ::= SEQUENCE {
502  *    SIZE (1..MAX) OF UTF8String }
503  * </pre>
504  */
505 KJUR.asn1.tsp.PKIFreeText = function(params) {
506     KJUR.asn1.tsp.PKIFreeText.superclass.constructor.call(this);
507     var nA = KJUR.asn1;
508     this.textList = [];
509 
510     this.getEncodedHex = function() {
511         var a = [];
512         for (var i = 0; i < this.textList.length; i++) {
513             a.push(new nA.DERUTF8String({str: this.textList[i]}));
514         }
515         var seq = new nA.DERSequence({array: a});
516         this.hTLV = seq.getEncodedHex();
517         return this.hTLV;
518     };
519 
520     if (typeof params != "undefined") {
521         if (typeof params.array == "object") {
522             this.textList = params.array;
523         }
524     }
525 };
526 YAHOO.lang.extend(KJUR.asn1.tsp.PKIFreeText, KJUR.asn1.ASN1Object);
527 
528 /**
529  * class for TSP PKIFailureInfo ASN.1 object
530  * @name KJUR.asn1.tsp.PKIFailureInfo
531  * @class class for TSP PKIFailureInfo ASN.1 object
532  * @param {Array} params associative array of parameters
533  * @extends KJUR.asn1.ASN1Object
534  * @since jsrsasign 4.6.0 asn1tsp 1.0.0
535  * @description
536  * <pre>
537  * PKIFailureInfo ::= BIT STRING {
538  *    badAlg                 (0),
539  *    badRequest             (2),
540  *    badDataFormat          (5),
541  *    timeNotAvailable       (14),
542  *    unacceptedPolicy       (15),
543  *    unacceptedExtension    (16),
544  *    addInfoNotAvailable    (17),
545  *    systemFailure          (25) }
546  * </pre>
547  */
548 KJUR.asn1.tsp.PKIFailureInfo = function(params) {
549     KJUR.asn1.tsp.PKIFailureInfo.superclass.constructor.call(this);
550     var nA = KJUR.asn1;
551     var nT = KJUR.asn1.tsp;
552     this.value = null;
553 
554     this.getEncodedHex = function() {
555         if (this.value == null)
556             throw "value shall be specified";
557         var binValue = new Number(this.value).toString(2);
558         var dValue = new nA.DERBitString();
559         dValue.setByBinaryString(binValue);
560         this.hTLV = dValue.getEncodedHex();
561         return this.hTLV;
562     };
563 
564     if (typeof params != "undefined") {
565         if (typeof params.name == "string") {
566             var list = nT.PKIFailureInfo.valueList;
567             if (typeof list[params.name] == "undefined")
568                 throw "name undefined: " + params.name;
569             this.value = list[params.name];
570         } else if (typeof params['int'] == "number") {
571             this.value = params['int'];
572         }
573     }
574 };
575 YAHOO.lang.extend(KJUR.asn1.tsp.PKIFailureInfo, KJUR.asn1.ASN1Object);
576 
577 KJUR.asn1.tsp.PKIFailureInfo.valueList = {
578     badAlg:                 0,
579     badRequest:             2,
580     badDataFormat:          5,
581     timeNotAvailable:       14,
582     unacceptedPolicy:       15,
583     unacceptedExtension:    16,
584     addInfoNotAvailable:    17,
585     systemFailure:          25
586 };
587 
588 // --- END OF RFC 2510 CMP -------------------------------------------
589 
590 /**
591  * abstract class for TimeStampToken generator
592  * @name KJUR.asn1.tsp.AbstractTSAAdapter
593  * @class abstract class for TimeStampToken generator
594  * @param {Array} params associative array of parameters
595  * @since jsrsasign 4.7.0 asn1tsp 1.0.1
596  * @description
597  */
598 KJUR.asn1.tsp.AbstractTSAAdapter = function(params) {
599     this.getTSTHex = function(msgHex, hashAlg) {
600         throw "not implemented yet";
601     };
602 };
603 
604 /**
605  * class for simple TimeStampToken generator
606  * @name KJUR.asn1.tsp.SimpleTSAAdapter
607  * @class class for simple TimeStampToken generator
608  * @param {Array} params associative array of parameters
609  * @since jsrsasign 4.7.0 asn1tsp 1.0.1
610  * @description
611  */
612 KJUR.asn1.tsp.SimpleTSAAdapter = function(initParams) {
613     KJUR.asn1.tsp.SimpleTSAAdapter.superclass.constructor.call(this);
614     this.params = null;
615     this.serial = 0;
616 
617     this.getTSTHex = function(msgHex, hashAlg) {
618         // messageImprint
619         var hashHex = KJUR.crypto.Util.hashHex(msgHex, hashAlg);
620         this.params.tstInfo.messageImprint =
621             {hashAlg: hashAlg, hashValue: hashHex};
622 
623         // serial
624         this.params.tstInfo.serialNumber = {'int': this.serial++};
625 
626         // nonce
627         var nonceValue = Math.floor(Math.random() * 1000000000);
628         this.params.tstInfo.nonce = {'int': nonceValue};
629 
630         var obj = 
631             KJUR.asn1.tsp.TSPUtil.newTimeStampToken(this.params);
632         return obj.getContentInfoEncodedHex();
633     };
634 
635     if (typeof initParams != "undefined") {
636         this.params = initParams;
637     }
638 };
639 YAHOO.lang.extend(KJUR.asn1.tsp.SimpleTSAAdapter,
640                   KJUR.asn1.tsp.AbstractTSAAdapter);
641 
642 /**
643  * class for fixed TimeStampToken generator
644  * @name KJUR.asn1.tsp.FixedTSAAdapter
645  * @class class for fixed TimeStampToken generator
646  * @param {Array} params associative array of parameters
647  * @since jsrsasign 4.7.0 asn1tsp 1.0.1
648  * @description
649  * This class generates fixed TimeStampToken except messageImprint
650  * for testing purpose.
651  * General TSA generates TimeStampToken which varies following
652  * fields:
653  * <ul>
654  * <li>genTime</li>
655  * <li>serialNumber</li>
656  * <li>nonce</li>
657  * </ul>
658  * Those values are provided by initial parameters.
659  */
660 KJUR.asn1.tsp.FixedTSAAdapter = function(initParams) {
661     KJUR.asn1.tsp.FixedTSAAdapter.superclass.constructor.call(this);
662     this.params = null;
663 
664     this.getTSTHex = function(msgHex, hashAlg) {
665         // fixed serialNumber
666         // fixed nonce        
667         var hashHex = KJUR.crypto.Util.hashHex(msgHex, hashAlg);
668         this.params.tstInfo.messageImprint =
669             {hashAlg: hashAlg, hashValue: hashHex};
670         var obj = 
671             KJUR.asn1.tsp.TSPUtil.newTimeStampToken(this.params);
672         return obj.getContentInfoEncodedHex();
673     };
674 
675     if (typeof initParams != "undefined") {
676         this.params = initParams;
677     }
678 };
679 YAHOO.lang.extend(KJUR.asn1.tsp.FixedTSAAdapter,
680                   KJUR.asn1.tsp.AbstractTSAAdapter);
681 
682 // --- TSP utilities -------------------------------------------------
683 
684 /**
685  * TSP utiliteis class
686  * @name KJUR.asn1.tsp.TSPUtil
687  * @class TSP utilities class
688  */
689 KJUR.asn1.tsp.TSPUtil = new function() {
690 };
691 /**
692  * generate TimeStampToken ASN.1 object specified by JSON parameters
693  * @name newTimeStampToken
694  * @memberOf KJUR.asn1.tsp.TSPUtil
695  * @function
696  * @param {Array} param JSON parameter to generate TimeStampToken
697  * @return {KJUR.asn1.cms.SignedData} object just generated
698  * @description
699  * @example
700  */
701 KJUR.asn1.tsp.TSPUtil.newTimeStampToken = function(param) {
702     var nC = KJUR.asn1.cms;
703     var nT = KJUR.asn1.tsp;
704     var sd = new nC.SignedData();
705 
706     var dTSTInfo = new nT.TSTInfo(param.tstInfo);
707     var tstInfoHex = dTSTInfo.getEncodedHex();
708     sd.dEncapContentInfo.setContentValue({hex: tstInfoHex});
709     sd.dEncapContentInfo.setContentType('tstinfo');
710 
711     if (typeof param.certs == "object") {
712         for (var i = 0; i < param.certs.length; i++) {
713             sd.addCertificatesByPEM(param.certs[i]);
714         }
715     }
716 
717     var si = sd.signerInfoList[0];
718     si.setSignerIdentifier(param.signerCert);
719     si.setForContentAndHash({sdObj: sd,
720                              eciObj: sd.dEncapContentInfo,
721                              hashAlg: param.hashAlg});
722     var signingCertificate = 
723         new nC.SigningCertificate({array: [param.signerCert]});
724     si.dSignedAttrs.add(signingCertificate);
725 
726     si.sign(param.signerPrvKey, param.sigAlg);
727 
728     return sd;
729 };
730 
731 /**
732  * parse hexadecimal string of TimeStampReq
733  * @name parseTimeStampReq
734  * @memberOf KJUR.asn1.tsp.TSPUtil
735  * @function
736  * @param {String} hexadecimal string of TimeStampReq
737  * @return {Array} JSON object of parsed parameters
738  * @description
739  * This method parses a hexadecimal string of TimeStampReq
740  * and returns parsed their fields:
741  * @example
742  * var json = KJUR.asn1.tsp.TSPUtil.parseTimeStampReq("302602...");
743  * // resulted DUMP of above 'json':
744  * {mi: {hashAlg: 'sha256',          // MessageImprint hashAlg
745  *       hashValue: 'a1a2a3a4...'},  // MessageImprint hashValue
746  *  policy: '1.2.3.4.5',             // tsaPolicy (OPTION)
747  *  nonce: '9abcf318...',            // nonce (OPTION)
748  *  certreq: true}                   // certReq (OPTION)
749  */
750 KJUR.asn1.tsp.TSPUtil.parseTimeStampReq = function(reqHex) {
751     var json = {};
752     json.certreq = false;
753 
754     var idxList = ASN1HEX.getPosArrayOfChildren_AtObj(reqHex, 0);
755 
756     if (idxList.length < 2)
757         throw "TimeStampReq must have at least 2 items";
758 
759     var miHex = ASN1HEX.getHexOfTLV_AtObj(reqHex, idxList[1]);
760     json.mi = KJUR.asn1.tsp.TSPUtil.parseMessageImprint(miHex); 
761 
762     for (var i = 2; i < idxList.length; i++) {
763         var idx = idxList[i];
764         var tag = reqHex.substr(idx, 2);
765         if (tag == "06") { // case OID
766             var policyHex = ASN1HEX.getHexOfV_AtObj(reqHex, idx);
767             json.policy = ASN1HEX.hextooidstr(policyHex);
768         }
769         if (tag == "02") { // case INTEGER
770             json.nonce = ASN1HEX.getHexOfV_AtObj(reqHex, idx);
771         }
772         if (tag == "01") { // case BOOLEAN
773             json.certreq = true;
774         }
775     }
776 
777     return json;
778 };
779 
780 /**
781  * parse hexadecimal string of MessageImprint
782  * @name parseMessageImprint
783  * @memberOf KJUR.asn1.tsp.TSPUtil
784  * @function
785  * @param {String} hexadecimal string of MessageImprint
786  * @return {Array} JSON object of parsed parameters
787  * @description
788  * This method parses a hexadecimal string of MessageImprint
789  * and returns parsed their fields:
790  * @example
791  * var json = KJUR.asn1.tsp.TSPUtil.parseMessageImprint("302602...");
792  * // resulted DUMP of above 'json':
793  * {hashAlg: 'sha256',          // MessageImprint hashAlg
794  *  hashValue: 'a1a2a3a4...'}   // MessageImprint hashValue
795  */
796 KJUR.asn1.tsp.TSPUtil.parseMessageImprint = function(miHex) {
797     var json = {};
798 
799     if (miHex.substr(0, 2) != "30")
800         throw "head of messageImprint hex shall be '30'";
801 
802     var idxList = ASN1HEX.getPosArrayOfChildren_AtObj(miHex, 0);
803     var hashAlgOidIdx = 
804         ASN1HEX.getDecendantIndexByNthList(miHex, 0, [0, 0]);
805     var hashAlgHex = ASN1HEX.getHexOfV_AtObj(miHex, hashAlgOidIdx);
806     var hashAlgOid = ASN1HEX.hextooidstr(hashAlgHex);
807     var hashAlgName = KJUR.asn1.x509.OID.oid2name(hashAlgOid);
808     if (hashAlgName == '')
809         throw "hashAlg name undefined: " + hashAlgOid;
810     var hashAlg = hashAlgName;
811 
812     var hashValueIdx =
813         ASN1HEX.getDecendantIndexByNthList(miHex, 0, [1]);
814 
815     json.hashAlg = hashAlg;
816     json.hashValue = ASN1HEX.getHexOfV_AtObj(miHex, hashValueIdx); 
817 
818     return json;
819 };
820 
821