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