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