1 /* asn1cms-2.0.5.js (c) 2013-2020 Kenji Urushima | kjur.github.io/jsrsasign/license
  2  */
  3 /*
  4  * asn1cms.js - ASN.1 DER encoder and verifier classes for Cryptographic Message Syntax(CMS)
  5  *
  6  * Copyright (c) 2013-2020 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 asn1cms-1.0.js
 18  * @author Kenji Urushima kenji.urushima@gmail.com
 19  * @version jsrsasign 10.5.16 asn1cms 2.0.5 (2022-Apr-08)
 20  * @since jsrsasign 4.2.4
 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 Cryptographic Message Syntax(CMS)
 42  * <p>
 43  * This name space provides 
 44  * <a href="https://tools.ietf.org/html/rfc5652">RFC 5652
 45  * Cryptographic Message Syntax (CMS)</a> SignedData generator.
 46  *
 47  * <h4>FEATURES</h4>
 48  * <ul>
 49  * <li>easily generate CMS SignedData</li>
 50  * <li>easily verify CMS SignedData</li>
 51  * <li>APIs are very similar to BouncyCastle library ASN.1 classes. So easy to learn.</li>
 52  * </ul>
 53  * 
 54  * <h4>PROVIDED CLASSES</h4>
 55  * <ul>
 56  * <li>{@link KJUR.asn1.cms.SignedData}</li>
 57  * <li>{@link KJUR.asn1.cms.SignerInfo}</li>
 58  * <li>{@link KJUR.asn1.cms.AttributeList}</li>
 59  * <li>{@link KJUR.asn1.cms.ContentInfo}</li>
 60  * <li>{@link KJUR.asn1.cms.EncapsulatedContentInfo}</li>
 61  * <li>{@link KJUR.asn1.cms.IssuerAndSerialNumber}</li>
 62  * <li>{@link KJUR.asn1.cms.IssuerSerial}</li>
 63  * <li>{@link KJUR.asn1.cms.CMSUtil}</li>
 64  * <li>{@link KJUR.asn1.cms.Attribute}</li>
 65  * <li>{@link KJUR.asn1.cms.ContentType}</li>
 66  * <li>{@link KJUR.asn1.cms.MessageDigest}</li>
 67  * <li>{@link KJUR.asn1.cms.SigningTime}</li>
 68  * <li>{@link KJUR.asn1.cms.SigningCertificate}</li>
 69  * <li>{@link KJUR.asn1.cms.SigningCertificateV2}</li>
 70  * </ul>
 71  * NOTE: Please ignore method summary and document of this namespace. 
 72  * This caused by a bug of jsdoc2.
 73  * </p>
 74  * @name KJUR.asn1.cms
 75  * @namespace
 76  */
 77 if (typeof KJUR.asn1.cms == "undefined" || !KJUR.asn1.cms) KJUR.asn1.cms = {};
 78 
 79 /**
 80  * Attribute class for base of CMS attribute<br/>
 81  * @name KJUR.asn1.cms.Attribute
 82  * @class Attribute class for base of CMS attribute
 83  * @param {Array} params JSON object for constructor
 84  * @property {Array} params JSON object for ASN.1 encode
 85  * @property {String} typeOid attribute type OID string
 86  * @extends KJUR.asn1.ASN1Object
 87  * @since jsrsasign 4.2.4 asn1cms 1.0.0
 88  *
 89  * @description
 90  * This is an abstract class for CMS attribute
 91  * ASN.1 encoder as defined in
 92  * <a href="https://tools.ietf.org/html/rfc5652#section-5.3">
 93  * RFC 5652 CMS 5.3 SignerInfo</a>.
 94  * <pre>
 95  * Attributes ::= SET OF Attribute
 96  * Attribute ::= SEQUENCE {
 97  *    type               OBJECT IDENTIFIER,
 98  *    values             AttributeSetValue }
 99  * AttributeSetValue ::= SET OF ANY
100  * </pre>
101  */
102 KJUR.asn1.cms.Attribute = function(params) {
103     var _Error = Error,
104 	_KJUR = KJUR,
105 	_KJUR_asn1 = _KJUR.asn1,
106 	_DERSequence = _KJUR_asn1.DERSequence,
107 	_DERSet = _KJUR_asn1.DERSet,
108 	_DERObjectIdentifier = _KJUR_asn1.DERObjectIdentifier;
109 
110     this.params = null;
111     this.typeOid = null;
112 
113     this.setByParam = function(params) {
114 	this.params = params;
115     };
116 
117     /**
118      * get ASN1Object array for Attributes<br/>
119      * @name getValueArray
120      * @memberOf KJUR.asn1.cms.Attribute#
121      * @function
122      * @return {Array} array of Attribute value ASN1Object
123      *
124      * @description
125      * This method shall be implemented in subclass.
126      */
127     this.getValueArray = function() {
128 	throw new _Error("not yet implemented abstract");
129     };
130 
131     this.tohex = function() {
132 	var dType = new _DERObjectIdentifier({oid: this.typeOid});
133 	var dValueSet = new _DERSet({array: this.getValueArray()});
134 	var seq = new _DERSequence({array: [dType, dValueSet]});
135 	return seq.tohex();
136     };
137     this.getEncodedHex = function() { return this.tohex(); };
138 };
139 extendClass(KJUR.asn1.cms.Attribute, KJUR.asn1.ASN1Object);
140 
141 /**
142  * class for CMS ContentType attribute
143  * @name KJUR.asn1.cms.ContentType
144  * @class class for CMS ContentType attribute
145  * @param {Array} params associative array of parameters
146  * @extends KJUR.asn1.cms.Attribute
147  * @since jsrsasign 4.2.4 asn1cms 1.0.0
148  *
149  * @description
150  * This is an ASN.1 encoder for ContentType attribute
151  * defined in
152  * <a href="https://tools.ietf.org/html/rfc5652#section-11.1">
153  * RFC 5652 CMS section 11.1</a>.
154  * <pre>
155  * Attribute ::= SEQUENCE {
156  *    type               OBJECT IDENTIFIER,
157  *    values             AttributeSetValue }
158  * AttributeSetValue ::= SET OF ANY
159  * ContentType ::= OBJECT IDENTIFIER
160  * </pre>
161  * Constructor may have following property in argument:
162  * <ul>
163  * <li>{String}type - name or OID string</li>
164  * </ul>
165  *
166  * @example
167  * o = new KJUR.asn1.cms.ContentType({type: 'data'});
168  * o = new KJUR.asn1.cms.ContentType({type: '1.2.840.113549.1.9.16.1.4'});
169  */
170 KJUR.asn1.cms.ContentType = function(params) {
171     var _KJUR = KJUR,
172 	_KJUR_asn1 = _KJUR.asn1;
173 
174     _KJUR_asn1.cms.ContentType.superclass.constructor.call(this);
175 
176     this.typeOid = "1.2.840.113549.1.9.3";
177 
178     this.getValueArray = function() {
179         var dOid = new _KJUR_asn1.DERObjectIdentifier(this.params.type);
180         return [dOid];
181     };
182 
183     if (params != undefined) this.setByParam(params);
184 };
185 extendClass(KJUR.asn1.cms.ContentType, KJUR.asn1.cms.Attribute);
186 
187 /**
188  * class for CMS MessageDigest attribute
189  * @name KJUR.asn1.cms.MessageDigest
190  * @class class for CMS MessageDigest attribute
191  * @param {Array} params associative array of parameters
192  * @extends KJUR.asn1.cms.Attribute
193  * @since jsrsasign 4.2.4 asn1cms 1.0.0
194  *
195  * @description
196  * This is an ASN.1 encoder for ContentType attribute
197  * defined in
198  * <a href="https://tools.ietf.org/html/rfc5652#section-11.2">
199  * RFC 5652 CMS section 11.2</a>.
200  * <pre>
201  * Attribute ::= SEQUENCE {
202  *    type               OBJECT IDENTIFIER,
203  *    values             AttributeSetValue }
204  * AttributeSetValue ::= SET OF ANY
205  * MessageDigest ::= OCTET STRING
206  * </pre>
207  *
208  * @example
209  * o = new KJUR.asn1.cms.MessageDigest({hex: 'a1a2a3a4...'});
210  */
211 KJUR.asn1.cms.MessageDigest = function(params) {
212     var _KJUR = KJUR,
213 	_KJUR_asn1 = _KJUR.asn1,
214 	_DEROctetString = _KJUR_asn1.DEROctetString,
215 	_KJUR_asn1_cms = _KJUR_asn1.cms;
216 
217     _KJUR_asn1_cms.MessageDigest.superclass.constructor.call(this);
218 
219     this.typeOid = "1.2.840.113549.1.9.4";
220 
221     this.getValueArray = function() {
222 	var dHash = new _DEROctetString(this.params);
223 	return [dHash];
224     };
225 
226     if (params != undefined) this.setByParam(params);
227 };
228 extendClass(KJUR.asn1.cms.MessageDigest, KJUR.asn1.cms.Attribute);
229 
230 /**
231  * class for CMS SigningTime attribute
232  * @name KJUR.asn1.cms.SigningTime
233  * @class class for CMS SigningTime attribute
234  * @param {Array} params associative array of parameters
235  * @extends KJUR.asn1.cms.Attribute
236  * @since jsrsasign 4.2.4 asn1cms 1.0.0
237  *
238  * @description
239  * This is an ASN.1 encoder for ContentType attribute
240  * defined in
241  * <a href="https://tools.ietf.org/html/rfc5652#section-11.3">
242  * RFC 5652 CMS section 11.3</a>.
243  * <pre>
244  * Attribute ::= SEQUENCE {
245  *    type               OBJECT IDENTIFIER,
246  *    values             AttributeSetValue }
247  * AttributeSetValue ::= SET OF ANY
248  * SigningTime  ::= Time
249  * Time ::= CHOICE {
250  *    utcTime UTCTime,
251  *    generalTime GeneralizedTime }
252  * </pre>
253  *
254  * @example
255  * o = new KJUR.asn1.cms.SigningTime(); // current time UTCTime by default
256  * o = new KJUR.asn1.cms.SigningTime({type: 'gen'}); // current time GeneralizedTime
257  * o = new KJUR.asn1.cms.SigningTime({str: '20140517093800Z'}); // specified GeneralizedTime
258  * o = new KJUR.asn1.cms.SigningTime({str: '140517093800Z'}); // specified UTCTime
259  */
260 KJUR.asn1.cms.SigningTime = function(params) {
261     var _KJUR = KJUR,
262 	_KJUR_asn1 = _KJUR.asn1;
263 
264     _KJUR_asn1.cms.SigningTime.superclass.constructor.call(this);
265 
266     this.typeOid = "1.2.840.113549.1.9.5";
267 
268     this.getValueArray = function() {
269 	var dTime = new _KJUR_asn1.x509.Time(this.params);
270 	return [dTime];
271     };
272 
273     if (params != undefined) this.setByParam(params);
274 };
275 extendClass(KJUR.asn1.cms.SigningTime, KJUR.asn1.cms.Attribute);
276 
277 /**
278  * class for CMS SigningCertificate attribute<br/>
279  * @name KJUR.asn1.cms.SigningCertificate
280  * @class class for CMS SigningCertificate attribute
281  * @param {Array} params associative array of parameters
282  * @extends KJUR.asn1.cms.Attribute
283  * @since jsrsasign 4.5.1 asn1cms 1.0.1
284  * @see KJUR.asn1.cms.ESSCertID
285  * @see KJUR.asn1.cms.IssuerSerial
286  *
287  * @description
288  * This is an ASN.1 encoder for SigningCertificate attribute
289  * defined in
290  * <a href="https://tools.ietf.org/html/rfc5035#section-5">
291  * RFC 5035 section 5</a>.
292  * <pre>
293  * Attribute ::= SEQUENCE {
294  *    type               OBJECT IDENTIFIER,
295  *    values             AttributeSetValue }
296  * AttributeSetValue ::= SET OF ANY
297  * SigningCertificate ::= SEQUENCE {
298  *    certs SEQUENCE OF ESSCertID,
299  *    policies SEQUENCE OF PolicyInformation OPTIONAL }
300  * ESSCertID ::= SEQUENCE {
301  *    certHash Hash,
302  *    issuerSerial IssuerSerial OPTIONAL }
303  * IssuerSerial ::= SEQUENCE {
304  *    issuer GeneralNames,
305  *    serialNumber CertificateSerialNumber }
306  * </pre>
307  *
308  * @example
309  * o = new KJUR.asn1.cms.SigningCertificate({array: [certPEM]});
310  */
311 KJUR.asn1.cms.SigningCertificate = function(params) {
312     var _Error = Error,
313 	_KJUR = KJUR,
314 	_KJUR_asn1 = _KJUR.asn1,
315 	_DERSequence = _KJUR_asn1.DERSequence,
316 	_KJUR_asn1_cms = _KJUR_asn1.cms,
317 	_ESSCertID = _KJUR_asn1_cms.ESSCertID,
318 	_KJUR_crypto = _KJUR.crypto;
319 
320     _KJUR_asn1_cms.SigningCertificate.superclass.constructor.call(this);
321     this.typeOid = "1.2.840.113549.1.9.16.2.12";
322 
323     this.getValueArray = function() {
324 	if (this.params == null || 
325 	    this.params == undefined || 
326 	    this.params.array == undefined) {
327 	    throw new _Error("parameter 'array' not specified");
328 	}
329 	var aESSCertIDParam = this.params.array;
330 	var aESSCertID = [];
331 	for (var i = 0; i < aESSCertIDParam.length; i++) {
332 	    var idparam = aESSCertIDParam[i];
333 
334 	    if (params.hasis == false &&
335 		(typeof idparam == "string" &&
336 		 (idparam.indexOf("-----BEGIN") != -1 ||
337 		  ASN1HEX.isASN1HEX(idparam)))) {
338 		idparam = {cert: idparam};
339 	    }
340 
341 	    if (idparam.hasis != false && params.hasis == false) {
342 		idparam.hasis = false;
343 	    }
344 
345 	    aESSCertID.push(new _ESSCertID(idparam));
346 	}
347 	var dCerts = new _DERSequence({array: aESSCertID});
348 	var dSigningCertificate = new _DERSequence({array: [dCerts]});
349 	return [dSigningCertificate];
350     };
351 
352     if (params != undefined) this.setByParam(params);
353 };
354 extendClass(KJUR.asn1.cms.SigningCertificate, KJUR.asn1.cms.Attribute);
355 
356 /**
357  * class for CMS ESSCertID ASN.1 encoder<br/>
358  * @name KJUR.asn1.cms.ESSCertID
359  * @class class for CMS ESSCertID ASN.1 encoder
360  * @param {Object} params PEM certificate string or JSON of parameters
361  * @extends KJUR.asn1.ASN1Object
362  * @since jsrsasign 10.0.0 asn1cms 2.0.0
363  * @see KJUR.asn1.cms.SigningCertificate
364  * @see KJUR.asn1.cms.IssuerSerial
365  * @see KJUR.asn1.cms.ESSCertIDv2
366  * @see KJUR.asn1.cades.OtherCertID
367  *
368  * @description
369  * This is an ASN.1 encoder for ESSCertID class
370  * defined in
371  * <a href="https://tools.ietf.org/html/rfc5035#section-6">
372  * RFC 5035 section 6</a>.
373  * <pre>
374  * ESSCertID ::= SEQUENCE {
375  *    certHash Hash,
376  *    issuerSerial IssuerSerial OPTIONAL }
377  * IssuerSerial ::= SEQUENCE {
378  *    issuer GeneralNames,
379  *    serialNumber CertificateSerialNumber }
380  * </pre>
381  *
382  * @example
383  * new KJUR.asn1.cms.ESSCertID("-----BEGIN...")
384  * new KJUR.asn1.cms.ESSCertID({cert: "-----BEGIN..."})
385  * new KJUR.asn1.cms.ESSCertID({cert: "-----BEGIN...", hasis: false})
386  * new KJUR.asn1.cms.ESSCertID({
387  *   hash: "3f2d...",
388  *   issuer: {str: "/C=JP/O=T1"},
389  *   serial: {hex: "12ab..."}
390  * })
391  */
392 KJUR.asn1.cms.ESSCertID = function(params) {
393     KJUR.asn1.cms.ESSCertID.superclass.constructor.call(this);
394 
395     var _Error = Error,
396 	_KJUR = KJUR,
397 	_KJUR_asn1 = _KJUR.asn1,
398 	_DEROctetString = _KJUR_asn1.DEROctetString,
399 	_DERSequence = _KJUR_asn1.DERSequence,
400 	_IssuerSerial = _KJUR_asn1.cms.IssuerSerial;
401 
402     this.params = null;
403 
404     this.getCertHash = function(params, defaultAlg) {
405 	if (params.hash != undefined) return params.hash;
406 
407 	// hash 
408 	if (typeof params == "string" &&
409 	    params.indexOf("-----BEGIN") == -1 &&
410 	    ! ASN1HEX.isASN1HEX(params)) {
411 	    return params;
412 	}
413 
414 	var certPEMorHex;
415 	if (typeof params == "string") {
416 	    certPEMorHex = params;
417 	} else if (params.cert != undefined) {
418 	    certPEMorHex = params.cert;
419 	} else {
420 	    throw new _Error("hash nor cert unspecified");
421 	}
422 
423 	var hCert;
424 	if (certPEMorHex.indexOf("-----BEGIN") != -1) {
425 	    hCert = pemtohex(certPEMorHex);
426 	} else {
427 	    hCert = certPEMorHex;
428 	}
429 
430 
431 	if (typeof params == "string") {
432 	    if (params.indexOf("-----BEGIN") != -1) {
433 		hCert = pemtohex(params);
434 	    } else if (ASN1HEX.isASN1HEX(params)) {
435 		hCert = params;
436 	    }
437 	}
438 
439 	var alg;
440 	if (params.alg != undefined) {
441 	    alg = params.alg;
442 	} else if (defaultAlg != undefined) {
443 	    alg = defaultAlg;
444 	} else {
445 	    throw new _Error("hash alg unspecified");
446 	}
447 	
448 	return _KJUR.crypto.Util.hashHex(hCert, alg);
449     };
450 
451     this.tohex = function() {
452 	var params = this.params;
453 
454 	var hCertHash = this.getCertHash(params, 'sha1');
455 
456 	var a = [];
457 	a.push(new _DEROctetString({hex: hCertHash}));
458 	if ((typeof params == "string" &&
459 	     params.indexOf("-----BEGIN") != -1) ||
460 	    (params.cert != undefined &&
461 	     params.hasis != false) ||
462 	    (params.issuer != undefined &&
463 	     params.serial != undefined))
464 	    a.push(new _IssuerSerial(params));
465 	var seq = new _DERSequence({array: a});
466 	return seq.tohex();
467     };
468     this.getEncodedHex = function() { return this.tohex(); };
469 
470     if (params != undefined) this.setByParam(params);
471 };
472 extendClass(KJUR.asn1.cms.ESSCertID, KJUR.asn1.ASN1Object);
473 
474 /**
475  * class for CMS SigningCertificateV2 attribute<br/>
476  * @name KJUR.asn1.cms.SigningCertificateV2
477  * @class class for CMS SigningCertificateV2 attribute
478  * @param {Array} params associative array of parameters
479  * @extends KJUR.asn1.cms.Attribute
480  * @since jsrsasign 4.5.1 asn1cms 1.0.1
481  *
482  * @description
483  * This is an ASN.1 encoder for SigningCertificateV2 attribute
484  * defined in
485  * <a href="https://tools.ietf.org/html/rfc5035#section-3">
486  * RFC 5035 section 3</a>.
487  * <pre>
488  * oid-signingCertificateV2 = 1.2.840.113549.1.9.16.2.47
489  * Attribute ::= SEQUENCE {
490  *    type               OBJECT IDENTIFIER,
491  *    values             AttributeSetValue }
492  * AttributeSetValue ::= SET OF ANY
493  * SigningCertificateV2 ::=  SEQUENCE {
494  *    certs        SEQUENCE OF ESSCertIDv2,
495  *    policies     SEQUENCE OF PolicyInformation OPTIONAL }
496  * ESSCertIDv2 ::=  SEQUENCE {
497  *    hashAlgorithm           AlgorithmIdentifier
498  *                            DEFAULT {algorithm id-sha256},
499  *    certHash                Hash,
500  *    issuerSerial            IssuerSerial OPTIONAL }
501  * Hash ::= OCTET STRING
502  * IssuerSerial ::= SEQUENCE {
503  *    issuer                  GeneralNames,
504  *    serialNumber            CertificateSerialNumber }
505  * </pre>
506  *
507  * @example
508  * new KJUR.asn1.cms.SigningCertificateV2({array: [certPEM]}); // DEFAULT sha256
509  * new KJUR.asn1.cms.SigningCertificateV2({array: [certPEM],
510  *                                         hashAlg: 'sha512'});
511  * new KJUR.asn1.cms.SigningCertificateV2({
512  *   array: [
513  *     {cert: certPEM1, hashAlg: 'sha512'},
514  *     {cert: certPEM2, hashAlg: 'sha256'},
515  *     {cert: certPEM3}, // DEFAULT sha256
516  *     certPEM4 // DEFAULT sha256
517  *   ]
518  * })
519  * new KJUR.asn1.cms.SigningCertificateV2({
520  *   array: [
521  *     {cert: certPEM1, hashAlg: 'sha512'},
522  *     {cert: certPEM2, hashAlg: 'sha256'},
523  *     {cert: certPEM3}, // DEFAULT sha256
524  *     certPEM4 // DEFAULT sha256
525  *   ]
526  * })
527  */
528 KJUR.asn1.cms.SigningCertificateV2 = function(params) {
529     var _Error = Error,
530 	_KJUR = KJUR,
531 	_KJUR_asn1 = _KJUR.asn1,
532 	_DERSequence = _KJUR_asn1.DERSequence,
533 	_KJUR_asn1_x509 = _KJUR_asn1.x509,
534 	_KJUR_asn1_cms = _KJUR_asn1.cms,
535 	_ESSCertIDv2 = _KJUR_asn1_cms.ESSCertIDv2,
536 	_KJUR_crypto = _KJUR.crypto;
537 
538     _KJUR_asn1_cms.SigningCertificateV2.superclass.constructor.call(this);
539     this.typeOid = "1.2.840.113549.1.9.16.2.47";
540 
541     this.getValueArray = function() {
542 	if (this.params == null || 
543 	    this.params == undefined || 
544 	    this.params.array == undefined) {
545 	    throw new _Error("parameter 'array' not specified");
546 	}
547 	var aESSCertIDv2Param = this.params.array;
548 	var aESSCertIDv2 = [];
549 	for (var i = 0; i < aESSCertIDv2Param.length; i++) {
550 	    var idparam = aESSCertIDv2Param[i];
551 
552 	    if ((params.alg != undefined ||
553 		 params.hasis == false) &&
554 		(typeof idparam == "string" &&
555 		 (idparam.indexOf("-----BEGIN") != -1 ||
556 		  ASN1HEX.isASN1HEX(idparam)))) {
557 		idparam = {cert: idparam};
558 	    }
559 
560 	    if (idparam.alg == undefined && params.alg != undefined) {
561 		idparam.alg = params.alg;
562 	    }
563 
564 	    if (idparam.hasis != false && params.hasis == false) {
565 		idparam.hasis = false;
566 	    }
567 
568 	    aESSCertIDv2.push(new _ESSCertIDv2(idparam));
569 	}
570 	var dCerts = new _DERSequence({array: aESSCertIDv2});
571 	var dSigningCertificatev2 = new _DERSequence({array: [dCerts]});
572 	return [dSigningCertificatev2];
573     };
574 
575     if (params != undefined) this.setByParam(params);
576 };
577 extendClass(KJUR.asn1.cms.SigningCertificateV2, KJUR.asn1.cms.Attribute);
578 
579 /**
580  * class for CMS ESSCertIDv2 ASN.1 encoder<br/>
581  * @name KJUR.asn1.cms.ESSCertIDv2
582  * @class class for CMS ESSCertIDv2 ASN.1 encoder
583  * @param {Object} params PEM certificate string or JSON of parameters
584  * @extends KJUR.asn1.ASN1Object
585  * @since jsrsasign 10.0.0 asn1cms 2.0.0
586  * @see KJUR.asn1.cms.SigningCertificate
587  * @see KJUR.asn1.cms.IssuerSerial
588  * @see KJUR.asn1.cms.ESSCertID
589  *
590  * @description
591  * This is an ASN.1 encoder for SigningCertificateV2 attribute
592  * defined in
593  * <a href="https://tools.ietf.org/html/rfc5035#section-4">
594  * RFC 5035 section 4</a>.
595  * <pre>
596  * ESSCertIDv2 ::=  SEQUENCE {
597  *    hashAlgorithm           AlgorithmIdentifier
598  *                            DEFAULT {algorithm id-sha256},
599  *    certHash                Hash,
600  *    issuerSerial            IssuerSerial OPTIONAL }
601  * Hash ::= OCTET STRING
602  * IssuerSerial ::= SEQUENCE {
603  *    issuer                  GeneralNames,
604  *    serialNumber            CertificateSerialNumber }
605  * </pre>
606  *
607  * @example
608  * new KJUR.asn1.cms.ESSCertIDv2("-----BEGIN...")
609  * new KJUR.asn1.cms.ESSCertIDv2({cert: "-----BEGIN..."})
610  * new KJUR.asn1.cms.ESSCertIDv2({cert: "-----BEGIN...", hasis: false})
611  * new KJUR.asn1.cms.ESSCertIDv2({
612  *   hash: "3f2d...",
613  *   alg: "sha512",
614  *   issuer: {str: "/C=JP/O=T1"},
615  *   serial: {hex: "12ab..."}
616  * })
617  */
618 KJUR.asn1.cms.ESSCertIDv2 = function(params) {
619     KJUR.asn1.cms.ESSCertIDv2.superclass.constructor.call(this);
620 
621     var _Error = Error,
622 	_KJUR = KJUR,
623 	_KJUR_asn1 = _KJUR.asn1,
624 	_DEROctetString = _KJUR_asn1.DEROctetString,
625 	_DERSequence = _KJUR_asn1.DERSequence,
626 	_IssuerSerial = _KJUR_asn1.cms.IssuerSerial,
627 	_AlgorithmIdentifier = _KJUR_asn1.x509.AlgorithmIdentifier;
628 
629     this.params = null;
630 
631     this.tohex = function() {
632 	var params = this.params;
633 
634 	var hCertHash = this.getCertHash(params, 'sha256');
635 
636 	var a = [];
637 	if (params.alg != undefined && params.alg != "sha256")
638 	    a.push(new _AlgorithmIdentifier({name: params.alg}));
639 	a.push(new _DEROctetString({hex: hCertHash}));
640 	if ((typeof params == "string" &&
641 	     params.indexOf("-----BEGIN") != -1) ||
642 	    (params.cert != undefined &&
643 	     params.hasis != false) ||
644 	    (params.issuer != undefined &&
645 	     params.serial != undefined))
646 	    a.push(new _IssuerSerial(params));
647 	var seq = new _DERSequence({array: a});
648 	return seq.tohex();
649     };
650     this.getEncodedHex = function() { return this.tohex(); };
651 
652     if (params != undefined) this.setByParam(params);
653 };
654 extendClass(KJUR.asn1.cms.ESSCertIDv2, KJUR.asn1.cms.ESSCertID);
655 
656 /**
657  * class for IssuerSerial ASN.1 structure for CMS<br/>
658  * @name KJUR.asn1.cms.IssuerSerial
659  * @class class for CMS IssuerSerial ASN.1 structure for CMS
660  * @param {Array} params associative array of parameters
661  * @extends KJUR.asn1.ASN1Object
662  * @since jsrsasign 8.0.24 asn1cms 1.0.8
663  * @see KJUR.asn1.cms.IssuerAndSerialNumber
664  * @see KJUR.asn1.cms.SigningCertificate
665  * @see KJUR.asn1.cms.SigningCertificateV2
666  * @see KJUR.asn1.cms.ESSCertID
667  * @see KJUR.asn1.cms.ESSCertIDv2
668  * @see KJUR.asn1.x509.GeneralNames
669  * @see KJUR.asn1.x509.X500Name
670  *
671  * @description
672  * This class represents IssuerSerial ASN.1 structure
673  * used by ESSCertID/v2 of SigningCertificate/V2 attribute
674  * defined in 
675  * <a href="https://tools.ietf.org/html/rfc5035#page-6">
676  * RFC 5034 section 4</a>.
677  * <pre>
678  * IssuerSerial ::= SEQUENCE {
679  *    issuer          GeneralNames,
680  *    serialNumber    CertificateSerialNumber }
681  * CertificateSerialNumber ::= INTEGER
682  * </pre>
683  *
684  * @example
685  * // specify by X500Name parameter and DERInteger
686  * o = new KJUR.asn1.cms.IssuerSerial(
687  *      {issuer: {str: '/C=US/O=T1'}, serial {int: 3}});
688  * // specify by PEM certificate
689  * o = new KJUR.asn1.cms.IssuerSerial({cert: certPEM});
690  * o = new KJUR.asn1.cms.IssuerSerial(certPEM); // since 1.0.3
691  */
692 KJUR.asn1.cms.IssuerSerial = function(params) {
693     var _Error = Error,
694 	_KJUR = KJUR,
695 	_KJUR_asn1 = _KJUR.asn1,
696 	_DERInteger = _KJUR_asn1.DERInteger,
697 	_DERSequence = _KJUR_asn1.DERSequence,
698 	_KJUR_asn1_cms = _KJUR_asn1.cms,
699 	_KJUR_asn1_x509 = _KJUR_asn1.x509,
700 	_GeneralNames = _KJUR_asn1_x509.GeneralNames,
701 	_X509 = X509;
702 
703     _KJUR_asn1_cms.IssuerSerial.superclass.constructor.call(this);
704 
705     this.setByParam = function(params) {
706 	this.params = params;
707     };
708 
709     this.tohex = function() {
710 	var params = this.params;
711 
712 	var pIssuer, pSerial;
713 	if ((typeof params == "string" &&
714 	     params.indexOf("-----BEGIN") != -1) ||
715 	    params.cert != undefined) {
716 	    var pem;
717 
718 	    if (params.cert != undefined) {
719 		pem = params.cert;
720 	    } else {
721 		pem = params;
722 	    }
723 
724 	    var x = new _X509();
725 	    x.readCertPEM(pem);
726 	    pIssuer = x.getIssuer();
727 	    pSerial = {hex: x.getSerialNumberHex()};
728 	} else if (params.issuer != undefined && params.serial) {
729 	    pIssuer = params.issuer;
730 	    pSerial = params.serial;
731 	} else {
732 	    throw new _Error("cert or issuer and serial parameter not specified");
733 	}
734 	
735 	var dIssuer = new _GeneralNames([{dn: pIssuer}]);
736 	var dSerial = new _DERInteger(pSerial);
737 	var seq = new _DERSequence({array: [dIssuer, dSerial]});
738 	return seq.tohex();
739     };
740     this.getEncodedHex = function() { return this.tohex(); };
741 
742     if (params != undefined) this.setByParam(params);
743 };
744 extendClass(KJUR.asn1.cms.IssuerSerial, KJUR.asn1.ASN1Object);
745 
746 /**
747  * class for SignerIdentifier ASN.1 structure for CMS
748  * @name KJUR.asn1.cms.SignerIdentifier
749  * @class class for CMS SignerIdentifier ASN.1 structure for CMS
750  * @param {Array} params JSON object of parameters
751  * @extends KJUR.asn1.ASN1Object
752  * @since jsrsasign 10.0.0 asn1cms 2.0.0
753  * @see KJUR.asn1.cms.SignedData
754  * @see KJUR.asn1.cms.SignerInfo
755  * @see KJUR.asn1.cms.IssuerAndSerialNumber
756  * @see KJUR.asn1.cms.SubjectKeyIdentifier
757  * @see KJUR.asn1.x509.X500Name
758  *
759  * @description
760  * This is an ASN.1 encoder for SignerIdentifier
761  * ASN.1 structure defined in
762  * <a href="https://tools.ietf.org/html/rfc5652#section-5.3">
763  * RFC 5652 CMS section 5.3</a>.
764  * <pre>
765  * SignerIdentifier ::= CHOICE {
766  *    issuerAndSerialNumber IssuerAndSerialNumber,
767  *    subjectKeyIdentifier [0] SubjectKeyIdentifier }
768  * </pre>
769  * Constructor argument can have following properties:
770  * <ul>
771  * <li>{String}type - "isssn" for IssuerAndSerialNumber or "skid"
772  * for SubjectKeyIdentifier</li>
773  * <li>{Array}issuer - {@link KJUR.asn1.x509.X500Name} parameter for issuer</li>
774  * <li>{Array}serial - {@link KJUR.asn1.DERInteger} parameter for serial number</li>
775  * <li>{String}skid - hexadecimal string of subject key identifier</li>
776  * <li>{String}cert - PEM certificate string for type "isssn" or "skid"</li>
777  * </ul>
778  * Constructor argument properties can have following combination:
779  * <ul>
780  * <li>type=isssn, issuer, serial - IssuerAndSerialNumber</li>
781  * <li>type=isssn, cert - IssuerAndSerialNumber</li>
782  * <li>type=skid, skid - SubjectKeyIdentifier</li>
783  * <li>type=skdi, cert - SubjectKeyIdentifier</li>
784  * </ul>
785  *
786  * @example
787  * new KJUR.asn1.cms.SignerIdentifier({
788  *   type: "isssn",
789  *   issuer: {str: "/C=JP/O=T1"},
790  *   serial: {hex: "12ab..."}
791  * })
792  * new KJUR.asn1.cms.SignerIdentifier({
793  *   type: "isssn",
794  *   cert: "-----BEGIN..."
795  * })
796  * new KJUR.asn1.cms.SignerIdentifier({
797  *   type: "skid",
798  *   skid: "12ab..."
799  * })
800  * new KJUR.asn1.cms.SignerIdentifier({
801  *   type: "skid",
802  *   cert: "-----BEGIN..."
803  * })
804  */
805 KJUR.asn1.cms.SignerIdentifier = function(params) {
806     var _KJUR = KJUR,
807 	_KJUR_asn1 = _KJUR.asn1,
808 	_DERInteger = _KJUR_asn1.DERInteger,
809 	_DERSequence = _KJUR_asn1.DERSequence,
810 	_KJUR_asn1_cms = _KJUR_asn1.cms,
811 	_IssuerAndSerialNumber = _KJUR_asn1_cms.IssuerAndSerialNumber,
812 	_SubjectKeyIdentifier = _KJUR_asn1_cms.SubjectKeyIdentifier,
813 	_KJUR_asn1_x509 = _KJUR_asn1.x509,
814 	_X500Name = _KJUR_asn1_x509.X500Name,
815 	_X509 = X509,
816 	_Error = Error;
817 
818     _KJUR_asn1_cms.SignerIdentifier.superclass.constructor.call(this);
819 
820     this.params = null;
821 
822     this.tohex = function() {
823 	var params = this.params;
824 	if (params.type == "isssn") {
825 	    var dISSSN = new _IssuerAndSerialNumber(params);
826 	    return dISSSN.tohex();
827 	} else if (params.type == "skid") {
828 	    var dSKID = new _SubjectKeyIdentifier(params);
829 	    return dSKID.tohex();
830 	} else {
831 	    throw new Error("wrong property for isssn or skid");
832 	}
833     };
834     this.getEncodedHex = function() { return this.tohex(); };
835 
836     if (params != undefined) this.setByParam(params);
837 };
838 extendClass(KJUR.asn1.cms.SignerIdentifier, KJUR.asn1.ASN1Object);
839 
840 /**
841  * class for IssuerAndSerialNumber ASN.1 structure for CMS<br/>
842  * @name KJUR.asn1.cms.IssuerAndSerialNumber
843  * @class class for CMS IssuerAndSerialNumber ASN.1 structure for CMS
844  * @param {Array} params associative array of parameters
845  * @extends KJUR.asn1.ASN1Object
846  * @since jsrsasign 4.2.4 asn1cms 1.0.0
847  * @see KJUR.asn1.cms.IssuerSerial
848  *
849  * @description
850  * This class encodes IssuerAndSerialNumber ASN.1 structure defined in
851  * <a href="https://tools.ietf.org/html/rfc5652#section-10.2.4">
852  * RFC 5662 CMS 10.2.4</a>. 
853  * <pre>
854  * IssuerAndSerialNumber ::= SEQUENCE {
855  *    issuer           Name,
856  *    serialNumber     CertificateSerialNumber }
857  * CertificateSerialNumber ::= INTEGER
858  * </pre>
859  * Constructor of this class can have following parameters:
860  * <ul>
861  * <li>{String}cert (OPTION) - PEM certificate string to specify issuer and serial</li>
862  * <li>{Array}issuer (OPTION) - {@link KJUR.asn1.x509.X500Name} parameter for issuer name</li>
863  * <li>{Array}serial (OPTION) - {@link KJUR.asn1.DERInteger} parameter for serialNumber</li>
864  * </ul>
865  *
866  * @example
867  * // specify by X500Name and DERInteger
868  * o = new KJUR.asn1.cms.IssuerAndSerialNumber(
869  *      {issuer: {str: '/C=US/O=T1'}, serial: {int: 3}});
870  * // specify by PEM certificate
871  * o = new KJUR.asn1.cms.IssuerAndSerialNumber({cert: certPEM});
872  * o = new KJUR.asn1.cms.IssuerAndSerialNumber(certPEM); // since 1.0.3
873  */
874 KJUR.asn1.cms.IssuerAndSerialNumber = function(params) {
875     var _KJUR = KJUR,
876 	_KJUR_asn1 = _KJUR.asn1,
877 	_DERInteger = _KJUR_asn1.DERInteger,
878 	_DERSequence = _KJUR_asn1.DERSequence,
879 	_KJUR_asn1_cms = _KJUR_asn1.cms,
880 	_KJUR_asn1_x509 = _KJUR_asn1.x509,
881 	_X500Name = _KJUR_asn1_x509.X500Name,
882 	_X509 = X509,
883 	_Error = Error;
884 
885     _KJUR_asn1_cms.IssuerAndSerialNumber.superclass.constructor.call(this);
886     
887     this.params = null;
888 
889     this.tohex = function() {
890 	var params = this.params;
891 
892 	var pIssuer, pSerial;
893 	if ((typeof params == "string" && params.indexOf("-----BEGIN") != -1) ||
894 	    params.cert != undefined) {
895 	    var pem;
896 
897 	    if (params.cert != undefined) {
898 		pem = params.cert;
899 	    } else {
900 		pem = params;
901 	    }
902 
903 	    var x = new _X509();
904 	    x.readCertPEM(pem);
905 	    pIssuer = x.getIssuer();
906 	    pSerial = {hex: x.getSerialNumberHex()};
907 	} else if (params.issuer != undefined && params.serial) {
908 	    pIssuer = params.issuer;
909 	    pSerial = params.serial;
910 	} else {
911 	    throw new _Error("cert or issuer and serial parameter not specified");
912 	}
913 	
914 	var dIssuer = new _X500Name(pIssuer);
915 	var dSerial = new _DERInteger(pSerial);
916 	var seq = new _DERSequence({array: [dIssuer, dSerial]});
917 	return seq.tohex();
918     };
919     this.getEncodedHex = function() { return this.tohex(); };
920 
921     this.setByParam = function(params) {
922 	this.params = params;
923     }
924 
925     if (params != undefined) this.setByParam(params);
926 };
927 extendClass(KJUR.asn1.cms.IssuerAndSerialNumber, KJUR.asn1.ASN1Object);
928 
929 /**
930  * class for SubjectKeyIdentifier ASN.1 structure for CMS SignerInfo<br/>
931  * @name KJUR.asn1.cms.SubjectKeyIdentifier
932  * @class class for SubjectKeyIdentifier ASN.1 structure for CMS SignerInfo
933  * @param {Array} params JSON object of parameters
934  * @extends KJUR.asn1.ASN1Object
935  * @since jsrsasign 10.0.0 asn1cms 2.0.0
936  *
937  * @description
938  * This class encodes SubjectKeyIdentifier ASN.1 structure defined in
939  * <a href="https://tools.ietf.org/html/rfc5652#section-12.1">
940  * RFC 5652 CMS 12.1</a>. 
941  * <pre>
942  * SubjectKeyIdentifier ::= OCTET STRING
943  * </pre>
944  *
945  * @example
946  * new KJUR.asn1.cms.SubjectKeyIdentifier({cert: "-----BEGIN..."})
947  * new KJUR.asn1.cms.SubjectKeyIdentifier({skid: "12ab..."})
948  */
949 KJUR.asn1.cms.SubjectKeyIdentifier = function(params) {
950     var _KJUR = KJUR,
951 	_KJUR_asn1 = _KJUR.asn1,
952 	_DERInteger = _KJUR_asn1.DERInteger,
953 	_DERSequence = _KJUR_asn1.DERSequence,
954 	_newObject = _KJUR_asn1.ASN1Util.newObject,
955 	_KJUR_asn1_cms = _KJUR_asn1.cms,
956 	_IssuerAndSerialName = _KJUR_asn1_cms.IssuerAndSerialName,
957 	_SubjectKeyIdentifier = _KJUR_asn1_cms.SubjectKeyIdentifier,
958 	_KJUR_asn1_x509 = _KJUR_asn1.x509,
959 	_X500Name = _KJUR_asn1_x509.X500Name,
960 	_X509 = X509,
961 	_Error = Error;
962 
963     _KJUR_asn1_cms.SubjectKeyIdentifier.superclass.constructor.call(this);
964 
965     this.tohex = function() {
966 	var params = this.params;
967 
968 	if (params.cert == undefined && params.skid == undefined)
969 	    throw new _Error("property cert nor skid undefined");
970 
971 	var hSKID;
972 	if (params.cert != undefined) {
973 	    var x = new _X509(params.cert);
974 	    var pSKID = x.getExtSubjectKeyIdentifier();
975 	    hSKID = pSKID.kid.hex;
976 	} else if (params.skid != undefined) {
977 	    hSKID = params.skid;
978 	}
979 	var dSKID = 
980 	    _newObject({tag:{tage:"a0",obj:{octstr:{hex:hSKID}}}});
981 	return dSKID.tohex();
982     };
983     this.getEncodedHex = function() { return this.tohex(); };
984 
985     if (params != undefined) this.setByParam(params);
986 };
987 extendClass(KJUR.asn1.cms.SubjectKeyIdentifier, KJUR.asn1.ASN1Object);
988 
989 /**
990  * class for Attributes ASN.1 structure for CMS<br/>
991  * @name KJUR.asn1.cms.AttributeList
992  * @class class for Attributes ASN.1 structure for CMS
993  * @param {Array} params associative array of parameters
994  * @extends KJUR.asn1.ASN1Object
995  * @since jsrsasign 4.2.4 asn1cms 1.0.0
996  *
997  * @description
998  * <pre>
999  * Attributes ::= SET OF Attribute
1000  * Attribute ::= SEQUENCE {
1001  *    type               OBJECT IDENTIFIER,
1002  *    values             AttributeSetValue }
1003  * </pre>
1004  *
1005  * @example
1006  * new KJUR.asn1.cms.AttributeList({
1007  *   array: [{
1008  *     attr: "contentType",
1009  *     type: "data"
1010  *   }],
1011  *   sortflag: false
1012  * })
1013  */
1014 KJUR.asn1.cms.AttributeList = function(params) {
1015     var _Error = Error,
1016 	_KJUR = KJUR,
1017 	_KJUR_asn1 = _KJUR.asn1,
1018 	_DERSet = _KJUR_asn1.DERSet,
1019 	_KJUR_asn1_cms = _KJUR_asn1.cms;
1020 
1021     _KJUR_asn1_cms.AttributeList.superclass.constructor.call(this);
1022 
1023     this.params = null;
1024     this.hTLV = null;
1025 
1026     this.setByParam = function(params) {
1027 	this.params = params;
1028     };
1029 
1030     this.tohex = function() {
1031 	var params = this.params;
1032 	if (this.hTLV != null) return this.hTLV;
1033 
1034 	var sortflag = true;
1035 	if (params.sortflag != undefined) {
1036 	    sortflag = params.sortflag;
1037 	}
1038 
1039         var aAttrParam = params.array;
1040 	var a = [];
1041 	for (var i = 0; i < aAttrParam.length; i++) {
1042 	    var pAttr = aAttrParam[i];
1043 	    var attrName = pAttr.attr;
1044 	    if (attrName == "contentType") {
1045 		a.push(new _KJUR_asn1_cms.ContentType(pAttr));
1046 	    } else if (attrName == "messageDigest") {
1047 		a.push(new _KJUR_asn1_cms.MessageDigest(pAttr));
1048 	    } else if (attrName == "signingTime") {
1049 		a.push(new _KJUR_asn1_cms.SigningTime(pAttr));
1050 	    } else if (attrName == "signingCertificate") {
1051 		a.push(new _KJUR_asn1_cms.SigningCertificate(pAttr));
1052 	    } else if (attrName == "signingCertificateV2") {
1053 		a.push(new _KJUR_asn1_cms.SigningCertificateV2(pAttr));
1054 	    } else if (attrName == "signaturePolicyIdentifier") {
1055 		a.push(new KJUR.asn1.cades.SignaturePolicyIdentifier(pAttr));
1056 	    } else if (attrName == "signatureTimeStamp" ||
1057 		       attrName == "timeStampToken") {
1058 		a.push(new KJUR.asn1.cades.SignatureTimeStamp(pAttr));
1059 	    } else {
1060 		throw new _Error("unknown attr: " + attrName);
1061 	    }
1062 	}
1063 	
1064 	var dSet = new _DERSet({array: a, sortflag: sortflag});
1065 	this.hTLV = dSet.tohex();
1066 	return this.hTLV;
1067     };
1068     this.getEncodedHex = function() { return this.tohex(); };
1069 
1070     if (params != undefined) this.setByParam(params);
1071 };
1072 extendClass(KJUR.asn1.cms.AttributeList, KJUR.asn1.ASN1Object);
1073 
1074 /**
1075  * class for SignerInfo ASN.1 structure of CMS SignedData<br/>
1076  * @name KJUR.asn1.cms.SignerInfo
1077  * @class class for Attributes ASN.1 structure of CMS SigndData
1078  * @param {Array} params associative array of parameters
1079  * @extends KJUR.asn1.ASN1Object
1080  * @since jsrsasign 4.2.4 asn1cms 1.0.0
1081  * @see KJUR.asn1.cms.SignerIdentifier
1082  * @see KJUR.asn1.x509.AlgorithmIdentifier
1083  * @see KJUR.asn1.cms.AttributeList
1084  *
1085  * @description
1086  * This class is an ASN.1 encoder for SignerInfo structure
1087  * defined in
1088  * <a https://tools.ietf.org/html/rfc5652#section-5.3">
1089  * RFC 5652 CMS section 5.3</a>.
1090  * <pre>
1091  * SignerInfo ::= SEQUENCE {
1092  *    version CMSVersion,
1093  *    sid SignerIdentifier,
1094  *    digestAlgorithm DigestAlgorithmIdentifier,
1095  *    signedAttrs [0] IMPLICIT SignedAttributes OPTIONAL,
1096  *    signatureAlgorithm SignatureAlgorithmIdentifier,
1097  *    signature SignatureValue,
1098  *    unsignedAttrs [1] IMPLICIT UnsignedAttributes OPTIONAL }
1099  * </pre>
1100  * Constractor parameter can have following properties:
1101  * <ul>
1102  * <li>{Integer}version - version of SignerInfo. </li>
1103  * <li>{Array}id - {@link KJUR.asn1.cms.SignerIdentifier} parameter for sid</li>
1104  * <li>{String}hashalg - digestAlgorithm name string (ex. "sha256")</li>
1105  * <li>{Array}sattrs - {@link KJUR.asn1.cms.AttributeList} parameter for 
1106  * signedAttributes</li>
1107  * <li>{String}sigalg - string for signatureAlgorithm name</a>
1108  * <li>{String}signkey (OPTION) - specifies signing private key.
1109  * Parameter "signkey" or "sighex" shall be specified. Following
1110  * values can be specified:
1111  *   <ul>
1112  *   <li>PKCS#1/5 or PKCS#8 PEM string of private key</li>
1113  *   <li>RSAKey/DSA/ECDSA key object. {@link KEYUTIL.getKey} is useful
1114  *   to generate a key object.</li>
1115  *   </ul>
1116  * </li>
1117  * <li>{String}sighex (OPTION) - hexadecimal string of signature value
1118  * (i.e. ASN.1 value(V) of signatureValue BIT STRING without
1119  * unused bits)</li>
1120  * </ul>
1121  *
1122  * @example
1123  * new KJUR.asn1.cms.SignerInfo({
1124  *   version: 1,
1125  *   id: {type: 'isssn', issuer: {str: '/C=US/O=T1'}, serial: {int: 1}},
1126  *   hashalg: "sha1",
1127  *   sattrs: {array: [{
1128  *     attr: "contentType",
1129  *     type: '1.2.840.113549.1.7.1'
1130  *   },{
1131  *     attr: "messageDigest",
1132  *     hex: 'a1a2a3a4a5a6a7a8a9a0a1a2a3a4a5a6a7a8a9a0'
1133  *   }]},
1134  *   sigalg: "SHA1withRSA",
1135  *   sighex: 'b1b2b...'
1136  * })
1137  */
1138 KJUR.asn1.cms.SignerInfo = function(params) {
1139     var _Error = Error,
1140 	_KJUR = KJUR,
1141 	_KJUR_asn1 = _KJUR.asn1,
1142 	_DERInteger = _KJUR_asn1.DERInteger,
1143 	_DEROctetString = _KJUR_asn1.DEROctetString,
1144 	_DERSequence = _KJUR_asn1.DERSequence,
1145 	_DERTaggedObject = _KJUR_asn1.DERTaggedObject,
1146 	_KJUR_asn1_cms = _KJUR_asn1.cms,
1147 	_SignerIdentifier = _KJUR_asn1_cms.SignerIdentifier,
1148 	_AttributeList = _KJUR_asn1_cms.AttributeList,
1149 	_ContentType = _KJUR_asn1_cms.ContentType,
1150 	_EncapsulatedContentInfo = _KJUR_asn1_cms.EncapsulatedContentInfo,
1151 	_MessageDigest = _KJUR_asn1_cms.MessageDigest,
1152 	_SignedData = _KJUR_asn1_cms.SignedData,
1153 	_KJUR_asn1_x509 = _KJUR_asn1.x509,
1154 	_AlgorithmIdentifier = _KJUR_asn1_x509.AlgorithmIdentifier,
1155 	_KJUR_crypto = _KJUR.crypto,
1156 	_KEYUTIL = KEYUTIL;
1157 
1158     _KJUR_asn1_cms.SignerInfo.superclass.constructor.call(this);
1159 
1160     this.params = null;
1161     
1162     /**
1163      * sign SignerInfo<br/>
1164      * @name sign
1165      * @memberOf KJUR.asn1.cms.SignerInfo#
1166      * @function
1167      *
1168      * @description
1169      * This method signs SignerInfo with a specified 
1170      * private key and algorithm by 
1171      * "params.signkey" and "params.sigalg" parameter.
1172      * In general, you don't need to call this method.
1173      * It will be called when tohex() method if necessary.
1174      *
1175      * @example
1176      * si = new KJUR.asn1.cms.SignerInfo({...});
1177      * si.sign()
1178      */
1179     this.sign = function() {
1180 	var params = this.params;
1181 	var sigalg = params.sigalg;
1182 
1183 	var hData = (new _AttributeList(params.sattrs)).tohex();
1184 	var prvkey = _KEYUTIL.getKey(params.signkey);
1185 	var sig = new _KJUR_crypto.Signature({alg: sigalg});
1186 	sig.init(prvkey);
1187 	sig.updateHex(hData);
1188 	var hSig = sig.sign();
1189 	params.sighex = hSig;
1190     };
1191 
1192     this.tohex = function() {
1193 	var params = this.params;
1194 
1195 	var a = [];
1196         a.push(new _DERInteger({"int": params.version}));
1197 	a.push(new _SignerIdentifier(params.id));
1198 	a.push(new _AlgorithmIdentifier({name: params.hashalg}));
1199 	if (params.sattrs != undefined) {
1200 	    var dList = new _AttributeList(params.sattrs);
1201 	    try {
1202 		a.push(new _DERTaggedObject({tag: "a0", 
1203 					     explicit: false,
1204 					     obj: dList}));
1205 	    } catch(ex) {
1206 		throw new _Error("si sattr error: " + ex);
1207 	    }
1208 	}
1209 
1210 	if (params.sigalgfield != undefined) {
1211 	    a.push(new _AlgorithmIdentifier({name: params.sigalgfield}));
1212 	} else {
1213 	    a.push(new _AlgorithmIdentifier({name: params.sigalg}));
1214 	}
1215 
1216 	if (params.sighex == undefined &&
1217 	    params.signkey != undefined) {
1218 	    this.sign();
1219 	}
1220 	a.push(new _DEROctetString({hex: params.sighex}));
1221 
1222 	if (params.uattrs != undefined) {
1223 	    var dList = new _AttributeList(params.uattrs);
1224 	    try {
1225 		a.push(new _DERTaggedObject({tag: "a1", 
1226 					     explicit: false,
1227 					     obj: dList}));
1228 	    } catch(ex) {
1229 		throw new _Error("si uattr error: " + ex);
1230 	    }
1231 	}
1232 
1233 	var seq = new _DERSequence({array: a});
1234 	return seq.tohex();
1235     };
1236     this.getEncodedHex = function() { return this.tohex(); };
1237 
1238     if (params != undefined) this.setByParam(params);
1239 };
1240 extendClass(KJUR.asn1.cms.SignerInfo, KJUR.asn1.ASN1Object);
1241 
1242 /**
1243  * class for EncapsulatedContentInfo ASN.1 structure for CMS<br/>
1244  * @name KJUR.asn1.cms.EncapsulatedContentInfo
1245  * @class class for EncapsulatedContentInfo ASN.1 structure for CMS
1246  * @param {Array} params associative array of parameters
1247  * @extends KJUR.asn1.ASN1Object
1248  * @since jsrsasign 4.2.4 asn1cms 1.0.0
1249  *
1250  * @description
1251  * <pre>
1252  * EncapsulatedContentInfo ::= SEQUENCE {
1253  *    eContentType ContentType,
1254  *    eContent [0] EXPLICIT OCTET STRING OPTIONAL }
1255  * ContentType ::= OBJECT IDENTIFIER
1256  * </pre>
1257  *
1258  * @example
1259  * new KJUR.asn1.cms.EncapsulatedContentInfo({
1260  *  type: "data",
1261  *  content: {str: "aaa"}
1262  * })
1263  * new KJUR.asn1.cms.EncapsulatedContentInfo({
1264  *  type: "data",
1265  *  content: {hex: "616161"}
1266  * })
1267  * new KJUR.asn1.cms.EncapsulatedContentInfo({
1268  *  type: "data",
1269  *  content: {hex: "616161"},
1270  *  isDetached: true
1271  * })
1272  * new KJUR.asn1.cms.EncapsulatedContentInfo({
1273  *  type: "tstinfo",
1274  *  content: ...TSTInfo parameters...
1275  * })
1276  */
1277 KJUR.asn1.cms.EncapsulatedContentInfo = function(params) {
1278     var _KJUR = KJUR,
1279 	_KJUR_asn1 = _KJUR.asn1,
1280 	_DERTaggedObject = _KJUR_asn1.DERTaggedObject,
1281 	_DERSequence = _KJUR_asn1.DERSequence,
1282 	_DERObjectIdentifier = _KJUR_asn1.DERObjectIdentifier,
1283 	_DEROctetString = _KJUR_asn1.DEROctetString,
1284 	_KJUR_asn1_cms = _KJUR_asn1.cms;
1285 
1286     _KJUR_asn1_cms.EncapsulatedContentInfo.superclass.constructor.call(this);
1287 
1288     this.params = null;
1289 
1290     this.tohex = function() {
1291 	var params = this.params;
1292 
1293 	var a = [];
1294 
1295 	a.push(new _DERObjectIdentifier(params.type));
1296 
1297 	if (params.content != undefined &&
1298 	    (params.content.hex != undefined || 
1299 	     params.content.str != undefined) &&
1300 	    params.isDetached != true) {
1301 	    var dOctStr = new _DEROctetString(params.content);
1302 	    var dEContent = new _DERTaggedObject({tag: "a0",
1303 						  explicit: true,
1304 						  obj: dOctStr});
1305 	    a.push(dEContent);
1306 	}
1307 
1308 	var seq = new _DERSequence({array: a});
1309 	return seq.tohex();
1310     };
1311     this.getEncodedHex = function() { return this.tohex(); };
1312 
1313     this.setByParam = function(params) {
1314 	this.params = params;
1315     };
1316 
1317     if (params != undefined) this.setByParam(params);
1318 };
1319 extendClass(KJUR.asn1.cms.EncapsulatedContentInfo, KJUR.asn1.ASN1Object);
1320 
1321 // - type
1322 // - obj
1323 /**
1324  * class for ContentInfo ASN.1 structure for CMS
1325  * @name KJUR.asn1.cms.ContentInfo
1326  * @class class for ContentInfo ASN.1 structure for CMS
1327  * @param {Array} params associative array of parameters
1328  * @extends KJUR.asn1.ASN1Object
1329  * @since jsrsasign 4.2.4 asn1cms 1.0.0
1330  * @description
1331  * <pre>
1332  * ContentInfo ::= SEQUENCE {
1333  *    contentType ContentType,
1334  *    content [0] EXPLICIT ANY DEFINED BY contentType }
1335  * ContentType ::= OBJECT IDENTIFIER
1336  * </pre>
1337  * @example
1338  * a = [new KJUR.asn1.DERInteger({int: 1}),
1339  *      new KJUR.asn1.DERInteger({int: 2})];
1340  * seq = new KJUR.asn1.DERSequence({array: a});
1341  * o = new KJUR.asn1.cms.ContentInfo({type: 'data', obj: seq});
1342  */
1343 KJUR.asn1.cms.ContentInfo = function(params) {
1344     var _KJUR = KJUR,
1345 	_KJUR_asn1 = _KJUR.asn1,
1346 	_DERTaggedObject = _KJUR_asn1.DERTaggedObject,
1347 	_DERSequence = _KJUR_asn1.DERSequence,
1348 	_DERObjectIdentifier = _KJUR_asn1.DERObjectIdentifier,
1349 	_KJUR_asn1_x509 = _KJUR_asn1.x509,
1350 	_name2obj = _KJUR_asn1_x509.OID.name2obj;
1351 
1352     KJUR.asn1.cms.ContentInfo.superclass.constructor.call(this);
1353     
1354     this.params = null;
1355 
1356     this.tohex = function() {
1357 	var params = this.params;
1358 
1359 	var a = [];
1360 	a.push(new _DERObjectIdentifier(params.type));
1361 
1362 	var dContent0 = new _DERTaggedObject({
1363 	    tag: "a0",
1364 	    explicit: true,
1365 	    obj: params.obj
1366 	});
1367 	a.push(dContent0);
1368 
1369 	var seq = new _DERSequence({array: a});
1370 	return seq.tohex();
1371     };
1372     this.getEncodedHex = function() { return this.tohex(); };
1373 
1374     this.setByParam = function(params) {
1375 	this.params = params;
1376     };
1377 
1378     if (params != undefined) this.setByParam(params);
1379 };
1380 extendClass(KJUR.asn1.cms.ContentInfo, KJUR.asn1.ASN1Object);
1381 
1382 /**
1383  * class for SignerInfo ASN.1 structure of CMS SignedData
1384  * @name KJUR.asn1.cms.SignedData
1385  * @class class for Attributes ASN.1 structure of CMS SigndData
1386  * @param {Array} params associative array of parameters
1387  * @extends KJUR.asn1.ASN1Object
1388  * @since jsrsasign 4.2.4 asn1cms 1.0.0
1389  *
1390  * @description
1391  * <pre>
1392  * ContentInfo ::= SEQUENCE {
1393  *    contentType ContentType,
1394  *    content [0] EXPLICIT ANY DEFINED BY contentType }
1395  * ContentType ::= OBJECT IDENTIFIER
1396  * SignedData ::= SEQUENCE {
1397  *    version CMSVersion,
1398  *    digestAlgorithms DigestAlgorithmIdentifiers,
1399  *    encapContentInfo EncapsulatedContentInfo,
1400  *    certificates [0] IMPLICIT CertificateSet OPTIONAL,
1401  *    crls [1] IMPLICIT RevocationInfoChoices OPTIONAL,
1402  *    signerInfos SignerInfos }
1403  * SignerInfos ::= SET OF SignerInfo
1404  * CertificateSet ::= SET OF CertificateChoices
1405  * DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier
1406  * CertificateSet ::= SET OF CertificateChoices
1407  * RevocationInfoChoices ::= SET OF RevocationInfoChoice
1408  * </pre>
1409  *
1410  * @example
1411  * sd = new KJUR.asn1.cms.SignedData({
1412  *   version: 1,
1413  *   hashalgs: ["sha1"],
1414  *   econtent: {
1415  *     type: "data",
1416  *     content: {
1417  *       hex: "616161"
1418  *     }
1419  *   },
1420  *   certs: [PEM1,...],
1421  *   revinfos: {array: [...]},
1422  *   sinfos: [{
1423  *     version: 1,
1424  *     id: {type:'isssn', issuer: {str: '/C=US/O=T1'}, serial: {int: 1}},
1425  *     hashalg: "sha1",
1426  *     sattrs: {array: [{
1427  *       attr: "contentType",
1428  *       type: '1.2.840.113549.1.7.1'
1429  *     },{
1430  *       attr: "messageDigest",
1431  *       hex: 'abcd'
1432  *     }]},
1433  *     sigalg: "SHA1withRSA",
1434  *     signkey: PEMPRIVATEKEY
1435  *   }]
1436  * });
1437  * hex = sd.getContentInfoEncodedHex();
1438  */
1439 KJUR.asn1.cms.SignedData = function(params) {
1440     var _Error = Error,
1441 	_KJUR = KJUR,
1442 	_KJUR_asn1 = _KJUR.asn1,
1443 	_ASN1Object = _KJUR_asn1.ASN1Object,
1444 	_DERInteger = _KJUR_asn1.DERInteger,
1445 	_DERSet = _KJUR_asn1.DERSet,
1446 	_DERSequence = _KJUR_asn1.DERSequence,
1447 	_DERTaggedObject = _KJUR_asn1.DERTaggedObject,
1448 	_KJUR_asn1_cms = _KJUR_asn1.cms,
1449 	_EncapsulatedContentInfo = _KJUR_asn1_cms.EncapsulatedContentInfo,
1450 	_SignerInfo = _KJUR_asn1_cms.SignerInfo,
1451 	_ContentInfo = _KJUR_asn1_cms.ContentInfo,
1452 	_CertificateSet = _KJUR_asn1_cms.CertificateSet,
1453 	_RevocationInfoChoices = _KJUR_asn1_cms.RevocationInfoChoices,
1454 	_KJUR_asn1_x509 = _KJUR_asn1.x509,
1455 	_AlgorithmIdentifier = _KJUR_asn1_x509.AlgorithmIdentifier;
1456 
1457     KJUR.asn1.cms.SignedData.superclass.constructor.call(this);
1458 
1459     this.params = null;
1460 
1461     /**
1462      * fix fields before ASN.1 encode<br/>
1463      * @name checkAndFixParam
1464      * @memberOf KJUR.asn1.cms.SignedData#
1465      * @function
1466      *
1467      * @description
1468      * Update following values of "params" property
1469      * as defined in RFC 5652:
1470      * <ul>
1471      * <li>set "digestAlgorithms" field of "signedData" by
1472      * signerInfos</li>
1473      * <li>set all "contentType" signed attribute value to
1474      * the same value of eContent</li>
1475      * <li>set all "messageDigest" signed attribute value
1476      * to hash value of eContent contents value</li>
1477      * <li>all signerInfo version by their fields</li>
1478      * <li>signedData version by their fields</li>
1479      * </ul>
1480      * In general, you don't need to call this method.
1481      * It will be called automatically when
1482      * getEncodedHex() method is called.
1483      * <br>
1484      * NOTE: If you don't want to do such property value
1485      * update, set "params.fixed" property to "true".
1486      */
1487     this.checkAndFixParam = function() {
1488 	var sdparams = this.params;
1489 	this._setDigestAlgs(sdparams);
1490 	this._setContentTypeByEContent(sdparams);
1491 	this._setMessageDigestByEContent(sdparams);
1492 	this._setSignerInfoVersion(sdparams);
1493 	this._setSignedDataVersion(sdparams);
1494     };
1495 
1496     /*
1497      * @description
1498      * Get params.sinfos[*].hashalg for all "signerInfo"
1499      * and set "params.hashalgs" of "signedData" as
1500      * array of hash algorithm names.
1501      */
1502     this._setDigestAlgs = function(sdparams) {
1503 	var pHash = {};
1504 	var sinfos = sdparams.sinfos;
1505 	for (var i = 0; i < sinfos.length; i++) {
1506 	    var sinfo = sinfos[i];
1507 	    pHash[sinfo.hashalg] = 1;
1508 	}
1509 	sdparams.hashalgs = Object.keys(pHash).sort();
1510     };
1511 
1512     /*
1513      * @description
1514      * set "contentType" attribute value in 
1515      * "params.sinfos[*].sattrs" to "params.econtent.type"
1516      * value.
1517      */
1518     this._setContentTypeByEContent = function(sdparams) {
1519 	var type = sdparams.econtent.type;
1520 	var sinfos = sdparams.sinfos;
1521 	for (var i = 0; i < sinfos.length; i++) {
1522 	    var sinfo = sinfos[i];
1523 	    var ctParam = this._getAttrParamByName(sinfo, "contentType");
1524 	    //console.log(ctParam.type + " > " + type);
1525 	    ctParam.type = type;
1526 	}
1527     };
1528 
1529     /*
1530      * @description
1531      * set "messageDigest" attribute value in
1532      * "params.sinfos[*].sattrs" to a
1533      * calculated hash value by "econtent.content.hex"
1534      * with "params.sinfos[*].hashalg" algorithm.
1535      */
1536     this._setMessageDigestByEContent = function(sdparams) {
1537 	var econtent = sdparams.econtent;
1538 	var type = sdparams.econtent.type;
1539 
1540 	var hContent = econtent.content.hex;
1541 	if (hContent == undefined &&
1542 	    econtent.type == "data" &&
1543 	    econtent.content.str != undefined) {
1544 	    hContent = rstrtohex(econtent.content.str);
1545 	}
1546 
1547 	var sinfos = sdparams.sinfos;
1548 	for (var i = 0; i < sinfos.length; i++) {
1549 	    var sinfo = sinfos[i];
1550 	    var hashalg = sinfo.hashalg;
1551 	    var mdParam = this._getAttrParamByName(sinfo, "messageDigest");
1552 
1553 	    var hNew = KJUR.crypto.Util.hashHex(hContent, hashalg);
1554 
1555 	    //console.log(mdParam.hex + " > " + hNew);
1556 	    mdParam.hex = hNew;
1557 	}
1558     };
1559 
1560     /*
1561      * @param {Array}siParam "signerInfo" JSON parameter reference
1562      * @param {String}attrName attribute name string
1563      * @return {Array} attribute JSON parameter reference
1564      * @description
1565      * Find signed attribute parameter from signerInfo parameter
1566      * by attribute name.
1567      */
1568     this._getAttrParamByName = function(siParam, attrName) {
1569 	var aSattrs = siParam.sattrs.array;
1570 	for (var i = 0; i < aSattrs.length; i++) {
1571 	    if (aSattrs[i].attr == attrName) return aSattrs[i];
1572 	}
1573     };
1574 
1575     /*
1576      * @description
1577      * set signerInfo version "params.sinfos[*].version" 
1578      * of all signerInfos by signerInfo parameter.
1579      * Version will be identified by "signerIdentifier" is
1580      * "skid" or not.
1581      */
1582     this._setSignerInfoVersion = function(sdparams) {
1583 	var sinfos = sdparams.sinfos;
1584 	for (var i = 0; i < sinfos.length; i++) {
1585 	    var sinfo = sinfos[i];
1586 	    var newVersion = 1;
1587 	    if (sinfo.id.type == "skid") newVersion = 3;
1588 	    sinfo.version = newVersion;
1589 	}
1590     };
1591 
1592     /*
1593      * @description
1594      * set "signedData" version "params.version"
1595      * to value by _getSignedDataVersion()
1596      */
1597     this._setSignedDataVersion = function(sdparams) {
1598 	var newVersion = this._getSignedDataVersion(sdparams);
1599 	//console.log("sd version: " + sdparams.version + " > " + newVersion);
1600 	sdparams.version = newVersion;
1601     };
1602 
1603     /*
1604      * @description
1605      * get "signedData" version from parameters.
1606      * If "revinfos" "ocsp" exists, then version 5.
1607      * If "signerInfo" version 3 exists, then version 3.
1608      * If "params.econtent.type" is not "data" then version 3.
1609      * Otherwise version 1.
1610      */
1611     this._getSignedDataVersion = function(sdparams) {
1612 	//alert(JSON.stringify(sdparams));
1613 
1614 	if (sdparams.revinfos != undefined) {
1615 	    var revinfos = sdparams.revinfos;
1616 	    for (var i = 0; i < revinfos.length; i++) {
1617 		var revinfo = revinfos[i];
1618 		if (revinfo.ocsp != undefined) return 5;
1619 	    }
1620 	}
1621 
1622 	var sinfos = sdparams.sinfos;
1623 	for (var i = 0; i < sinfos.length; i++) {
1624 	    var sinfo = sdparams.sinfos[i];
1625 	    if (sinfo.version == 3) return 3;
1626 	}
1627 
1628 	if (sdparams.econtent.type != "data") return 3;
1629 	return 1;
1630     };
1631 
1632     this.tohex = function() {
1633 	var params = this.params;
1634 
1635 	if (this.getEncodedHexPrepare != undefined) {
1636 	    this.getEncodedHexPrepare();
1637 	}
1638 
1639 	if (params.fixed != true) {
1640 	    this.checkAndFixParam();
1641 	}
1642 
1643 	var a = [];
1644 
1645 	a.push(new _DERInteger({"int": params.version}));
1646 
1647 	var aHashAlg = [];
1648 	for (var i = 0; i < params.hashalgs.length; i++) {
1649 	    var name = params.hashalgs[i];
1650 	    aHashAlg.push(new _AlgorithmIdentifier({name: name}));
1651 	}
1652 	a.push(new _DERSet({array: aHashAlg}));
1653 
1654 	a.push(new _EncapsulatedContentInfo(params.econtent));
1655 
1656 	if (params.certs != undefined) {
1657 	    a.push(new _CertificateSet(params.certs));
1658 	}
1659 
1660 	if (params.revinfos != undefined) {
1661 	    a.push(new _RevocationInfoChoices(params.revinfos));
1662 	}
1663 
1664 	var aSignerInfo = [];
1665 	for (var i = 0; i < params.sinfos.length; i++) {
1666 	    var pSI = params.sinfos[i];
1667 	    aSignerInfo.push(new _SignerInfo(pSI));
1668 	}
1669 	a.push(new _DERSet({array: aSignerInfo}));
1670 
1671 	var seq = new _DERSequence({array: a});
1672 	return seq.tohex();
1673     };
1674     this.getEncodedHex = function() { return this.tohex(); };
1675 
1676     /**
1677      * get CotentInfo ASN.1 object concluding CMS SignedData<br/>
1678      * @name getContentInfo
1679      * @memberOf KJUR.asn1.cms.SignedData#
1680      * @function
1681      * @return {Object} ContentInfo of SigneData as {@link KJUR.asn1.ASN1Object}
1682      * @see KJUR.asn1.cms.ContentInfo
1683      *
1684      * @description
1685      * This method returns a {@link KJUR.asn1.ASN1Object}
1686      * of 
1687      * ContentInfo concludes SignedData.
1688      *
1689      * @example
1690      * sd = new KJUR.asn1.cms.SignedData({...});
1691      * sd.getContentInfo();
1692      */
1693     this.getContentInfo = function() {
1694 	var dContentInfo = new _ContentInfo({
1695 	    type: 'signed-data',
1696 	    obj: this
1697 	});
1698 	return dContentInfo;
1699     };
1700 
1701     /**
1702      * get hex of entire ContentInfo of CMS SignedData<br/>
1703      * @name getContentInfoEncodedHex
1704      * @memberOf KJUR.asn1.cms.SignedData#
1705      * @function
1706      * @return {String} hexadecimal string of entire ContentInfo of CMS SignedData
1707      * @see KJUR.asn1.cms.SignedData#getContentInfo
1708      * @see KJUR.asn1.cms.ContentInfo
1709      *
1710      * @description
1711      * This method returns a hexadecimal string of
1712      * ContentInfo concludes SignedData.
1713      *
1714      * @example
1715      * sd = new KJUR.asn1.cms.SignedData({...});
1716      * sd.getContentInfoEncodedHex() &rarr "3082..."
1717      */
1718     this.getContentInfoEncodedHex = function() {
1719 	return this.getContentInfo().tohex();
1720     };
1721 
1722     if (params != undefined) this.setByParam(params);
1723 };
1724 extendClass(KJUR.asn1.cms.SignedData, KJUR.asn1.ASN1Object);
1725 
1726 /**
1727  * class for CertificateSet ASN.1 structure for CMS SignedData<br/>
1728  * @name KJUR.asn1.cms.CertificateSet
1729  * @class class for CertificateSet ASN.1 structure for CMS SignedData
1730  * @param {Array} params array of RevocationInfoChoice parameters
1731  * @extends KJUR.asn1.ASN1Object
1732  * @since jsrsasign 10.0.0 asn1cms 2.0.0
1733  * @see KJUR.asn1.cms.SignedData
1734  * @see KJUR.asn1.cms.RevocationInfoChoice
1735  *
1736  * @description
1737  * This is an ASN.1 encoder for CertificateSet
1738  * ASN.1 structure defined in
1739  * <a href="https://tools.ietf.org/html/rfc5652#section-10.2.3">
1740  * RFC 5652 CMS section 10.2.3</a> and 
1741  * <a href="https://tools.ietf.org/html/rfc5652#section-10.2.2">
1742  * section 10.2.2</a>.
1743  * <pre>
1744  * CertificateSet ::= SET OF CertificateChoices
1745  * CertificateChoices ::= CHOICE {
1746  *   certificate Certificate,
1747  *   extendedCertificate [0] IMPLICIT ExtendedCertificate, -- Obsolete
1748  *   v1AttrCert [1] IMPLICIT AttributeCertificateV1,       -- Obsolete
1749  *   v2AttrCert [2] IMPLICIT AttributeCertificateV2,
1750  *   other [3] IMPLICIT OtherCertificateFormat }
1751  * OtherCertificateFormat ::= SEQUENCE {
1752  *   otherCertFormat OBJECT IDENTIFIER,
1753  *   otherCert ANY DEFINED BY otherCertFormat }
1754  * </pre>
1755  * Currently only "certificate" is supported in
1756  * CertificateChoices.
1757  * 
1758  * @example
1759  * new KJUR.asn1.cms.CertificateSet([certpem1,certpem2,...])
1760  * new KJUR.asn1.cms.CertificateSet({
1761  *   array: [certpem1,certpem2,...],
1762  *   sortflag: false
1763  * })
1764  */
1765 KJUR.asn1.cms.CertificateSet = function(params) {
1766     KJUR.asn1.cms.CertificateSet.superclass.constructor.call(this);
1767 
1768     var _Error = Error,
1769 	_KJUR_asn1 = KJUR.asn1,
1770 	_DERTaggedObject = _KJUR_asn1.DERTaggedObject,
1771 	_DERSet = _KJUR_asn1.DERSet,
1772 	_ASN1Object = _KJUR_asn1.ASN1Object;
1773 
1774     this.params = null;
1775 
1776     this.tohex = function() {
1777 	var params = this.params;
1778 	var a = [];
1779 
1780 	var aParam;
1781 	if (params instanceof Array) {
1782 	    aParam = params;
1783 	} else if (params.array != undefined) {
1784 	    aParam = params.array;
1785 	} else {
1786 	    throw new _Error("cert array not specified");
1787 	}
1788 
1789 	for (var i = 0; i < aParam.length; i++) {
1790 	    var pem = aParam[i];
1791 	    var hCert = pemtohex(pem);
1792 	    var dCert = new _ASN1Object();
1793 	    dCert.hTLV = hCert;
1794 	    a.push(dCert);
1795 	}
1796 	var pSet = {array: a};
1797 	if (params.sortflag == false) pSet.sortflag = false;
1798 	var dSet = new _DERSet(pSet);
1799 
1800 	var dTagObj = new _DERTaggedObject({
1801 	    tag: "a0",
1802 	    explicit: false,
1803 	    obj: dSet
1804 	});
1805 	return dTagObj.tohex();
1806     };
1807     this.getEncodedHex = function() { return this.tohex(); };
1808 
1809     if (params != undefined) this.setByParam(params);
1810 };
1811 extendClass(KJUR.asn1.cms.CertificateSet, KJUR.asn1.ASN1Object);
1812 
1813 /**
1814  * class for RevocationInfoChoices ASN.1 structure for CMS SignedData<br/>
1815  * @name KJUR.asn1.cms.RevocationInfoChoices
1816  * @class class for RevocationInfoChoices ASN.1 structure for CMS SignedData
1817  * @param {Array} params array of parameters
1818  * @extends KJUR.asn1.ASN1Object
1819  * @since jsrsasign 10.0.0 asn1cms 2.0.0
1820  * @see KJUR.asn1.cms.SignedData
1821  *
1822  * @description
1823  * This is an ASN.1 encoder for RevocationInfoChoices
1824  * ASN.1 structure defined in
1825  * <a href="https://tools.ietf.org/html/rfc5652#section-10.2.1">
1826  * RFC 5652 CMS section 10.2.1</a>.
1827  * <pre>
1828  * RevocationInfoChoices ::= SET OF RevocationInfoChoice
1829  * RevocationInfoChoice ::= CHOICE {
1830  *   crl CertificateList,
1831  *   other [1] IMPLICIT OtherRevocationInfoFormat }
1832  * OtherRevocationInfoFormat ::= SEQUENCE {
1833  *   otherRevInfoFormat OBJECT IDENTIFIER,
1834  *   otherRevInfo ANY DEFINED BY otherRevInfoFormat }
1835  * </pre>
1836  *
1837  * @example
1838  * new KJUR.asn1.cms.RevocationInfoChoices([
1839  *   {crl: CRLPEMorHex1},
1840  *   {ocsp: OCSPResponseHex1},
1841  *   ...
1842  * ]})
1843  */
1844 KJUR.asn1.cms.RevocationInfoChoices = function(params) {
1845     KJUR.asn1.cms.RevocationInfoChoices.superclass.constructor.call(this);
1846 
1847     this.params = null;
1848 
1849     this.tohex = function() {
1850 	var params = this.params;
1851 
1852 	if (! params instanceof Array)
1853 	    throw new Error("params is not array");
1854 
1855 	var a = [];
1856 	for (var i = 0; i < params.length; i++) {
1857 	    a.push(new KJUR.asn1.cms.RevocationInfoChoice(params[i]));
1858 	}
1859 	var dRevInfos = KJUR.asn1.ASN1Util.newObject({tag: {tagi:"a1",obj:{set:a}}});
1860 	return dRevInfos.tohex();
1861     };
1862     this.getEncodedHex = function() { return this.tohex(); };
1863 
1864     if (params != undefined) this.setByParam(params);
1865 };
1866 extendClass(KJUR.asn1.cms.RevocationInfoChoices, KJUR.asn1.ASN1Object);
1867 
1868 /**
1869  * class for RevocationInfoChoice ASN.1 structure for CMS SignedData<br/>
1870  * @name KJUR.asn1.cms.RevocationInfoChoice
1871  * @class class for RevocationInfoChoice ASN.1 structure for CMS SignedData
1872  * @param {Array} params array of parameters
1873  * @extends KJUR.asn1.ASN1Object
1874  * @since jsrsasign 10.0.0 asn1cms 2.0.0
1875  * @see KJUR.asn1.cms.SignedData
1876  * @see KJUR.asn1.cms.RevocationInfoChoices
1877  *
1878  * @description
1879  * This is an ASN.1 encoder for RevocationInfoChoice
1880  * ASN.1 structure defined in
1881  * <a href="https://tools.ietf.org/html/rfc5652#section-10.2.1">
1882  * RFC 5652 CMS section 10.2.1</a>.
1883  * <pre>
1884  * RevocationInfoChoice ::= CHOICE {
1885  *   crl CertificateList,
1886  *   other [1] IMPLICIT OtherRevocationInfoFormat }
1887  * OtherRevocationInfoFormat ::= SEQUENCE {
1888  *   otherRevInfoFormat OBJECT IDENTIFIER,
1889  *   otherRevInfo ANY DEFINED BY otherRevInfoFormat }
1890  * </pre>
1891  *
1892  * @example
1893  * new KJUR.asn1.cms.RevocationInfoChoice({
1894  *   crl: CRLPEMorHex
1895  * })
1896  * new KJUR.asn1.cms.RevocationInfoChoice({
1897  *   ocsp: OCSPResponseHex
1898  * })
1899  */
1900 KJUR.asn1.cms.RevocationInfoChoice = function(params) {
1901     KJUR.asn1.cms.RevocationInfoChoice.superclass.constructor.call(this);
1902 
1903     this.params = null;
1904 
1905     this.tohex = function() {
1906 	var params = this.params;
1907 
1908 	if (params.crl != undefined && typeof params.crl == "string") {
1909 	    var hCRL = params.crl;
1910 	    if (params.crl.indexOf("-----BEGIN") != -1) {
1911 		hCRL = pemtohex(params.crl);
1912 	    }
1913 	    return hCRL;
1914 	} else if (params.ocsp != undefined) {
1915 	    var dTag1 = KJUR.asn1.ASN1Util.newObject({tag: {
1916 		tagi: "a1",
1917 		obj: new KJUR.asn1.cms.OtherRevocationFormat(params)
1918 	    }});
1919 	    return dTag1.tohex();
1920 	} else {
1921 	    throw new Error("property crl or ocsp undefined");
1922 	}
1923     };
1924     this.getEncodedHex = function() { return this.tohex(); };
1925 
1926     if (params != undefined) this.setByParam(params);
1927 };
1928 extendClass(KJUR.asn1.cms.RevocationInfoChoice, KJUR.asn1.ASN1Object);
1929 
1930 /**
1931  * class for OtherRevocationFormat ASN.1 structure for CMS SignedData<br/>
1932  * @name KJUR.asn1.cms.OtherRevocationFormat
1933  * @class class for OtherRevocationFormat ASN.1 structure for CMS SignedData
1934  * @param {Array} params array of parameters
1935  * @extends KJUR.asn1.ASN1Object
1936  * @since jsrsasign 10.0.0 asn1cms 2.0.0
1937  * @see KJUR.asn1.cms.SignedData
1938  * @see KJUR.asn1.cms.RevocationInfoChoices
1939  * @see KJUR.asn1.cms.RevocationInfoChoice
1940  *
1941  * @description
1942  * This is an ASN.1 encoder for OtherRevocationFormat
1943  * ASN.1 structure defined in
1944  * <a href="https://tools.ietf.org/html/rfc5940">
1945  * RFC 5652</a>.
1946  * <pre>
1947  * OtherRevocationInfoFormat ::= SEQUENCE {
1948  *   otherRevInfoFormat  OBJECT IDENTIFIER,
1949  *   otherRevInfo        ANY DEFINED BY otherRevInfoFormat }
1950  * id-ri OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
1951  *   dod(6) internet(1) security(5) mechanisms(5) pkix(7) ri(16) }
1952  * id-ri-ocsp-response OBJECT IDENTIFIER ::= { id-ri 2 }
1953  * --  id-ri-ocsp-response 1.3.6.1.5.5.7.16.2
1954  * </pre>
1955  * NOTE: Currently this class only supports "ocsp"
1956  *
1957  * @example
1958  * new KJUR.asn1.cms.OtherRevocationFormat({
1959  *   ocsp: OCSPResponseHex
1960  * })
1961  */
1962 KJUR.asn1.cms.OtherRevocationFormat = function(params) {
1963     KJUR.asn1.cms.OtherRevocationFormat.superclass.constructor.call(this);
1964 
1965     var _Error = Error,
1966 	_KJUR = KJUR,
1967 	_KJUR_asn1 = _KJUR.asn1,
1968 	_newObject = _KJUR_asn1.ASN1Util.newObject,
1969 	_isHex = _KJUR.lang.String.isHex;
1970 
1971     this.params = null;
1972 
1973     this.tohex = function() {
1974 	var params = this.params;
1975 	if (params.ocsp == undefined)
1976 	    throw new _Error("property ocsp not specified");
1977 	if (! _isHex(params.ocsp) ||
1978 	    ! ASN1HEX.isASN1HEX(params.ocsp))
1979 	    throw new _Error("ocsp value not ASN.1 hex string");
1980 	
1981 	var dOtherRev = _newObject({
1982 	    seq: [
1983 		{oid: "1.3.6.1.5.5.7.16.2"},
1984 		{asn1: {tlv: params.ocsp}}
1985 	    ]
1986 	});
1987 	return dOtherRev.tohex();
1988     };
1989     this.getEncodedHex = function() { return this.tohex(); };
1990 
1991     if (params != undefined) this.setByParam(params);
1992 };
1993 extendClass(KJUR.asn1.cms.OtherRevocationFormat, KJUR.asn1.ASN1Object);
1994 
1995 /**
1996  * CMS utiliteis class
1997  * @name KJUR.asn1.cms.CMSUtil
1998  * @class CMS utilities class
1999  */
2000 KJUR.asn1.cms.CMSUtil = new function() {
2001 };
2002 
2003 /**
2004  * generate SignedData object specified by JSON parameters (DEPRECATED)<br/>
2005  * @name newSignedData
2006  * @memberOf KJUR.asn1.cms.CMSUtil
2007  * @function
2008  * @param {Array} params JSON parameter to generate CMS SignedData
2009  * @return {KJUR.asn1.cms.SignedData} object just generated
2010  * @deprecated since jsrsasign 10.0.0 asn1cms 2.0.0. 
2011  *
2012  * @description
2013  * This class generates {@link KJUR.asn1.cms.SignedData} object.
2014  * However this class is deprecated.
2015  * Please use {@link KJUR.asn1.cms.SignedData} class constructor
2016  * instead. As for "params" parameter, 
2017  * {@link KJUR.asn1.cms.SignedData} parameters are available.
2018  */
2019 KJUR.asn1.cms.CMSUtil.newSignedData = function(param) {
2020     return new KJUR.asn1.cms.SignedData(param);
2021 };
2022 
2023 /**
2024  * verify SignedData specified by JSON parameters
2025  * @name verifySignedData
2026  * @memberOf KJUR.asn1.cms.CMSUtil
2027  * @function
2028  * @param {Array} param JSON parameter to verify CMS SignedData
2029  * @return {Object} JSON data as the result of validation
2030  * @since jsrsasign 8.0.4 asn1cms 1.0.5
2031  * @description
2032  * This method provides validation for CMS SignedData.
2033  * Following parameters can be applied:
2034  * <ul>
2035  * <li>cms - hexadecimal data of DER CMS SignedData (aka. PKCS#7 or p7s)</li>
2036  *     to verify (OPTION)</li>
2037  * </ul>
2038  * @example
2039  * KJUR.asn1.cms.CMSUtil.verifySignedData({ cms: "3082058a..." }) 
2040  * →
2041  * {
2042  *   isValid: true,
2043  *   parse: ... // parsed data
2044  *   signerInfos: [
2045  *     {
2046  *     }
2047  *   ]
2048  * }
2049  */
2050 KJUR.asn1.cms.CMSUtil.verifySignedData = function(param) {
2051     var _KJUR = KJUR,
2052 	_KJUR_asn1 = _KJUR.asn1,
2053 	_KJUR_asn1_cms = _KJUR_asn1.cms,
2054 	_SignerInfo = _KJUR_asn1_cms.SignerInfo,
2055 	_SignedData = _KJUR_asn1_cms.SignedData,
2056 	_SigningTime = _KJUR_asn1_cms.SigningTime,
2057 	_SigningCertificate = _KJUR_asn1_cms.SigningCertificate,
2058 	_SigningCertificateV2 = _KJUR_asn1_cms.SigningCertificateV2,
2059 	_KJUR_asn1_cades = _KJUR_asn1.cades,
2060 	_SignaturePolicyIdentifier = _KJUR_asn1_cades.SignaturePolicyIdentifier,
2061 	_isHex = _KJUR.lang.String.isHex,
2062 	_ASN1HEX = ASN1HEX,
2063 	_getVbyList = _ASN1HEX.getVbyList,
2064 	_getTLVbyList = _ASN1HEX.getTLVbyList,
2065 	_getIdxbyList = _ASN1HEX.getIdxbyList,
2066 	_getChildIdx = _ASN1HEX.getChildIdx,
2067 	_getTLV = _ASN1HEX.getTLV,
2068 	_oidname = _ASN1HEX.oidname,
2069 	_hashHex = _KJUR.crypto.Util.hashHex;
2070 
2071     if (param.cms === undefined &&
2072         ! _isHex(param.cms)) {
2073     }
2074 
2075     var hCMS = param.cms;
2076 
2077     var _findSignerInfos = function(hCMS, result) {
2078 	var idx;
2079 	for (var i = 3; i < 6; i++) {
2080 	    idx = _getIdxbyList(hCMS, 0, [1, 0, i]);
2081 	    if (idx !== undefined) {
2082 		var tag = hCMS.substr(idx, 2);
2083 		if (tag === "a0") result.certsIdx = idx;
2084 		if (tag === "a1") result.revinfosIdx = idx;
2085 		if (tag === "31") result.signerinfosIdx = idx;
2086 	    }
2087 	}
2088     };
2089 
2090     var _parseSignerInfos = function(hCMS, result) {
2091 	var idxSignerInfos = result.signerinfosIdx;
2092 	if (idxSignerInfos === undefined) return;
2093 	var idxList = _getChildIdx(hCMS, idxSignerInfos);
2094 	result.signerInfoIdxList = idxList;
2095 	for (var i = 0; i < idxList.length; i++) {
2096 	    var idxSI = idxList[i];
2097 	    var info = { idx: idxSI };
2098 	    _parseSignerInfo(hCMS, info);
2099 	    result.signerInfos.push(info);
2100 	};
2101     };
2102 
2103     var _parseSignerInfo = function(hCMS, info) {
2104 	var idx = info.idx;
2105 
2106 	// 1. signer identifier
2107 	info.signerid_issuer1 = _getTLVbyList(hCMS, idx, [1, 0], "30");
2108 	info.signerid_serial1 = _getVbyList(hCMS, idx, [1, 1], "02");
2109 
2110 	// 2. hash alg
2111 	info.hashalg = _oidname(_getVbyList(hCMS, idx, [2, 0], "06"));
2112 
2113 	// 3. [0] singedAtttrs
2114 	var idxSignedAttrs = _getIdxbyList(hCMS, idx, [3], "a0");
2115 	info.idxSignedAttrs = idxSignedAttrs;
2116 	_parseSignedAttrs(hCMS, info, idxSignedAttrs);
2117 
2118 	var aIdx = _getChildIdx(hCMS, idx);
2119 	var n = aIdx.length;
2120 	if (n < 6) throw "malformed SignerInfo";
2121 	
2122 	info.sigalg = _oidname(_getVbyList(hCMS, idx, [n - 2, 0], "06"));
2123 	info.sigval = _getVbyList(hCMS, idx, [n - 1], "04");
2124 	//info.sigval = _getVbyList(hCMS, 0, [1, 0, 4, 0, 5], "04");
2125 	//info.sigval = hCMS;
2126     };
2127 
2128     var _parseSignedAttrs = function(hCMS, info, idx) {
2129 	var aIdx = _getChildIdx(hCMS, idx);
2130 	info.signedAttrIdxList = aIdx;
2131 	for (var i = 0; i < aIdx.length; i++) {
2132 	    var idxAttr = aIdx[i];
2133 	    var hAttrType = _getVbyList(hCMS, idxAttr, [0], "06");
2134 	    var v;
2135 
2136 	    if (hAttrType === "2a864886f70d010905") { // siging time
2137 		v = hextoutf8(_getVbyList(hCMS, idxAttr, [1, 0]));
2138 		info.saSigningTime = v;
2139 	    } else if (hAttrType === "2a864886f70d010904") { // message digest
2140 		v = _getVbyList(hCMS, idxAttr, [1, 0], "04");
2141 		info.saMessageDigest = v;
2142 	    }
2143 	}
2144     };
2145 
2146     var _parseSignedData = function(hCMS, result) {
2147 	// check if signedData (1.2.840.113549.1.7.2) type
2148 	if (_getVbyList(hCMS, 0, [0], "06") !== "2a864886f70d010702") {
2149 	    return result;
2150 	}
2151 	result.cmsType = "signedData";
2152 
2153 	// find eContent data
2154 	result.econtent = _getVbyList(hCMS, 0, [1, 0, 2, 1, 0]);
2155 
2156 	// find certificates,revInfos,signerInfos index
2157 	_findSignerInfos(hCMS, result);
2158 
2159 	result.signerInfos = [];
2160 	_parseSignerInfos(hCMS, result);
2161     };
2162 
2163     var _verify = function(hCMS, result) {
2164 	var aSI = result.parse.signerInfos;
2165 	var n = aSI.length;
2166 	var isValid = true;
2167 	for (var i = 0; i < n; i++) {
2168 	    var si = aSI[i];
2169 	    _verifySignerInfo(hCMS, result, si, i);
2170 	    if (! si.isValid)
2171 		isValid = false;
2172 	}
2173 	result.isValid = isValid;
2174     };
2175 
2176     /*
2177      * _findCert
2178      * 
2179      * @param hCMS {String} hexadecimal string of CMS signed data
2180      * @param result {Object} JSON object of validation result
2181      * @param si {Object} JSON object of signerInfo in the result above
2182      * @param idx {Number} index of signerInfo???
2183      */
2184     var _findCert = function(hCMS, result, si, idx) {
2185 	var certsIdx = result.parse.certsIdx;
2186 	var aCert;
2187 
2188 	if (result.certs === undefined) {
2189 	    aCert = [];
2190 	    result.certkeys = [];
2191 	    var aIdx = _getChildIdx(hCMS, certsIdx);
2192 	    for (var i = 0; i < aIdx.length; i++) {
2193 		var hCert = _getTLV(hCMS, aIdx[i]);
2194 		var x = new X509();
2195 		x.readCertHex(hCert);
2196 		aCert[i] = x;
2197 		result.certkeys[i] = x.getPublicKey();
2198 	    }
2199 	    result.certs = aCert;
2200 	} else {
2201 	    aCert = result.certs;
2202 	}
2203 
2204 	result.cccc = aCert.length;
2205 	result.cccci = aIdx.length;
2206 
2207 	for (var i = 0; i < aCert.length; i++) {
2208 	    var issuer2 = x.getIssuerHex();
2209 	    var serial2 = x.getSerialNumberHex();
2210 	    if (si.signerid_issuer1 === issuer2 &&
2211 		si.signerid_serial1 === serial2) {
2212 		si.certkey_idx = i;
2213 	    }
2214 	}
2215     };
2216 
2217     var _verifySignerInfo = function(hCMS, result, si, idx) {
2218 	si.verifyDetail = {};
2219 
2220 	var _detail = si.verifyDetail;
2221 
2222 	var econtent = result.parse.econtent;
2223 
2224 	// verify MessageDigest signed attribute
2225 	var hashalg = si.hashalg;
2226 	var saMessageDigest = si.saMessageDigest;
2227 	
2228 	// verify messageDigest
2229 	_detail.validMessageDigest = false;
2230 	//_detail._econtent = econtent;
2231 	//_detail._hashalg = hashalg;
2232 	//_detail._saMD = saMessageDigest;
2233 	if (_hashHex(econtent, hashalg) === saMessageDigest)
2234 	    _detail.validMessageDigest = true;
2235 
2236 	// find signing certificate
2237 	_findCert(hCMS, result, si, idx);
2238 	//if (si.signerid_cert === undefined)
2239 	//    throw Error("can't find signer certificate");
2240 
2241 	// verify signature value
2242 	_detail.validSignatureValue = false;
2243 	var sigalg = si.sigalg;
2244 	var hSignedAttr = "31" + _getTLV(hCMS, si.idxSignedAttrs).substr(2);
2245 	si.signedattrshex = hSignedAttr;
2246 	var pubkey = result.certs[si.certkey_idx].getPublicKey();
2247 	var sig = new KJUR.crypto.Signature({alg: sigalg});
2248 	sig.init(pubkey);
2249 	sig.updateHex(hSignedAttr);
2250 	var isValid = sig.verify(si.sigval);
2251 	_detail.validSignatureValue_isValid = isValid;
2252 	if (isValid === true)
2253 	    _detail.validSignatureValue = true;
2254 
2255 	// verify SignerInfo totally
2256 	si.isValid =false;
2257 	if (_detail.validMessageDigest &&
2258 	    _detail.validSignatureValue) {
2259 	    si.isValid = true;
2260 	}
2261     };
2262 
2263     var _findSignerCert = function() {
2264     };
2265 
2266     var result = { isValid: false, parse: {} };
2267     _parseSignedData(hCMS, result.parse);
2268 
2269     _verify(hCMS, result);
2270     
2271     return result;
2272 };
2273 
2274 /**
2275  * class for parsing CMS SignedData<br/>
2276  * @name KJUR.asn1.cms.CMSParser
2277  * @class CMS SignedData parser class
2278  * @since jsrsasign 10.1.0 asn1cms 2.0.1
2279  *
2280  * @description
2281  * This is an ASN.1 parser for CMS SignedData defined in
2282  * <a href="https://tools.ietf.org/html/rfc5652">RFC 5652
2283  * Cryptographic Message Syntax (CMS)</a>.
2284  * <pre>
2285  * ContentInfo ::= SEQUENCE {
2286  *    contentType ContentType,
2287  *    content [0] EXPLICIT ANY DEFINED BY contentType }
2288  * ContentType ::= OBJECT IDENTIFIER
2289  * SignedData ::= SEQUENCE {
2290  *    version CMSVersion,
2291  *    digestAlgorithms DigestAlgorithmIdentifiers,
2292  *    encapContentInfo EncapsulatedContentInfo,
2293  *    certificates [0] IMPLICIT CertificateSet OPTIONAL,
2294  *    crls [1] IMPLICIT RevocationInfoChoices OPTIONAL,
2295  *    signerInfos SignerInfos }
2296  * SignerInfos ::= SET OF SignerInfo
2297  * CertificateSet ::= SET OF CertificateChoices
2298  * DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier
2299  * CertificateSet ::= SET OF CertificateChoices
2300  * RevocationInfoChoices ::= SET OF RevocationInfoChoice
2301  * </pre>
2302  */
2303 KJUR.asn1.cms.CMSParser = function() {
2304     var _Error = Error,
2305 	_X509 = X509,
2306 	_x509obj = new _X509(),
2307 	_ASN1HEX = ASN1HEX,
2308 	_getV = _ASN1HEX.getV,
2309 	_getTLV = _ASN1HEX.getTLV,
2310 	_getIdxbyList = _ASN1HEX.getIdxbyList,
2311 	_getTLVbyList = _ASN1HEX.getTLVbyList,
2312 	_getTLVbyListEx = _ASN1HEX.getTLVbyListEx,
2313 	_getVbyList = _ASN1HEX.getVbyList,
2314 	_getVbyListEx = _ASN1HEX.getVbyListEx,
2315 	_getChildIdx = _ASN1HEX.getChildIdx;
2316 
2317     /**
2318      * parse ASN.1 ContentInfo with SignedData<br/>
2319      * @name getCMSSignedData
2320      * @memberOf KJUR.asn1.cms.CMSParser#
2321      * @function
2322      * @param {String} h hexadecimal string of ASN.1 ContentInfo with SignedData
2323      * @return {Array} array of JSON object of SignedData parameter
2324      * @see KJUR.asn1.cms.SignedData
2325      * @see KJUR.asn1.cms.CMSParser#getSignedData
2326      *
2327      * @description
2328      * This method parses ASN.1 ContentInfo with SignedData defined in 
2329      * RFC 5652 
2330      * <a href="https://tools.ietf.org/html/rfc5652#section-3">section 3</a>
2331      * and 
2332      * <a href="https://tools.ietf.org/html/rfc5652#section-5">section 5</a>.
2333      * The result parameter can be passed to
2334      * {@link KJUR.asn1.cms.SignedData} constructor.
2335      * 
2336      * @example
2337      * parser = new KJUR.asn1.cms.CMSParser();
2338      * parser.getCMSSignedData("30...") →
2339      * {
2340      *   version: 1,
2341      *   hashalgs: ["sha1"],
2342      *   econtent: {
2343      *     type: "data",
2344      *     content: {hex:"616161"}
2345      *   },
2346      *   certs: [PEM1,...],
2347      *   sinfos: [{
2348      *     version: 1,
2349      *     id: {type:'isssn',issuer:{str:'/C=US/O=T1'},serial:{int: 1}},
2350      *     hashalg: "sha1",
2351      *     sattrs: {array: [{
2352      *       attr: "contentType",
2353      *       type: '1.2.840.113549.1.7.1'
2354      *     },{
2355      *       attr: "messageDigest",
2356      *       hex: 'abcd'
2357      *     }]},
2358      *     sigalg: "SHA1withRSA",
2359      *     sighex: "1234abcd..."
2360      *   }]
2361      * }
2362      */
2363     this.getCMSSignedData = function(h) {
2364 	var hSignedData = _getTLVbyList(h, 0, [1, 0]);
2365 	var pResult = this.getSignedData(hSignedData);
2366 	return pResult;
2367     };
2368 
2369     /**
2370      * parse ASN.1 SignedData<br/>
2371      * @name getSignedData
2372      * @memberOf KJUR.asn1.cms.CMSParser#
2373      * @function
2374      * @param {String} h hexadecimal string of ASN.1 SignedData
2375      * @return {Array} array of JSON object of SignedData parameter
2376      * @see KJUR.asn1.cms.SignedData
2377      * @see KJUR.asn1.cms.CMSParser#getSignedData
2378      *
2379      * @description
2380      * This method parses ASN.1 SignedData defined in 
2381      * RFC 5652 
2382      * <a href="https://tools.ietf.org/html/rfc5652#section-5">section 5</a>.
2383      * The result parameter can be passed to
2384      * {@link KJUR.asn1.cms.SignedData} constructor.
2385      * 
2386      * @example
2387      * parser = new KJUR.asn1.cms.CMSParser();
2388      * parser.getSignedData("30...")
2389      */
2390     this.getSignedData = function(h) {
2391 	var aIdx = _getChildIdx(h, 0);
2392 	var pResult = {};
2393 
2394 	var hVersion = _getV(h, aIdx[0]);
2395 	var iVersion = parseInt(hVersion, 16);
2396 	pResult.version = iVersion;
2397 	
2398 	var hHashAlgs = _getTLV(h, aIdx[1]);
2399 	pResult.hashalgs = this.getHashAlgArray(hHashAlgs);
2400 
2401 	var hEContent = _getTLV(h, aIdx[2]);
2402 	pResult.econtent = this.getEContent(hEContent);
2403 
2404 	var hCerts = _getTLVbyListEx(h, 0, ["[0]"]);
2405 	if (hCerts != null) {
2406 	    pResult.certs = this.getCertificateSet(hCerts);
2407 	}
2408 
2409 	// RevocationInfoChoices not supported yet
2410 	var hRevInfos = _getTLVbyListEx(h, 0, ["[1]"]);
2411 	if (hRevInfos != null) {
2412 	}
2413 
2414 	var hSignerInfos = _getTLVbyListEx(h, 0, [3]);
2415 	pResult.sinfos = this.getSignerInfos(hSignerInfos);
2416 
2417 	return pResult;
2418     };
2419 
2420     /**
2421      * parse ASN.1 DigestAlgorithmIdentifiers<br/>
2422      * @name getHashAlgArray
2423      * @memberOf KJUR.asn1.cms.CMSParser#
2424      * @function
2425      * @param {String} h hexadecimal string of ASN.1 DigestAlgorithmIdentifiers
2426      * @return {Array} array of JSON object of digest algorithm names
2427      * @see KJUR.asn1.cms.SignedData
2428      * @see KJUR.asn1.cms.CMSParser#getSignedData
2429      *
2430      * @description
2431      * This method parses ASN.1 SignedData defined in 
2432      * RFC 5652 
2433      * <a href="https://tools.ietf.org/html/rfc5652#section-5.1">
2434      * section 5.1</a>.
2435      * 
2436      * @example
2437      * parser = new KJUR.asn1.cms.CMSParser();
2438      * parser.getHashAlgArray("30...") → ["sha256"]
2439      */
2440     this.getHashAlgArray = function(h) {
2441 	var aIdx = _getChildIdx(h, 0);
2442 	var x = new _X509();
2443 	var a = [];
2444 	for (var i = 0; i < aIdx.length; i++) {
2445 	    var hAlg = _getTLV(h, aIdx[i]);
2446 	    var sAlg = x.getAlgorithmIdentifierName(hAlg);
2447 	    a.push(sAlg);
2448 	}
2449 	return a;
2450     };
2451 
2452     /**
2453      * parse ASN.1 EncapsulatedContentInfo<br/>
2454      * @name getEContent
2455      * @memberOf KJUR.asn1.cms.CMSParser#
2456      * @function
2457      * @param {String} h hexadecimal string of ASN.1 EncapsulatedContentInfo
2458      * @return {Array} array of JSON object of EncapsulatedContentInfo parameter
2459      * @see KJUR.asn1.cms.EncapsulatedContentInfo
2460      * @see KJUR.asn1.cms.CMSParser#getSignedData
2461      *
2462      * @description
2463      * This method parses ASN.1 SignedData defined in 
2464      * RFC 5652 
2465      * <a href="https://tools.ietf.org/html/rfc5652#section-5.1">
2466      * section 5</a>.
2467      * The result parameter can be passed to
2468      * {@link KJUR.asn1.cms.EncapsulatedContentInfo} constructor.
2469      * 
2470      * @example
2471      * parser = new KJUR.asn1.cms.CMSParser();
2472      * parser.getEContent("30...") →
2473      * {type: "tstinfo", content: {hex: "30..."}}
2474      */
2475     this.getEContent = function(h) {
2476 	var pResult = {};
2477 	var hType = _getVbyList(h, 0, [0]);
2478 	var hContent = _getVbyList(h, 0, [1, 0]);
2479 	pResult.type = KJUR.asn1.x509.OID.oid2name(ASN1HEX.hextooidstr(hType));
2480 	pResult.content = {hex: hContent};
2481 	return pResult;
2482     };
2483 
2484     /**
2485      * parse ASN.1 SignerInfos<br/>
2486      * @name getSignerInfos
2487      * @memberOf KJUR.asn1.cms.CMSParser#
2488      * @function
2489      * @param {String} h hexadecimal string of ASN.1 SignerInfos
2490      * @return {Array} array of JSON object of SignerInfos parameter
2491      * @see KJUR.asn1.cms.SignerInfos
2492      * @see KJUR.asn1.cms.CMSParser#getSignedData
2493      *
2494      * @description
2495      * This method parses ASN.1 SignerInfos defined in 
2496      * RFC 5652 
2497      * <a href="https://tools.ietf.org/html/rfc5652#section-5.1">
2498      * section 5</a>.
2499      * 
2500      * @example
2501      * parser = new KJUR.asn1.cms.CMSParser();
2502      * parser.getSignerInfos("30...") →
2503      * [{
2504      *   version: 1,
2505      *   id: {type: 'isssn', issuer: {str: '/C=US/O=T1'}, serial: {int: 1}},
2506      *   hashalg: "sha1",
2507      *   sattrs: {array: [{
2508      *     attr: "contentType",
2509      *     type: '1.2.840.113549.1.7.1'
2510      *   },{
2511      *     attr: "messageDigest",
2512      *     hex: 'a1a2a3a4a5a6a7a8a9a0a1a2a3a4a5a6a7a8a9a0'
2513      *   }]},
2514      *   sigalg: "SHA1withRSA",
2515      *   sighex: 'b1b2b...'
2516      * }]
2517      */
2518     this.getSignerInfos = function(h) {
2519 	var aResult = [];
2520 
2521 	var aIdx = _getChildIdx(h, 0);
2522 	for (var i = 0; i < aIdx.length; i++) {
2523 	    var hSignerInfo = _getTLV(h, aIdx[i]);
2524 	    var pSignerInfo = this.getSignerInfo(hSignerInfo);
2525 	    aResult.push(pSignerInfo);
2526 	}
2527 
2528 	return aResult;
2529     };
2530 
2531     /**
2532      * parse ASN.1 SignerInfo<br/>
2533      * @name getSignerInfo
2534      * @memberOf KJUR.asn1.cms.CMSParser#
2535      * @function
2536      * @param {String} h hexadecimal string of ASN.1 SignerInfo
2537      * @return {Array} array of JSON object of SignerInfo parameter
2538      * @see KJUR.asn1.cms.SignerInfo
2539      * @see KJUR.asn1.cms.CMSParser#getSignedData
2540      *
2541      * @description
2542      * This method parses ASN.1 SignerInfos defined in 
2543      * RFC 5652 
2544      * <a href="https://tools.ietf.org/html/rfc5652#section-5.1">
2545      * section 5</a>.
2546      * <pre>
2547      * SignerInfo ::= SEQUENCE {
2548      *    version CMSVersion,
2549      *    sid SignerIdentifier,
2550      *    digestAlgorithm DigestAlgorithmIdentifier,
2551      *    signedAttrs [0] IMPLICIT SignedAttributes OPTIONAL,
2552      *    signatureAlgorithm SignatureAlgorithmIdentifier,
2553      *    signature SignatureValue,
2554      *    unsignedAttrs [1] IMPLICIT UnsignedAttributes OPTIONAL }
2555      * </pre>
2556      * The result parameter can be passed to
2557      * {@link KJUR.asn1.cms.SignerInfo} constructor.
2558      * 
2559      * @example
2560      * parser = new KJUR.asn1.cms.CMSParser();
2561      * parser.getSignerInfos("30...") →
2562      * [{
2563      *   version: 1,
2564      *   id: {type: 'isssn', issuer: {str: '/C=US/O=T1'}, serial: {int: 1}},
2565      *   hashalg: "sha1",
2566      *   sattrs: {array: [{
2567      *     attr: "contentType",
2568      *     type: '1.2.840.113549.1.7.1'
2569      *   },{
2570      *     attr: "messageDigest",
2571      *     hex: 'a1a2a3a4a5a6a7a8a9a0a1a2a3a4a5a6a7a8a9a0'
2572      *   }]},
2573      *   sigalg: "SHA1withRSA",
2574      *   sighex: 'b1b2b...'
2575      * }]
2576      */
2577     this.getSignerInfo = function(h) {
2578 	var pResult = {};
2579 	var aIdx = _getChildIdx(h, 0);
2580 
2581 	var iVersion = _ASN1HEX.getInt(h, aIdx[0], -1);
2582 	if (iVersion != -1) pResult.version = iVersion;
2583 
2584 	var hSI = _getTLV(h, aIdx[1]);
2585 	var pSI = this.getIssuerAndSerialNumber(hSI);
2586 	pResult.id = pSI;
2587 
2588 	var hAlg = _getTLV(h, aIdx[2]);
2589 	//alert(hAlg);
2590 	var sAlg = _x509obj.getAlgorithmIdentifierName(hAlg);
2591 	pResult.hashalg = sAlg;
2592 
2593 	var hSattrs = _getTLVbyListEx(h, 0, ["[0]"]);
2594 	if (hSattrs != null) {
2595 	    var aSattrs = this.getAttributeList(hSattrs);
2596 	    pResult.sattrs = aSattrs;
2597 	}
2598 
2599 	var hSigAlg = _getTLVbyListEx(h, 0, [3]);
2600 	var sSigAlg = _x509obj.getAlgorithmIdentifierName(hSigAlg);
2601 	pResult.sigalg = sSigAlg;
2602 
2603 	var hSigHex = _getVbyListEx(h, 0, [4]);
2604 	pResult.sighex = hSigHex;
2605 
2606 	var hUattrs = _getTLVbyListEx(h, 0, ["[1]"]);
2607 	if (hUattrs != null) {
2608 	    var aUattrs = this.getAttributeList(hUattrs);
2609 	    pResult.uattrs = aUattrs;
2610 	}
2611 
2612 	return pResult;
2613     };
2614 
2615     /**
2616      * parse ASN.1 SignerIdentifier<br/>
2617      * @name getSignerIdentifier
2618      * @memberOf KJUR.asn1.cms.CMSParser#
2619      * @function
2620      * @param {String} h hexadecimal string of ASN.1 SignerIdentifier
2621      * @return {Array} array of JSON object of SignerIdentifier parameter
2622      * @see KJUR.asn1.cms.SignerInfo
2623      * @see KJUR.asn1.cms.SignerIdentifier
2624      * @see KJUR.asn1.cms.CMSParser#getSignedData
2625      *
2626      * @description
2627      * This method parses ASN.1 SignerIdentifier defined in 
2628      * RFC 5652 
2629      * <a href="https://tools.ietf.org/html/rfc5652#section-5.1">
2630      * section 5</a>.
2631      * 
2632      * @example
2633      * parser = new KJUR.asn1.cms.CMSParser();
2634      * parser.getSignerIdentifier("30...") →
2635      * { type: "isssn",
2636      *   issuer: {
2637      *     array: [[{type:"C",value:"JP",ds:"prn"},...]]
2638      *     str: '/C=US/O=T1'
2639      *   },
2640      *   serial: {int: 1} }
2641      */
2642     this.getSignerIdentifier = function(h) {
2643 	if (h.substr(0, 2) == "30") {
2644 	    return this.getIssuerAndSerialNumber(h);
2645 	} else {
2646 	    throw new Error("SKID of signerIdentifier not supported");
2647 	}
2648     };
2649 
2650     /**
2651      * parse ASN.1 IssuerAndSerialNumber<br/>
2652      * @name getIssuerAndSerialNumber
2653      * @memberOf KJUR.asn1.cms.CMSParser#
2654      * @function
2655      * @param {String} h hexadecimal string of ASN.1 IssuerAndSerialNumber
2656      * @return {Array} array of JSON object of IssuerAndSerialNumber parameter
2657      * @see KJUR.asn1.cms.SignerInfo
2658      * @see KJUR.asn1.cms.CMSParser#getSignedData
2659      *
2660      * @description
2661      * This method parses ASN.1 IssuerAndSerialNumber defined in 
2662      * RFC 5652 
2663      * <a href="https://tools.ietf.org/html/rfc5652#section-5.1">
2664      * section 5</a>.
2665      * 
2666      * @example
2667      * parser = new KJUR.asn1.cms.CMSParser();
2668      * parser.getIssuerAndSerialNumber("30...") →
2669      * { type: "isssn",
2670      *   issuer: {
2671      *     array: [[{type:"C",value:"JP",ds:"prn"},...]]
2672      *     str: '/C=US/O=T1'
2673      *   },
2674      *   serial: {int: 1} }
2675      */
2676     this.getIssuerAndSerialNumber = function(h) {
2677 	var pResult = {type: "isssn"};
2678 
2679 	var aIdx = _getChildIdx(h, 0);
2680 
2681 	var hName = _getTLV(h, aIdx[0]);
2682 	pResult.issuer = _x509obj.getX500Name(hName);
2683 
2684 	var hSerial = _getV(h, aIdx[1]);
2685 	pResult.serial = {hex: hSerial};
2686 
2687 	return pResult;
2688     };
2689 
2690     /**
2691      * parse ASN.1 SET OF Attributes<br/>
2692      * @name getAttributeList
2693      * @memberOf KJUR.asn1.cms.CMSParser#
2694      * @function
2695      * @param {String} h hexadecimal string of ASN.1 SET OF Attribute
2696      * @return {Array} array of JSON object of Attribute parameter
2697      * @see KJUR.asn1.cms.SignerInfo
2698      * @see KJUR.asn1.cms.CMSParser#getAttribute
2699      *
2700      * @description
2701      * This method parses ASN.1 SET OF Attribute defined in 
2702      * RFC 5652 
2703      * <a href="https://tools.ietf.org/html/rfc5652#section-5.1">
2704      * section 5</a>.
2705      * This can be used for SignedAttributes and UnsignedAttributes.
2706      * 
2707      * @example
2708      * parser = new KJUR.asn1.cms.CMSParser();
2709      * parser.getAttributeList("30...") →
2710      * [{attr: "contentType", type: "tstinfo"},
2711      *  {attr: "messageDigest", hex: "1234abcd..."}]
2712      */
2713     this.getAttributeList = function(h) {
2714 	var a = [];
2715 
2716 	var aIdx = _getChildIdx(h, 0);
2717 	for (var i = 0; i < aIdx.length; i++) {
2718 	    var hAttr = _getTLV(h, aIdx[i]);
2719 	    var pAttr = this.getAttribute(hAttr);
2720 	    a.push(pAttr);
2721 	}
2722 
2723 	return {array: a};
2724     };
2725 
2726     /**
2727      * parse ASN.1 Attributes<br/>
2728      * @name getAttribute
2729      * @memberOf KJUR.asn1.cms.CMSParser#
2730      * @function
2731      * @param {String} h hexadecimal string of ASN.1 Attribute
2732      * @return {Array} array of JSON object of Attribute parameter
2733      * @see KJUR.asn1.cms.SignerInfo
2734      * @see KJUR.asn1.cms.CMSParser#getAttributeList
2735      *
2736      * @description
2737      * This method parses ASN.1 Attribute defined in 
2738      * RFC 5652 
2739      * <a href="https://tools.ietf.org/html/rfc5652#section-5.1">
2740      * section 5</a>.
2741      * Following attribute type are supported in the
2742      * latest version:
2743      * <ul>
2744      * <li>contentType - {@link KJUR.asn1.cms.CMSParser.setContentType}</li>
2745      * <li>messageDigest - {@link KJUR.asn1.cms.CMSParser.setMessageDigest}</li>
2746      * <li>signingTime - {@link KJUR.asn1.cms.CMSParser.setSigningTime}</li>
2747      * <li>signingCertificate - {@link KJUR.asn1.cms.CMSParser.setSigningCertificate}</li>
2748      * <li>signingCertificateV2 - {@link KJUR.asn1.cms.CMSParser.setSigningCertificateV2}</li>
2749      * </ul>
2750      * 
2751      * @example
2752      * parser = new KJUR.asn1.cms.CMSParser();
2753      * parser.getAttribute("30...") →
2754      * {attr: "contentType", type: "tstinfo"}
2755      */
2756     this.getAttribute = function(h) {
2757 	var pResult = {};
2758 	var aIdx = _getChildIdx(h, 0);
2759 
2760 	var attrTypeOID = _ASN1HEX.getOID(h, aIdx[0]);
2761 	var attrType = KJUR.asn1.x509.OID.oid2name(attrTypeOID);
2762 	pResult.attr = attrType;
2763 
2764 	var hSet = _getTLV(h, aIdx[1]);
2765 	var aSetIdx = _getChildIdx(hSet, 0);
2766 	if (aSetIdx.length == 1) {
2767 	    pResult.valhex = _getTLV(hSet, aSetIdx[0]);
2768 	} else {
2769 	    var a = [];
2770 	    for (var i = 0; i < aSetIdx.length; i++) {
2771 		a.push(_getTLV(hSet, aSetIdx[i]));
2772 	    }
2773 	    pResult.valhex = a;
2774 	}
2775 
2776 	if (attrType == "contentType") {
2777 	    this.setContentType(pResult);
2778 	} else if (attrType == "messageDigest") {
2779 	    this.setMessageDigest(pResult);
2780 	} else if (attrType == "signingTime") {
2781 	    this.setSigningTime(pResult);
2782 	} else if (attrType == "signingCertificate") {
2783 	    this.setSigningCertificate(pResult);
2784 	} else if (attrType == "signingCertificateV2") {
2785 	    this.setSigningCertificateV2(pResult);
2786 	} else if (attrType == "signaturePolicyIdentifier") {
2787 	    this.setSignaturePolicyIdentifier(pResult);
2788 	}
2789 
2790 	return pResult;
2791     };
2792 
2793     /**
2794      * set ContentType attribute<br/>
2795      * @name setContentType
2796      * @memberOf KJUR.asn1.cms.CMSParser#
2797      * @function
2798      * @param {Array} pAttr JSON object of attribute parameter
2799      * @see KJUR.asn1.cms.CMSParser#getAttribute
2800      *
2801      * @description
2802      * This sets an attribute as ContentType defined in
2803      * RFC 5652 
2804      * <a href="https://tools.ietf.org/html/rfc5652#section-5.1">
2805      * section 5</a>.
2806      *
2807      * @example
2808      * parser = new KJUR.asn1.cms.CMSParser();
2809      * pAttr = {
2810      *   attr: "contentType"
2811      *   valhex: '060b2a864886f70d0109100104'
2812      * };
2813      * parser.setContentInfo(pAttr);
2814      * pAttr → {
2815      *   attr: "contentType"
2816      *   type: "tstinfo"
2817      * }
2818      */
2819     this.setContentType = function(pAttr) {
2820 	var contentType = _ASN1HEX.getOIDName(pAttr.valhex, 0, null);
2821 	if (contentType != null) {
2822 	    pAttr.type = contentType;
2823 	    delete pAttr.valhex;
2824 	}
2825     };
2826 
2827     /**
2828      * set SigningTime attribute<br/>
2829      * @name setSigningTime
2830      * @memberOf KJUR.asn1.cms.CMSParser#
2831      * @function
2832      * @param {Array} pAttr JSON object of attribute parameter
2833      * @see KJUR.asn1.cms.CMSParser#getAttribute
2834      *
2835      * @description
2836      * This sets an attribute as SigningTime defined in
2837      * RFC 5652 
2838      * <a href="https://tools.ietf.org/html/rfc5652#section-5.1">
2839      * section 5</a>.
2840      *
2841      * @example
2842      * parser = new KJUR.asn1.cms.CMSParser();
2843      * pAttr = {
2844      *   attr: "signingTime"
2845      *   valhex: '170d3230313233313233353935395a'
2846      * };
2847      * parser.setSigningTime(pAttr);
2848      * pAttr → {
2849      *   attr: "signingTime",
2850      *   str: "2012315959Z"
2851      * }
2852      */
2853     this.setSigningTime = function(pAttr) {
2854 	var hSigningTime = _getV(pAttr.valhex, 0);
2855 	var signingTime = hextoutf8(hSigningTime);
2856 	pAttr.str = signingTime;
2857 	delete pAttr.valhex;
2858     };
2859 
2860     /**
2861      * set MessageDigest attribute<br/>
2862      * @name setMessageDigest
2863      * @memberOf KJUR.asn1.cms.CMSParser#
2864      * @function
2865      * @param {Array} pAttr JSON object of attribute parameter
2866      * @see KJUR.asn1.cms.CMSParser#getAttribute
2867      *
2868      * @description
2869      * This sets an attribute as SigningTime defined in
2870      * RFC 5652 
2871      * <a href="https://tools.ietf.org/html/rfc5652#section-5.1">
2872      * section 5</a>.
2873      *
2874      * @example
2875      * parser = new KJUR.asn1.cms.CMSParser();
2876      * pAttr = {
2877      *   attr: "messageDigest"
2878      *   valhex: '0403123456'
2879      * };
2880      * parser.setMessageDigest(pAttr);
2881      * pAttr → {
2882      *   attr: "messageDigest",
2883      *   hex: "123456"
2884      * }
2885      */
2886     this.setMessageDigest = function(pAttr) {
2887 	var hMD = _getV(pAttr.valhex, 0);
2888 	pAttr.hex = hMD;
2889 	delete pAttr.valhex;
2890     };
2891 
2892     /**
2893      * set SigningCertificate attribute<br/>
2894      * @name setSigningCertificate
2895      * @memberOf KJUR.asn1.cms.CMSParser#
2896      * @function
2897      * @param {Array} pAttr JSON object of attribute parameter
2898      * @see KJUR.asn1.cms.CMSParser#getAttribute
2899      *
2900      * @description
2901      * This sets an attribute as SigningCertificate defined in
2902      * <a href="https://tools.ietf.org/html/rfc5035#section-5">
2903      * RFC 5035 section 5</a>.
2904      *
2905      * @example
2906      * parser = new KJUR.asn1.cms.CMSParser();
2907      * pAttr = {
2908      *   attr: "signingCertificate"
2909      *   valhex: '...'
2910      * };
2911      * parser.setSigningCertificate(pAttr);
2912      * pAttr → {
2913      *   attr: "signingCertificate",
2914      *   array: [{
2915      *     hash: "123456...",
2916      *     issuer: {
2917      *       array: [[{type:"C",value:"JP",ds:"prn"},...]],
2918      *       str: "/C=JP/O=T1"
2919      *     },
2920      *     serial: {hex: "123456..."}
2921      *   }]
2922      * }
2923      */
2924     this.setSigningCertificate = function(pAttr) {
2925 	var aIdx = _getChildIdx(pAttr.valhex, 0);
2926 	if (aIdx.length > 0) {
2927 	    var hCerts = _getTLV(pAttr.valhex, aIdx[0]);
2928 	    var aCertIdx = _getChildIdx(hCerts, 0);
2929 	    var a = [];
2930 	    for (var i = 0; i < aCertIdx.length; i++) {
2931 		var hESSCertID = _getTLV(hCerts, aCertIdx[i]);
2932 		var pESSCertID = this.getESSCertID(hESSCertID);
2933 		a.push(pESSCertID);
2934 	    }
2935 	    pAttr.array = a;
2936 	}
2937 
2938 	if (aIdx.length > 1) {
2939 	    var hPolicies = _getTLV(pAttr.valhex, aIdx[1]);
2940 	    pAttr.polhex = hPolicies;
2941 	}
2942 	delete pAttr.valhex;
2943     };
2944 
2945     /**
2946      * set SignaturePolicyIdentifier attribute<br/>
2947      * @name setSignaturePolicyIdentifier
2948      * @memberOf KJUR.asn1.cms.CMSParser#
2949      * @function
2950      * @param {Array} pAttr JSON object of attribute parameter
2951      * @since jsrsasign 10.1.5 asn1cms 2.0.4
2952      * @see KJUR.asn1.cms.CMSParser#getAttribute
2953      * @see KJUR.asn1.cades.SignaturePolicyIdentifier
2954      *
2955      * @description
2956      * This sets an attribute as SignaturePolicyIdentifier defined in
2957      * <a href="https://tools.ietf.org/html/rfc5126#section-5.8.1">
2958      * RFC 5126 CAdES section 5.8.1</a>.
2959      *
2960      * @example
2961      * parser = new KJUR.asn1.cms.CMSParser();
2962      * pAttr = {
2963      *   attr: "signaturePolicyIdentifier"
2964      *   valhex: '...'
2965      * };
2966      * parser.setSignaturePolicyIdentifier(pAttr);
2967      * pAttr → {
2968      *   attr: "signaturePolicyIdentifier",
2969      *   oid: "1.2.3.4.5",
2970      *   alg: "sha1",
2971      *   hash: "1a2b..."
2972      * }
2973      */
2974     this.setSignaturePolicyIdentifier = function(pAttr) {
2975 	var aIdx = _getChildIdx(pAttr.valhex, 0);
2976 	if (aIdx.length > 0) {
2977 	    var oid = _ASN1HEX.getOID(pAttr.valhex, aIdx[0]);
2978 	    pAttr.oid = oid;
2979 	}
2980 	if (aIdx.length > 1) {
2981 	    var x = new _X509();
2982 	    var a2Idx = _getChildIdx(pAttr.valhex, aIdx[1]);
2983 	    var hAlg = _getTLV(pAttr.valhex, a2Idx[0]);
2984 	    var sAlg = x.getAlgorithmIdentifierName(hAlg);
2985 	    pAttr.alg = sAlg;
2986 
2987 	    var hHash = _getV(pAttr.valhex, a2Idx[1]);
2988 	    pAttr.hash = hHash;
2989 	}
2990 	delete pAttr.valhex;
2991     };
2992 
2993     /**
2994      * set SigningCertificateV2 attribute<br/>
2995      * @name setSigningCertificateV2
2996      * @memberOf KJUR.asn1.cms.CMSParser#
2997      * @function
2998      * @param {Array} pAttr JSON object of attribute parameter
2999      * @since jsrsasign 10.1.2 asn1cms 2.0.3
3000      * @see KJUR.asn1.cms.CMSParser#getAttribute
3001      * @see KJUR.asn1.cms.CMSParser#getESSCertIDv2
3002      * @see KJUR.asn1.cms.SigningCertificateV2
3003      * @see KJUR.asn1.cms.ESSCertIDv2
3004      *
3005      * @description
3006      * This sets an attribute as SigningCertificateV2 defined in
3007      * <a href="https://tools.ietf.org/html/rfc5035#section-3">
3008      * RFC 5035 section 3</a>.
3009      *
3010      * @example
3011      * parser = new KJUR.asn1.cms.CMSParser();
3012      * pAttr = {
3013      *   attr: "signingCertificateV2"
3014      *   valhex: '...'
3015      * };
3016      * parser.setSigningCertificateV2(pAttr);
3017      * pAttr → {
3018      *   attr: "signingCertificateV2",
3019      *   array: [{
3020      *     hash: "123456...",
3021      *     alg: "sha256",
3022      *     issuer: {
3023      *       array: [[{type:"C",value:"JP",ds:"prn"},...]],
3024      *       str: "/C=JP/O=T1"
3025      *     },
3026      *     serial: {hex: "123456..."}
3027      *   }]
3028      * }
3029      */
3030     this.setSigningCertificateV2 = function(pAttr) {
3031 	var aIdx = _getChildIdx(pAttr.valhex, 0);
3032 	if (aIdx.length > 0) {
3033 	    var hCerts = _getTLV(pAttr.valhex, aIdx[0]);
3034 	    var aCertIdx = _getChildIdx(hCerts, 0);
3035 	    var a = [];
3036 	    for (var i = 0; i < aCertIdx.length; i++) {
3037 		var hESSCertIDv2 = _getTLV(hCerts, aCertIdx[i]);
3038 		var pESSCertIDv2 = this.getESSCertIDv2(hESSCertIDv2);
3039 		a.push(pESSCertIDv2);
3040 	    }
3041 	    pAttr.array = a;
3042 	}
3043 
3044 	if (aIdx.length > 1) {
3045 	    var hPolicies = _getTLV(pAttr.valhex, aIdx[1]);
3046 	    pAttr.polhex = hPolicies;
3047 	}
3048 	delete pAttr.valhex;
3049     };
3050 
3051     /**
3052      * parse ASN.1 ESSCertID<br/>
3053      * @name getESSCertID
3054      * @memberOf KJUR.asn1.cms.CMSParser#
3055      * @function
3056      * @param {String} h hexadecimal string of ASN.1 ESSCertID
3057      * @return {Array} array of JSON object of ESSCertID parameter
3058      * @see KJUR.asn1.cms.ESSCertID
3059      *
3060      * @description
3061      * This method parses ASN.1 ESSCertID defined in 
3062      * <a href="https://tools.ietf.org/html/rfc5035#section-6">
3063      * RFC 5035 section 6</a>.
3064      * <pre>
3065      * ESSCertID ::= SEQUENCE {
3066      *    certHash Hash,
3067      *    issuerSerial IssuerSerial OPTIONAL }
3068      * IssuerSerial ::= SEQUENCE {
3069      *    issuer GeneralNames,
3070      *    serialNumber CertificateSerialNumber }
3071      * </pre>
3072      * 
3073      * @example
3074      * parser = new KJUR.asn1.cms.CMSParser();
3075      * parser.getESSCertID("30...") →
3076      * { hash: "12ab...",
3077      *   issuer: {
3078      *     array: [[{type:"C",value:"JP",ds:"prn"}],...],
3079      *     str: "/C=JP/O=T1"
3080      *   },
3081      *   serial: {hex: "12ab..."} }
3082      */
3083     this.getESSCertID = function(h) {
3084 	var pResult = {};
3085 	var aIdx = _getChildIdx(h, 0);
3086 
3087 	if (aIdx.length > 0) {
3088 	    var hCertHash = _getV(h, aIdx[0]);
3089 	    pResult.hash = hCertHash;
3090 	}
3091 
3092 	if (aIdx.length > 1) {
3093 	    var hIssuerSerial = _getTLV(h, aIdx[1]);
3094 	    var pIssuerSerial = 
3095 		this.getIssuerSerial(hIssuerSerial);
3096 
3097 	    if (pIssuerSerial.serial != undefined)
3098 		pResult.serial = pIssuerSerial.serial;
3099 
3100 	    if (pIssuerSerial.issuer != undefined)
3101 		pResult.issuer = pIssuerSerial.issuer;
3102 	}
3103 
3104 	return pResult;
3105     };
3106 
3107     /**
3108      * parse ASN.1 ESSCertIDv2<br/>
3109      * @name getESSCertIDv2
3110      * @memberOf KJUR.asn1.cms.CMSParser#
3111      * @function
3112      * @param {String} h hexadecimal string of ASN.1 ESSCertIDv2
3113      * @return {Array} array of JSON object of ESSCertIDv2 parameter
3114      * @since jsrsasign 10.1.2 asn1cms 2.0.3
3115      * @see KJUR.asn1.cms.ESSCertIDv2
3116      * @see KJUR.asn1.cms.CMSParser.getESSCertID
3117      *
3118      * @description
3119      * This method parses ASN.1 ESSCertIDv2 defined in 
3120      * <a href="https://tools.ietf.org/html/rfc5035#section-4">
3121      * RFC 5035 section 4</a>.
3122      * <pre>
3123      * ESSCertIDv2 ::=  SEQUENCE {
3124      *    hashAlgorithm           AlgorithmIdentifier
3125      *                            DEFAULT {algorithm id-sha256},
3126      *    certHash                Hash,
3127      *    issuerSerial            IssuerSerial OPTIONAL }
3128      * Hash ::= OCTET STRING
3129      * IssuerSerial ::= SEQUENCE {
3130      *    issuer                  GeneralNames,
3131      *    serialNumber            CertificateSerialNumber }
3132      * </pre>
3133      * 
3134      * @example
3135      * parser = new KJUR.asn1.cms.CMSParser();
3136      * parser.getESSCertID("30...") →
3137      * {
3138      *   hash: "3f2d...",
3139      *   alg: "sha512",
3140      *   issuer: {str: "/C=JP/O=T1"},
3141      *   serial: {hex: "12ab..."}
3142      * }
3143      */
3144     this.getESSCertIDv2 = function(h) {
3145 	var aResult = {};
3146 	var aIdx = _getChildIdx(h, 0); 
3147 
3148 	if (aIdx.length < 1 || 3 < aIdx.length)
3149 	    throw new _Error("wrong number of elements");
3150 
3151 	var offset = 0;
3152 	if (h.substr(aIdx[0], 2) == "30") {
3153 	    var hHashAlg = _getTLV(h, aIdx[0]);
3154 	    aResult.alg = 
3155 		_x509obj.getAlgorithmIdentifierName(hHashAlg);
3156 	    offset++;
3157 	} else {
3158 	    aResult.alg = "sha256";
3159 	}
3160 
3161 	var hHash = _getV(h, aIdx[offset]);
3162 	aResult.hash = hHash;
3163 
3164 	if (aIdx.length > offset + 1) {
3165 	    var hIssuerSerial = _getTLV(h, aIdx[offset + 1]);
3166 	    var pIssuerSerial = 
3167 		this.getIssuerSerial(hIssuerSerial);
3168 	    aResult.issuer = pIssuerSerial.issuer;
3169 	    aResult.serial = pIssuerSerial.serial;
3170 	}
3171 
3172 	return aResult;
3173     };
3174 
3175     /**
3176      * parse ASN.1 IssuerSerial<br/>
3177      * @name getIssuerSerial
3178      * @memberOf KJUR.asn1.cms.CMSParser#
3179      * @function
3180      * @param {String} h hexadecimal string of ASN.1 IssuerSerial
3181      * @return {Array} array of JSON object of IssuerSerial parameter
3182      * @see KJUR.asn1.cms.IssuerSerial
3183      * @see KJUR.asn1.x509.X500Name
3184      *
3185      * @description
3186      * This method parses ASN.1 IssuerSerial defined in 
3187      * <a href="https://tools.ietf.org/html/rfc5035#section-6">
3188      * RFC 5035 section 6</a>.
3189      * <pre>
3190      * IssuerSerial ::= SEQUENCE {
3191      *    issuer GeneralNames,
3192      *    serialNumber CertificateSerialNumber }
3193      * </pre>
3194      * 
3195      * @example
3196      * parser = new KJUR.asn1.cms.CMSParser();
3197      * parser.getIssuerSerial("30...") →
3198      * { issuer: {
3199      *     array: [[{type:"C",value:"JP",ds:"prn"}],...],
3200      *     str: "/C=JP/O=T1",
3201      *   },
3202      *   serial: {hex: "12ab..."} }
3203      */
3204     this.getIssuerSerial = function(h) {
3205 	var pResult = {};
3206 	var aIdx = _getChildIdx(h, 0);
3207 
3208 	var hIssuer = _getTLV(h, aIdx[0]);
3209 	var pIssuerGN = _x509obj.getGeneralNames(hIssuer);
3210 	var pIssuerName = pIssuerGN[0].dn;
3211 	pResult.issuer = pIssuerName;
3212 
3213 	var hSerial = _getV(h, aIdx[1]);
3214 	pResult.serial = {hex: hSerial};
3215 
3216 	return pResult;
3217     };
3218 
3219     /**
3220      * parse ASN.1 CertificateSet<br/>
3221      * @name getCertificateSet
3222      * @memberOf KJUR.asn1.cms.CMSParser#
3223      * @function
3224      * @param {String} h hexadecimal string of ASN.1 CertificateSet
3225      * @return {Array} array of JSON object of CertificateSet parameter
3226      * @see KJUR.asn1.cms.CertificateSet
3227      *
3228      * @description
3229      * This method parses ASN.1 IssuerSerial defined in 
3230      * <a href="https://tools.ietf.org/html/rfc5652#section-10.2.3">
3231      * RFC 5652 CMS section 10.2.3</a> and 
3232      * <a href="https://tools.ietf.org/html/rfc5652#section-10.2.2">
3233      * section 10.2.2</a>.
3234      * <pre>
3235      * CertificateSet ::= SET OF CertificateChoices
3236      * CertificateChoices ::= CHOICE {
3237      *   certificate Certificate,
3238      *   extendedCertificate [0] IMPLICIT ExtendedCertificate, -- Obsolete
3239      *   v1AttrCert [1] IMPLICIT AttributeCertificateV1,       -- Obsolete
3240      *   v2AttrCert [2] IMPLICIT AttributeCertificateV2,
3241      *   other [3] IMPLICIT OtherCertificateFormat }
3242      * OtherCertificateFormat ::= SEQUENCE {
3243      *   otherCertFormat OBJECT IDENTIFIER,
3244      *   otherCert ANY DEFINED BY otherCertFormat }
3245      * </pre>
3246      * Currently only "certificate" is supported in
3247      * CertificateChoices.
3248      * 
3249      * @example
3250      * parser = new KJUR.asn1.cms.CMSParser();
3251      * parser.getCertificateSet("a0...") →
3252      * [ "-----BEGIN CERTIFICATE...", ... ]
3253      */
3254     this.getCertificateSet = function(h) {
3255 	var aIdx = _getChildIdx(h, 0);
3256 	var  a = [];
3257 	for (var i = 0; i < aIdx.length; i++) {
3258 	    var hCert = _getTLV(h, aIdx[i]);
3259 	    if (hCert.substr(0, 2) == "30") {
3260 		var pem = hextopem(hCert, "CERTIFICATE");
3261 		a.push(pem);
3262 	    }
3263 	}
3264 	return {array: a, sortflag: false};
3265     };
3266 };
3267