1 /* asn1cms-2.0.3.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.2 asn1cms 2.0.3 (2020-Nov-21)
 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 YAHOO.lang.extend(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 YAHOO.lang.extend(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 YAHOO.lang.extend(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 YAHOO.lang.extend(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 YAHOO.lang.extend(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 YAHOO.lang.extend(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 YAHOO.lang.extend(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 YAHOO.lang.extend(KJUR.asn1.cms.ESSCertIDv2, KJUR.asn1.cms.ESSCertID);
652 
653 /**
654  * class for IssuerSerial ASN.1 structure for CMS
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  * defined in 
671  * <a href="https://tools.ietf.org/html/rfc5035#page-6>
672  * RFC 5034 section 4</a>.
673  * <pre>
674  * IssuerSerial ::= SEQUENCE {
675  *    issuer                   GeneralNames,
676  *    serialNumber             CertificateSerialNumber
677  * }
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 YAHOO.lang.extend(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 YAHOO.lang.extend(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  *
843  * @description
844  * This class encodes IssuerAndSerialNumber ASN.1 structure defined in
845  * <a href="https://tools.ietf.org/html/rfc5652#section-10.2.4">
846  * RFC 5662 CMS 10.2.4</a>. 
847  * <pre>
848  * IssuerAndSerialNumber ::= SEQUENCE {
849  *    issuer Name,
850  *    serialNumber CertificateSerialNumber }
851  * CertificateSerialNumber ::= INTEGER
852  * </pre>
853  * Constructor of this class can have following parameters:
854  * <ul>
855  * <li>{String}cert (OPTION) - PEM certificate string to specify issuer and serial</li>
856  * <li>{Array}issuer (OPTION) - {@link KJUR.asn1.x509.X500Name} parameter for issuer name</li>
857  * <li>{Array}serial (OPTION) - {@link KJUR.asn1.DERInteger} parameter for serialNumber</li>
858  * </ul>
859  *
860  * @example
861  * // specify by X500Name and DERInteger
862  * o = new KJUR.asn1.cms.IssuerAndSerialNumber(
863  *      {issuer: {str: '/C=US/O=T1'}, serial: {int: 3}});
864  * // specify by PEM certificate
865  * o = new KJUR.asn1.cms.IssuerAndSerialNumber({cert: certPEM});
866  * o = new KJUR.asn1.cms.IssuerAndSerialNumber(certPEM); // since 1.0.3
867  */
868 KJUR.asn1.cms.IssuerAndSerialNumber = function(params) {
869     var _KJUR = KJUR,
870 	_KJUR_asn1 = _KJUR.asn1,
871 	_DERInteger = _KJUR_asn1.DERInteger,
872 	_DERSequence = _KJUR_asn1.DERSequence,
873 	_KJUR_asn1_cms = _KJUR_asn1.cms,
874 	_KJUR_asn1_x509 = _KJUR_asn1.x509,
875 	_X500Name = _KJUR_asn1_x509.X500Name,
876 	_X509 = X509,
877 	_Error = Error;
878 
879     _KJUR_asn1_cms.IssuerAndSerialNumber.superclass.constructor.call(this);
880     
881     this.params = null;
882 
883     this.getEncodedHex = function() {
884 	var params = this.params;
885 
886 	var pIssuer, pSerial;
887 	if ((typeof params == "string" && params.indexOf("-----BEGIN") != -1) ||
888 	    params.cert != undefined) {
889 	    var pem;
890 
891 	    if (params.cert != undefined) {
892 		pem = params.cert;
893 	    } else {
894 		pem = params;
895 	    }
896 
897 	    var x = new _X509();
898 	    x.readCertPEM(pem);
899 	    pIssuer = x.getIssuer();
900 	    pSerial = {hex: x.getSerialNumberHex()};
901 	} else if (params.issuer != undefined && params.serial) {
902 	    pIssuer = params.issuer;
903 	    pSerial = params.serial;
904 	} else {
905 	    throw new _Error("cert or issuer and serial parameter not specified");
906 	}
907 	
908 	var dIssuer = new _X500Name(pIssuer);
909 	var dSerial = new _DERInteger(pSerial);
910 	var seq = new _DERSequence({array: [dIssuer, dSerial]});
911 	return seq.getEncodedHex();
912     };
913 
914 
915     this.setByParam = function(params) {
916 	this.params = params;
917     }
918 
919     if (params != undefined) this.setByParam(params);
920 };
921 YAHOO.lang.extend(KJUR.asn1.cms.IssuerAndSerialNumber, KJUR.asn1.ASN1Object);
922 
923 /**
924  * class for SubjectKeyIdentifier ASN.1 structure for CMS SignerInfo<br/>
925  * @name KJUR.asn1.cms.SubjectKeyIdentifier
926  * @class class for SubjectKeyIdentifier ASN.1 structure for CMS SignerInfo
927  * @param {Array} params JSON object of parameters
928  * @extends KJUR.asn1.ASN1Object
929  * @since jsrsasign 10.0.0 asn1cms 2.0.0
930  *
931  * @description
932  * This class encodes SubjectKeyIdentifier ASN.1 structure defined in
933  * <a href="https://tools.ietf.org/html/rfc5652#section-12.1">
934  * RFC 5652 CMS 12.1</a>. 
935  * <pre>
936  * SubjectKeyIdentifier ::= OCTET STRING
937  * </pre>
938  *
939  * @example
940  * new KJUR.asn1.cms.SubjectKeyIdentifier({cert: "-----BEGIN..."})
941  * new KJUR.asn1.cms.SubjectKeyIdentifier({skid: "12ab..."})
942  */
943 KJUR.asn1.cms.SubjectKeyIdentifier = function(params) {
944     var _KJUR = KJUR,
945 	_KJUR_asn1 = _KJUR.asn1,
946 	_DERInteger = _KJUR_asn1.DERInteger,
947 	_DERSequence = _KJUR_asn1.DERSequence,
948 	_newObject = _KJUR_asn1.ASN1Util.newObject,
949 	_KJUR_asn1_cms = _KJUR_asn1.cms,
950 	_IssuerAndSerialName = _KJUR_asn1_cms.IssuerAndSerialName,
951 	_SubjectKeyIdentifier = _KJUR_asn1_cms.SubjectKeyIdentifier,
952 	_KJUR_asn1_x509 = _KJUR_asn1.x509,
953 	_X500Name = _KJUR_asn1_x509.X500Name,
954 	_X509 = X509,
955 	_Error = Error;
956 
957     _KJUR_asn1_cms.SubjectKeyIdentifier.superclass.constructor.call(this);
958 
959     this.getEncodedHex = function() {
960 	var params = this.params;
961 
962 	if (params.cert == undefined && params.skid == undefined)
963 	    throw new _Error("property cert nor skid undefined");
964 
965 	var hSKID;
966 	if (params.cert != undefined) {
967 	    var x = new _X509(params.cert);
968 	    var pSKID = x.getExtSubjectKeyIdentifier();
969 	    hSKID = pSKID.kid.hex;
970 	} else if (params.skid != undefined) {
971 	    hSKID = params.skid;
972 	}
973 	var dSKID = 
974 	    _newObject({tag:{tage:"a0",obj:{octstr:{hex:hSKID}}}});
975 	return dSKID.getEncodedHex();
976     };
977 
978     if (params != undefined) this.setByParam(params);
979 };
980 YAHOO.lang.extend(KJUR.asn1.cms.SubjectKeyIdentifier, KJUR.asn1.ASN1Object);
981 
982 /**
983  * class for Attributes ASN.1 structure for CMS<br/>
984  * @name KJUR.asn1.cms.AttributeList
985  * @class class for Attributes ASN.1 structure for CMS
986  * @param {Array} params associative array of parameters
987  * @extends KJUR.asn1.ASN1Object
988  * @since jsrsasign 4.2.4 asn1cms 1.0.0
989  *
990  * @description
991  * <pre>
992  * Attributes ::= SET OF Attribute
993  * Attribute ::= SEQUENCE {
994  *    type               OBJECT IDENTIFIER,
995  *    values             AttributeSetValue }
996  * </pre>
997  *
998  * @example
999  * new KJUR.asn1.cms.AttributeList({
1000  *   array: [{
1001  *     attr: "contentType",
1002  *     type: "data"
1003  *   }]
1004  * })
1005  */
1006 KJUR.asn1.cms.AttributeList = function(params) {
1007     var _Error = Error,
1008 	_KJUR = KJUR,
1009 	_KJUR_asn1 = _KJUR.asn1,
1010 	_DERSet = _KJUR_asn1.DERSet,
1011 	_KJUR_asn1_cms = _KJUR_asn1.cms;
1012 
1013     _KJUR_asn1_cms.AttributeList.superclass.constructor.call(this);
1014 
1015     this.params = null;
1016     this.hTLV = null;
1017 
1018     this.setByParam = function(params) {
1019 	this.params = params;
1020     };
1021 
1022     this.getEncodedHex = function() {
1023 	var params = this.params;
1024 	if (this.hTLV != null) return this.hTLV;
1025 
1026 	var sortflag = true;
1027 	if (params.sortflag != undefined) {
1028 	    sortflag = params.sortflag;
1029 	}
1030 
1031         var aAttrParam = params.array;
1032 	var a = [];
1033 	for (var i = 0; i < aAttrParam.length; i++) {
1034 	    var pAttr = aAttrParam[i];
1035 	    var attrName = pAttr.attr;
1036 	    if (attrName == "contentType") {
1037 		a.push(new _KJUR_asn1_cms.ContentType(pAttr));
1038 	    } else if (attrName == "messageDigest") {
1039 		a.push(new _KJUR_asn1_cms.MessageDigest(pAttr));
1040 	    } else if (attrName == "signingTime") {
1041 		a.push(new _KJUR_asn1_cms.SigningTime(pAttr));
1042 	    } else if (attrName == "signingCertificate") {
1043 		a.push(new _KJUR_asn1_cms.SigningCertificate(pAttr));
1044 	    } else if (attrName == "signingCertificateV2") {
1045 		a.push(new _KJUR_asn1_cms.SigningCertificateV2(pAttr));
1046 	    } else if (attrName == "signaturePolicyIdentifier") {
1047 		a.push(new KJUR.asn1.cades.SignaturePolicyIdentifier(pAttr));
1048 	    } else {
1049 		throw new _Error("unknown attr: " + attrName);
1050 	    }
1051 	}
1052 	
1053 	var dSet = new _DERSet({array: a, sortflag: sortflag});
1054 	this.hTLV = dSet.getEncodedHex();
1055 	return this.hTLV;
1056     };
1057 
1058     if (params != undefined) this.setByParam(params);
1059 };
1060 YAHOO.lang.extend(KJUR.asn1.cms.AttributeList, KJUR.asn1.ASN1Object);
1061 
1062 /**
1063  * class for SignerInfo ASN.1 structure of CMS SignedData<br/>
1064  * @name KJUR.asn1.cms.SignerInfo
1065  * @class class for Attributes ASN.1 structure of CMS SigndData
1066  * @param {Array} params associative array of parameters
1067  * @extends KJUR.asn1.ASN1Object
1068  * @since jsrsasign 4.2.4 asn1cms 1.0.0
1069  * @see KJUR.asn1.cms.SignerIdentifier
1070  * @see KJUR.asn1.x509.AlgorithmIdentifier
1071  * @see KJUR.asn1.cms.AttributeList
1072  *
1073  * @description
1074  * This class is an ASN.1 encoder for SignerInfo structure
1075  * defined in
1076  * <a https://tools.ietf.org/html/rfc5652#section-5.3">
1077  * RFC 5652 CMS section 5.3</a>.
1078  * <pre>
1079  * SignerInfo ::= SEQUENCE {
1080  *    version CMSVersion,
1081  *    sid SignerIdentifier,
1082  *    digestAlgorithm DigestAlgorithmIdentifier,
1083  *    signedAttrs [0] IMPLICIT SignedAttributes OPTIONAL,
1084  *    signatureAlgorithm SignatureAlgorithmIdentifier,
1085  *    signature SignatureValue,
1086  *    unsignedAttrs [1] IMPLICIT UnsignedAttributes OPTIONAL }
1087  * </pre>
1088  * Constractor parameter can have following properties:
1089  * <ul>
1090  * <li>{Integer}version - version of SignerInfo. </li>
1091  * <li>{Array}id - {@link KJUR.asn1.cms.SignerIdentifier} parameter for sid</li>
1092  * <li>{String}hashalg - digestAlgorithm name string (ex. "sha256")</li>
1093  * <li>{Array}sattrs - {@link KJUR.asn1.cms.AttributeList} parameter for 
1094  * signedAttributes</li>
1095  * <li>{String}sigalg - string for signatureAlgorithm name</a>
1096  * <li>{String}signkey (OPTION) - specifies signing private key.
1097  * Parameter "signkey" or "sighex" shall be specified. Following
1098  * values can be specified:
1099  *   <ul>
1100  *   <li>PKCS#1/5 or PKCS#8 PEM string of private key</li>
1101  *   <li>RSAKey/DSA/ECDSA key object. {@link KEYUTIL.getKey} is useful
1102  *   to generate a key object.</li>
1103  *   </ul>
1104  * </li>
1105  * <li>{String}sighex (OPTION) - hexadecimal string of signature value
1106  * (i.e. ASN.1 value(V) of signatureValue BIT STRING without
1107  * unused bits)</li>
1108  * </ul>
1109  *
1110  * @example
1111  * new KJUR.asn1.cms.SignerInfo({
1112  *   version: 1,
1113  *   id: {type: 'isssn', issuer: {str: '/C=US/O=T1'}, serial: {int: 1}},
1114  *   hashalg: "sha1",
1115  *   sattrs: {array: [{
1116  *     attr: "contentType",
1117  *     type: '1.2.840.113549.1.7.1'
1118  *   },{
1119  *     attr: "messageDigest",
1120  *     hex: 'a1a2a3a4a5a6a7a8a9a0a1a2a3a4a5a6a7a8a9a0'
1121  *   }]},
1122  *   sigalg: "SHA1withRSA",
1123  *   sighex: 'b1b2b...'
1124  * })
1125  */
1126 KJUR.asn1.cms.SignerInfo = function(params) {
1127     var _Error = Error,
1128 	_KJUR = KJUR,
1129 	_KJUR_asn1 = _KJUR.asn1,
1130 	_DERInteger = _KJUR_asn1.DERInteger,
1131 	_DEROctetString = _KJUR_asn1.DEROctetString,
1132 	_DERSequence = _KJUR_asn1.DERSequence,
1133 	_DERTaggedObject = _KJUR_asn1.DERTaggedObject,
1134 	_KJUR_asn1_cms = _KJUR_asn1.cms,
1135 	_SignerIdentifier = _KJUR_asn1_cms.SignerIdentifier,
1136 	_AttributeList = _KJUR_asn1_cms.AttributeList,
1137 	_ContentType = _KJUR_asn1_cms.ContentType,
1138 	_EncapsulatedContentInfo = _KJUR_asn1_cms.EncapsulatedContentInfo,
1139 	_MessageDigest = _KJUR_asn1_cms.MessageDigest,
1140 	_SignedData = _KJUR_asn1_cms.SignedData,
1141 	_KJUR_asn1_x509 = _KJUR_asn1.x509,
1142 	_AlgorithmIdentifier = _KJUR_asn1_x509.AlgorithmIdentifier,
1143 	_KJUR_crypto = _KJUR.crypto,
1144 	_KEYUTIL = KEYUTIL;
1145 
1146     _KJUR_asn1_cms.SignerInfo.superclass.constructor.call(this);
1147 
1148     this.params = null;
1149     
1150     /**
1151      * sign SignerInfo<br/>
1152      * @name sign
1153      * @memberOf KJUR.asn1.cms.SignerInfo#
1154      * @function
1155      *
1156      * @description
1157      * This method signs SignerInfo with a specified 
1158      * private key and algorithm by 
1159      * "params.signkey" and "params.sigalg" parameter.
1160      * In general, you don't need to call this method.
1161      * It will be called when getEncodedHex() method
1162      * if necessary.
1163      *
1164      * @example
1165      * si = new KJUR.asn1.cms.SignerInfo({...});
1166      * si.sign()
1167      */
1168     this.sign = function() {
1169 	var params = this.params;
1170 	var sigalg = params.sigalg;
1171 
1172 	var hData = (new _AttributeList(params.sattrs)).getEncodedHex();
1173 	var prvkey = _KEYUTIL.getKey(params.signkey);
1174 	var sig = new _KJUR_crypto.Signature({alg: sigalg});
1175 	sig.init(prvkey);
1176 	sig.updateHex(hData);
1177 	var hSig = sig.sign();
1178 	params.sighex = hSig;
1179     };
1180 
1181     this.getEncodedHex = function() {
1182 	var params = this.params;
1183 
1184 	var a = [];
1185         a.push(new _DERInteger({"int": params.version}));
1186 	a.push(new _SignerIdentifier(params.id));
1187 	a.push(new _AlgorithmIdentifier({name: params.hashalg}));
1188 	if (params.sattrs != undefined) {
1189 	    var dList = new _AttributeList(params.sattrs);
1190 	    try {
1191 		a.push(new _DERTaggedObject({tag: "a0", 
1192 					     explicit: false,
1193 					     obj: dList}));
1194 	    } catch(ex) {
1195 		throw new _Error("si sattr error: " + ex);
1196 	    }
1197 	}
1198 
1199 	if (params.sigalgfield != undefined) {
1200 	    a.push(new _AlgorithmIdentifier({name: params.sigalgfield}));
1201 	} else {
1202 	    a.push(new _AlgorithmIdentifier({name: params.sigalg}));
1203 	}
1204 
1205 	if (params.sighex == undefined &&
1206 	    params.signkey != undefined) {
1207 	    this.sign();
1208 	}
1209 
1210 	a.push(new _DEROctetString({hex: params.sighex}));
1211 
1212 	var seq = new _DERSequence({array: a});
1213 	return seq.getEncodedHex();
1214     };
1215 
1216     if (params != undefined) this.setByParam(params);
1217 };
1218 YAHOO.lang.extend(KJUR.asn1.cms.SignerInfo, KJUR.asn1.ASN1Object);
1219 
1220 /**
1221  * class for EncapsulatedContentInfo ASN.1 structure for CMS<br/>
1222  * @name KJUR.asn1.cms.EncapsulatedContentInfo
1223  * @class class for EncapsulatedContentInfo ASN.1 structure for CMS
1224  * @param {Array} params associative array of parameters
1225  * @extends KJUR.asn1.ASN1Object
1226  * @since jsrsasign 4.2.4 asn1cms 1.0.0
1227  *
1228  * @description
1229  * <pre>
1230  * EncapsulatedContentInfo ::= SEQUENCE {
1231  *    eContentType ContentType,
1232  *    eContent [0] EXPLICIT OCTET STRING OPTIONAL }
1233  * ContentType ::= OBJECT IDENTIFIER
1234  * </pre>
1235  *
1236  * @example
1237  * new KJUR.asn1.cms.EncapsulatedContentInfo({
1238  *  type: "data",
1239  *  content: {str: "aaa"}
1240  * })
1241  * new KJUR.asn1.cms.EncapsulatedContentInfo({
1242  *  type: "data",
1243  *  content: {hex: "616161"}
1244  * })
1245  * new KJUR.asn1.cms.EncapsulatedContentInfo({
1246  *  type: "data",
1247  *  content: {hex: "616161"},
1248  *  isDetached: true
1249  * })
1250  * new KJUR.asn1.cms.EncapsulatedContentInfo({
1251  *  type: "tstinfo",
1252  *  content: ...TSTInfo parameters...
1253  * })
1254  */
1255 KJUR.asn1.cms.EncapsulatedContentInfo = function(params) {
1256     var _KJUR = KJUR,
1257 	_KJUR_asn1 = _KJUR.asn1,
1258 	_DERTaggedObject = _KJUR_asn1.DERTaggedObject,
1259 	_DERSequence = _KJUR_asn1.DERSequence,
1260 	_DERObjectIdentifier = _KJUR_asn1.DERObjectIdentifier,
1261 	_DEROctetString = _KJUR_asn1.DEROctetString,
1262 	_KJUR_asn1_cms = _KJUR_asn1.cms;
1263 
1264     _KJUR_asn1_cms.EncapsulatedContentInfo.superclass.constructor.call(this);
1265 
1266     this.params = null;
1267 
1268     this.getEncodedHex = function() {
1269 	var params = this.params;
1270 
1271 	var a = [];
1272 
1273 	a.push(new _DERObjectIdentifier(params.type));
1274 
1275 	if (params.content != undefined &&
1276 	    (params.content.hex != undefined || 
1277 	     params.content.str != undefined) &&
1278 	    params.isDetached != true) {
1279 	    var dOctStr = new _DEROctetString(params.content);
1280 	    var dEContent = new _DERTaggedObject({tag: "a0",
1281 						  explicit: true,
1282 						  obj: dOctStr});
1283 	    a.push(dEContent);
1284 	}
1285 
1286 	var seq = new _DERSequence({array: a});
1287 	return seq.getEncodedHex();
1288     };
1289 
1290     this.setByParam = function(params) {
1291 	this.params = params;
1292     };
1293 
1294     if (params != undefined) this.setByParam(params);
1295 };
1296 YAHOO.lang.extend(KJUR.asn1.cms.EncapsulatedContentInfo, KJUR.asn1.ASN1Object);
1297 
1298 // - type
1299 // - obj
1300 /**
1301  * class for ContentInfo ASN.1 structure for CMS
1302  * @name KJUR.asn1.cms.ContentInfo
1303  * @class class for ContentInfo ASN.1 structure for CMS
1304  * @param {Array} params associative array of parameters
1305  * @extends KJUR.asn1.ASN1Object
1306  * @since jsrsasign 4.2.4 asn1cms 1.0.0
1307  * @description
1308  * <pre>
1309  * ContentInfo ::= SEQUENCE {
1310  *    contentType ContentType,
1311  *    content [0] EXPLICIT ANY DEFINED BY contentType }
1312  * ContentType ::= OBJECT IDENTIFIER
1313  * </pre>
1314  * @example
1315  * a = [new KJUR.asn1.DERInteger({int: 1}),
1316  *      new KJUR.asn1.DERInteger({int: 2})];
1317  * seq = new KJUR.asn1.DERSequence({array: a});
1318  * o = new KJUR.asn1.cms.ContentInfo({type: 'data', obj: seq});
1319  */
1320 KJUR.asn1.cms.ContentInfo = function(params) {
1321     var _KJUR = KJUR,
1322 	_KJUR_asn1 = _KJUR.asn1,
1323 	_DERTaggedObject = _KJUR_asn1.DERTaggedObject,
1324 	_DERSequence = _KJUR_asn1.DERSequence,
1325 	_DERObjectIdentifier = _KJUR_asn1.DERObjectIdentifier,
1326 	_KJUR_asn1_x509 = _KJUR_asn1.x509,
1327 	_name2obj = _KJUR_asn1_x509.OID.name2obj;
1328 
1329     KJUR.asn1.cms.ContentInfo.superclass.constructor.call(this);
1330     
1331     this.params = null;
1332 
1333     this.getEncodedHex = function() {
1334 	var params = this.params;
1335 
1336 	var a = [];
1337 	a.push(new _DERObjectIdentifier(params.type));
1338 
1339 	var dContent0 = new _DERTaggedObject({
1340 	    tag: "a0",
1341 	    explicit: true,
1342 	    obj: params.obj
1343 	});
1344 	a.push(dContent0);
1345 
1346 	var seq = new _DERSequence({array: a});
1347 	return seq.getEncodedHex();
1348     };
1349 
1350     this.setByParam = function(params) {
1351 	this.params = params;
1352     };
1353 
1354     if (params != undefined) this.setByParam(params);
1355 };
1356 YAHOO.lang.extend(KJUR.asn1.cms.ContentInfo, KJUR.asn1.ASN1Object);
1357 
1358 /**
1359  * class for SignerInfo ASN.1 structure of CMS SignedData
1360  * @name KJUR.asn1.cms.SignedData
1361  * @class class for Attributes ASN.1 structure of CMS SigndData
1362  * @param {Array} params associative array of parameters
1363  * @extends KJUR.asn1.ASN1Object
1364  * @since jsrsasign 4.2.4 asn1cms 1.0.0
1365  *
1366  * @description
1367  * <pre>
1368  * ContentInfo ::= SEQUENCE {
1369  *    contentType ContentType,
1370  *    content [0] EXPLICIT ANY DEFINED BY contentType }
1371  * ContentType ::= OBJECT IDENTIFIER
1372  * SignedData ::= SEQUENCE {
1373  *    version CMSVersion,
1374  *    digestAlgorithms DigestAlgorithmIdentifiers,
1375  *    encapContentInfo EncapsulatedContentInfo,
1376  *    certificates [0] IMPLICIT CertificateSet OPTIONAL,
1377  *    crls [1] IMPLICIT RevocationInfoChoices OPTIONAL,
1378  *    signerInfos SignerInfos }
1379  * SignerInfos ::= SET OF SignerInfo
1380  * CertificateSet ::= SET OF CertificateChoices
1381  * DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier
1382  * CertificateSet ::= SET OF CertificateChoices
1383  * RevocationInfoChoices ::= SET OF RevocationInfoChoice
1384  * </pre>
1385  *
1386  * @example
1387  * sd = new KJUR.asn1.cms.SignedData({
1388  *   version: 1,
1389  *   hashalgs: ["sha1"],
1390  *   econtent: {
1391  *     type: "data",
1392  *     content: {
1393  *       hex: "616161"
1394  *     }
1395  *   },
1396  *   certs: [PEM1,...],
1397  *   revinfos: {array: [...]},
1398  *   sinfos: [{
1399  *     version: 1,
1400  *     id: {type:'isssn', issuer: {str: '/C=US/O=T1'}, serial: {int: 1}},
1401  *     hashalg: "sha1",
1402  *     sattrs: {array: [{
1403  *       attr: "contentType",
1404  *       type: '1.2.840.113549.1.7.1'
1405  *     },{
1406  *       attr: "messageDigest",
1407  *       hex: 'abcd'
1408  *     }]},
1409  *     sigalg: "SHA1withRSA",
1410  *     signkey: PEMPRIVATEKEY
1411  *   }]
1412  * });
1413  * hex = sd.getContentInfoEncodedHex();
1414  */
1415 KJUR.asn1.cms.SignedData = function(params) {
1416     var _Error = Error,
1417 	_KJUR = KJUR,
1418 	_KJUR_asn1 = _KJUR.asn1,
1419 	_ASN1Object = _KJUR_asn1.ASN1Object,
1420 	_DERInteger = _KJUR_asn1.DERInteger,
1421 	_DERSet = _KJUR_asn1.DERSet,
1422 	_DERSequence = _KJUR_asn1.DERSequence,
1423 	_DERTaggedObject = _KJUR_asn1.DERTaggedObject,
1424 	_KJUR_asn1_cms = _KJUR_asn1.cms,
1425 	_EncapsulatedContentInfo = _KJUR_asn1_cms.EncapsulatedContentInfo,
1426 	_SignerInfo = _KJUR_asn1_cms.SignerInfo,
1427 	_ContentInfo = _KJUR_asn1_cms.ContentInfo,
1428 	_CertificateSet = _KJUR_asn1_cms.CertificateSet,
1429 	_RevocationInfoChoices = _KJUR_asn1_cms.RevocationInfoChoices,
1430 	_KJUR_asn1_x509 = _KJUR_asn1.x509,
1431 	_AlgorithmIdentifier = _KJUR_asn1_x509.AlgorithmIdentifier;
1432 
1433     KJUR.asn1.cms.SignedData.superclass.constructor.call(this);
1434 
1435     this.params = null;
1436 
1437     /**
1438      * fix fields before ASN.1 encode<br/>
1439      * @name checkAndFixParam
1440      * @memberOf KJUR.asn1.cms.SignedData#
1441      * @function
1442      *
1443      * @description
1444      * Update following values of "params" property
1445      * as defined in RFC 5652:
1446      * <ul>
1447      * <li>set "digestAlgorithms" field of "signedData" by
1448      * signerInfos</li>
1449      * <li>set all "contentType" signed attribute value to
1450      * the same value of eContent</li>
1451      * <li>set all "messageDigest" signed attribute value
1452      * to hash value of eContent contents value</li>
1453      * <li>all signerInfo version by their fields</li>
1454      * <li>signedData version by their fields</li>
1455      * </ul>
1456      * In general, you don't need to call this method.
1457      * It will be called automatically when
1458      * getEncodedHex() method is called.
1459      * <br>
1460      * NOTE: If you don't want to do such property value
1461      * update, set "params.fixed" property to "true".
1462      */
1463     this.checkAndFixParam = function() {
1464 	var sdparams = this.params;
1465 	this._setDigestAlgs(sdparams);
1466 	this._setContentTypeByEContent(sdparams);
1467 	this._setMessageDigestByEContent(sdparams);
1468 	this._setSignerInfoVersion(sdparams);
1469 	this._setSignedDataVersion(sdparams);
1470     };
1471 
1472     /*
1473      * @description
1474      * Get params.sinfos[*].hashalg for all "signerInfo"
1475      * and set "params.hashalgs" of "signedData" as
1476      * array of hash algorithm names.
1477      */
1478     this._setDigestAlgs = function(sdparams) {
1479 	var pHash = {};
1480 	var sinfos = sdparams.sinfos;
1481 	for (var i = 0; i < sinfos.length; i++) {
1482 	    var sinfo = sinfos[i];
1483 	    pHash[sinfo.hashalg] = 1;
1484 	}
1485 	sdparams.hashalgs = Object.keys(pHash).sort();
1486     };
1487 
1488     /*
1489      * @description
1490      * set "contentType" attribute value in 
1491      * "params.sinfos[*].sattrs" to "params.econtent.type"
1492      * value.
1493      */
1494     this._setContentTypeByEContent = function(sdparams) {
1495 	var type = sdparams.econtent.type;
1496 	var sinfos = sdparams.sinfos;
1497 	for (var i = 0; i < sinfos.length; i++) {
1498 	    var sinfo = sinfos[i];
1499 	    var ctParam = this._getAttrParamByName(sinfo, "contentType");
1500 	    //console.log(ctParam.type + " > " + type);
1501 	    ctParam.type = type;
1502 	}
1503     };
1504 
1505     /*
1506      * @description
1507      * set "messageDigest" attribute value in
1508      * "params.sinfos[*].sattrs" to a
1509      * calculated hash value by "econtent.content.hex"
1510      * with "params.sinfos[*].hashalg" algorithm.
1511      */
1512     this._setMessageDigestByEContent = function(sdparams) {
1513 	var econtent = sdparams.econtent;
1514 	var type = sdparams.econtent.type;
1515 
1516 	var hContent = econtent.content.hex;
1517 	if (hContent == undefined &&
1518 	    econtent.type == "data" &&
1519 	    econtent.content.str != undefined) {
1520 	    hContent = rstrtohex(econtent.content.str);
1521 	}
1522 
1523 	var sinfos = sdparams.sinfos;
1524 	for (var i = 0; i < sinfos.length; i++) {
1525 	    var sinfo = sinfos[i];
1526 	    var hashalg = sinfo.hashalg;
1527 	    var mdParam = this._getAttrParamByName(sinfo, "messageDigest");
1528 
1529 	    var hNew = KJUR.crypto.Util.hashHex(hContent, hashalg);
1530 
1531 	    //console.log(mdParam.hex + " > " + hNew);
1532 	    mdParam.hex = hNew;
1533 	}
1534     };
1535 
1536     /*
1537      * @param {Array}siParam "signerInfo" JSON parameter reference
1538      * @param {String}attrName attribute name string
1539      * @return {Array} attribute JSON parameter reference
1540      * @description
1541      * Find signed attribute parameter from signerInfo parameter
1542      * by attribute name.
1543      */
1544     this._getAttrParamByName = function(siParam, attrName) {
1545 	var aSattrs = siParam.sattrs.array;
1546 	for (var i = 0; i < aSattrs.length; i++) {
1547 	    if (aSattrs[i].attr == attrName) return aSattrs[i];
1548 	}
1549     };
1550 
1551     /*
1552      * @description
1553      * set signerInfo version "params.sinfos[*].version" 
1554      * of all signerInfos by signerInfo parameter.
1555      * Version will be identified by "signerIdentifier" is
1556      * "skid" or not.
1557      */
1558     this._setSignerInfoVersion = function(sdparams) {
1559 	var sinfos = sdparams.sinfos;
1560 	for (var i = 0; i < sinfos.length; i++) {
1561 	    var sinfo = sinfos[i];
1562 	    var newVersion = 1;
1563 	    if (sinfo.id.type == "skid") newVersion = 3;
1564 	    sinfo.version = newVersion;
1565 	}
1566     };
1567 
1568     /*
1569      * @description
1570      * set "signedData" version "params.version"
1571      * to value by _getSignedDataVersion()
1572      */
1573     this._setSignedDataVersion = function(sdparams) {
1574 	var newVersion = this._getSignedDataVersion(sdparams);
1575 	//console.log("sd version: " + sdparams.version + " > " + newVersion);
1576 	sdparams.version = newVersion;
1577     };
1578 
1579     /*
1580      * @description
1581      * get "signedData" version from parameters.
1582      * If "revinfos" "ocsp" exists, then version 5.
1583      * If "signerInfo" version 3 exists, then version 3.
1584      * If "params.econtent.type" is not "data" then version 3.
1585      * Otherwise version 1.
1586      */
1587     this._getSignedDataVersion = function(sdparams) {
1588 	//alert(JSON.stringify(sdparams));
1589 
1590 	if (sdparams.revinfos != undefined) {
1591 	    var revinfos = sdparams.revinfos;
1592 	    for (var i = 0; i < revinfos.length; i++) {
1593 		var revinfo = revinfos[i];
1594 		if (revinfo.ocsp != undefined) return 5;
1595 	    }
1596 	}
1597 
1598 	var sinfos = sdparams.sinfos;
1599 	for (var i = 0; i < sinfos.length; i++) {
1600 	    var sinfo = sdparams.sinfos[i];
1601 	    if (sinfo.version == 3) return 3;
1602 	}
1603 
1604 	if (sdparams.econtent.type != "data") return 3;
1605 	return 1;
1606     };
1607 
1608     this.getEncodedHex = function() {
1609 	var params = this.params;
1610 
1611 	if (this.getEncodedHexPrepare != undefined) {
1612 	    this.getEncodedHexPrepare();
1613 	}
1614 
1615 	if (params.fixed != true) {
1616 	    this.checkAndFixParam();
1617 	}
1618 
1619 	var a = [];
1620 
1621 	a.push(new _DERInteger({"int": params.version}));
1622 
1623 	var aHashAlg = [];
1624 	for (var i = 0; i < params.hashalgs.length; i++) {
1625 	    var name = params.hashalgs[i];
1626 	    aHashAlg.push(new _AlgorithmIdentifier({name: name}));
1627 	}
1628 	a.push(new _DERSet({array: aHashAlg}));
1629 
1630 	a.push(new _EncapsulatedContentInfo(params.econtent));
1631 
1632 	if (params.certs != undefined) {
1633 	    a.push(new _CertificateSet(params.certs));
1634 	}
1635 
1636 	if (params.revinfos != undefined) {
1637 	    a.push(new _RevocationInfoChoices(params.revinfos));
1638 	}
1639 
1640 	var aSignerInfo = [];
1641 	for (var i = 0; i < params.sinfos.length; i++) {
1642 	    var pSI = params.sinfos[i];
1643 	    aSignerInfo.push(new _SignerInfo(pSI));
1644 	}
1645 	a.push(new _DERSet({array: aSignerInfo}));
1646 
1647 	var seq = new _DERSequence({array: a});
1648 	return seq.getEncodedHex();
1649     };
1650 
1651     /**
1652      * get CotentInfo ASN.1 object concluding CMS SignedData<br/>
1653      * @name getContentInfo
1654      * @memberOf KJUR.asn1.cms.SignedData#
1655      * @function
1656      * @return {Object} ContentInfo of SigneData as {@link KJUR.asn1.ASN1Object}
1657      * @see KJUR.asn1.cms.ContentInfo
1658      *
1659      * @description
1660      * This method returns a {@link KJUR.asn1.ASN1Object}
1661      * of 
1662      * ContentInfo concludes SignedData.
1663      *
1664      * @example
1665      * sd = new KJUR.asn1.cms.SignedData({...});
1666      * sd.getContentInfo();
1667      */
1668     this.getContentInfo = function() {
1669 	var dContentInfo = new _ContentInfo({
1670 	    type: 'signed-data',
1671 	    obj: this
1672 	});
1673 	return dContentInfo;
1674     };
1675 
1676     /**
1677      * get hex of entire ContentInfo of CMS SignedData<br/>
1678      * @name getContentInfoEncodedHex
1679      * @memberOf KJUR.asn1.cms.SignedData#
1680      * @function
1681      * @return {String} hexadecimal string of entire ContentInfo of CMS SignedData
1682      * @see KJUR.asn1.cms.SignedData#getContentInfo
1683      * @see KJUR.asn1.cms.ContentInfo
1684      *
1685      * @description
1686      * This method returns a hexadecimal string of
1687      * ContentInfo concludes SignedData.
1688      *
1689      * @example
1690      * sd = new KJUR.asn1.cms.SignedData({...});
1691      * sd.getContentInfoEncodedHex() &rarr "3082..."
1692      */
1693     this.getContentInfoEncodedHex = function() {
1694 	return this.getContentInfo().getEncodedHex();
1695     };
1696 
1697     if (params != undefined) this.setByParam(params);
1698 };
1699 YAHOO.lang.extend(KJUR.asn1.cms.SignedData, KJUR.asn1.ASN1Object);
1700 
1701 /**
1702  * class for CertificateSet ASN.1 structure for CMS SignedData<br/>
1703  * @name KJUR.asn1.cms.CertificateSet
1704  * @class class for CertificateSet ASN.1 structure for CMS SignedData
1705  * @param {Array} params array of RevocationInfoChoice parameters
1706  * @extends KJUR.asn1.ASN1Object
1707  * @since jsrsasign 10.0.0 asn1cms 2.0.0
1708  * @see KJUR.asn1.cms.SignedData
1709  * @see KJUR.asn1.cms.RevocationInfoChoice
1710  *
1711  * @description
1712  * This is an ASN.1 encoder for CertificateSet
1713  * ASN.1 structure defined in
1714  * <a href="https://tools.ietf.org/html/rfc5652#section-10.2.3">
1715  * RFC 5652 CMS section 10.2.3</a> and 
1716  * <a href="https://tools.ietf.org/html/rfc5652#section-10.2.2">
1717  * section 10.2.2</a>.
1718  * <pre>
1719  * CertificateSet ::= SET OF CertificateChoices
1720  * CertificateChoices ::= CHOICE {
1721  *   certificate Certificate,
1722  *   extendedCertificate [0] IMPLICIT ExtendedCertificate, -- Obsolete
1723  *   v1AttrCert [1] IMPLICIT AttributeCertificateV1,       -- Obsolete
1724  *   v2AttrCert [2] IMPLICIT AttributeCertificateV2,
1725  *   other [3] IMPLICIT OtherCertificateFormat }
1726  * OtherCertificateFormat ::= SEQUENCE {
1727  *   otherCertFormat OBJECT IDENTIFIER,
1728  *   otherCert ANY DEFINED BY otherCertFormat }
1729  * </pre>
1730  * Currently only "certificate" is supported in
1731  * CertificateChoices.
1732  * 
1733  * @example
1734  * new KJUR.asn1.cms.CertificateSet([certpem1,certpem2,...])
1735  * new KJUR.asn1.cms.CertificateSet({
1736  *   array: [certpem1,certpem2,...],
1737  *   sortflag: false
1738  * })
1739  */
1740 KJUR.asn1.cms.CertificateSet = function(params) {
1741     KJUR.asn1.cms.CertificateSet.superclass.constructor.call(this);
1742 
1743     var _Error = Error,
1744 	_KJUR_asn1 = KJUR.asn1,
1745 	_DERTaggedObject = _KJUR_asn1.DERTaggedObject,
1746 	_DERSet = _KJUR_asn1.DERSet,
1747 	_ASN1Object = _KJUR_asn1.ASN1Object;
1748 
1749     this.params = null;
1750 
1751     this.getEncodedHex = function() {
1752 	var params = this.params;
1753 	var a = [];
1754 
1755 	var aParam;
1756 	if (params instanceof Array) {
1757 	    aParam = params;
1758 	} else if (params.array != undefined) {
1759 	    aParam = params.array;
1760 	} else {
1761 	    throw new _Error("cert array not specified");
1762 	}
1763 
1764 	for (var i = 0; i < aParam.length; i++) {
1765 	    var pem = aParam[i];
1766 	    var hCert = pemtohex(pem);
1767 	    var dCert = new _ASN1Object();
1768 	    dCert.hTLV = hCert;
1769 	    a.push(dCert);
1770 	}
1771 	var pSet = {array: a};
1772 	if (params.sortflag == false) pSet.sortflag = false;
1773 	var dSet = new _DERSet(pSet);
1774 
1775 	var dTagObj = new _DERTaggedObject({
1776 	    tag: "a0",
1777 	    explicit: false,
1778 	    obj: dSet
1779 	});
1780 	return dTagObj.getEncodedHex();
1781     };
1782 
1783     if (params != undefined) this.setByParam(params);
1784 };
1785 YAHOO.lang.extend(KJUR.asn1.cms.CertificateSet, KJUR.asn1.ASN1Object);
1786 
1787 /**
1788  * class for RevocationInfoChoices ASN.1 structure for CMS SignedData<br/>
1789  * @name KJUR.asn1.cms.RevocationInfoChoices
1790  * @class class for RevocationInfoChoices ASN.1 structure for CMS SignedData
1791  * @param {Array} params array of parameters
1792  * @extends KJUR.asn1.ASN1Object
1793  * @since jsrsasign 10.0.0 asn1cms 2.0.0
1794  * @see KJUR.asn1.cms.SignedData
1795  *
1796  * @description
1797  * This is an ASN.1 encoder for RevocationInfoChoices
1798  * ASN.1 structure defined in
1799  * <a href="https://tools.ietf.org/html/rfc5652#section-10.2.1">
1800  * RFC 5652 CMS section 10.2.1</a>.
1801  * <pre>
1802  * RevocationInfoChoices ::= SET OF RevocationInfoChoice
1803  * RevocationInfoChoice ::= CHOICE {
1804  *   crl CertificateList,
1805  *   other [1] IMPLICIT OtherRevocationInfoFormat }
1806  * OtherRevocationInfoFormat ::= SEQUENCE {
1807  *   otherRevInfoFormat OBJECT IDENTIFIER,
1808  *   otherRevInfo ANY DEFINED BY otherRevInfoFormat }
1809  * </pre>
1810  *
1811  * @example
1812  * new KJUR.asn1.cms.RevocationInfoChoices([
1813  *   {crl: CRLPEMorHex1},
1814  *   {ocsp: OCSPResponseHex1},
1815  *   ...
1816  * ]})
1817  */
1818 KJUR.asn1.cms.RevocationInfoChoices = function(params) {
1819     KJUR.asn1.cms.RevocationInfoChoices.superclass.constructor.call(this);
1820 
1821     this.params = null;
1822 
1823     this.getEncodedHex = function() {
1824 	var params = this.params;
1825 
1826 	if (! params instanceof Array)
1827 	    throw new Error("params is not array");
1828 
1829 	var a = [];
1830 	for (var i = 0; i < params.length; i++) {
1831 	    a.push(new KJUR.asn1.cms.RevocationInfoChoice(params[i]));
1832 	}
1833 	var dRevInfos = KJUR.asn1.ASN1Util.newObject({tag: {tagi:"a1",obj:{set:a}}});
1834 	return dRevInfos.getEncodedHex();
1835     };
1836 
1837     if (params != undefined) this.setByParam(params);
1838 };
1839 YAHOO.lang.extend(KJUR.asn1.cms.RevocationInfoChoices, KJUR.asn1.ASN1Object);
1840 
1841 /**
1842  * class for RevocationInfoChoice ASN.1 structure for CMS SignedData<br/>
1843  * @name KJUR.asn1.cms.RevocationInfoChoice
1844  * @class class for RevocationInfoChoice ASN.1 structure for CMS SignedData
1845  * @param {Array} params array of parameters
1846  * @extends KJUR.asn1.ASN1Object
1847  * @since jsrsasign 10.0.0 asn1cms 2.0.0
1848  * @see KJUR.asn1.cms.SignedData
1849  * @see KJUR.asn1.cms.RevocationInfoChoices
1850  *
1851  * @description
1852  * This is an ASN.1 encoder for RevocationInfoChoice
1853  * ASN.1 structure defined in
1854  * <a href="https://tools.ietf.org/html/rfc5652#section-10.2.1">
1855  * RFC 5652 CMS section 10.2.1</a>.
1856  * <pre>
1857  * RevocationInfoChoice ::= CHOICE {
1858  *   crl CertificateList,
1859  *   other [1] IMPLICIT OtherRevocationInfoFormat }
1860  * OtherRevocationInfoFormat ::= SEQUENCE {
1861  *   otherRevInfoFormat OBJECT IDENTIFIER,
1862  *   otherRevInfo ANY DEFINED BY otherRevInfoFormat }
1863  * </pre>
1864  *
1865  * @example
1866  * new KJUR.asn1.cms.RevocationInfoChoice({
1867  *   crl: CRLPEMorHex
1868  * })
1869  * new KJUR.asn1.cms.RevocationInfoChoice({
1870  *   ocsp: OCSPResponseHex
1871  * })
1872  */
1873 KJUR.asn1.cms.RevocationInfoChoice = function(params) {
1874     KJUR.asn1.cms.RevocationInfoChoice.superclass.constructor.call(this);
1875 
1876     this.params = null;
1877 
1878     this.getEncodedHex = function() {
1879 	var params = this.params;
1880 
1881 	if (params.crl != undefined && typeof params.crl == "string") {
1882 	    var hCRL = params.crl;
1883 	    if (params.crl.indexOf("-----BEGIN") != -1) {
1884 		hCRL = pemtohex(params.crl);
1885 	    }
1886 	    return hCRL;
1887 	} else if (params.ocsp != undefined) {
1888 	    var dTag1 = KJUR.asn1.ASN1Util.newObject({tag: {
1889 		tagi: "a1",
1890 		obj: new KJUR.asn1.cms.OtherRevocationFormat(params)
1891 	    }});
1892 	    return dTag1.getEncodedHex();
1893 	} else {
1894 	    throw new Error("property crl or ocsp undefined");
1895 	}
1896     };
1897 
1898     if (params != undefined) this.setByParam(params);
1899 };
1900 YAHOO.lang.extend(KJUR.asn1.cms.RevocationInfoChoice, KJUR.asn1.ASN1Object);
1901 
1902 /**
1903  * class for OtherRevocationFormat ASN.1 structure for CMS SignedData<br/>
1904  * @name KJUR.asn1.cms.OtherRevocationFormat
1905  * @class class for OtherRevocationFormat ASN.1 structure for CMS SignedData
1906  * @param {Array} params array of parameters
1907  * @extends KJUR.asn1.ASN1Object
1908  * @since jsrsasign 10.0.0 asn1cms 2.0.0
1909  * @see KJUR.asn1.cms.SignedData
1910  * @see KJUR.asn1.cms.RevocationInfoChoices
1911  * @see KJUR.asn1.cms.RevocationInfoChoice
1912  *
1913  * @description
1914  * This is an ASN.1 encoder for OtherRevocationFormat
1915  * ASN.1 structure defined in
1916  * <a href="https://tools.ietf.org/html/rfc5940">
1917  * RFC 5652</a>.
1918  * <pre>
1919  * OtherRevocationInfoFormat ::= SEQUENCE {
1920  *   otherRevInfoFormat  OBJECT IDENTIFIER,
1921  *   otherRevInfo        ANY DEFINED BY otherRevInfoFormat }
1922  * id-ri OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
1923  *   dod(6) internet(1) security(5) mechanisms(5) pkix(7) ri(16) }
1924  * id-ri-ocsp-response OBJECT IDENTIFIER ::= { id-ri 2 }
1925  * --  id-ri-ocsp-response 1.3.6.1.5.5.7.16.2
1926  * </pre>
1927  * NOTE: Currently this class only supports "ocsp"
1928  *
1929  * @example
1930  * new KJUR.asn1.cms.OtherRevocationFormat({
1931  *   ocsp: OCSPResponseHex
1932  * })
1933  */
1934 KJUR.asn1.cms.OtherRevocationFormat = function(params) {
1935     KJUR.asn1.cms.OtherRevocationFormat.superclass.constructor.call(this);
1936 
1937     var _Error = Error,
1938 	_KJUR = KJUR,
1939 	_KJUR_asn1 = _KJUR.asn1,
1940 	_newObject = _KJUR_asn1.ASN1Util.newObject,
1941 	_isHex = _KJUR.lang.String.isHex;
1942 
1943     this.params = null;
1944 
1945     this.getEncodedHex = function() {
1946 	var params = this.params;
1947 	if (params.ocsp == undefined)
1948 	    throw new _Error("property ocsp not specified");
1949 	if (! _isHex(params.ocsp) ||
1950 	    ! ASN1HEX.isASN1HEX(params.ocsp))
1951 	    throw new _Error("ocsp value not ASN.1 hex string");
1952 	
1953 	var dOtherRev = _newObject({
1954 	    seq: [
1955 		{oid: "1.3.6.1.5.5.7.16.2"},
1956 		{asn1: {tlv: params.ocsp}}
1957 	    ]
1958 	});
1959 	return dOtherRev.getEncodedHex();
1960     };
1961 
1962     if (params != undefined) this.setByParam(params);
1963 };
1964 YAHOO.lang.extend(KJUR.asn1.cms.OtherRevocationFormat, KJUR.asn1.ASN1Object);
1965 
1966 /**
1967  * CMS utiliteis class
1968  * @name KJUR.asn1.cms.CMSUtil
1969  * @class CMS utilities class
1970  */
1971 KJUR.asn1.cms.CMSUtil = new function() {
1972 };
1973 
1974 /**
1975  * generate SignedData object specified by JSON parameters (DEPRECATED)<br/>
1976  * @name newSignedData
1977  * @memberOf KJUR.asn1.cms.CMSUtil
1978  * @function
1979  * @param {Array} params JSON parameter to generate CMS SignedData
1980  * @return {KJUR.asn1.cms.SignedData} object just generated
1981  * @deprecated since jsrsasign 10.0.0 asn1cms 2.0.0. 
1982  *
1983  * @description
1984  * This class generates {@link KJUR.asn1.cms.SignedData} object.
1985  * However this class is deprecated.
1986  * Please use {@link KJUR.asn1.cms.SignedData} class constructor
1987  * instead. As for "params" parameter, 
1988  * {@link KJUR.asn1.cms.SignedData} parameters are available.
1989  */
1990 KJUR.asn1.cms.CMSUtil.newSignedData = function(param) {
1991     return new KJUR.asn1.cms.SignedData(param);
1992 };
1993 
1994 /**
1995  * verify SignedData specified by JSON parameters
1996  * @name verifySignedData
1997  * @memberOf KJUR.asn1.cms.CMSUtil
1998  * @function
1999  * @param {Array} param JSON parameter to verify CMS SignedData
2000  * @return {Object} JSON data as the result of validation
2001  * @since jsrsasign 8.0.4 asn1cms 1.0.5
2002  * @description
2003  * This method provides validation for CMS SignedData.
2004  * Following parameters can be applied:
2005  * <ul>
2006  * <li>cms - hexadecimal data of DER CMS SignedData (aka. PKCS#7 or p7s)</li>
2007  *     to verify (OPTION)</li>
2008  * </ul>
2009  * @example
2010  * KJUR.asn1.cms.CMSUtil.verifySignedData({ cms: "3082058a..." }) 
2011  * →
2012  * {
2013  *   isValid: true,
2014  *   parse: ... // parsed data
2015  *   signerInfos: [
2016  *     {
2017  *     }
2018  *   ]
2019  * }
2020  */
2021 KJUR.asn1.cms.CMSUtil.verifySignedData = function(param) {
2022     var _KJUR = KJUR,
2023 	_KJUR_asn1 = _KJUR.asn1,
2024 	_KJUR_asn1_cms = _KJUR_asn1.cms,
2025 	_SignerInfo = _KJUR_asn1_cms.SignerInfo,
2026 	_SignedData = _KJUR_asn1_cms.SignedData,
2027 	_SigningTime = _KJUR_asn1_cms.SigningTime,
2028 	_SigningCertificate = _KJUR_asn1_cms.SigningCertificate,
2029 	_SigningCertificateV2 = _KJUR_asn1_cms.SigningCertificateV2,
2030 	_KJUR_asn1_cades = _KJUR_asn1.cades,
2031 	_SignaturePolicyIdentifier = _KJUR_asn1_cades.SignaturePolicyIdentifier,
2032 	_isHex = _KJUR.lang.String.isHex,
2033 	_ASN1HEX = ASN1HEX,
2034 	_getVbyList = _ASN1HEX.getVbyList,
2035 	_getTLVbyList = _ASN1HEX.getTLVbyList,
2036 	_getIdxbyList = _ASN1HEX.getIdxbyList,
2037 	_getChildIdx = _ASN1HEX.getChildIdx,
2038 	_getTLV = _ASN1HEX.getTLV,
2039 	_oidname = _ASN1HEX.oidname,
2040 	_hashHex = _KJUR.crypto.Util.hashHex;
2041 
2042     if (param.cms === undefined &&
2043         ! _isHex(param.cms)) {
2044     }
2045 
2046     var hCMS = param.cms;
2047 
2048     var _findSignerInfos = function(hCMS, result) {
2049 	var idx;
2050 	for (var i = 3; i < 6; i++) {
2051 	    idx = _getIdxbyList(hCMS, 0, [1, 0, i]);
2052 	    if (idx !== undefined) {
2053 		var tag = hCMS.substr(idx, 2);
2054 		if (tag === "a0") result.certsIdx = idx;
2055 		if (tag === "a1") result.revinfosIdx = idx;
2056 		if (tag === "31") result.signerinfosIdx = idx;
2057 	    }
2058 	}
2059     };
2060 
2061     var _parseSignerInfos = function(hCMS, result) {
2062 	var idxSignerInfos = result.signerinfosIdx;
2063 	if (idxSignerInfos === undefined) return;
2064 	var idxList = _getChildIdx(hCMS, idxSignerInfos);
2065 	result.signerInfoIdxList = idxList;
2066 	for (var i = 0; i < idxList.length; i++) {
2067 	    var idxSI = idxList[i];
2068 	    var info = { idx: idxSI };
2069 	    _parseSignerInfo(hCMS, info);
2070 	    result.signerInfos.push(info);
2071 	};
2072     };
2073 
2074     var _parseSignerInfo = function(hCMS, info) {
2075 	var idx = info.idx;
2076 
2077 	// 1. signer identifier
2078 	info.signerid_issuer1 = _getTLVbyList(hCMS, idx, [1, 0], "30");
2079 	info.signerid_serial1 = _getVbyList(hCMS, idx, [1, 1], "02");
2080 
2081 	// 2. hash alg
2082 	info.hashalg = _oidname(_getVbyList(hCMS, idx, [2, 0], "06"));
2083 
2084 	// 3. [0] singedAtttrs
2085 	var idxSignedAttrs = _getIdxbyList(hCMS, idx, [3], "a0");
2086 	info.idxSignedAttrs = idxSignedAttrs;
2087 	_parseSignedAttrs(hCMS, info, idxSignedAttrs);
2088 
2089 	var aIdx = _getChildIdx(hCMS, idx);
2090 	var n = aIdx.length;
2091 	if (n < 6) throw "malformed SignerInfo";
2092 	
2093 	info.sigalg = _oidname(_getVbyList(hCMS, idx, [n - 2, 0], "06"));
2094 	info.sigval = _getVbyList(hCMS, idx, [n - 1], "04");
2095 	//info.sigval = _getVbyList(hCMS, 0, [1, 0, 4, 0, 5], "04");
2096 	//info.sigval = hCMS;
2097     };
2098 
2099     var _parseSignedAttrs = function(hCMS, info, idx) {
2100 	var aIdx = _getChildIdx(hCMS, idx);
2101 	info.signedAttrIdxList = aIdx;
2102 	for (var i = 0; i < aIdx.length; i++) {
2103 	    var idxAttr = aIdx[i];
2104 	    var hAttrType = _getVbyList(hCMS, idxAttr, [0], "06");
2105 	    var v;
2106 
2107 	    if (hAttrType === "2a864886f70d010905") { // siging time
2108 		v = hextoutf8(_getVbyList(hCMS, idxAttr, [1, 0]));
2109 		info.saSigningTime = v;
2110 	    } else if (hAttrType === "2a864886f70d010904") { // message digest
2111 		v = _getVbyList(hCMS, idxAttr, [1, 0], "04");
2112 		info.saMessageDigest = v;
2113 	    }
2114 	}
2115     };
2116 
2117     var _parseSignedData = function(hCMS, result) {
2118 	// check if signedData (1.2.840.113549.1.7.2) type
2119 	if (_getVbyList(hCMS, 0, [0], "06") !== "2a864886f70d010702") {
2120 	    return result;
2121 	}
2122 	result.cmsType = "signedData";
2123 
2124 	// find eContent data
2125 	result.econtent = _getVbyList(hCMS, 0, [1, 0, 2, 1, 0]);
2126 
2127 	// find certificates,revInfos,signerInfos index
2128 	_findSignerInfos(hCMS, result);
2129 
2130 	result.signerInfos = [];
2131 	_parseSignerInfos(hCMS, result);
2132     };
2133 
2134     var _verify = function(hCMS, result) {
2135 	var aSI = result.parse.signerInfos;
2136 	var n = aSI.length;
2137 	var isValid = true;
2138 	for (var i = 0; i < n; i++) {
2139 	    var si = aSI[i];
2140 	    _verifySignerInfo(hCMS, result, si, i);
2141 	    if (! si.isValid)
2142 		isValid = false;
2143 	}
2144 	result.isValid = isValid;
2145     };
2146 
2147     /*
2148      * _findCert
2149      * 
2150      * @param hCMS {String} hexadecimal string of CMS signed data
2151      * @param result {Object} JSON object of validation result
2152      * @param si {Object} JSON object of signerInfo in the result above
2153      * @param idx {Number} index of signerInfo???
2154      */
2155     var _findCert = function(hCMS, result, si, idx) {
2156 	var certsIdx = result.parse.certsIdx;
2157 	var aCert;
2158 
2159 	if (result.certs === undefined) {
2160 	    aCert = [];
2161 	    result.certkeys = [];
2162 	    var aIdx = _getChildIdx(hCMS, certsIdx);
2163 	    for (var i = 0; i < aIdx.length; i++) {
2164 		var hCert = _getTLV(hCMS, aIdx[i]);
2165 		var x = new X509();
2166 		x.readCertHex(hCert);
2167 		aCert[i] = x;
2168 		result.certkeys[i] = x.getPublicKey();
2169 	    }
2170 	    result.certs = aCert;
2171 	} else {
2172 	    aCert = result.certs;
2173 	}
2174 
2175 	result.cccc = aCert.length;
2176 	result.cccci = aIdx.length;
2177 
2178 	for (var i = 0; i < aCert.length; i++) {
2179 	    var issuer2 = x.getIssuerHex();
2180 	    var serial2 = x.getSerialNumberHex();
2181 	    if (si.signerid_issuer1 === issuer2 &&
2182 		si.signerid_serial1 === serial2) {
2183 		si.certkey_idx = i;
2184 	    }
2185 	}
2186     };
2187 
2188     var _verifySignerInfo = function(hCMS, result, si, idx) {
2189 	si.verifyDetail = {};
2190 
2191 	var _detail = si.verifyDetail;
2192 
2193 	var econtent = result.parse.econtent;
2194 
2195 	// verify MessageDigest signed attribute
2196 	var hashalg = si.hashalg;
2197 	var saMessageDigest = si.saMessageDigest;
2198 	
2199 	// verify messageDigest
2200 	_detail.validMessageDigest = false;
2201 	//_detail._econtent = econtent;
2202 	//_detail._hashalg = hashalg;
2203 	//_detail._saMD = saMessageDigest;
2204 	if (_hashHex(econtent, hashalg) === saMessageDigest)
2205 	    _detail.validMessageDigest = true;
2206 
2207 	// find signing certificate
2208 	_findCert(hCMS, result, si, idx);
2209 	//if (si.signerid_cert === undefined)
2210 	//    throw Error("can't find signer certificate");
2211 
2212 	// verify signature value
2213 	_detail.validSignatureValue = false;
2214 	var sigalg = si.sigalg;
2215 	var hSignedAttr = "31" + _getTLV(hCMS, si.idxSignedAttrs).substr(2);
2216 	si.signedattrshex = hSignedAttr;
2217 	var pubkey = result.certs[si.certkey_idx].getPublicKey();
2218 	var sig = new KJUR.crypto.Signature({alg: sigalg});
2219 	sig.init(pubkey);
2220 	sig.updateHex(hSignedAttr);
2221 	var isValid = sig.verify(si.sigval);
2222 	_detail.validSignatureValue_isValid = isValid;
2223 	if (isValid === true)
2224 	    _detail.validSignatureValue = true;
2225 
2226 	// verify SignerInfo totally
2227 	si.isValid =false;
2228 	if (_detail.validMessageDigest &&
2229 	    _detail.validSignatureValue) {
2230 	    si.isValid = true;
2231 	}
2232     };
2233 
2234     var _findSignerCert = function() {
2235     };
2236 
2237     var result = { isValid: false, parse: {} };
2238     _parseSignedData(hCMS, result.parse);
2239 
2240     _verify(hCMS, result);
2241     
2242     return result;
2243 };
2244 
2245 /**
2246  * class for parsing CMS SignedData<br/>
2247  * @name KJUR.asn1.cms.CMSParser
2248  * @class CMS SignedData parser class
2249  * @since jsrsasign 10.1.0 asn1cms 2.0.1
2250  *
2251  * @description
2252  * This is an ASN.1 parser for CMS SignedData defined in
2253  * <a href="https://tools.ietf.org/html/rfc5652">RFC 5652
2254  * Cryptographic Message Syntax (CMS)</a>.
2255  * <pre>
2256  * ContentInfo ::= SEQUENCE {
2257  *    contentType ContentType,
2258  *    content [0] EXPLICIT ANY DEFINED BY contentType }
2259  * ContentType ::= OBJECT IDENTIFIER
2260  * SignedData ::= SEQUENCE {
2261  *    version CMSVersion,
2262  *    digestAlgorithms DigestAlgorithmIdentifiers,
2263  *    encapContentInfo EncapsulatedContentInfo,
2264  *    certificates [0] IMPLICIT CertificateSet OPTIONAL,
2265  *    crls [1] IMPLICIT RevocationInfoChoices OPTIONAL,
2266  *    signerInfos SignerInfos }
2267  * SignerInfos ::= SET OF SignerInfo
2268  * CertificateSet ::= SET OF CertificateChoices
2269  * DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier
2270  * CertificateSet ::= SET OF CertificateChoices
2271  * RevocationInfoChoices ::= SET OF RevocationInfoChoice
2272  * </pre>
2273  */
2274 KJUR.asn1.cms.CMSParser = function() {
2275     var _Error = Error,
2276 	_X509 = X509,
2277 	_x509obj = new _X509(),
2278 	_ASN1HEX = ASN1HEX,
2279 	_getV = _ASN1HEX.getV,
2280 	_getTLV = _ASN1HEX.getTLV,
2281 	_getIdxbyList = _ASN1HEX.getIdxbyList,
2282 	_getTLVbyList = _ASN1HEX.getTLVbyList,
2283 	_getTLVbyListEx = _ASN1HEX.getTLVbyListEx,
2284 	_getVbyList = _ASN1HEX.getVbyList,
2285 	_getVbyListEx = _ASN1HEX.getVbyListEx,
2286 	_getChildIdx = _ASN1HEX.getChildIdx;
2287 
2288     /**
2289      * parse ASN.1 ContentInfo with SignedData<br/>
2290      * @name getCMSSignedData
2291      * @memberOf KJUR.asn1.cms.CMSParser#
2292      * @function
2293      * @param {String} h hexadecimal string of ASN.1 ContentInfo with SignedData
2294      * @return {Array} array of JSON object of SignedData parameter
2295      * @see KJUR.asn1.cms.SignedData
2296      * @see KJUR.asn1.cms.CMSParser#getSignedData
2297      *
2298      * @description
2299      * This method parses ASN.1 ContentInfo with SignedData defined in 
2300      * RFC 5652 
2301      * <a href="https://tools.ietf.org/html/rfc5652#section-3">section 3</a>
2302      * and 
2303      * <a href="https://tools.ietf.org/html/rfc5652#section-5">section 5</a>.
2304      * The result parameter can be passed to
2305      * {@link KJUR.asn1.cms.SignedData} constructor.
2306      * 
2307      * @example
2308      * parser = new KJUR.asn1.cms.CMSParser();
2309      * parser.getCMSSignedData("30...") →
2310      * {
2311      *   version: 1,
2312      *   hashalgs: ["sha1"],
2313      *   econtent: {
2314      *     type: "data",
2315      *     content: {hex:"616161"}
2316      *   },
2317      *   certs: [PEM1,...],
2318      *   sinfos: [{
2319      *     version: 1,
2320      *     id: {type:'isssn',issuer:{str:'/C=US/O=T1'},serial:{int: 1}},
2321      *     hashalg: "sha1",
2322      *     sattrs: {array: [{
2323      *       attr: "contentType",
2324      *       type: '1.2.840.113549.1.7.1'
2325      *     },{
2326      *       attr: "messageDigest",
2327      *       hex: 'abcd'
2328      *     }]},
2329      *     sigalg: "SHA1withRSA",
2330      *     sighex: "1234abcd..."
2331      *   }]
2332      * }
2333      */
2334     this.getCMSSignedData = function(h) {
2335 	var hSignedData = _getTLVbyList(h, 0, [1, 0]);
2336 	var pResult = this.getSignedData(hSignedData);
2337 	return pResult;
2338     };
2339 
2340     /**
2341      * parse ASN.1 SignedData<br/>
2342      * @name getSignedData
2343      * @memberOf KJUR.asn1.cms.CMSParser#
2344      * @function
2345      * @param {String} h hexadecimal string of ASN.1 SignedData
2346      * @return {Array} array of JSON object of SignedData parameter
2347      * @see KJUR.asn1.cms.SignedData
2348      * @see KJUR.asn1.cms.CMSParser#getSignedData
2349      *
2350      * @description
2351      * This method parses ASN.1 SignedData defined in 
2352      * RFC 5652 
2353      * <a href="https://tools.ietf.org/html/rfc5652#section-5">section 5</a>.
2354      * The result parameter can be passed to
2355      * {@link KJUR.asn1.cms.SignedData} constructor.
2356      * 
2357      * @example
2358      * parser = new KJUR.asn1.cms.CMSParser();
2359      * parser.getSignedData("30...")
2360      */
2361     this.getSignedData = function(h) {
2362 	var aIdx = _getChildIdx(h, 0);
2363 	var pResult = {};
2364 
2365 	var hVersion = _getV(h, aIdx[0]);
2366 	var iVersion = parseInt(hVersion, 16);
2367 	pResult.version = iVersion;
2368 	
2369 	var hHashAlgs = _getTLV(h, aIdx[1]);
2370 	pResult.hashalgs = this.getHashAlgArray(hHashAlgs);
2371 
2372 	var hEContent = _getTLV(h, aIdx[2]);
2373 	pResult.econtent = this.getEContent(hEContent);
2374 
2375 	var hCerts = _getTLVbyListEx(h, 0, ["[0]"]);
2376 	if (hCerts != null) {
2377 	    pResult.certs = this.getCertificateSet(hCerts);
2378 	}
2379 
2380 	// RevocationInfoChoices not supported yet
2381 	var hRevInfos = _getTLVbyListEx(h, 0, ["[1]"]);
2382 	if (hRevInfos != null) {
2383 	}
2384 
2385 	var hSignerInfos = _getTLVbyListEx(h, 0, [3]);
2386 	pResult.sinfos = this.getSignerInfos(hSignerInfos);
2387 
2388 	return pResult;
2389     };
2390 
2391     /**
2392      * parse ASN.1 DigestAlgorithmIdentifiers<br/>
2393      * @name getHashAlgArray
2394      * @memberOf KJUR.asn1.cms.CMSParser#
2395      * @function
2396      * @param {String} h hexadecimal string of ASN.1 DigestAlgorithmIdentifiers
2397      * @return {Array} array of JSON object of digest algorithm names
2398      * @see KJUR.asn1.cms.SignedData
2399      * @see KJUR.asn1.cms.CMSParser#getSignedData
2400      *
2401      * @description
2402      * This method parses ASN.1 SignedData defined in 
2403      * RFC 5652 
2404      * <a href="https://tools.ietf.org/html/rfc5652#section-5.1">
2405      * section 5.1</a>.
2406      * 
2407      * @example
2408      * parser = new KJUR.asn1.cms.CMSParser();
2409      * parser.getHashAlgArray("30...") → ["sha256"]
2410      */
2411     this.getHashAlgArray = function(h) {
2412 	var aIdx = _getChildIdx(h, 0);
2413 	var x = new _X509();
2414 	var a = [];
2415 	for (var i = 0; i < aIdx.length; i++) {
2416 	    var hAlg = _getTLV(h, aIdx[i]);
2417 	    var sAlg = x.getAlgorithmIdentifierName(hAlg);
2418 	    a.push(sAlg);
2419 	}
2420 	return a;
2421     };
2422 
2423     /**
2424      * parse ASN.1 EncapsulatedContentInfo<br/>
2425      * @name getEContent
2426      * @memberOf KJUR.asn1.cms.CMSParser#
2427      * @function
2428      * @param {String} h hexadecimal string of ASN.1 EncapsulatedContentInfo
2429      * @return {Array} array of JSON object of EncapsulatedContentInfo parameter
2430      * @see KJUR.asn1.cms.EncapsulatedContentInfo
2431      * @see KJUR.asn1.cms.CMSParser#getSignedData
2432      *
2433      * @description
2434      * This method parses ASN.1 SignedData defined in 
2435      * RFC 5652 
2436      * <a href="https://tools.ietf.org/html/rfc5652#section-5.1">
2437      * section 5</a>.
2438      * The result parameter can be passed to
2439      * {@link KJUR.asn1.cms.EncapsulatedContentInfo} constructor.
2440      * 
2441      * @example
2442      * parser = new KJUR.asn1.cms.CMSParser();
2443      * parser.getEContent("30...") →
2444      * {type: "tstinfo", content: {hex: "30..."}}
2445      */
2446     this.getEContent = function(h) {
2447 	var pResult = {};
2448 	var hType = _getVbyList(h, 0, [0]);
2449 	var hContent = _getVbyList(h, 0, [1, 0]);
2450 	pResult.type = KJUR.asn1.x509.OID.oid2name(ASN1HEX.hextooidstr(hType));
2451 	pResult.content = {hex: hContent};
2452 	return pResult;
2453     };
2454 
2455     /**
2456      * parse ASN.1 SignerInfos<br/>
2457      * @name getSignerInfos
2458      * @memberOf KJUR.asn1.cms.CMSParser#
2459      * @function
2460      * @param {String} h hexadecimal string of ASN.1 SignerInfos
2461      * @return {Array} array of JSON object of SignerInfos parameter
2462      * @see KJUR.asn1.cms.SignerInfos
2463      * @see KJUR.asn1.cms.CMSParser#getSignedData
2464      *
2465      * @description
2466      * This method parses ASN.1 SignerInfos defined in 
2467      * RFC 5652 
2468      * <a href="https://tools.ietf.org/html/rfc5652#section-5.1">
2469      * section 5</a>.
2470      * 
2471      * @example
2472      * parser = new KJUR.asn1.cms.CMSParser();
2473      * parser.getSignerInfos("30...") →
2474      * [{
2475      *   version: 1,
2476      *   id: {type: 'isssn', issuer: {str: '/C=US/O=T1'}, serial: {int: 1}},
2477      *   hashalg: "sha1",
2478      *   sattrs: {array: [{
2479      *     attr: "contentType",
2480      *     type: '1.2.840.113549.1.7.1'
2481      *   },{
2482      *     attr: "messageDigest",
2483      *     hex: 'a1a2a3a4a5a6a7a8a9a0a1a2a3a4a5a6a7a8a9a0'
2484      *   }]},
2485      *   sigalg: "SHA1withRSA",
2486      *   sighex: 'b1b2b...'
2487      * }]
2488      */
2489     this.getSignerInfos = function(h) {
2490 	var aResult = [];
2491 
2492 	var aIdx = _getChildIdx(h, 0);
2493 	for (var i = 0; i < aIdx.length; i++) {
2494 	    var hSignerInfo = _getTLV(h, aIdx[i]);
2495 	    var pSignerInfo = this.getSignerInfo(hSignerInfo);
2496 	    aResult.push(pSignerInfo);
2497 	}
2498 
2499 	return aResult;
2500     };
2501 
2502     /**
2503      * parse ASN.1 SignerInfo<br/>
2504      * @name getSignerInfo
2505      * @memberOf KJUR.asn1.cms.CMSParser#
2506      * @function
2507      * @param {String} h hexadecimal string of ASN.1 SignerInfo
2508      * @return {Array} array of JSON object of SignerInfo parameter
2509      * @see KJUR.asn1.cms.SignerInfo
2510      * @see KJUR.asn1.cms.CMSParser#getSignedData
2511      *
2512      * @description
2513      * This method parses ASN.1 SignerInfos defined in 
2514      * RFC 5652 
2515      * <a href="https://tools.ietf.org/html/rfc5652#section-5.1">
2516      * section 5</a>.
2517      * <pre>
2518      * SignerInfo ::= SEQUENCE {
2519      *    version CMSVersion,
2520      *    sid SignerIdentifier,
2521      *    digestAlgorithm DigestAlgorithmIdentifier,
2522      *    signedAttrs [0] IMPLICIT SignedAttributes OPTIONAL,
2523      *    signatureAlgorithm SignatureAlgorithmIdentifier,
2524      *    signature SignatureValue,
2525      *    unsignedAttrs [1] IMPLICIT UnsignedAttributes OPTIONAL }
2526      * </pre>
2527      * The result parameter can be passed to
2528      * {@link KJUR.asn1.cms.SignerInfo} constructor.
2529      * 
2530      * @example
2531      * parser = new KJUR.asn1.cms.CMSParser();
2532      * parser.getSignerInfos("30...") →
2533      * [{
2534      *   version: 1,
2535      *   id: {type: 'isssn', issuer: {str: '/C=US/O=T1'}, serial: {int: 1}},
2536      *   hashalg: "sha1",
2537      *   sattrs: {array: [{
2538      *     attr: "contentType",
2539      *     type: '1.2.840.113549.1.7.1'
2540      *   },{
2541      *     attr: "messageDigest",
2542      *     hex: 'a1a2a3a4a5a6a7a8a9a0a1a2a3a4a5a6a7a8a9a0'
2543      *   }]},
2544      *   sigalg: "SHA1withRSA",
2545      *   sighex: 'b1b2b...'
2546      * }]
2547      */
2548     this.getSignerInfo = function(h) {
2549 	var pResult = {};
2550 	var aIdx = _getChildIdx(h, 0);
2551 
2552 	var iVersion = _ASN1HEX.getInt(h, aIdx[0], -1);
2553 	if (iVersion != -1) pResult.version = iVersion;
2554 
2555 	var hSI = _getTLV(h, aIdx[1]);
2556 	var pSI = this.getIssuerAndSerialNumber(hSI);
2557 	pResult.id = pSI;
2558 
2559 	var hAlg = _getTLV(h, aIdx[2]);
2560 	//alert(hAlg);
2561 	var sAlg = _x509obj.getAlgorithmIdentifierName(hAlg);
2562 	pResult.hashalg = sAlg;
2563 
2564 	var hSattrs = _getTLVbyListEx(h, 0, ["[0]"]);
2565 	if (hSattrs != null) {
2566 	    var aSattrs = this.getAttributeList(hSattrs);
2567 	    pResult.sattrs = aSattrs;
2568 	}
2569 
2570 	var hSigAlg = _getTLVbyListEx(h, 0, [3]);
2571 	var sSigAlg = _x509obj.getAlgorithmIdentifierName(hSigAlg);
2572 	pResult.sigalg = sSigAlg;
2573 
2574 	var hSigHex = _getVbyListEx(h, 0, [4]);
2575 	pResult.sighex = hSigHex;
2576 
2577 	var hUattrs = _getTLVbyListEx(h, 0, ["[1]"]);
2578 	if (hUattrs != null) {
2579 	    var aUattrs = this.getAttributeList(hUattrs);
2580 	    pResult.uattrs = aUattrs;
2581 	}
2582 
2583 	return pResult;
2584     };
2585 
2586     /**
2587      * parse ASN.1 SignerIdentifier<br/>
2588      * @name getSignerIdentifier
2589      * @memberOf KJUR.asn1.cms.CMSParser#
2590      * @function
2591      * @param {String} h hexadecimal string of ASN.1 SignerIdentifier
2592      * @return {Array} array of JSON object of SignerIdentifier parameter
2593      * @see KJUR.asn1.cms.SignerInfo
2594      * @see KJUR.asn1.cms.SignerIdentifier
2595      * @see KJUR.asn1.cms.CMSParser#getSignedData
2596      *
2597      * @description
2598      * This method parses ASN.1 SignerIdentifier defined in 
2599      * RFC 5652 
2600      * <a href="https://tools.ietf.org/html/rfc5652#section-5.1">
2601      * section 5</a>.
2602      * 
2603      * @example
2604      * parser = new KJUR.asn1.cms.CMSParser();
2605      * parser.getSignerIdentifier("30...") →
2606      * { type: "isssn",
2607      *   issuer: {
2608      *     array: [[{type:"C",value:"JP",ds:"prn"},...]]
2609      *     str: '/C=US/O=T1'
2610      *   },
2611      *   serial: {int: 1} }
2612      */
2613     this.getSignerIdentifier = function(h) {
2614 	if (h.substr(0, 2) == "30") {
2615 	    return this.getIssuerAndSerialNumber(h);
2616 	} else {
2617 	    throw new Error("SKID of signerIdentifier not supported");
2618 	}
2619     };
2620 
2621     /**
2622      * parse ASN.1 IssuerAndSerialNumber<br/>
2623      * @name getIssuerAndSerialNumber
2624      * @memberOf KJUR.asn1.cms.CMSParser#
2625      * @function
2626      * @param {String} h hexadecimal string of ASN.1 IssuerAndSerialNumber
2627      * @return {Array} array of JSON object of IssuerAndSerialNumber parameter
2628      * @see KJUR.asn1.cms.SignerInfo
2629      * @see KJUR.asn1.cms.CMSParser#getSignedData
2630      *
2631      * @description
2632      * This method parses ASN.1 IssuerAndSerialNumber defined in 
2633      * RFC 5652 
2634      * <a href="https://tools.ietf.org/html/rfc5652#section-5.1">
2635      * section 5</a>.
2636      * 
2637      * @example
2638      * parser = new KJUR.asn1.cms.CMSParser();
2639      * parser.getIssuerAndSerialNumber("30...") →
2640      * { type: "isssn",
2641      *   issuer: {
2642      *     array: [[{type:"C",value:"JP",ds:"prn"},...]]
2643      *     str: '/C=US/O=T1'
2644      *   },
2645      *   serial: {int: 1} }
2646      */
2647     this.getIssuerAndSerialNumber = function(h) {
2648 	var pResult = {type: "isssn"};
2649 
2650 	var aIdx = _getChildIdx(h, 0);
2651 
2652 	var hName = _getTLV(h, aIdx[0]);
2653 	pResult.issuer = _x509obj.getX500Name(hName);
2654 
2655 	var hSerial = _getV(h, aIdx[1]);
2656 	pResult.serial = {hex: hSerial};
2657 
2658 	return pResult;
2659     };
2660 
2661     /**
2662      * parse ASN.1 SET OF Attributes<br/>
2663      * @name getAttributeList
2664      * @memberOf KJUR.asn1.cms.CMSParser#
2665      * @function
2666      * @param {String} h hexadecimal string of ASN.1 SET OF Attribute
2667      * @return {Array} array of JSON object of Attribute parameter
2668      * @see KJUR.asn1.cms.SignerInfo
2669      * @see KJUR.asn1.cms.CMSParser#getAttribute
2670      *
2671      * @description
2672      * This method parses ASN.1 SET OF Attribute defined in 
2673      * RFC 5652 
2674      * <a href="https://tools.ietf.org/html/rfc5652#section-5.1">
2675      * section 5</a>.
2676      * This can be used for SignedAttributes and UnsignedAttributes.
2677      * 
2678      * @example
2679      * parser = new KJUR.asn1.cms.CMSParser();
2680      * parser.getAttributeList("30...") →
2681      * [{attr: "contentType", type: "tstinfo"},
2682      *  {attr: "messageDigest", hex: "1234abcd..."}]
2683      */
2684     this.getAttributeList = function(h) {
2685 	var a = [];
2686 
2687 	var aIdx = _getChildIdx(h, 0);
2688 	for (var i = 0; i < aIdx.length; i++) {
2689 	    var hAttr = _getTLV(h, aIdx[i]);
2690 	    var pAttr = this.getAttribute(hAttr);
2691 	    a.push(pAttr);
2692 	}
2693 
2694 	return {array: a};
2695     };
2696 
2697     /**
2698      * parse ASN.1 Attributes<br/>
2699      * @name getAttribute
2700      * @memberOf KJUR.asn1.cms.CMSParser#
2701      * @function
2702      * @param {String} h hexadecimal string of ASN.1 Attribute
2703      * @return {Array} array of JSON object of Attribute parameter
2704      * @see KJUR.asn1.cms.SignerInfo
2705      * @see KJUR.asn1.cms.CMSParser#getAttributeList
2706      *
2707      * @description
2708      * This method parses ASN.1 Attribute defined in 
2709      * RFC 5652 
2710      * <a href="https://tools.ietf.org/html/rfc5652#section-5.1">
2711      * section 5</a>.
2712      * Following attribute type are supported in the
2713      * latest version:
2714      * <ul>
2715      * <li>contentType - {@link KJUR.asn1.cms.CMSParser.setContentType}</li>
2716      * <li>messageDigest - {@link KJUR.asn1.cms.CMSParser.setMessageDigest}</li>
2717      * <li>signingTime - {@link KJUR.asn1.cms.CMSParser.setSigningTime}</li>
2718      * <li>signingCertificate - {@link KJUR.asn1.cms.CMSParser.setSigningCertificate}</li>
2719      * <li>signingCertificateV2 - {@link KJUR.asn1.cms.CMSParser.setSigningCertificateV2}</li>
2720      * </ul>
2721      * 
2722      * @example
2723      * parser = new KJUR.asn1.cms.CMSParser();
2724      * parser.getAttribute("30...") →
2725      * {attr: "contentType", type: "tstinfo"}
2726      */
2727     this.getAttribute = function(h) {
2728 	var pResult = {};
2729 	var aIdx = _getChildIdx(h, 0);
2730 
2731 	var attrTypeOID = _ASN1HEX.getOID(h, aIdx[0]);
2732 	var attrType = KJUR.asn1.x509.OID.oid2name(attrTypeOID);
2733 	pResult.attr = attrType;
2734 
2735 	var hSet = _getTLV(h, aIdx[1]);
2736 	var aSetIdx = _getChildIdx(hSet, 0);
2737 	if (aSetIdx.length == 1) {
2738 	    pResult.valhex = _getTLV(hSet, aSetIdx[0]);
2739 	} else {
2740 	    var a = [];
2741 	    for (var i = 0; i < aSetIdx.length; i++) {
2742 		a.push(_getTLV(hSet, aSetIdx[i]));
2743 	    }
2744 	    pResult.valhex = a;
2745 	}
2746 
2747 	if (attrType == "contentType") {
2748 	    this.setContentType(pResult);
2749 	} else if (attrType == "messageDigest") {
2750 	    this.setMessageDigest(pResult);
2751 	} else if (attrType == "signingTime") {
2752 	    this.setSigningTime(pResult);
2753 	} else if (attrType == "signingCertificate") {
2754 	    this.setSigningCertificate(pResult);
2755 	} else if (attrType == "signingCertificateV2") {
2756 	    //alert(pResult.valhex);
2757 	    this.setSigningCertificateV2(pResult);
2758 	}
2759 
2760 	return pResult;
2761     };
2762 
2763     /**
2764      * set ContentType attribute<br/>
2765      * @name setContentType
2766      * @memberOf KJUR.asn1.cms.CMSParser#
2767      * @function
2768      * @param {Array} pAttr JSON object of attribute parameter
2769      * @see KJUR.asn1.cms.CMSParser#getAttribute
2770      *
2771      * @description
2772      * This sets an attribute as ContentType defined in
2773      * RFC 5652 
2774      * <a href="https://tools.ietf.org/html/rfc5652#section-5.1">
2775      * section 5</a>.
2776      *
2777      * @example
2778      * parser = new KJUR.asn1.cms.CMSParser();
2779      * pAttr = {
2780      *   attr: "contentType"
2781      *   valhex: '060b2a864886f70d0109100104'
2782      * };
2783      * parser.setContentInfo(pAttr);
2784      * pAttr → {
2785      *   attr: "contentType"
2786      *   type: "tstinfo"
2787      * }
2788      */
2789     this.setContentType = function(pAttr) {
2790 	var contentType = _ASN1HEX.getOIDName(pAttr.valhex, 0, null);
2791 	if (contentType != null) {
2792 	    pAttr.type = contentType;
2793 	    delete pAttr.valhex;
2794 	}
2795     };
2796 
2797     /**
2798      * set SigningTime attribute<br/>
2799      * @name setSigningTime
2800      * @memberOf KJUR.asn1.cms.CMSParser#
2801      * @function
2802      * @param {Array} pAttr JSON object of attribute parameter
2803      * @see KJUR.asn1.cms.CMSParser#getAttribute
2804      *
2805      * @description
2806      * This sets an attribute as SigningTime defined in
2807      * RFC 5652 
2808      * <a href="https://tools.ietf.org/html/rfc5652#section-5.1">
2809      * section 5</a>.
2810      *
2811      * @example
2812      * parser = new KJUR.asn1.cms.CMSParser();
2813      * pAttr = {
2814      *   attr: "signingTime"
2815      *   valhex: '170d3230313233313233353935395a'
2816      * };
2817      * parser.setSigningTime(pAttr);
2818      * pAttr → {
2819      *   attr: "signingTime",
2820      *   str: "2012315959Z"
2821      * }
2822      */
2823     this.setSigningTime = function(pAttr) {
2824 	var hSigningTime = _getV(pAttr.valhex, 0);
2825 	var signingTime = hextoutf8(hSigningTime);
2826 	pAttr.str = signingTime;
2827 	delete pAttr.valhex;
2828     };
2829 
2830     /**
2831      * set MessageDigest attribute<br/>
2832      * @name setMessageDigest
2833      * @memberOf KJUR.asn1.cms.CMSParser#
2834      * @function
2835      * @param {Array} pAttr JSON object of attribute parameter
2836      * @see KJUR.asn1.cms.CMSParser#getAttribute
2837      *
2838      * @description
2839      * This sets an attribute as SigningTime defined in
2840      * RFC 5652 
2841      * <a href="https://tools.ietf.org/html/rfc5652#section-5.1">
2842      * section 5</a>.
2843      *
2844      * @example
2845      * parser = new KJUR.asn1.cms.CMSParser();
2846      * pAttr = {
2847      *   attr: "messageDigest"
2848      *   valhex: '0403123456'
2849      * };
2850      * parser.setMessageDigest(pAttr);
2851      * pAttr → {
2852      *   attr: "messageDigest",
2853      *   hex: "123456"
2854      * }
2855      */
2856     this.setMessageDigest = function(pAttr) {
2857 	var hMD = _getV(pAttr.valhex, 0);
2858 	pAttr.hex = hMD;
2859 	delete pAttr.valhex;
2860     };
2861 
2862     /**
2863      * set SigningCertificate attribute<br/>
2864      * @name setSigningCertificate
2865      * @memberOf KJUR.asn1.cms.CMSParser#
2866      * @function
2867      * @param {Array} pAttr JSON object of attribute parameter
2868      * @see KJUR.asn1.cms.CMSParser#getAttribute
2869      *
2870      * @description
2871      * This sets an attribute as SigningCertificate defined in
2872      * <a href="https://tools.ietf.org/html/rfc5035#section-5">
2873      * RFC 5035 section 5</a>.
2874      *
2875      * @example
2876      * parser = new KJUR.asn1.cms.CMSParser();
2877      * pAttr = {
2878      *   attr: "signingCertificate"
2879      *   valhex: '...'
2880      * };
2881      * parser.setSigningCertificate(pAttr);
2882      * pAttr → {
2883      *   attr: "signingCertificate",
2884      *   array: [{
2885      *     hash: "123456...",
2886      *     issuer: {
2887      *       array: [[{type:"C",value:"JP",ds:"prn"},...]],
2888      *       str: "/C=JP/O=T1"
2889      *     },
2890      *     serial: {hex: "123456..."}
2891      *   }]
2892      * }
2893      */
2894     this.setSigningCertificate = function(pAttr) {
2895 	var aIdx = _getChildIdx(pAttr.valhex, 0);
2896 	if (aIdx.length > 0) {
2897 	    var hCerts = _getTLV(pAttr.valhex, aIdx[0]);
2898 	    var aCertIdx = _getChildIdx(hCerts, 0);
2899 	    var a = [];
2900 	    for (var i = 0; i < aCertIdx.length; i++) {
2901 		var hESSCertID = _getTLV(hCerts, aCertIdx[i]);
2902 		var pESSCertID = this.getESSCertID(hESSCertID);
2903 		a.push(pESSCertID);
2904 	    }
2905 	    pAttr.array = a;
2906 	}
2907 
2908 	if (aIdx.length > 1) {
2909 	    var hPolicies = _getTLV(pAttr.valhex, aIdx[1]);
2910 	    pAttr.polhex = hPolicies;
2911 	}
2912 	delete pAttr.valhex;
2913     };
2914 
2915     /**
2916      * set SigningCertificateV2 attribute<br/>
2917      * @name setSigningCertificateV2
2918      * @memberOf KJUR.asn1.cms.CMSParser#
2919      * @function
2920      * @param {Array} pAttr JSON object of attribute parameter
2921      * @since jsrsasign 10.1.2 asn1cms 2.0.3
2922      * @see KJUR.asn1.cms.CMSParser#getAttribute
2923      * @see KJUR.asn1.cms.CMSParser#getESSCertIDv2
2924      * @see KJUR.asn1.cms.SigningCertificateV2
2925      * @see KJUR.asn1.cms.ESSCertIDv2
2926      *
2927      * @description
2928      * This sets an attribute as SigningCertificateV2 defined in
2929      * <a href="https://tools.ietf.org/html/rfc5035#section-3">
2930      * RFC 5035 section 3</a>.
2931      *
2932      * @example
2933      * parser = new KJUR.asn1.cms.CMSParser();
2934      * pAttr = {
2935      *   attr: "signingCertificateV2"
2936      *   valhex: '...'
2937      * };
2938      * parser.setSigningCertificateV2(pAttr);
2939      * pAttr → {
2940      *   attr: "signingCertificateV2",
2941      *   array: [{
2942      *     hash: "123456...",
2943      *     alg: "sha256",
2944      *     issuer: {
2945      *       array: [[{type:"C",value:"JP",ds:"prn"},...]],
2946      *       str: "/C=JP/O=T1"
2947      *     },
2948      *     serial: {hex: "123456..."}
2949      *   }]
2950      * }
2951      */
2952     this.setSigningCertificateV2 = function(pAttr) {
2953 	var aIdx = _getChildIdx(pAttr.valhex, 0);
2954 	if (aIdx.length > 0) {
2955 	    var hCerts = _getTLV(pAttr.valhex, aIdx[0]);
2956 	    var aCertIdx = _getChildIdx(hCerts, 0);
2957 	    var a = [];
2958 	    for (var i = 0; i < aCertIdx.length; i++) {
2959 		var hESSCertIDv2 = _getTLV(hCerts, aCertIdx[i]);
2960 		var pESSCertIDv2 = this.getESSCertIDv2(hESSCertIDv2);
2961 		a.push(pESSCertIDv2);
2962 	    }
2963 	    pAttr.array = a;
2964 	}
2965 
2966 	if (aIdx.length > 1) {
2967 	    var hPolicies = _getTLV(pAttr.valhex, aIdx[1]);
2968 	    pAttr.polhex = hPolicies;
2969 	}
2970 	delete pAttr.valhex;
2971     };
2972 
2973     /**
2974      * parse ASN.1 ESSCertID<br/>
2975      * @name getESSCertID
2976      * @memberOf KJUR.asn1.cms.CMSParser#
2977      * @function
2978      * @param {String} h hexadecimal string of ASN.1 ESSCertID
2979      * @return {Array} array of JSON object of ESSCertID parameter
2980      * @see KJUR.asn1.cms.ESSCertID
2981      *
2982      * @description
2983      * This method parses ASN.1 ESSCertID defined in 
2984      * <a href="https://tools.ietf.org/html/rfc5035#section-6">
2985      * RFC 5035 section 6</a>.
2986      * <pre>
2987      * ESSCertID ::= SEQUENCE {
2988      *    certHash Hash,
2989      *    issuerSerial IssuerSerial OPTIONAL }
2990      * IssuerSerial ::= SEQUENCE {
2991      *    issuer GeneralNames,
2992      *    serialNumber CertificateSerialNumber }
2993      * </pre>
2994      * 
2995      * @example
2996      * parser = new KJUR.asn1.cms.CMSParser();
2997      * parser.getESSCertID("30...") →
2998      * { hash: "12ab...",
2999      *   issuer: {
3000      *     array: [[{type:"C",value:"JP",ds:"prn"}],...],
3001      *     str: "/C=JP/O=T1"
3002      *   },
3003      *   serial: {hex: "12ab..."} }
3004      */
3005     this.getESSCertID = function(h) {
3006 	var pResult = {};
3007 	var aIdx = _getChildIdx(h, 0);
3008 
3009 	if (aIdx.length > 0) {
3010 	    var hCertHash = _getV(h, aIdx[0]);
3011 	    pResult.hash = hCertHash;
3012 	}
3013 
3014 	if (aIdx.length > 1) {
3015 	    var hIssuerSerial = _getTLV(h, aIdx[1]);
3016 	    var pIssuerSerial = 
3017 		this.getIssuerSerial(hIssuerSerial);
3018 
3019 	    if (pIssuerSerial.serial != undefined)
3020 		pResult.serial = pIssuerSerial.serial;
3021 
3022 	    if (pIssuerSerial.issuer != undefined)
3023 		pResult.issuer = pIssuerSerial.issuer;
3024 	}
3025 
3026 	return pResult;
3027     };
3028 
3029     /**
3030      * parse ASN.1 ESSCertIDv2<br/>
3031      * @name getESSCertIDv2
3032      * @memberOf KJUR.asn1.cms.CMSParser#
3033      * @function
3034      * @param {String} h hexadecimal string of ASN.1 ESSCertIDv2
3035      * @return {Array} array of JSON object of ESSCertIDv2 parameter
3036      * @since jsrsasign 10.1.2 asn1cms 2.0.3
3037      * @see KJUR.asn1.cms.ESSCertIDv2
3038      * @see KJUR.asn1.cms.CMSParser.getESSCertID
3039      *
3040      * @description
3041      * This method parses ASN.1 ESSCertIDv2 defined in 
3042      * <a href="https://tools.ietf.org/html/rfc5035#section-4">
3043      * RFC 5035 section 4</a>.
3044      * <pre>
3045      * ESSCertIDv2 ::=  SEQUENCE {
3046      *    hashAlgorithm           AlgorithmIdentifier
3047      *                            DEFAULT {algorithm id-sha256},
3048      *    certHash                Hash,
3049      *    issuerSerial            IssuerSerial OPTIONAL }
3050      * Hash ::= OCTET STRING
3051      * IssuerSerial ::= SEQUENCE {
3052      *    issuer                  GeneralNames,
3053      *    serialNumber            CertificateSerialNumber }
3054      * </pre>
3055      * 
3056      * @example
3057      * parser = new KJUR.asn1.cms.CMSParser();
3058      * parser.getESSCertID("30...") →
3059      * {
3060      *   hash: "3f2d...",
3061      *   alg: "sha512",
3062      *   issuer: {str: "/C=JP/O=T1"},
3063      *   serial: {hex: "12ab..."}
3064      * }
3065      */
3066     this.getESSCertIDv2 = function(h) {
3067 	var aResult = {};
3068 	var aIdx = _getChildIdx(h, 0); 
3069 
3070 	if (aIdx.length < 1 || 3 < aIdx.length)
3071 	    throw new _Error("wrong number of elements");
3072 
3073 	var offset = 0;
3074 	if (h.substr(aIdx[0], 2) == "30") {
3075 	    var hHashAlg = _getTLV(h, aIdx[0]);
3076 	    aResult.alg = 
3077 		_x509obj.getAlgorithmIdentifierName(hHashAlg);
3078 	    offset++;
3079 	} else {
3080 	    aResult.alg = "sha256";
3081 	}
3082 
3083 	var hHash = _getV(h, aIdx[offset]);
3084 	aResult.hash = hHash;
3085 
3086 	if (aIdx.length > offset + 1) {
3087 	    var hIssuerSerial = _getTLV(h, aIdx[offset + 1]);
3088 	    var pIssuerSerial = 
3089 		this.getIssuerSerial(hIssuerSerial);
3090 	    aResult.issuer = pIssuerSerial.issuer;
3091 	    aResult.serial = pIssuerSerial.serial;
3092 	}
3093 
3094 	return aResult;
3095     };
3096 
3097     /**
3098      * parse ASN.1 IssuerSerial<br/>
3099      * @name getIssuerSerial
3100      * @memberOf KJUR.asn1.cms.CMSParser#
3101      * @function
3102      * @param {String} h hexadecimal string of ASN.1 IssuerSerial
3103      * @return {Array} array of JSON object of IssuerSerial parameter
3104      * @see KJUR.asn1.cms.IssuerSerial
3105      * @see KJUR.asn1.x509.X500Name
3106      *
3107      * @description
3108      * This method parses ASN.1 IssuerSerial defined in 
3109      * <a href="https://tools.ietf.org/html/rfc5035#section-6">
3110      * RFC 5035 section 6</a>.
3111      * <pre>
3112      * IssuerSerial ::= SEQUENCE {
3113      *    issuer GeneralNames,
3114      *    serialNumber CertificateSerialNumber }
3115      * </pre>
3116      * 
3117      * @example
3118      * parser = new KJUR.asn1.cms.CMSParser();
3119      * parser.getIssuerSerial("30...") →
3120      * { issuer: {
3121      *     array: [[{type:"C",value:"JP",ds:"prn"}],...],
3122      *     str: "/C=JP/O=T1",
3123      *   },
3124      *   serial: {hex: "12ab..."} }
3125      */
3126     this.getIssuerSerial = function(h) {
3127 	var pResult = {};
3128 	var aIdx = _getChildIdx(h, 0);
3129 
3130 	var hIssuer = _getTLV(h, aIdx[0]);
3131 	var pIssuerGN = _x509obj.getGeneralNames(hIssuer);
3132 	var pIssuerName = pIssuerGN[0].dn;
3133 	pResult.issuer = pIssuerName;
3134 
3135 	var hSerial = _getV(h, aIdx[1]);
3136 	pResult.serial = {hex: hSerial};
3137 
3138 	return pResult;
3139     };
3140 
3141     /**
3142      * parse ASN.1 CertificateSet<br/>
3143      * @name getCertificateSet
3144      * @memberOf KJUR.asn1.cms.CMSParser#
3145      * @function
3146      * @param {String} h hexadecimal string of ASN.1 CertificateSet
3147      * @return {Array} array of JSON object of CertificateSet parameter
3148      * @see KJUR.asn1.cms.CertificateSet
3149      *
3150      * @description
3151      * This method parses ASN.1 IssuerSerial defined in 
3152      * <a href="https://tools.ietf.org/html/rfc5652#section-10.2.3">
3153      * RFC 5652 CMS section 10.2.3</a> and 
3154      * <a href="https://tools.ietf.org/html/rfc5652#section-10.2.2">
3155      * section 10.2.2</a>.
3156      * <pre>
3157      * CertificateSet ::= SET OF CertificateChoices
3158      * CertificateChoices ::= CHOICE {
3159      *   certificate Certificate,
3160      *   extendedCertificate [0] IMPLICIT ExtendedCertificate, -- Obsolete
3161      *   v1AttrCert [1] IMPLICIT AttributeCertificateV1,       -- Obsolete
3162      *   v2AttrCert [2] IMPLICIT AttributeCertificateV2,
3163      *   other [3] IMPLICIT OtherCertificateFormat }
3164      * OtherCertificateFormat ::= SEQUENCE {
3165      *   otherCertFormat OBJECT IDENTIFIER,
3166      *   otherCert ANY DEFINED BY otherCertFormat }
3167      * </pre>
3168      * Currently only "certificate" is supported in
3169      * CertificateChoices.
3170      * 
3171      * @example
3172      * parser = new KJUR.asn1.cms.CMSParser();
3173      * parser.getCertificateSet("a0...") →
3174      * [ "-----BEGIN CERTIFICATE...", ... ]
3175      */
3176     this.getCertificateSet = function(h) {
3177 	var aIdx = _getChildIdx(h, 0);
3178 	var  a = [];
3179 	for (var i = 0; i < aIdx.length; i++) {
3180 	    var hCert = _getTLV(h, aIdx[i]);
3181 	    if (hCert.substr(0, 2) == "30") {
3182 		var pem = hextopem(hCert, "CERTIFICATE");
3183 		a.push(pem);
3184 	    }
3185 	}
3186 	return {array: a, sortflag: false};
3187     };
3188 };
3189