1 /* asn1tsp-1.0.5.js (c) 2014-2020 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-2017 Kenji Urushima (kenji.urushima@gmail.com)
  7  *
  8  * This software is licensed under the terms of the MIT License.
  9  * https://kjur.github.io/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 jsrsasign 9.0.2 asn1tsp 1.0.5 (2020-Aug-22)
 20  * @since jsrsasign 4.5.1
 21  * @license <a href="https://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     var _KJUR = KJUR,
 84 	_KJUR_asn1 = _KJUR.asn1,
 85 	_DERInteger = _KJUR_asn1.DERInteger,
 86 	_DERSequence = _KJUR_asn1.DERSequence,
 87 	_DERTaggedObject = _KJUR_asn1.DERTaggedObject;
 88 
 89     _KJUR_asn1.tsp.Accuracy.superclass.constructor.call(this);
 90 
 91     this.seconds = null;
 92     this.millis = null;
 93     this.micros = null;
 94 
 95     this.getEncodedHex = function() {
 96         var dSeconds = null;
 97         var dTagMillis = null;
 98         var dTagMicros = null;
 99         
100         var a = [];
101         if (this.seconds != null) {
102             dSeconds = new _DERInteger({'int': this.seconds});
103             a.push(dSeconds);
104         }
105         if (this.millis != null) {
106             var dMillis = new _DERInteger({'int': this.millis});
107             dTagMillis = new _DERTaggedObject({obj: dMillis,
108                                                tag: '80',
109                                                explicit: false});
110             a.push(dTagMillis);
111         }
112         if (this.micros != null) {
113             var dMicros = new _DERInteger({'int': this.micros});
114             dTagMicros = new _DERTaggedObject({obj: dMicros,
115                                                tag: '81',
116                                                explicit: false});
117             a.push(dTagMicros);
118         }
119         var seq = new _DERSequence({array: a});
120         this.hTLV = seq.getEncodedHex();
121         return this.hTLV;
122     };
123 
124     if (params !== undefined) {
125         if (typeof params.seconds == "number") this.seconds = params.seconds;
126         if (typeof params.millis == "number") this.millis = params.millis;
127         if (typeof params.micros == "number") this.micros = params.micros;
128     }
129 };
130 YAHOO.lang.extend(KJUR.asn1.tsp.Accuracy, KJUR.asn1.ASN1Object);
131 
132 /**
133  * class for TSP MessageImprint ASN.1 object
134  * @name KJUR.asn1.tsp.MessageImprint
135  * @class class for TSP MessageImprint ASN.1 object
136  * @param {Array} params associative array of parameters
137  * @extends KJUR.asn1.ASN1Object
138  * @since jsrsasign 4.6.0 asn1tsp 1.0.0
139  * @description
140  * <pre>
141  * MessageImprint ::= SEQUENCE  {
142  *      hashAlgorithm                AlgorithmIdentifier,
143  *      hashedMessage                OCTET STRING  }
144  * </pre>
145  * @example
146  * o = new KJUR.asn1.tsp.MessageImprint({hashAlg: 'sha1',
147  *                                       hashValue: '1f3dea...'});
148  */
149 KJUR.asn1.tsp.MessageImprint = function(params) {
150     var _KJUR = KJUR,
151 	_KJUR_asn1 = _KJUR.asn1,
152 	_DERSequence = _KJUR_asn1.DERSequence,
153 	_DEROctetString = _KJUR_asn1.DEROctetString,
154 	_KJUR_asn1_x509 = _KJUR_asn1.x509,
155 	_AlgorithmIdentifier = _KJUR_asn1_x509.AlgorithmIdentifier;
156 
157     _KJUR_asn1.tsp.MessageImprint.superclass.constructor.call(this);
158 
159     this.dHashAlg = null;
160     this.dHashValue = null;
161 
162     this.getEncodedHex = function() {
163         if (typeof this.hTLV == "string") return this.hTLV;
164         var seq = 
165             new _DERSequence({array: [this.dHashAlg, this.dHashValue]});
166         return seq.getEncodedHex();
167     };
168 
169     if (params !== undefined) {
170         if (typeof params.hashAlg == "string") {
171             this.dHashAlg = new _AlgorithmIdentifier({name: params.hashAlg});
172         } 
173         if (typeof params.hashValue == "string") {
174             this.dHashValue = new _DEROctetString({hex: params.hashValue});
175         }
176     }
177 };
178 YAHOO.lang.extend(KJUR.asn1.tsp.MessageImprint, KJUR.asn1.ASN1Object);
179 
180 /**
181  * class for TSP TimeStampReq ASN.1 object
182  * @name KJUR.asn1.tsp.TimeStampReq
183  * @class class for TSP TimeStampReq ASN.1 object
184  * @param {Array} params associative array of parameters
185  * @extends KJUR.asn1.ASN1Object
186  * @since jsrsasign 4.6.0 asn1tsp 1.0.0
187  * @description
188  * <pre>
189  * TimeStampReq ::= SEQUENCE  {
190  *    version          INTEGER  { v1(1) },
191  *    messageImprint   MessageImprint,
192  *    reqPolicy        TSAPolicyId               OPTIONAL,
193  *    nonce            INTEGER                   OPTIONAL,
194  *    certReq          BOOLEAN                   DEFAULT FALSE,
195  *    extensions       [0] IMPLICIT Extensions   OPTIONAL  }
196  * </pre>
197  */
198 KJUR.asn1.tsp.TimeStampReq = function(params) {
199     var _KJUR = KJUR,
200 	_KJUR_asn1 = _KJUR.asn1,
201 	_DERSequence = _KJUR_asn1.DERSequence,
202 	_DERInteger = _KJUR_asn1.DERInteger,
203 	_DERBoolean = _KJUR_asn1.DERBoolean,
204 	_DERObjectIdentifier = _KJUR_asn1.DERObjectIdentifier,
205 	_KJUR_asn1_tsp = _KJUR_asn1.tsp,
206 	_MessageImprint = _KJUR_asn1_tsp.MessageImprint;
207 
208     _KJUR_asn1_tsp.TimeStampReq.superclass.constructor.call(this);
209 
210     this.dVersion = new _DERInteger({'int': 1});
211     this.dMessageImprint = null;
212     this.dPolicy = null;
213     this.dNonce = null;
214     this.certReq = true;
215 
216     this.setMessageImprint = function(params) {
217         if (params instanceof _MessageImprint) {
218             this.dMessageImprint = params;
219             return;
220         }
221         if (typeof params == "object") {
222             this.dMessageImprint = new _MessageImprint(params);
223         }
224     };
225 
226     this.getEncodedHex = function() {
227         if (this.dMessageImprint == null)
228             throw "messageImprint shall be specified";
229 
230         var a = [this.dVersion, this.dMessageImprint];
231         if (this.dPolicy != null) a.push(this.dPolicy);
232         if (this.dNonce != null)  a.push(this.dNonce);
233         if (this.certReq)         a.push(new _DERBoolean());
234 
235         var seq = new _DERSequence({array: a});
236         this.hTLV = seq.getEncodedHex();
237         return this.hTLV;
238     };
239 
240     if (params !== undefined) {
241         if (typeof params.mi == "object") {
242             this.setMessageImprint(params.mi);
243         }
244         if (typeof params.policy == "object") {
245             this.dPolicy = new _DERObjectIdentifier(params.policy);
246         }
247         if (typeof params.nonce == "object") {
248             this.dNonce = new _DERInteger(params.nonce);
249         }
250         if (typeof params.certreq == "boolean") {
251             this.certReq = params.certreq;
252         }
253     }
254 };
255 YAHOO.lang.extend(KJUR.asn1.tsp.TimeStampReq, KJUR.asn1.ASN1Object);
256 
257 /**
258  * class for TSP TSTInfo ASN.1 object
259  * @name KJUR.asn1.tsp.TSTInfo
260  * @class class for TSP TSTInfo ASN.1 object
261  * @param {Array} params JSON object for TSTInfo parameters
262  * @extends KJUR.asn1.ASN1Object
263  * @since jsrsasign 4.6.0 asn1tsp 1.0.0
264  * @see KJUR.asn1.x509.X500Name
265  * @see KJUR.asn1.x509.GeneralName
266  * @description
267  * This class represents TSTInfo ASN.1 structure.
268  * <pre>
269  * TSTInfo ::= SEQUENCE  {
270  *    version         INTEGER  { v1(1) },
271  *    policy          TSAPolicyId,
272  *    messageImprint  MessageImprint,
273  *    serialNumber    INTEGER, -- up to 160bit
274  *    genTime         GeneralizedTime,
275  *    accuracy        Accuracy                 OPTIONAL,
276  *    ordering        BOOLEAN                  DEFAULT FALSE,
277  *    nonce           INTEGER                  OPTIONAL,
278  *    tsa             [0] GeneralName          OPTIONAL,
279  *    extensions      [1] IMPLICIT Extensions  OPTIONAL   }
280  * </pre>
281  * For "params" arguent, following properties are accepted:
282  * <ul>
283  * <li>{Array}tsa - {@link KJUR.asn1.x509.X500Name} parameter for
284  * tsa field even though tsa field is GeneralName.</li>
285  * </ul>
286  * @example
287  * o = new KJUR.asn1.tsp.TSTInfo({
288  *     policy:    '1.2.3.4.5',
289  *     messageImprint: {hashAlg: 'sha256', hashMsgHex: '1abc...'},
290  *     genTime:   {withMillis: true},     // OPTION
291  *     accuracy:  {micros: 500},          // OPTION
292  *     ordering:  true,                   // OPITON
293  *     nonce:     {hex: '52fab1...'},     // OPTION
294  *     tsa:       {str: '/C=US/O=TSA1'}   // OPITON
295  * });
296  */
297 KJUR.asn1.tsp.TSTInfo = function(params) {
298     var _KJUR = KJUR,
299 	_KJUR_asn1 = _KJUR.asn1,
300 	_DERSequence = _KJUR_asn1.DERSequence,
301 	_DERInteger = _KJUR_asn1.DERInteger,
302 	_DERBoolean = _KJUR_asn1.DERBoolean,
303 	_DERGeneralizedTime = _KJUR_asn1.DERGeneralizedTime,
304 	_DERObjectIdentifier = _KJUR_asn1.DERObjectIdentifier,
305 	_DERTaggedObject = _KJUR_asn1.DERTaggedObject,
306 	_KJUR_asn1_tsp = _KJUR_asn1.tsp,
307 	_MessageImprint = _KJUR_asn1_tsp.MessageImprint,
308 	_Accuracy = _KJUR_asn1_tsp.Accuracy,
309         _X500Name = _KJUR_asn1.x509.X500Name,
310         _GeneralName = _KJUR_asn1.x509.GeneralName;
311 	
312 
313     _KJUR_asn1_tsp.TSTInfo.superclass.constructor.call(this);
314 
315     this.dVersion = new _DERInteger({'int': 1});
316     this.dPolicy = null;
317     this.dMessageImprint = null;
318     this.dSerialNumber = null;
319     this.dGenTime = null;
320     this.dAccuracy = null;
321     this.dOrdering = null;
322     this.dNonce = null;
323     this.dTsa = null;
324 
325     this.getEncodedHex = function() {
326         var a = [this.dVersion];
327 
328         if (this.dPolicy == null) throw "policy shall be specified.";
329         a.push(this.dPolicy);
330 
331         if (this.dMessageImprint == null)
332             throw "messageImprint shall be specified.";
333         a.push(this.dMessageImprint);
334 
335         if (this.dSerialNumber == null)
336             throw "serialNumber shall be specified.";
337         a.push(this.dSerialNumber);
338 
339         if (this.dGenTime == null)
340             throw "genTime shall be specified.";
341         a.push(this.dGenTime);
342 
343         if (this.dAccuracy != null) a.push(this.dAccuracy);
344         if (this.dOrdering != null) a.push(this.dOrdering);
345         if (this.dNonce != null) a.push(this.dNonce);
346         if (this.dTsa != null) a.push(this.dTsa);
347 
348         var seq = new _DERSequence({array: a});
349         this.hTLV = seq.getEncodedHex();
350         return this.hTLV;
351     };
352 
353     if (params !== undefined) {
354         if (typeof params.policy == "string") {
355             if (! params.policy.match(/^[0-9.]+$/))
356                 throw "policy shall be oid like 0.1.4.134";
357             this.dPolicy = new _DERObjectIdentifier({oid: params.policy});
358         }
359         if (params.messageImprint !== undefined) {
360             this.dMessageImprint = new _MessageImprint(params.messageImprint);
361         }
362         if (params.serialNumber !== undefined) {
363             this.dSerialNumber = new _DERInteger(params.serialNumber);
364         }
365         if (params.genTime !== undefined) {
366             this.dGenTime = new _DERGeneralizedTime(params.genTime);
367         }
368         if (params.accuracy !== undefined) {
369             this.dAccuracy = new _Accuracy(params.accuracy);
370         }
371         if (params.ordering !== undefined &&
372             params.ordering == true) {
373             this.dOrdering = new _DERBoolean();
374         }
375         if (params.nonce !== undefined) {
376             this.dNonce = new _DERInteger(params.nonce);
377         }
378         if (params.tsa !== undefined) {
379             this.dTsa = new _DERTaggedObject({
380 		tag: "a0",
381 		explicit: true,
382 		obj: new _GeneralName({dn: params.tsa})
383 	    });
384         }
385     }
386 };
387 YAHOO.lang.extend(KJUR.asn1.tsp.TSTInfo, KJUR.asn1.ASN1Object);
388 
389 /**
390  * class for TSP TimeStampResp ASN.1 object
391  * @name KJUR.asn1.tsp.TimeStampResp
392  * @class class for TSP TimeStampResp ASN.1 object
393  * @param {Array} params associative array of parameters
394  * @extends KJUR.asn1.ASN1Object
395  * @since jsrsasign 4.6.0 asn1tsp 1.0.0
396  * @description
397  * <pre>
398  * TimeStampResp ::= SEQUENCE  {
399  *    status                  PKIStatusInfo,
400  *    timeStampToken          TimeStampToken     OPTIONAL  }
401  * </pre>
402  */
403 KJUR.asn1.tsp.TimeStampResp = function(params) {
404     var _KJUR = KJUR,
405 	_KJUR_asn1 = _KJUR.asn1,
406 	_DERSequence = _KJUR_asn1.DERSequence,
407 	_ASN1Object = _KJUR_asn1.ASN1Object,
408 	_KJUR_asn1_tsp = _KJUR_asn1.tsp,
409 	_PKIStatusInfo = _KJUR_asn1_tsp.PKIStatusInfo;
410 
411     _KJUR_asn1_tsp.TimeStampResp.superclass.constructor.call(this);
412 
413     this.dStatus = null;
414     this.dTST = null;
415 
416     this.getEncodedHex = function() {
417         if (this.dStatus == null)
418             throw "status shall be specified";
419         var a = [this.dStatus];
420         if (this.dTST != null) a.push(this.dTST);
421         var seq = new _DERSequence({array: a});
422         this.hTLV = seq.getEncodedHex();
423         return this.hTLV;
424     };
425 
426     if (params !== undefined) {
427         if (typeof params.status == "object") {
428             this.dStatus = new _PKIStatusInfo(params.status);
429         }
430         if (params.tst !== undefined &&
431             params.tst instanceof _ASN1Object) {
432             this.dTST = params.tst.getContentInfo();
433         }
434     }
435 };
436 YAHOO.lang.extend(KJUR.asn1.tsp.TimeStampResp, KJUR.asn1.ASN1Object);
437 
438 // --- BEGIN OF RFC 2510 CMP -----------------------------------------------
439 
440 /**
441  * class for TSP PKIStatusInfo ASN.1 object
442  * @name KJUR.asn1.tsp.PKIStatusInfo
443  * @class class for TSP PKIStatusInfo 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  * PKIStatusInfo ::= SEQUENCE {
450  *    status                  PKIStatus,
451  *    statusString            PKIFreeText     OPTIONAL,
452  *    failInfo                PKIFailureInfo  OPTIONAL  }
453  * </pre>
454  */
455 KJUR.asn1.tsp.PKIStatusInfo = function(params) {
456     var _KJUR = KJUR,
457 	_KJUR_asn1 = _KJUR.asn1,
458 	_DERSequence = _KJUR_asn1.DERSequence,
459 	_KJUR_asn1_tsp = _KJUR_asn1.tsp,
460 	_PKIStatus = _KJUR_asn1_tsp.PKIStatus,
461 	_PKIFreeText = _KJUR_asn1_tsp.PKIFreeText,
462 	_PKIFailureInfo = _KJUR_asn1_tsp.PKIFailureInfo;
463 
464     _KJUR_asn1_tsp.PKIStatusInfo.superclass.constructor.call(this);
465 
466     this.dStatus = null;
467     this.dStatusString = null;
468     this.dFailureInfo = null;
469 
470     this.getEncodedHex = function() {
471         if (this.dStatus == null)
472             throw "status shall be specified";
473         var a = [this.dStatus];
474         if (this.dStatusString != null) a.push(this.dStatusString);
475         if (this.dFailureInfo != null) a.push(this.dFailureInfo);
476         var seq = new _DERSequence({array: a});
477         this.hTLV = seq.getEncodedHex();
478         return this.hTLV;
479     };
480 
481     if (params !== undefined) {
482         if (typeof params.status == "object") { // param for int
483             this.dStatus = new _PKIStatus(params.status);
484         }
485         if (typeof params.statstr == "object") { // array of str
486             this.dStatusString = 
487                 new _PKIFreeText({array: params.statstr});
488         }
489         if (typeof params.failinfo == "object") {
490             this.dFailureInfo = 
491                 new _PKIFailureInfo(params.failinfo); // param for bitstr
492         }
493     };
494 };
495 YAHOO.lang.extend(KJUR.asn1.tsp.PKIStatusInfo, KJUR.asn1.ASN1Object);
496 
497 /**
498  * class for TSP PKIStatus ASN.1 object
499  * @name KJUR.asn1.tsp.PKIStatus
500  * @class class for TSP PKIStatus ASN.1 object
501  * @param {Array} params associative array of parameters
502  * @extends KJUR.asn1.ASN1Object
503  * @since jsrsasign 4.6.0 asn1tsp 1.0.0
504  * @description
505  * <pre>
506  * PKIStatus ::= INTEGER {
507  *    granted                (0),
508  *    grantedWithMods        (1),
509  *    rejection              (2),
510  *    waiting                (3),
511  *    revocationWarning      (4),
512  *    revocationNotification (5) }
513  * </pre>
514  */
515 KJUR.asn1.tsp.PKIStatus = function(params) {
516     var _KJUR = KJUR,
517 	_KJUR_asn1 = _KJUR.asn1,
518 	_DERInteger = _KJUR_asn1.DERInteger,
519 	_KJUR_asn1_tsp = _KJUR_asn1.tsp,
520 	_PKIStatus = _KJUR_asn1_tsp.PKIStatus;
521 
522     _KJUR_asn1_tsp.PKIStatus.superclass.constructor.call(this);
523 
524     var dStatus = null;
525 
526     this.getEncodedHex = function() {
527         this.hTLV = this.dStatus.getEncodedHex();
528         return this.hTLV;
529     };
530 
531     if (params !== undefined) {
532         if (params.name !== undefined) {
533             var list = _PKIStatus.valueList;
534             if (list[params.name] === undefined)
535                 throw "name undefined: " + params.name;
536             this.dStatus = 
537                 new _DERInteger({'int': list[params.name]});
538         } else {
539             this.dStatus = new _DERInteger(params);
540         }
541     }
542 };
543 YAHOO.lang.extend(KJUR.asn1.tsp.PKIStatus, KJUR.asn1.ASN1Object);
544 
545 KJUR.asn1.tsp.PKIStatus.valueList = {
546     granted:                0,
547     grantedWithMods:        1,
548     rejection:              2,
549     waiting:                3,
550     revocationWarning:      4,
551     revocationNotification: 5
552 };
553 
554 /**
555  * class for TSP PKIFreeText ASN.1 object
556  * @name KJUR.asn1.tsp.PKIFreeText
557  * @class class for TSP PKIFreeText ASN.1 object
558  * @param {Array} params associative array of parameters
559  * @extends KJUR.asn1.ASN1Object
560  * @since jsrsasign 4.6.0 asn1tsp 1.0.0
561  * @description
562  * <pre>
563  * PKIFreeText ::= SEQUENCE {
564  *    SIZE (1..MAX) OF UTF8String }
565  * </pre>
566  */
567 KJUR.asn1.tsp.PKIFreeText = function(params) {
568     var _KJUR = KJUR,
569 	_KJUR_asn1 = _KJUR.asn1,
570 	_DERSequence = _KJUR_asn1.DERSequence,
571 	_DERUTF8String = _KJUR_asn1.DERUTF8String,
572 	_KJUR_asn1_tsp = _KJUR_asn1.tsp;
573 
574     _KJUR_asn1_tsp.PKIFreeText.superclass.constructor.call(this);
575 
576     this.textList = [];
577 
578     this.getEncodedHex = function() {
579         var a = [];
580         for (var i = 0; i < this.textList.length; i++) {
581             a.push(new _DERUTF8String({str: this.textList[i]}));
582         }
583         var seq = new _DERSequence({array: a});
584         this.hTLV = seq.getEncodedHex();
585         return this.hTLV;
586     };
587 
588     if (params !== undefined) {
589         if (typeof params.array == "object") {
590             this.textList = params.array;
591         }
592     }
593 };
594 YAHOO.lang.extend(KJUR.asn1.tsp.PKIFreeText, KJUR.asn1.ASN1Object);
595 
596 /**
597  * class for TSP PKIFailureInfo ASN.1 object
598  * @name KJUR.asn1.tsp.PKIFailureInfo
599  * @class class for TSP PKIFailureInfo ASN.1 object
600  * @param {Array} params associative array of parameters
601  * @extends KJUR.asn1.ASN1Object
602  * @since jsrsasign 4.6.0 asn1tsp 1.0.0
603  * @description
604  * <pre>
605  * PKIFailureInfo ::= BIT STRING {
606  *    badAlg                 (0),
607  *    badRequest             (2),
608  *    badDataFormat          (5),
609  *    timeNotAvailable       (14),
610  *    unacceptedPolicy       (15),
611  *    unacceptedExtension    (16),
612  *    addInfoNotAvailable    (17),
613  *    systemFailure          (25) }
614  * </pre>
615  */
616 KJUR.asn1.tsp.PKIFailureInfo = function(params) {
617     var _KJUR = KJUR,
618 	_KJUR_asn1 = _KJUR.asn1,
619 	_DERBitString = _KJUR_asn1.DERBitString,
620 	_KJUR_asn1_tsp = _KJUR_asn1.tsp,
621 	_PKIFailureInfo = _KJUR_asn1_tsp.PKIFailureInfo;
622 
623     _PKIFailureInfo.superclass.constructor.call(this);
624 
625     this.value = null;
626 
627     this.getEncodedHex = function() {
628         if (this.value == null)
629             throw "value shall be specified";
630         var binValue = new Number(this.value).toString(2);
631         var dValue = new _DERBitString();
632         dValue.setByBinaryString(binValue);
633         this.hTLV = dValue.getEncodedHex();
634         return this.hTLV;
635     };
636 
637     if (params !== undefined) {
638         if (typeof params.name == "string") {
639             var list = _PKIFailureInfo.valueList;
640             if (list[params.name] === undefined)
641                 throw "name undefined: " + params.name;
642             this.value = list[params.name];
643         } else if (typeof params['int'] == "number") {
644             this.value = params['int'];
645         }
646     }
647 };
648 YAHOO.lang.extend(KJUR.asn1.tsp.PKIFailureInfo, KJUR.asn1.ASN1Object);
649 
650 KJUR.asn1.tsp.PKIFailureInfo.valueList = {
651     badAlg:                 0,
652     badRequest:             2,
653     badDataFormat:          5,
654     timeNotAvailable:       14,
655     unacceptedPolicy:       15,
656     unacceptedExtension:    16,
657     addInfoNotAvailable:    17,
658     systemFailure:          25
659 };
660 
661 // --- END OF RFC 2510 CMP -------------------------------------------
662 
663 /**
664  * abstract class for TimeStampToken generator
665  * @name KJUR.asn1.tsp.AbstractTSAAdapter
666  * @class abstract class for TimeStampToken generator
667  * @param {Array} params associative array of parameters
668  * @since jsrsasign 4.7.0 asn1tsp 1.0.1
669  * @description
670  */
671 KJUR.asn1.tsp.AbstractTSAAdapter = function(params) {
672     this.getTSTHex = function(msgHex, hashAlg) {
673         throw "not implemented yet";
674     };
675 };
676 
677 /**
678  * class for simple TimeStampToken generator
679  * @name KJUR.asn1.tsp.SimpleTSAAdapter
680  * @class class for simple TimeStampToken generator
681  * @param {Array} params associative array of parameters
682  * @since jsrsasign 4.7.0 asn1tsp 1.0.1
683  * @description
684  */
685 KJUR.asn1.tsp.SimpleTSAAdapter = function(initParams) {
686     var _KJUR = KJUR,
687 	_KJUR_asn1 = _KJUR.asn1,
688 	_KJUR_asn1_tsp = _KJUR_asn1.tsp,
689 	_hashHex = _KJUR.crypto.Util.hashHex;
690 
691     _KJUR_asn1_tsp.SimpleTSAAdapter.superclass.constructor.call(this);
692     this.params = null;
693     this.serial = 0;
694 
695     this.getTSTHex = function(msgHex, hashAlg) {
696         // messageImprint
697         var hashHex = _hashHex(msgHex, hashAlg);
698         this.params.tstInfo.messageImprint =
699             {hashAlg: hashAlg, hashValue: hashHex};
700 
701         // serial
702         this.params.tstInfo.serialNumber = {'int': this.serial++};
703 
704         // nonce
705         var nonceValue = Math.floor(Math.random() * 1000000000);
706         this.params.tstInfo.nonce = {'int': nonceValue};
707 
708         var obj = 
709             _KJUR_asn1_tsp.TSPUtil.newTimeStampToken(this.params);
710         return obj.getContentInfoEncodedHex();
711     };
712 
713     if (initParams !== undefined) {
714         this.params = initParams;
715     }
716 };
717 YAHOO.lang.extend(KJUR.asn1.tsp.SimpleTSAAdapter,
718                   KJUR.asn1.tsp.AbstractTSAAdapter);
719 
720 /**
721  * class for fixed TimeStampToken generator
722  * @name KJUR.asn1.tsp.FixedTSAAdapter
723  * @class class for fixed TimeStampToken generator
724  * @param {Array} params associative array of parameters
725  * @since jsrsasign 4.7.0 asn1tsp 1.0.1
726  * @description
727  * This class generates fixed TimeStampToken except messageImprint
728  * for testing purpose.
729  * General TSA generates TimeStampToken which varies following
730  * fields:
731  * <ul>
732  * <li>genTime</li>
733  * <li>serialNumber</li>
734  * <li>nonce</li>
735  * </ul>
736  * Those values are provided by initial parameters.
737  */
738 KJUR.asn1.tsp.FixedTSAAdapter = function(initParams) {
739     var _KJUR = KJUR,
740 	_KJUR_asn1 = _KJUR.asn1,
741 	_KJUR_asn1_tsp = _KJUR_asn1.tsp,
742 	_hashHex = _KJUR.crypto.Util.hashHex; //o
743 
744     _KJUR_asn1_tsp.FixedTSAAdapter.superclass.constructor.call(this);
745     this.params = null;
746 
747     this.getTSTHex = function(msgHex, hashAlg) {
748         // fixed serialNumber
749         // fixed nonce        
750         var hashHex = _hashHex(msgHex, hashAlg);
751         this.params.tstInfo.messageImprint =
752             {hashAlg: hashAlg, hashValue: hashHex};
753         var obj = 
754             _KJUR_asn1_tsp.TSPUtil.newTimeStampToken(this.params);
755         return obj.getContentInfoEncodedHex();
756     };
757 
758     if (initParams !== undefined) {
759         this.params = initParams;
760     }
761 };
762 YAHOO.lang.extend(KJUR.asn1.tsp.FixedTSAAdapter,
763                   KJUR.asn1.tsp.AbstractTSAAdapter);
764 
765 // --- TSP utilities -------------------------------------------------
766 
767 /**
768  * TSP utiliteis class
769  * @name KJUR.asn1.tsp.TSPUtil
770  * @class TSP utilities class
771  */
772 KJUR.asn1.tsp.TSPUtil = new function() {
773 };
774 /**
775  * generate TimeStampToken ASN.1 object specified by JSON parameters
776  * @name newTimeStampToken
777  * @memberOf KJUR.asn1.tsp.TSPUtil
778  * @function
779  * @param {Array} param JSON parameter to generate TimeStampToken
780  * @return {KJUR.asn1.cms.SignedData} object just generated
781  * @description
782  * @example
783  */
784 KJUR.asn1.tsp.TSPUtil.newTimeStampToken = function(param) {
785     var _KJUR = KJUR,
786 	_KJUR_asn1 = _KJUR.asn1,
787 	_DERInteger = _KJUR.asn1.DERInteger,
788 	_KJUR_asn1_cms = _KJUR_asn1.cms,
789 	_KJUR_asn1_tsp = _KJUR_asn1.tsp,
790 	_TSTInfo = _KJUR_asn1.tsp.TSTInfo;
791 
792     var sd = new _KJUR_asn1_cms.SignedData();
793 
794     var dTSTInfo = new _TSTInfo(param.tstInfo);
795     var tstInfoHex = dTSTInfo.getEncodedHex();
796     sd.dCMSVersion = new _DERInteger({'int': 3});
797     sd.dEncapContentInfo.setContentValue({hex: tstInfoHex});
798     sd.dEncapContentInfo.setContentType('tstinfo');
799 
800     if (typeof param.certs == "object") {
801         for (var i = 0; i < param.certs.length; i++) {
802             sd.addCertificatesByPEM(param.certs[i]);
803         }
804     }
805 
806     var si = sd.signerInfoList[0];
807     si.setSignerIdentifier(param.signerCert);
808     si.setForContentAndHash({sdObj: sd,
809                              eciObj: sd.dEncapContentInfo,
810 			     contentType: 'tstinfo',
811                              hashAlg: param.hashAlg});
812     var signingCertificate = 
813         new _KJUR_asn1_cms.SigningCertificate({array: [param.signerCert]});
814     si.dSignedAttrs.add(signingCertificate);
815 
816     si.sign(param.signerPrvKey, param.sigAlg);
817 
818     return sd;
819 };
820 
821 /**
822  * parse hexadecimal string of TimeStampReq
823  * @name parseTimeStampReq
824  * @memberOf KJUR.asn1.tsp.TSPUtil
825  * @function
826  * @param {String} hexadecimal string of TimeStampReq
827  * @return {Array} JSON object of parsed parameters
828  * @description
829  * This method parses a hexadecimal string of TimeStampReq
830  * and returns parsed their fields:
831  * @example
832  * var json = KJUR.asn1.tsp.TSPUtil.parseTimeStampReq("302602...");
833  * // resulted DUMP of above 'json':
834  * {mi: {hashAlg: 'sha256',          // MessageImprint hashAlg
835  *       hashValue: 'a1a2a3a4...'},  // MessageImprint hashValue
836  *  policy: '1.2.3.4.5',             // tsaPolicy (OPTION)
837  *  nonce: '9abcf318...',            // nonce (OPTION)
838  *  certreq: true}                   // certReq (OPTION)
839  */
840 KJUR.asn1.tsp.TSPUtil.parseTimeStampReq = function(reqHex) {
841     var _ASN1HEX = ASN1HEX;
842     var _getChildIdx = _ASN1HEX.getChildIdx;
843     var _getV = _ASN1HEX.getV;
844     var _getTLV = _ASN1HEX.getTLV;
845     var json = {};
846     json.certreq = false;
847 
848     var idxList = _getChildIdx(reqHex, 0);
849 
850     if (idxList.length < 2)
851         throw "TimeStampReq must have at least 2 items";
852 
853     var miHex = _getTLV(reqHex, idxList[1]);
854     json.mi = KJUR.asn1.tsp.TSPUtil.parseMessageImprint(miHex); 
855 
856     for (var i = 2; i < idxList.length; i++) {
857         var idx = idxList[i];
858         var tag = reqHex.substr(idx, 2);
859         if (tag == "06") { // case OID
860             var policyHex = _getV(reqHex, idx);
861             json.policy = _ASN1HEX.hextooidstr(policyHex);
862         }
863         if (tag == "02") { // case INTEGER
864             json.nonce = _getV(reqHex, idx);
865         }
866         if (tag == "01") { // case BOOLEAN
867             json.certreq = true;
868         }
869     }
870 
871     return json;
872 };
873 
874 /**
875  * parse hexadecimal string of MessageImprint
876  * @name parseMessageImprint
877  * @memberOf KJUR.asn1.tsp.TSPUtil
878  * @function
879  * @param {String} hexadecimal string of MessageImprint
880  * @return {Array} JSON object of parsed parameters
881  * @description
882  * This method parses a hexadecimal string of MessageImprint
883  * and returns parsed their fields:
884  * @example
885  * var json = KJUR.asn1.tsp.TSPUtil.parseMessageImprint("302602...");
886  * // resulted DUMP of above 'json':
887  * {hashAlg: 'sha256',          // MessageImprint hashAlg
888  *  hashValue: 'a1a2a3a4...'}   // MessageImprint hashValue
889  */
890 KJUR.asn1.tsp.TSPUtil.parseMessageImprint = function(miHex) {
891     var _ASN1HEX = ASN1HEX;
892     var _getChildIdx = _ASN1HEX.getChildIdx;
893     var _getV = _ASN1HEX.getV;
894     var _getIdxbyList = _ASN1HEX.getIdxbyList;
895     var json = {};
896 
897     if (miHex.substr(0, 2) != "30")
898         throw "head of messageImprint hex shall be '30'";
899 
900     var idxList = _getChildIdx(miHex, 0);
901     var hashAlgOidIdx = _getIdxbyList(miHex, 0, [0, 0]);
902     var hashAlgHex = _getV(miHex, hashAlgOidIdx);
903     var hashAlgOid = _ASN1HEX.hextooidstr(hashAlgHex);
904     var hashAlgName = KJUR.asn1.x509.OID.oid2name(hashAlgOid);
905     if (hashAlgName == '')
906         throw "hashAlg name undefined: " + hashAlgOid;
907     var hashAlg = hashAlgName;
908     var hashValueIdx = _getIdxbyList(miHex, 0, [1]);
909 
910     json.hashAlg = hashAlg;
911     json.hashValue = _getV(miHex, hashValueIdx); 
912 
913     return json;
914 };
915 
916