1 /*! asn1cades-1.0.0.js (c) 2013-2014 Kenji Urushima | kjur.github.com/jsrsasign/license
  2  */
  3 /*
  4  * asn1cades.js - ASN.1 DER encoder classes for RFC 5126 CAdES long term signature
  5  *
  6  * Copyright (c) 2014 Kenji Urushima (kenji.urushima@gmail.com)
  7  *
  8  * This software is licensed under the terms of the MIT License.
  9  * http://kjur.github.com/jsrsasign/license
 10  *
 11  * The above copyright and license notice shall be 
 12  * included in all copies or substantial portions of the Software.
 13  */
 14 
 15 /**
 16  * @fileOverview
 17  * @name asn1cades-1.0.js
 18  * @author Kenji Urushima kenji.urushima@gmail.com
 19  * @version 1.0.0 (2014-May-28)
 20  * @since jsrsasign 4.7.0
 21  * @license <a href="http://kjur.github.io/jsrsasign/license/">MIT License</a>
 22  */
 23 
 24 /** 
 25  * kjur's class library name space
 26  * // already documented in asn1-1.0.js
 27  * @name KJUR
 28  * @namespace kjur's class library name space
 29  */
 30 if (typeof KJUR == "undefined" || !KJUR) KJUR = {};
 31 
 32 /**
 33  * kjur's ASN.1 class library name space
 34  * // already documented in asn1-1.0.js
 35  * @name KJUR.asn1
 36  * @namespace
 37  */
 38 if (typeof KJUR.asn1 == "undefined" || !KJUR.asn1) KJUR.asn1 = {};
 39 
 40 /**
 41  * kjur's ASN.1 class for RFC 5126 CAdES long term signature
 42  * <p>
 43  * This name space provides 
 44  * <a href="https://tools.ietf.org/html/rfc5126">RFC 5126
 45  * CAdES(CMS Advanced Electronic Signature)</a> generator.
 46  *
 47  * <h4>SUPPORTED FORMATS</h4>
 48  * Following CAdES formats is supported by this library.
 49  * <ul>
 50  * <li>CAdES-BES - CAdES Basic Electronic Signature</li>
 51  * <li>CAdES-EPES - CAdES Explicit Policy-based Electronic Signature</li>
 52  * <li>CAdES-T - Electronic Signature with Time</li>
 53  * </ul>
 54  * </p>
 55  *
 56  * <h4>PROVIDED ATTRIBUTE CLASSES</h4>
 57  * <ul>
 58  * <li>{@link KJUR.asn1.cades.SignaturePolicyIdentifier} - for CAdES-EPES</li>
 59  * <li>{@link KJUR.asn1.cades.SignatureTimeStamp} - for CAdES-T</li>
 60  * <li>{@link KJUR.asn1.cades.CompleteCertificateRefs} - for CAdES-C(for future use)</li>
 61  * </ul>
 62  * NOTE: Currntly CAdES-C is not supported since parser can't
 63  * handle unsigned attribute.
 64  * 
 65  * <h4>OTHER CLASSES</h4>
 66  * <ul>
 67  * <li>{@link KJUR.asn1.cades.OtherHashAlgAndValue}</li>
 68  * <li>{@link KJUR.asn1.cades.OtherHash}</li>
 69  * <li>{@link KJUR.asn1.cades.OtherCertID}</li>
 70  * <li>{@link KJUR.asn1.cades.CAdESUtil} - utilities for CAdES</li>
 71  * </ul>
 72  *
 73  * <h4>GENERATE CAdES-BES</h4>
 74  * To generate CAdES-BES, {@link KJUR.asn.cades} namespace 
 75  * classes are not required and already {@link KJUR.asn.cms} namespace 
 76  * provides attributes for CAdES-BES.
 77  * Create {@link KJUR.asn1.cms.SignedData} with following
 78  * mandatory attribute in CAdES-BES:
 79  * <ul>
 80  * <li>{@link KJUR.asn1.cms.ContentType}</li>
 81  * <li>{@link KJUR.asn1.cms.MessageDigest}</li>
 82  * <li>{@link KJUR.asn1.cms.SigningCertificate} or </li>
 83  * <li>{@link KJUR.asn1.cms.SigningCertificateV2}</li>
 84  * </ul>
 85  * CMSUtil.newSignedData method is very useful to generate CAdES-BES.
 86  * <pre>
 87  * sd = KJUR.asn1.cms.CMSUtil.newSignedData({
 88  *   content: {str: "aaa"},
 89  *   certs: [certPEM],
 90  *   signerInfos: [{
 91  *     hashAlg: 'sha256',
 92  *     sAttr: {SigningCertificateV2: {array: [certPEM]}},
 93  *     signerCert: certPEM,
 94  *     sigAlg: 'SHA256withRSA',
 95  *     signerPrvKey: pkcs8PrvKeyPEM
 96  *   }]
 97  * });
 98  * signedDataHex = sd.getContentInfoEncodedHex();
 99  * </pre>
100  * NOTE: ContentType and MessageDigest signed attributes
101  * are automatically added by default.
102  *
103  * <h4>GENERATE CAdES-BES with multiple signers</h4>
104  * If you need signature by multiple signers, you can 
105  * specify one or more items in 'signerInfos' property as below.
106  * <pre>
107  * sd = KJUR.asn1.cms.CMSUtil.newSignedData({
108  *   content: {str: "aaa"},
109  *   certs: [certPEM1, certPEM2],
110  *   signerInfos: [{
111  *     hashAlg: 'sha256',
112  *     sAttr: {SigningCertificateV2: {array: [certPEM1]}},
113  *     signerCert: certPEM1,
114  *     sigAlg: 'SHA256withRSA',
115  *     signerPrvKey: pkcs8PrvKeyPEM1
116  *   },{
117  *     hashAlg: 'sha1',
118  *     sAttr: {SigningCertificateV2: {array: [certPEM2]}},
119  *     signerCert: certPEM2,
120  *     sigAlg: 'SHA1withRSA',
121  *     signerPrvKey: pkcs8PrvKeyPEM2
122  *   }]
123  * });
124  * signedDataHex = sd.getContentInfoEncodedHex();
125  * </pre>
126  *
127  * <h4>GENERATE CAdES-EPES</h4>
128  * When you need a CAdES-EPES signature,
129  * you just need to add 'SignaturePolicyIdentifier'
130  * attribute as below.
131  * <pre>
132  * sd = KJUR.asn1.cms.CMSUtil.newSignedData({
133  *   content: {str: "aaa"},
134  *   certs: [certPEM],
135  *   signerInfos: [{
136  *     hashAlg: 'sha256',
137  *     sAttr: {
138  *       SigningCertificateV2: {array: [certPEM]},
139  *       SignaturePolicyIdentifier: {
140  *         oid: '1.2.3.4.5',
141  *         hash: {alg: 'sha1', hash: 'b1b2b3b4b...'}
142  *       },
143  *     },
144  *     signerCert: certPEM,
145  *     sigAlg: 'SHA256withRSA',
146  *     signerPrvKey: pkcs8PrvKeyPEM
147  *   }]
148  * });
149  * signedDataHex = sd.getContentInfoEncodedHex();
150  * </pre>
151  *
152  * <h4>GENERATE CAdES-T</h4>
153  * After a signed CAdES-BES or CAdES-EPES signature have been generated,
154  * you can generate CAdES-T by adding SigningTimeStamp unsigned attribute.
155  * <pre>
156  * beshex = "30..."; // hex of CAdES-BES or EPES data 
157  * info = KJUR.asn1.cades.CAdESUtil.parseSignedDataForAddingUnsigned(beshex);
158  * // You can refer a hexadecimal string of signature value 
159  * // in the first signerInfo in the CAdES-BES/EPES with a variable:
160  * // 'info.si[0].sigval'. You need to get RFC 3161 TimeStampToken
161  * // from a trusted time stamp authority. Otherwise you can also 
162  * // get it by 'KJUR.asn1.tsp' module. We suppose that we could 
163  * // get proper time stamp.
164  * tsthex0 = "30..."; // hex of TimeStampToken for signerInfo[0] sigval
165  * si0 = info.obj.signerInfoList[0];
166  * si0.addUnsigned(new KJUR.asn1.cades.SignatureTimeStamp({tst: tsthex0});
167  * esthex = info.obj.getContentInfoEncodedHex(); // CAdES-T
168  * </pre>
169  * </p>
170  *
171  * <h4>SAMPLE CODES</h4>
172  * <ul>
173  * <li><a href="../../tool_cades.html">demo program for CAdES-BES/EPES/T generation</a></li>
174  * <li><a href="../../test/qunit-do-asn1cades.html">Unit test code for KJUR.asn1.cades package</a></li>
175  * <li><a href="../../test/qunit-do-asn1tsp.html">Unit test code for KJUR.asn1.tsp package (See SimpleTSAAdaptor test)</a></li>
176  * <li><a href="../../test/qunit-do-asn1cms.html">Unit test code for KJUR.asn1.cms package (See newSignedData test)</a></li>
177  * </ul>
178  * 
179  * @name KJUR.asn1.cades
180  * @namespace
181  */
182 if (typeof KJUR.asn1.cades == "undefined" || !KJUR.asn1.cades) KJUR.asn1.cades = {};
183 
184 /**
185  * class for RFC 5126 CAdES SignaturePolicyIdentifier attribute
186  * @name KJUR.asn1.cades.SignaturePolicyIdentifier
187  * @class class for RFC 5126 CAdES SignaturePolicyIdentifier attribute
188  * @param {Array} params associative array of parameters
189  * @extends KJUR.asn1.cms.Attribute
190  * @since jsrsasign 4.7.0 asn1cades 1.0.0
191  * @description
192  * <pre>
193  * SignaturePolicyIdentifier ::= CHOICE {
194  *    signaturePolicyId       SignaturePolicyId,
195  *    signaturePolicyImplied  SignaturePolicyImplied } -- not used
196  *
197  * SignaturePolicyImplied ::= NULL
198  * SignaturePolicyId ::= SEQUENCE {
199  *    sigPolicyId           SigPolicyId,
200  *    sigPolicyHash         SigPolicyHash,
201  *    sigPolicyQualifiers   SEQUENCE SIZE (1..MAX) OF
202  *                             SigPolicyQualifierInfo OPTIONAL }
203  * SigPolicyId ::= OBJECT IDENTIFIER
204  * SigPolicyHash ::= OtherHashAlgAndValue
205  * </pre>
206  * @example
207  * var o = new KJUR.asn1.cades.SignaturePolicyIdentifier({
208  *   oid: '1.2.3.4.5',
209  *   hash: {alg: 'sha1', hash: 'a1a2a3a4...'}
210  * });
211  */
212 /*
213  * id-aa-ets-sigPolicyId OBJECT IDENTIFIER ::= { iso(1)
214  *    member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs9(9)
215  *    smime(16) id-aa(2) 15 }
216  *
217  * signature-policy-identifier attribute values have ASN.1 type
218  * SignaturePolicyIdentifier:
219  *
220  * SigPolicyQualifierInfo ::= SEQUENCE {
221  *    sigPolicyQualifierId  SigPolicyQualifierId,
222  *    sigQualifier          ANY DEFINED BY sigPolicyQualifierId } 
223  *
224  * sigpolicyQualifierIds defined in the present document:
225  * SigPolicyQualifierId ::= OBJECT IDENTIFIER
226  * id-spq-ets-uri OBJECT IDENTIFIER ::= { iso(1)
227  *    member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs9(9)
228  *    smime(16) id-spq(5) 1 }
229  *
230  * SPuri ::= IA5String
231  *
232  * id-spq-ets-unotice OBJECT IDENTIFIER ::= { iso(1)
233  *    member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs9(9)
234  *    smime(16) id-spq(5) 2 }
235  *
236  * SPUserNotice ::= SEQUENCE {
237  *    noticeRef        NoticeReference OPTIONAL,
238  *    explicitText     DisplayText OPTIONAL}
239  *
240  * NoticeReference ::= SEQUENCE {
241  *    organization     DisplayText,
242  *    noticeNumbers    SEQUENCE OF INTEGER }
243  *
244  * DisplayText ::= CHOICE {
245  *    visibleString    VisibleString  (SIZE (1..200)),
246  *    bmpString        BMPString      (SIZE (1..200)),
247  *    utf8String       UTF8String     (SIZE (1..200)) }
248  */
249 KJUR.asn1.cades.SignaturePolicyIdentifier = function(params) {
250     KJUR.asn1.cades.SignaturePolicyIdentifier.superclass.constructor.call(this);
251     this.attrTypeOid = "1.2.840.113549.1.9.16.2.15";
252     var nA = KJUR.asn1;
253     var nC = KJUR.asn1.cades;
254 
255     if (typeof params != "undefined") {
256         if (typeof params.oid == "string" &&
257             typeof params.hash == "object") {
258             var dOid = new nA.DERObjectIdentifier({oid: params.oid});
259             var dHash = new nC.OtherHashAlgAndValue(params.hash);
260             var seq = new nA.DERSequence({array: [dOid, dHash]});
261             this.valueList = [seq];
262         }
263     }
264 };
265 YAHOO.lang.extend(KJUR.asn1.cades.SignaturePolicyIdentifier,
266                   KJUR.asn1.cms.Attribute);
267 
268 /**
269  * class for OtherHashAlgAndValue ASN.1 object
270  * @name KJUR.asn1.cades.OtherHashAlgAndValue
271  * @class class for OtherHashAlgAndValue ASN.1 object
272  * @param {Array} params associative array of parameters
273  * @extends KJUR.asn1.ASN1Object
274  * @since jsrsasign 4.7.0 asn1cades 1.0.0
275  * @description
276  * <pre>
277  * OtherHashAlgAndValue ::= SEQUENCE {
278  *    hashAlgorithm   AlgorithmIdentifier,
279  *    hashValue       OtherHashValue }
280  * OtherHashValue ::= OCTET STRING
281  * </pre>
282  */
283 KJUR.asn1.cades.OtherHashAlgAndValue = function(params) {
284     KJUR.asn1.cades.OtherHashAlgAndValue.superclass.constructor.call(this);
285     var nA = KJUR.asn1;
286     var nX = KJUR.asn1.x509;
287     this.dAlg = null;
288     this.dHash = null;
289 
290     this.getEncodedHex = function() {
291         var seq = new nA.DERSequence({array: [this.dAlg, this.dHash]});
292         this.hTLV = seq.getEncodedHex();
293         return this.hTLV;
294     };
295 
296     if (typeof params != "undefined") {
297         if (typeof params.alg == "string" &&
298             typeof params.hash == "string") {
299             this.dAlg = new nX.AlgorithmIdentifier({name: params.alg});
300             this.dHash = new nA.DEROctetString({hex: params.hash});
301         }
302     }
303 };
304 YAHOO.lang.extend(KJUR.asn1.cades.OtherHashAlgAndValue, KJUR.asn1.ASN1Object);
305 
306 /**
307  * class for RFC 5126 CAdES SignatureTimeStamp attribute
308  * @name KJUR.asn1.cades.SignatureTimeStamp
309  * @class class for RFC 5126 CAdES SignatureTimeStamp attribute
310  * @param {Array} params associative array of parameters
311  * @extends KJUR.asn1.cms.Attribute
312  * @since jsrsasign 4.7.0 asn1cades 1.0.0
313  * @description
314  * <pre>
315  * id-aa-signatureTimeStampToken OBJECT IDENTIFIER ::=
316  *    1.2.840.113549.1.9.16.2.14
317  * SignatureTimeStampToken ::= TimeStampToken
318  * </pre>
319  */
320 KJUR.asn1.cades.SignatureTimeStamp = function(params) {
321     KJUR.asn1.cades.SignatureTimeStamp.superclass.constructor.call(this);
322     this.attrTypeOid = "1.2.840.113549.1.9.16.2.14";
323     this.tstHex = null;
324     var nA = KJUR.asn1;
325 
326     if (typeof params != "undefined") {
327         if (typeof params.res != "undefined") {
328             if (typeof params.res == "string" &&
329                 params.res.match(/^[0-9A-Fa-f]+$/)) {
330             } else if (params.res instanceof KJUR.asn1.ASN1Object) {
331             } else {
332                 throw "res param shall be ASN1Object or hex string";
333             }
334         }
335         if (typeof params.tst != "undefined") {
336             if (typeof params.tst == "string" &&
337                 params.tst.match(/^[0-9A-Fa-f]+$/)) {
338                 var d = new nA.ASN1Object();
339                 this.tstHex = params.tst;
340                 d.hTLV = this.tstHex;
341                 d.getEncodedHex();
342                 this.valueList = [d];
343             } else if (params.tst instanceof KJUR.asn1.ASN1Object) {
344             } else {
345                 throw "tst param shall be ASN1Object or hex string";
346             }
347         }
348     }
349 };
350 YAHOO.lang.extend(KJUR.asn1.cades.SignatureTimeStamp,
351                   KJUR.asn1.cms.Attribute);
352 
353 /**
354  * class for RFC 5126 CAdES CompleteCertificateRefs attribute
355  * @name KJUR.asn1.cades.CompleteCertificateRefs
356  * @class class for RFC 5126 CAdES CompleteCertificateRefs attribute
357  * @param {Array} params associative array of parameters
358  * @extends KJUR.asn1.cms.Attribute
359  * @since jsrsasign 4.7.0 asn1cades 1.0.0
360  * @description
361  * <pre>
362  * id-aa-ets-certificateRefs OBJECT IDENTIFIER = 
363  *    1.2.840.113549.1.9.16.2.21
364  * CompleteCertificateRefs ::=  SEQUENCE OF OtherCertID
365  * </pre>
366  * @example
367  * o = new KJUR.asn1.cades.CompleteCertificateRefs([certPEM1,certPEM2]);
368  */
369 KJUR.asn1.cades.CompleteCertificateRefs = function(params) {
370     KJUR.asn1.cades.CompleteCertificateRefs.superclass.constructor.call(this);
371     this.attrTypeOid = "1.2.840.113549.1.9.16.2.21";
372     var nA = KJUR.asn1;
373     var nD = KJUR.asn1.cades;
374 
375     /**
376      * set value by array
377      * @name setByArray
378      * @memberOf KJUR.asn1.cades.CompleteCertificateRefs
379      * @function
380      * @param {Array} a array of {@link KJUR.asn1.cades.OtherCertID} argument
381      * @return unspecified
382      * @description
383      */
384     this.setByArray = function(a) {
385         this.valueList = [];
386         for (var i = 0; i < a.length; i++) {
387             var o = new nD.OtherCertID(a[i]);
388             this.valueList.push(o);
389         }
390     };
391 
392     if (typeof params != "undefined") {
393         if (typeof params == "object" &&
394             typeof params.length == "number") {
395             this.setByArray(params);
396         }
397     }
398 };
399 YAHOO.lang.extend(KJUR.asn1.cades.CompleteCertificateRefs,
400                   KJUR.asn1.cms.Attribute);
401 
402 /**
403  * class for OtherCertID ASN.1 object
404  * @name KJUR.asn1.cades.OtherCertID
405  * @class class for OtherCertID ASN.1 object
406  * @param {Array} params associative array of parameters
407  * @extends KJUR.asn1.ASN1Object
408  * @since jsrsasign 4.7.0 asn1cades 1.0.0
409  * @description
410  * <pre>
411  * OtherCertID ::= SEQUENCE {
412  *    otherCertHash    OtherHash,
413  *    issuerSerial     IssuerSerial OPTIONAL }
414  * </pre>
415  * @example
416  * o = new KJUR.asn1.cades.OtherCertID(certPEM);
417  * o = new KJUR.asn1.cades.OtherCertID({cert:certPEM, hasis: false});
418  */
419 KJUR.asn1.cades.OtherCertID = function(params) {
420     KJUR.asn1.cades.OtherCertID.superclass.constructor.call(this);
421     var nA = KJUR.asn1;
422     var nC = KJUR.asn1.cms;
423     var nD = KJUR.asn1.cades;
424     this.hasIssuerSerial = true;
425     this.dOtherCertHash = null;
426     this.dIssuerSerial = null;
427 
428     /**
429      * set value by PEM string of certificate
430      * @name setByCertPEM
431      * @memberOf KJUR.asn1.cades.OtherCertID
432      * @function
433      * @param {String} certPEM PEM string of certificate
434      * @return unspecified
435      * @description
436      * This method will set value by a PEM string of a certificate.
437      * This will add IssuerAndSerialNumber by default 
438      * which depends on hasIssuerSerial flag.
439      */
440     this.setByCertPEM = function(certPEM) {
441         this.dOtherCertHash = new nD.OtherHash(certPEM);
442         if (this.hasIssuerSerial)
443             this.dIssuerSerial = new nC.IssuerAndSerialNumber(certPEM);
444     };
445 
446     this.getEncodedHex = function() {
447         if (this.hTLV != null) return this.hTLV;
448         if (this.dOtherCertHash == null)
449             throw "otherCertHash not set";
450         var a = [this.dOtherCertHash];
451         if (this.dIssuerSerial != null)
452             a.push(this.dIssuerSerial);
453         var seq = new nA.DERSequence({array: a});
454         this.hTLV = seq.getEncodedHex();
455         return this.hTLV;
456     };
457 
458     if (typeof params != "undefined") {
459         if (typeof params == "string" &&
460             params.indexOf("-----BEGIN ") != -1) {
461             this.setByCertPEM(params);
462         }
463         if (typeof params == "object") {
464             if (params.hasis === false)
465                 this.hasIssuerSerial = false;
466             if (typeof params.cert == "string")
467                 this.setByCertPEM(params.cert);
468         }
469     }
470 };
471 YAHOO.lang.extend(KJUR.asn1.cades.OtherCertID, KJUR.asn1.ASN1Object);
472 
473 /**
474  * class for OtherHash ASN.1 object
475  * @name KJUR.asn1.cades.OtherHash
476  * @class class for OtherHash ASN.1 object
477  * @param {Array} params associative array of parameters
478  * @extends KJUR.asn1.ASN1Object
479  * @since jsrsasign 4.7.0 asn1cades 1.0.0
480  * @description
481  * <pre>
482  * OtherHash ::= CHOICE {
483  *    sha1Hash   OtherHashValue,  -- This contains a SHA-1 hash
484  *    otherHash  OtherHashAlgAndValue}
485  * OtherHashValue ::= OCTET STRING
486  * </pre>
487  * @example
488  * o = new KJUR.asn1.cades.OtherHash("1234");
489  * o = new KJUR.asn1.cades.OtherHash(certPEMStr); // default alg=sha256
490  * o = new KJUR.asn1.cades.OtherHash({alg: 'sha256', hash: '1234'});
491  * o = new KJUR.asn1.cades.OtherHash({alg: 'sha256', cert: certPEM});
492  * o = new KJUR.asn1.cades.OtherHash({cert: certPEM});
493  */
494 KJUR.asn1.cades.OtherHash = function(params) {
495     KJUR.asn1.cades.OtherHash.superclass.constructor.call(this);
496     var nA = KJUR.asn1;
497     var nD = KJUR.asn1.cades;
498     this.alg = 'sha256';
499     this.dOtherHash = null;
500 
501     /**
502      * set value by PEM string of certificate
503      * @name setByCertPEM
504      * @memberOf KJUR.asn1.cades.OtherHash
505      * @function
506      * @param {String} certPEM PEM string of certificate
507      * @return unspecified
508      * @description
509      * This method will set value by a PEM string of a certificate.
510      * An algorithm used to hash certificate data will
511      * be defined by 'alg' property and 'sha256' is default.
512      */
513     this.setByCertPEM = function(certPEM) {
514         if (certPEM.indexOf("-----BEGIN ") == -1)
515             throw "certPEM not to seem PEM format";
516         var hex = X509.pemToHex(certPEM);
517         var hash = KJUR.crypto.Util.hashHex(hex, this.alg);
518         this.dOtherHash = 
519             new nD.OtherHashAlgAndValue({alg: this.alg, hash: hash});
520     };
521 
522     this.getEncodedHex = function() {
523         if (this.dOtherHash == null)
524             throw "OtherHash not set";
525         return this.dOtherHash.getEncodedHex();
526     };
527 
528     if (typeof params != "undefined") {
529         if (typeof params == "string") {
530             if (params.indexOf("-----BEGIN ") != -1) {
531                 this.setByCertPEM(params);
532             } else if (params.match(/^[0-9A-Fa-f]+$/)) {
533                 this.dOtherHash = new nA.DEROctetString({hex: params});
534             } else {
535                 throw "unsupported string value for params";
536             }
537         } else if (typeof params == "object") {
538             if (typeof params.cert == "string") {
539                 if (typeof params.alg == "string")
540                     this.alg = params.alg;
541                 this.setByCertPEM(params.cert);
542             } else {
543                 this.dOtherHash = new nD.OtherHashAlgAndValue(params);
544             }
545         }
546     }
547 };
548 YAHOO.lang.extend(KJUR.asn1.cades.OtherHash, KJUR.asn1.ASN1Object);
549 
550 
551 // == BEGIN UTILITIES =====================================================
552 
553 /**
554  * CAdES utiliteis class
555  * @name KJUR.asn1.cades.CAdESUtil
556  * @class CAdES utilities class
557  * @since jsrsasign 4.7.0 asn1cades 1.0.0
558  */
559 KJUR.asn1.cades.CAdESUtil = new function() {
560 };
561 /*
562  *
563  */
564 KJUR.asn1.cades.CAdESUtil.addSigTS = function(dCMS, siIdx, sigTSHex) {
565 };
566 /**
567  * parse CMS SignedData to add unsigned attributes
568  * @name parseSignedDataForAddingUnsigned
569  * @memberOf KJUR.asn1.cades.CAdESUtil
570  * @function
571  * @param {String} hex hexadecimal string of ContentInfo of CMS SignedData
572  * @return {Object} associative array of parsed data
573  * @description
574  * This method will parse a hexadecimal string of 
575  * ContentInfo with CMS SignedData to add a attribute
576  * to unsigned attributes field in a signerInfo field.
577  * Parsed result will be an associative array which has
578  * following properties:
579  * <ul>
580  * <li>version - hex of CMSVersion ASN.1 TLV</li>
581  * <li>algs - hex of DigestAlgorithms ASN.1 TLV</li>
582  * <li>encapcontent - hex of EncapContentInfo ASN.1 TLV</li>
583  * <li>certs - hex of Certificates ASN.1 TLV</li>
584  * <li>revs - hex of RevocationInfoChoices ASN.1 TLV</li>
585  * <li>si[] - array of SignerInfo properties</li>
586  * <li>obj - parsed KJUR.asn1.cms.SignedData object</li>
587  * </ul>
588  * @example
589  * info = KJUR.asn1.cades.CAdESUtil.parseSignedDataForAddingUnsigned(beshex);
590  * sd = info.obj;
591  */
592 KJUR.asn1.cades.CAdESUtil.parseSignedDataForAddingUnsigned = function(hex) {
593     var nA = KJUR.asn1;
594     var nC = KJUR.asn1.cms;
595     var nU = KJUR.asn1.cades.CAdESUtil;
596     var r = {};
597 
598     // 1. not oid signed-data then error
599     if (ASN1HEX.getDecendantHexTLVByNthList(hex, 0, [0]) != 
600         "06092a864886f70d010702")
601         throw "hex is not CMS SignedData";
602 
603     var iSD = ASN1HEX.getDecendantIndexByNthList(hex, 0, [1, 0]);
604     var aSDChildIdx = ASN1HEX.getPosArrayOfChildren_AtObj(hex, iSD);
605     if (aSDChildIdx.length < 4)
606         throw "num of SignedData elem shall be 4 at least";
607 
608     // 2. HEXs of SignedData children
609     // 2.1. SignedData.CMSVersion
610     var iVersion = aSDChildIdx.shift();
611     r.version = ASN1HEX.getHexOfTLV_AtObj(hex, iVersion);
612 
613     // 2.2. SignedData.DigestAlgorithms
614     var iAlgs = aSDChildIdx.shift();
615     r.algs = ASN1HEX.getHexOfTLV_AtObj(hex, iAlgs);
616 
617     // 2.3. SignedData.EncapContentInfo
618     var iEncapContent = aSDChildIdx.shift();
619     r.encapcontent = ASN1HEX.getHexOfTLV_AtObj(hex, iEncapContent);
620 
621     // 2.4. [0]Certs 
622     r.certs = null;
623     r.revs = null;
624     r.si = [];
625 
626     var iNext = aSDChildIdx.shift();
627     if (hex.substr(iNext, 2) == "a0") {
628         r.certs = ASN1HEX.getHexOfTLV_AtObj(hex, iNext);
629         iNext = aSDChildIdx.shift();
630     }
631 
632     // 2.5. [1]Revs
633     if (hex.substr(iNext, 2) == "a1") {
634         r.revs = ASN1HEX.getHexOfTLV_AtObj(hex, iNext);
635         iNext = aSDChildIdx.shift();
636     }
637 
638     // 2.6. SignerInfos
639     var iSignerInfos = iNext;
640     if (hex.substr(iSignerInfos, 2) != "31")
641         throw "Can't find signerInfos";
642 
643     var aSIIndex = ASN1HEX.getPosArrayOfChildren_AtObj(hex, iSignerInfos);
644     //alert(aSIIndex.join("-"));
645 
646     for (var i = 0; i < aSIIndex.length; i++) {
647         var iSI = aSIIndex[i];
648         var pSI = nU.parseSignerInfoForAddingUnsigned(hex, iSI, i);
649         r.si[i] = pSI;
650     }
651 
652     // x. obj(SignedData)
653     var tmp = null;
654     r.obj = new nC.SignedData();
655 
656     tmp = new nA.ASN1Object();
657     tmp.hTLV = r.version;
658     r.obj.dCMSVersion = tmp;
659 
660     tmp = new nA.ASN1Object();
661     tmp.hTLV = r.algs;
662     r.obj.dDigestAlgs = tmp;
663 
664     tmp = new nA.ASN1Object();
665     tmp.hTLV = r.encapcontent;
666     r.obj.dEncapContentInfo = tmp;
667 
668     tmp = new nA.ASN1Object();
669     tmp.hTLV = r.certs;
670     r.obj.dCerts = tmp;
671 
672     r.obj.signerInfoList = [];
673     for (var i = 0; i < r.si.length; i++) {
674         r.obj.signerInfoList.push(r.si[i].obj);
675     }
676 
677     return r;
678 };
679 
680 /**
681  * parse SignerInfo to add unsigned attributes
682  * @name parseSignerInfoForAddingUnsigned
683  * @memberOf KJUR.asn1.cades.CAdESUtil
684  * @function
685  * @param {String} hex hexadecimal string of SignerInfo
686  * @return {Object} associative array of parsed data
687  * @description
688  * This method will parse a hexadecimal string of 
689  * SignerInfo to add a attribute
690  * to unsigned attributes field in a signerInfo field.
691  * Parsed result will be an associative array which has
692  * following properties:
693  * <ul>
694  * <li>version - hex TLV of version</li>
695  * <li>si - hex TLV of SignerIdentifier</li>
696  * <li>digalg - hex TLV of DigestAlgorithm</li>
697  * <li>sattrs - hex TLV of SignedAttributes</li>
698  * <li>sigalg - hex TLV of SignatureAlgorithm</li>
699  * <li>sig - hex TLV of signature</li>
700  * <li>sigval = hex V of signature</li>
701  * <li>obj - parsed KJUR.asn1.cms.SignerInfo object</li>
702  * </ul>
703  * NOTE: Parsing of unsigned attributes will be provided in the
704  * future version. That's way this version provides support
705  * for CAdES-T and not for CAdES-C.
706  */
707 KJUR.asn1.cades.CAdESUtil.parseSignerInfoForAddingUnsigned = 
708     function(hex, iSI, nth) {
709     var nA = KJUR.asn1;
710     var nC = KJUR.asn1.cms;
711     var r = {};
712     var aSIChildIdx = ASN1HEX.getPosArrayOfChildren_AtObj(hex, iSI);
713     //alert(aSIChildIdx.join("="));
714 
715     if (aSIChildIdx.length != 6)
716         throw "not supported items for SignerInfo (!=6)"; 
717 
718     // 1. SignerInfo.CMSVersion
719     var iVersion = aSIChildIdx.shift();
720     r.version = ASN1HEX.getHexOfTLV_AtObj(hex, iVersion);
721 
722     // 2. SignerIdentifier(IssuerAndSerialNumber)
723     var iIdentifier = aSIChildIdx.shift();
724     r.si = ASN1HEX.getHexOfTLV_AtObj(hex, iIdentifier);
725 
726     // 3. DigestAlgorithm
727     var iDigestAlg = aSIChildIdx.shift();
728     r.digalg = ASN1HEX.getHexOfTLV_AtObj(hex, iDigestAlg);
729 
730     // 4. SignedAttrs
731     var iSignedAttrs = aSIChildIdx.shift();
732     r.sattrs = ASN1HEX.getHexOfTLV_AtObj(hex, iSignedAttrs);
733 
734     // 5. SigAlg
735     var iSigAlg = aSIChildIdx.shift();
736     r.sigalg = ASN1HEX.getHexOfTLV_AtObj(hex, iSigAlg);
737 
738     // 6. Signature
739     var iSig = aSIChildIdx.shift();
740     r.sig = ASN1HEX.getHexOfTLV_AtObj(hex, iSig);
741     r.sigval = ASN1HEX.getHexOfV_AtObj(hex, iSig);
742 
743     // 7. obj(SignerInfo)
744     var tmp = null;
745     r.obj = new nC.SignerInfo();
746 
747     tmp = new nA.ASN1Object();
748     tmp.hTLV = r.version;
749     r.obj.dCMSVersion = tmp;
750 
751     tmp = new nA.ASN1Object();
752     tmp.hTLV = r.si;
753     r.obj.dSignerIdentifier = tmp;
754 
755     tmp = new nA.ASN1Object();
756     tmp.hTLV = r.digalg;
757     r.obj.dDigestAlgorithm = tmp;
758 
759     tmp = new nA.ASN1Object();
760     tmp.hTLV = r.sattrs;
761     r.obj.dSignedAttrs = tmp;
762 
763     tmp = new nA.ASN1Object();
764     tmp.hTLV = r.sigalg;
765     r.obj.dSigAlg = tmp;
766 
767     tmp = new nA.ASN1Object();
768     tmp.hTLV = r.sig;
769     r.obj.dSig = tmp;
770 
771     r.obj.dUnsignedAttrs = new nC.AttributeList();
772 
773     return r;
774 };
775 
776