1 /* asn1x509-1.1.0.js (c) 2013-2017 Kenji Urushima | kjur.github.com/jsrsasign/license 2 */ 3 /* 4 * asn1x509.js - ASN.1 DER encoder classes for X.509 certificate 5 * 6 * Copyright (c) 2013-2017 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 asn1x509-1.0.js 18 * @author Kenji Urushima kenji.urushima@gmail.com 19 * @version jsrsasign 8.0.0 asn1x509 1.1.0 (2017-Jun-25) 20 * @since jsrsasign 2.1 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 X.509 certificate library name space 42 * <p> 43 * <h4>FEATURES</h4> 44 * <ul> 45 * <li>easily issue any kind of certificate</li> 46 * <li>APIs are very similar to BouncyCastle library ASN.1 classes. So easy to learn.</li> 47 * </ul> 48 * </p> 49 * <h4>PROVIDED CLASSES</h4> 50 * <ul> 51 * <li>{@link KJUR.asn1.x509.Certificate}</li> 52 * <li>{@link KJUR.asn1.x509.TBSCertificate}</li> 53 * <li>{@link KJUR.asn1.x509.Extension}</li> 54 * <li>{@link KJUR.asn1.x509.X500Name}</li> 55 * <li>{@link KJUR.asn1.x509.RDN}</li> 56 * <li>{@link KJUR.asn1.x509.AttributeTypeAndValue}</li> 57 * <li>{@link KJUR.asn1.x509.SubjectPublicKeyInfo}</li> 58 * <li>{@link KJUR.asn1.x509.AlgorithmIdentifier}</li> 59 * <li>{@link KJUR.asn1.x509.GeneralName}</li> 60 * <li>{@link KJUR.asn1.x509.GeneralNames}</li> 61 * <li>{@link KJUR.asn1.x509.DistributionPointName}</li> 62 * <li>{@link KJUR.asn1.x509.DistributionPoint}</li> 63 * <li>{@link KJUR.asn1.x509.CRL}</li> 64 * <li>{@link KJUR.asn1.x509.TBSCertList}</li> 65 * <li>{@link KJUR.asn1.x509.CRLEntry}</li> 66 * <li>{@link KJUR.asn1.x509.OID}</li> 67 * </ul> 68 * <h4>SUPPORTED EXTENSIONS</h4> 69 * <ul> 70 * <li>{@link KJUR.asn1.x509.BasicConstraints}</li> 71 * <li>{@link KJUR.asn1.x509.KeyUsage}</li> 72 * <li>{@link KJUR.asn1.x509.CRLDistributionPoints}</li> 73 * <li>{@link KJUR.asn1.x509.ExtKeyUsage}</li> 74 * <li>{@link KJUR.asn1.x509.AuthorityKeyIdentifier}</li> 75 * <li>{@link KJUR.asn1.x509.AuthorityInfoAccess}</li> 76 * <li>{@link KJUR.asn1.x509.SubjectAltName}</li> 77 * <li>{@link KJUR.asn1.x509.IssuerAltName}</li> 78 * </ul> 79 * NOTE1: Please ignore method summary and document of this namespace. This caused by a bug of jsdoc2.<br/> 80 * NOTE2: SubjectAltName and IssuerAltName extension were supported since 81 * jsrsasign 6.2.3 asn1x509 1.0.19.<br/> 82 * @name KJUR.asn1.x509 83 * @namespace 84 */ 85 if (typeof KJUR.asn1.x509 == "undefined" || !KJUR.asn1.x509) KJUR.asn1.x509 = {}; 86 87 // === BEGIN Certificate =================================================== 88 89 /** 90 * X.509 Certificate class to sign and generate hex encoded certificate 91 * @name KJUR.asn1.x509.Certificate 92 * @class X.509 Certificate class to sign and generate hex encoded certificate 93 * @param {Array} params associative array of parameters (ex. {'tbscertobj': obj, 'prvkeyobj': key}) 94 * @extends KJUR.asn1.ASN1Object 95 * @description 96 * <br/> 97 * As for argument 'params' for constructor, you can specify one of 98 * following properties: 99 * <ul> 100 * <li>tbscertobj - specify {@link KJUR.asn1.x509.TBSCertificate} object</li> 101 * <li>prvkeyobj - specify {@link RSAKey}, {@link KJUR.crypto.ECDSA} or {@link KJUR.crypto.DSA} object for CA private key to sign the certificate</li> 102 * </ul> 103 * NOTE1: 'params' can be omitted.<br/> 104 * NOTE2: DSA/ECDSA is also supported for CA signging key from asn1x509 1.0.6. 105 * @example 106 * var caKey = KEYUTIL.getKey(caKeyPEM); // CA's private key 107 * var cert = new KJUR.asn1x509.Certificate({'tbscertobj': tbs, 'prvkeyobj': caKey}); 108 * cert.sign(); // issue certificate by CA's private key 109 * var certPEM = cert.getPEMString(); 110 * 111 * // Certificate ::= SEQUENCE { 112 * // tbsCertificate TBSCertificate, 113 * // signatureAlgorithm AlgorithmIdentifier, 114 * // signature BIT STRING } 115 */ 116 KJUR.asn1.x509.Certificate = function(params) { 117 KJUR.asn1.x509.Certificate.superclass.constructor.call(this); 118 var asn1TBSCert = null, 119 asn1SignatureAlg = null, 120 asn1Sig = null, 121 hexSig = null, 122 prvKey = null, 123 _KJUR = KJUR, 124 _KJUR_crypto = _KJUR.crypto, 125 _KJUR_asn1 = _KJUR.asn1, 126 _DERSequence = _KJUR_asn1.DERSequence, 127 _DERBitString = _KJUR_asn1.DERBitString; 128 129 /** 130 * sign TBSCertificate and set signature value internally 131 * @name sign 132 * @memberOf KJUR.asn1.x509.Certificate# 133 * @function 134 * @description 135 * @example 136 * var cert = new KJUR.asn1.x509.Certificate({tbscertobj: tbs, prvkeyobj: prvKey}); 137 * cert.sign(); 138 */ 139 this.sign = function() { 140 this.asn1SignatureAlg = this.asn1TBSCert.asn1SignatureAlg; 141 142 var sig = new KJUR.crypto.Signature({alg: this.asn1SignatureAlg.nameAlg}); 143 sig.init(this.prvKey); 144 sig.updateHex(this.asn1TBSCert.getEncodedHex()); 145 this.hexSig = sig.sign(); 146 147 this.asn1Sig = new _DERBitString({'hex': '00' + this.hexSig}); 148 149 var seq = new _DERSequence({'array': [this.asn1TBSCert, 150 this.asn1SignatureAlg, 151 this.asn1Sig]}); 152 this.hTLV = seq.getEncodedHex(); 153 this.isModified = false; 154 }; 155 156 /** 157 * set signature value internally by hex string 158 * @name setSignatureHex 159 * @memberOf KJUR.asn1.x509.Certificate# 160 * @function 161 * @since asn1x509 1.0.8 162 * @description 163 * @example 164 * var cert = new KJUR.asn1.x509.Certificate({'tbscertobj': tbs}); 165 * cert.setSignatureHex('01020304'); 166 */ 167 this.setSignatureHex = function(sigHex) { 168 this.asn1SignatureAlg = this.asn1TBSCert.asn1SignatureAlg; 169 this.hexSig = sigHex; 170 this.asn1Sig = new _DERBitString({'hex': '00' + this.hexSig}); 171 172 var seq = new _DERSequence({'array': [this.asn1TBSCert, 173 this.asn1SignatureAlg, 174 this.asn1Sig]}); 175 this.hTLV = seq.getEncodedHex(); 176 this.isModified = false; 177 }; 178 179 this.getEncodedHex = function() { 180 if (this.isModified == false && this.hTLV != null) return this.hTLV; 181 throw "not signed yet"; 182 }; 183 184 /** 185 * get PEM formatted certificate string after signed 186 * @name getPEMString 187 * @memberOf KJUR.asn1.x509.Certificate# 188 * @function 189 * @return PEM formatted string of certificate 190 * @description 191 * @example 192 * var cert = new KJUR.asn1.x509.Certificate({'tbscertobj': tbs, 'prvkeyobj': prvKey}); 193 * cert.sign(); 194 * var sPEM = cert.getPEMString(); 195 */ 196 this.getPEMString = function() { 197 var pemBody = hextob64nl(this.getEncodedHex()); 198 return "-----BEGIN CERTIFICATE-----\r\n" + 199 pemBody + 200 "\r\n-----END CERTIFICATE-----\r\n"; 201 }; 202 203 if (params !== undefined) { 204 if (params.tbscertobj !== undefined) { 205 this.asn1TBSCert = params.tbscertobj; 206 } 207 if (params.prvkeyobj !== undefined) { 208 this.prvKey = params.prvkeyobj; 209 } 210 } 211 }; 212 YAHOO.lang.extend(KJUR.asn1.x509.Certificate, KJUR.asn1.ASN1Object); 213 214 /** 215 * ASN.1 TBSCertificate structure class 216 * @name KJUR.asn1.x509.TBSCertificate 217 * @class ASN.1 TBSCertificate structure class 218 * @param {Array} params associative array of parameters (ex. {}) 219 * @extends KJUR.asn1.ASN1Object 220 * @description 221 * <br/> 222 * <h4>EXAMPLE</h4> 223 * @example 224 * var o = new KJUR.asn1.x509.TBSCertificate(); 225 * o.setSerialNumberByParam({'int': 4}); 226 * o.setSignatureAlgByParam({'name': 'SHA1withRSA'}); 227 * o.setIssuerByParam({'str': '/C=US/O=a'}); 228 * o.setNotBeforeByParam({'str': '130504235959Z'}); 229 * o.setNotAfterByParam({'str': '140504235959Z'}); 230 * o.setSubjectByParam({'str': '/C=US/CN=b'}); 231 * o.setSubjectPublicKey(rsaPubKey); 232 * o.appendExtension(new KJUR.asn1.x509.BasicConstraints({'cA':true})); 233 * o.appendExtension(new KJUR.asn1.x509.KeyUsage({'bin':'11'})); 234 */ 235 KJUR.asn1.x509.TBSCertificate = function(params) { 236 KJUR.asn1.x509.TBSCertificate.superclass.constructor.call(this); 237 238 var _KJUR = KJUR, 239 _KJUR_asn1 = _KJUR.asn1, 240 _DERSequence = _KJUR_asn1.DERSequence, 241 _DERInteger = _KJUR_asn1.DERInteger, 242 _DERTaggedObject = _KJUR_asn1.DERTaggedObject, 243 _KJUR_asn1_x509 = _KJUR_asn1.x509, 244 _Time = _KJUR_asn1_x509.Time, 245 _X500Name = _KJUR_asn1_x509.X500Name, 246 _SubjectPublicKeyInfo = _KJUR_asn1_x509.SubjectPublicKeyInfo; 247 248 this._initialize = function() { 249 this.asn1Array = new Array(); 250 251 this.asn1Version = 252 new _DERTaggedObject({'obj': new _DERInteger({'int': 2})}); 253 this.asn1SerialNumber = null; 254 this.asn1SignatureAlg = null; 255 this.asn1Issuer = null; 256 this.asn1NotBefore = null; 257 this.asn1NotAfter = null; 258 this.asn1Subject = null; 259 this.asn1SubjPKey = null; 260 this.extensionsArray = new Array(); 261 }; 262 263 /** 264 * set serial number field by parameter 265 * @name setSerialNumberByParam 266 * @memberOf KJUR.asn1.x509.TBSCertificate# 267 * @function 268 * @param {Array} intParam DERInteger param 269 * @description 270 * @example 271 * tbsc.setSerialNumberByParam({'int': 3}); 272 */ 273 this.setSerialNumberByParam = function(intParam) { 274 this.asn1SerialNumber = new _DERInteger(intParam); 275 }; 276 277 /** 278 * set signature algorithm field by parameter 279 * @name setSignatureAlgByParam 280 * @memberOf KJUR.asn1.x509.TBSCertificate# 281 * @function 282 * @param {Array} algIdParam AlgorithmIdentifier parameter 283 * @description 284 * @example 285 * tbsc.setSignatureAlgByParam({'name': 'SHA1withRSA'}); 286 */ 287 this.setSignatureAlgByParam = function(algIdParam) { 288 this.asn1SignatureAlg = new _KJUR_asn1_x509.AlgorithmIdentifier(algIdParam); 289 }; 290 291 /** 292 * set issuer name field by parameter 293 * @name setIssuerByParam 294 * @memberOf KJUR.asn1.x509.TBSCertificate# 295 * @function 296 * @param {Array} x500NameParam X500Name parameter 297 * @description 298 * @example 299 * tbsc.setIssuerParam({'str': '/C=US/CN=b'}); 300 * @see KJUR.asn1.x509.X500Name 301 */ 302 this.setIssuerByParam = function(x500NameParam) { 303 this.asn1Issuer = new _X500Name(x500NameParam); 304 }; 305 306 /** 307 * set notBefore field by parameter 308 * @name setNotBeforeByParam 309 * @memberOf KJUR.asn1.x509.TBSCertificate# 310 * @function 311 * @param {Array} timeParam Time parameter 312 * @description 313 * @example 314 * tbsc.setNotBeforeByParam({'str': '130508235959Z'}); 315 * @see KJUR.asn1.x509.Time 316 */ 317 this.setNotBeforeByParam = function(timeParam) { 318 this.asn1NotBefore = new _Time(timeParam); 319 }; 320 321 /** 322 * set notAfter field by parameter 323 * @name setNotAfterByParam 324 * @memberOf KJUR.asn1.x509.TBSCertificate# 325 * @function 326 * @param {Array} timeParam Time parameter 327 * @description 328 * @example 329 * tbsc.setNotAfterByParam({'str': '130508235959Z'}); 330 * @see KJUR.asn1.x509.Time 331 */ 332 this.setNotAfterByParam = function(timeParam) { 333 this.asn1NotAfter = new _Time(timeParam); 334 }; 335 336 /** 337 * set subject name field by parameter 338 * @name setSubjectByParam 339 * @memberOf KJUR.asn1.x509.TBSCertificate# 340 * @function 341 * @param {Array} x500NameParam X500Name parameter 342 * @description 343 * @example 344 * tbsc.setSubjectParam({'str': '/C=US/CN=b'}); 345 * @see KJUR.asn1.x509.X500Name 346 */ 347 this.setSubjectByParam = function(x500NameParam) { 348 this.asn1Subject = new _X500Name(x500NameParam); 349 }; 350 351 /** 352 * set subject public key info field by key object 353 * @name setSubjectPublicKey 354 * @memberOf KJUR.asn1.x509.TBSCertificate# 355 * @function 356 * @param {Array} param {@link KJUR.asn1.x509.SubjectPublicKeyInfo} class constructor parameter 357 * @description 358 * @example 359 * tbsc.setSubjectPublicKey(keyobj); 360 * @see KJUR.asn1.x509.SubjectPublicKeyInfo 361 */ 362 this.setSubjectPublicKey = function(param) { 363 this.asn1SubjPKey = new _SubjectPublicKeyInfo(param); 364 }; 365 366 /** 367 * set subject public key info by RSA/ECDSA/DSA key parameter 368 * @name setSubjectPublicKeyByGetKey 369 * @memberOf KJUR.asn1.x509.TBSCertificate 370 * @function 371 * @param {Object} keyParam public key parameter which passed to {@link KEYUTIL.getKey} argument 372 * @description 373 * @example 374 * tbsc.setSubjectPublicKeyByGetKeyParam(certPEMString); // or 375 * tbsc.setSubjectPublicKeyByGetKeyParam(pkcs8PublicKeyPEMString); // or 376 * tbsc.setSubjectPublicKeyByGetKeyParam(kjurCryptoECDSAKeyObject); // et.al. 377 * @see KJUR.asn1.x509.SubjectPublicKeyInfo 378 * @see KEYUTIL.getKey 379 * @since asn1x509 1.0.6 380 */ 381 this.setSubjectPublicKeyByGetKey = function(keyParam) { 382 var keyObj = KEYUTIL.getKey(keyParam); 383 this.asn1SubjPKey = new _SubjectPublicKeyInfo(keyObj); 384 }; 385 386 /** 387 * append X.509v3 extension to this object 388 * @name appendExtension 389 * @memberOf KJUR.asn1.x509.TBSCertificate# 390 * @function 391 * @param {Extension} extObj X.509v3 Extension object 392 * @description 393 * @example 394 * tbsc.appendExtension(new KJUR.asn1.x509.BasicConstraints({'cA':true, 'critical': true})); 395 * tbsc.appendExtension(new KJUR.asn1.x509.KeyUsage({'bin':'11'})); 396 * @see KJUR.asn1.x509.Extension 397 */ 398 this.appendExtension = function(extObj) { 399 this.extensionsArray.push(extObj); 400 }; 401 402 /** 403 * append X.509v3 extension to this object by name and parameters 404 * @name appendExtensionByName 405 * @memberOf KJUR.asn1.x509.TBSCertificate# 406 * @function 407 * @param {name} name name of X.509v3 Extension object 408 * @param {Array} extParams parameters as argument of Extension constructor. 409 * @description 410 * @example 411 * var o = new KJUR.asn1.x509.TBSCertificate(); 412 * o.appendExtensionByName('BasicConstraints', {'cA':true, 'critical': true}); 413 * o.appendExtensionByName('KeyUsage', {'bin':'11'}); 414 * o.appendExtensionByName('CRLDistributionPoints', {uri: 'http://aaa.com/a.crl'}); 415 * o.appendExtensionByName('ExtKeyUsage', {array: [{name: 'clientAuth'}]}); 416 * o.appendExtensionByName('AuthorityKeyIdentifier', {kid: '1234ab..'}); 417 * o.appendExtensionByName('AuthorityInfoAccess', {array: [{accessMethod:{oid:...},accessLocation:{uri:...}}]}); 418 * @see KJUR.asn1.x509.Extension 419 */ 420 this.appendExtensionByName = function(name, extParams) { 421 KJUR.asn1.x509.Extension.appendByNameToArray(name, 422 extParams, 423 this.extensionsArray); 424 }; 425 426 this.getEncodedHex = function() { 427 if (this.asn1NotBefore == null || this.asn1NotAfter == null) 428 throw "notBefore and/or notAfter not set"; 429 var asn1Validity = 430 new _DERSequence({'array':[this.asn1NotBefore, this.asn1NotAfter]}); 431 432 this.asn1Array = new Array(); 433 434 this.asn1Array.push(this.asn1Version); 435 this.asn1Array.push(this.asn1SerialNumber); 436 this.asn1Array.push(this.asn1SignatureAlg); 437 this.asn1Array.push(this.asn1Issuer); 438 this.asn1Array.push(asn1Validity); 439 this.asn1Array.push(this.asn1Subject); 440 this.asn1Array.push(this.asn1SubjPKey); 441 442 if (this.extensionsArray.length > 0) { 443 var extSeq = new _DERSequence({"array": this.extensionsArray}); 444 var extTagObj = new _DERTaggedObject({'explicit': true, 445 'tag': 'a3', 446 'obj': extSeq}); 447 this.asn1Array.push(extTagObj); 448 } 449 450 var o = new _DERSequence({"array": this.asn1Array}); 451 this.hTLV = o.getEncodedHex(); 452 this.isModified = false; 453 return this.hTLV; 454 }; 455 456 this._initialize(); 457 }; 458 YAHOO.lang.extend(KJUR.asn1.x509.TBSCertificate, KJUR.asn1.ASN1Object); 459 460 // === END TBSCertificate =================================================== 461 462 // === BEGIN X.509v3 Extensions Related ======================================= 463 464 /** 465 * base Extension ASN.1 structure class 466 * @name KJUR.asn1.x509.Extension 467 * @class base Extension ASN.1 structure class 468 * @param {Array} params associative array of parameters (ex. {'critical': true}) 469 * @extends KJUR.asn1.ASN1Object 470 * @description 471 * @example 472 * // Extension ::= SEQUENCE { 473 * // extnID OBJECT IDENTIFIER, 474 * // critical BOOLEAN DEFAULT FALSE, 475 * // extnValue OCTET STRING } 476 */ 477 KJUR.asn1.x509.Extension = function(params) { 478 KJUR.asn1.x509.Extension.superclass.constructor.call(this); 479 var asn1ExtnValue = null, 480 _KJUR = KJUR, 481 _KJUR_asn1 = _KJUR.asn1, 482 _DERObjectIdentifier = _KJUR_asn1.DERObjectIdentifier, 483 _DEROctetString = _KJUR_asn1.DEROctetString, 484 _DERBitString = _KJUR_asn1.DERBitString, 485 _DERBoolean = _KJUR_asn1.DERBoolean, 486 _DERSequence = _KJUR_asn1.DERSequence; 487 488 this.getEncodedHex = function() { 489 var asn1Oid = new _DERObjectIdentifier({'oid': this.oid}); 490 var asn1EncapExtnValue = 491 new _DEROctetString({'hex': this.getExtnValueHex()}); 492 493 var asn1Array = new Array(); 494 asn1Array.push(asn1Oid); 495 if (this.critical) asn1Array.push(new _DERBoolean()); 496 asn1Array.push(asn1EncapExtnValue); 497 498 var asn1Seq = new _DERSequence({'array': asn1Array}); 499 return asn1Seq.getEncodedHex(); 500 }; 501 502 this.critical = false; 503 if (typeof params != "undefined") { 504 if (typeof params['critical'] != "undefined") { 505 this.critical = params['critical']; 506 } 507 } 508 }; 509 YAHOO.lang.extend(KJUR.asn1.x509.Extension, KJUR.asn1.ASN1Object); 510 511 /** 512 * append X.509v3 extension to any specified array<br/> 513 * @name appendByNameToArray 514 * @memberOf KJUR.asn1.x509.Extension 515 * @function 516 * @param {String} name X.509v3 extension name 517 * @param {Object} extParams associative array of extension parameters 518 * @param {Array} a array to add specified extension 519 * @see KJUR.asn1.x509.Extension 520 * @since jsrsasign 6.2.3 asn1x509 1.0.19 521 * @description 522 * This static function add a X.509v3 extension specified by name and extParams to 523 * array 'a' so that 'a' will be an array of X.509v3 extension objects. 524 * @example 525 * var a = new Array(); 526 * KJUR.asn1.x509.Extension.appendByNameToArray("BasicConstraints", {'cA':true, 'critical': true}, a); 527 * KJUR.asn1.x509.Extension.appendByNameToArray("KeyUsage", {'bin':'11'}, a); 528 */ 529 KJUR.asn1.x509.Extension.appendByNameToArray = function(name, extParams, a) { 530 var _lowname = name.toLowerCase(), 531 _KJUR_asn1_x509 = KJUR.asn1.x509; 532 533 if (_lowname == "basicconstraints") { 534 var extObj = new _KJUR_asn1_x509.BasicConstraints(extParams); 535 a.push(extObj); 536 } else if (_lowname == "keyusage") { 537 var extObj = new _KJUR_asn1_x509.KeyUsage(extParams); 538 a.push(extObj); 539 } else if (_lowname == "crldistributionpoints") { 540 var extObj = new _KJUR_asn1_x509.CRLDistributionPoints(extParams); 541 a.push(extObj); 542 } else if (_lowname == "extkeyusage") { 543 var extObj = new _KJUR_asn1_x509.ExtKeyUsage(extParams); 544 a.push(extObj); 545 } else if (_lowname == "authoritykeyidentifier") { 546 var extObj = new _KJUR_asn1_x509.AuthorityKeyIdentifier(extParams); 547 a.push(extObj); 548 } else if (_lowname == "authorityinfoaccess") { 549 var extObj = new _KJUR_asn1_x509.AuthorityInfoAccess(extParams); 550 a.push(extObj); 551 } else if (_lowname == "subjectaltname") { 552 var extObj = new _KJUR_asn1_x509.SubjectAltName(extParams); 553 a.push(extObj); 554 } else if (_lowname == "issueraltname") { 555 var extObj = new _KJUR_asn1_x509.IssuerAltName(extParams); 556 a.push(extObj); 557 } else { 558 throw "unsupported extension name: " + name; 559 } 560 }; 561 562 /** 563 * KeyUsage ASN.1 structure class 564 * @name KJUR.asn1.x509.KeyUsage 565 * @class KeyUsage ASN.1 structure class 566 * @param {Array} params associative array of parameters (ex. {'bin': '11', 'critical': true}) 567 * @extends KJUR.asn1.x509.Extension 568 * @description 569 * @example 570 */ 571 KJUR.asn1.x509.KeyUsage = function(params) { 572 KJUR.asn1.x509.KeyUsage.superclass.constructor.call(this, params); 573 574 this.getExtnValueHex = function() { 575 return this.asn1ExtnValue.getEncodedHex(); 576 }; 577 578 this.oid = "2.5.29.15"; 579 if (typeof params != "undefined") { 580 if (typeof params['bin'] != "undefined") { 581 this.asn1ExtnValue = new KJUR.asn1.DERBitString(params); 582 } 583 } 584 }; 585 YAHOO.lang.extend(KJUR.asn1.x509.KeyUsage, KJUR.asn1.x509.Extension); 586 587 /** 588 * BasicConstraints ASN.1 structure class 589 * @name KJUR.asn1.x509.BasicConstraints 590 * @class BasicConstraints ASN.1 structure class 591 * @param {Array} params associative array of parameters (ex. {'cA': true, 'critical': true}) 592 * @extends KJUR.asn1.x509.Extension 593 * @description 594 * @example 595 */ 596 KJUR.asn1.x509.BasicConstraints = function(params) { 597 KJUR.asn1.x509.BasicConstraints.superclass.constructor.call(this, params); 598 var cA = false; 599 var pathLen = -1; 600 601 this.getExtnValueHex = function() { 602 var asn1Array = new Array(); 603 if (this.cA) asn1Array.push(new KJUR.asn1.DERBoolean()); 604 if (this.pathLen > -1) 605 asn1Array.push(new KJUR.asn1.DERInteger({'int': this.pathLen})); 606 var asn1Seq = new KJUR.asn1.DERSequence({'array': asn1Array}); 607 this.asn1ExtnValue = asn1Seq; 608 return this.asn1ExtnValue.getEncodedHex(); 609 }; 610 611 this.oid = "2.5.29.19"; 612 this.cA = false; 613 this.pathLen = -1; 614 if (typeof params != "undefined") { 615 if (typeof params['cA'] != "undefined") { 616 this.cA = params['cA']; 617 } 618 if (typeof params['pathLen'] != "undefined") { 619 this.pathLen = params['pathLen']; 620 } 621 } 622 }; 623 YAHOO.lang.extend(KJUR.asn1.x509.BasicConstraints, KJUR.asn1.x509.Extension); 624 625 /** 626 * CRLDistributionPoints ASN.1 structure class 627 * @name KJUR.asn1.x509.CRLDistributionPoints 628 * @class CRLDistributionPoints ASN.1 structure class 629 * @param {Array} params associative array of parameters (ex. {'uri': 'http://a.com/', 'critical': true}) 630 * @extends KJUR.asn1.x509.Extension 631 * @description 632 * <pre> 633 * id-ce-cRLDistributionPoints OBJECT IDENTIFIER ::= { id-ce 31 } 634 * 635 * CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint 636 * 637 * DistributionPoint ::= SEQUENCE { 638 * distributionPoint [0] DistributionPointName OPTIONAL, 639 * reasons [1] ReasonFlags OPTIONAL, 640 * cRLIssuer [2] GeneralNames OPTIONAL } 641 * 642 * DistributionPointName ::= CHOICE { 643 * fullName [0] GeneralNames, 644 * nameRelativeToCRLIssuer [1] RelativeDistinguishedName } 645 * 646 * ReasonFlags ::= BIT STRING { 647 * unused (0), 648 * keyCompromise (1), 649 * cACompromise (2), 650 * affiliationChanged (3), 651 * superseded (4), 652 * cessationOfOperation (5), 653 * certificateHold (6), 654 * privilegeWithdrawn (7), 655 * aACompromise (8) } 656 * </pre> 657 * @example 658 */ 659 KJUR.asn1.x509.CRLDistributionPoints = function(params) { 660 KJUR.asn1.x509.CRLDistributionPoints.superclass.constructor.call(this, params); 661 var _KJUR = KJUR, 662 _KJUR_asn1 = _KJUR.asn1, 663 _KJUR_asn1_x509 = _KJUR_asn1.x509; 664 665 this.getExtnValueHex = function() { 666 return this.asn1ExtnValue.getEncodedHex(); 667 }; 668 669 this.setByDPArray = function(dpArray) { 670 this.asn1ExtnValue = new _KJUR_asn1.DERSequence({'array': dpArray}); 671 }; 672 673 this.setByOneURI = function(uri) { 674 var gn1 = new _KJUR_asn1_x509.GeneralNames([{'uri': uri}]); 675 var dpn1 = new _KJUR_asn1_x509.DistributionPointName(gn1); 676 var dp1 = new _KJUR_asn1_x509.DistributionPoint({'dpobj': dpn1}); 677 this.setByDPArray([dp1]); 678 }; 679 680 this.oid = "2.5.29.31"; 681 if (typeof params != "undefined") { 682 if (typeof params['array'] != "undefined") { 683 this.setByDPArray(params['array']); 684 } else if (typeof params['uri'] != "undefined") { 685 this.setByOneURI(params['uri']); 686 } 687 } 688 }; 689 YAHOO.lang.extend(KJUR.asn1.x509.CRLDistributionPoints, KJUR.asn1.x509.Extension); 690 691 /** 692 * KeyUsage ASN.1 structure class 693 * @name KJUR.asn1.x509.ExtKeyUsage 694 * @class ExtKeyUsage ASN.1 structure class 695 * @param {Array} params associative array of parameters 696 * @extends KJUR.asn1.x509.Extension 697 * @description 698 * @example 699 * e1 = new KJUR.asn1.x509.ExtKeyUsage({ 700 * critical: true, 701 * array: [ 702 * {oid: '2.5.29.37.0'}, // anyExtendedKeyUsage 703 * {name: 'clientAuth'} 704 * ] 705 * }); 706 * // id-ce-extKeyUsage OBJECT IDENTIFIER ::= { id-ce 37 } 707 * // ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId 708 * // KeyPurposeId ::= OBJECT IDENTIFIER 709 */ 710 KJUR.asn1.x509.ExtKeyUsage = function(params) { 711 KJUR.asn1.x509.ExtKeyUsage.superclass.constructor.call(this, params); 712 var _KJUR = KJUR, 713 _KJUR_asn1 = _KJUR.asn1; 714 715 this.setPurposeArray = function(purposeArray) { 716 this.asn1ExtnValue = new _KJUR_asn1.DERSequence(); 717 for (var i = 0; i < purposeArray.length; i++) { 718 var o = new _KJUR_asn1.DERObjectIdentifier(purposeArray[i]); 719 this.asn1ExtnValue.appendASN1Object(o); 720 } 721 }; 722 723 this.getExtnValueHex = function() { 724 return this.asn1ExtnValue.getEncodedHex(); 725 }; 726 727 this.oid = "2.5.29.37"; 728 if (typeof params != "undefined") { 729 if (typeof params['array'] != "undefined") { 730 this.setPurposeArray(params['array']); 731 } 732 } 733 }; 734 YAHOO.lang.extend(KJUR.asn1.x509.ExtKeyUsage, KJUR.asn1.x509.Extension); 735 736 /** 737 * AuthorityKeyIdentifier ASN.1 structure class 738 * @name KJUR.asn1.x509.AuthorityKeyIdentifier 739 * @class AuthorityKeyIdentifier ASN.1 structure class 740 * @param {Array} params associative array of parameters (ex. {'uri': 'http://a.com/', 'critical': true}) 741 * @extends KJUR.asn1.x509.Extension 742 * @since asn1x509 1.0.8 743 * @description 744 * <pre> 745 * d-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 35 } 746 * AuthorityKeyIdentifier ::= SEQUENCE { 747 * keyIdentifier [0] KeyIdentifier OPTIONAL, 748 * authorityCertIssuer [1] GeneralNames OPTIONAL, 749 * authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL } 750 * KeyIdentifier ::= OCTET STRING 751 * </pre> 752 * @example 753 * e1 = new KJUR.asn1.x509.AuthorityKeyIdentifier({ 754 * critical: true, 755 * kid: {hex: '89ab'}, 756 * issuer: {str: '/C=US/CN=a'}, 757 * sn: {hex: '1234'} 758 * }); 759 */ 760 KJUR.asn1.x509.AuthorityKeyIdentifier = function(params) { 761 KJUR.asn1.x509.AuthorityKeyIdentifier.superclass.constructor.call(this, params); 762 var _KJUR = KJUR, 763 _KJUR_asn1 = _KJUR.asn1, 764 _DERTaggedObject = _KJUR_asn1.DERTaggedObject; 765 766 this.asn1KID = null; 767 this.asn1CertIssuer = null; 768 this.asn1CertSN = null; 769 770 this.getExtnValueHex = function() { 771 var a = new Array(); 772 if (this.asn1KID) 773 a.push(new _DERTaggedObject({'explicit': false, 774 'tag': '80', 775 'obj': this.asn1KID})); 776 if (this.asn1CertIssuer) 777 a.push(new _DERTaggedObject({'explicit': false, 778 'tag': 'a1', 779 'obj': this.asn1CertIssuer})); 780 if (this.asn1CertSN) 781 a.push(new _DERTaggedObject({'explicit': false, 782 'tag': '82', 783 'obj': this.asn1CertSN})); 784 785 var asn1Seq = new _KJUR_asn1.DERSequence({'array': a}); 786 this.asn1ExtnValue = asn1Seq; 787 return this.asn1ExtnValue.getEncodedHex(); 788 }; 789 790 /** 791 * set keyIdentifier value by DERInteger parameter 792 * @name setKIDByParam 793 * @memberOf KJUR.asn1.x509.AuthorityKeyIdentifier# 794 * @function 795 * @param {Array} param array of {@link KJUR.asn1.DERInteger} parameter 796 * @since asn1x509 1.0.8 797 * @description 798 * NOTE: Automatic keyIdentifier value calculation by an issuer 799 * public key will be supported in future version. 800 */ 801 this.setKIDByParam = function(param) { 802 this.asn1KID = new KJUR.asn1.DEROctetString(param); 803 }; 804 805 /** 806 * set authorityCertIssuer value by X500Name parameter 807 * @name setCertIssuerByParam 808 * @memberOf KJUR.asn1.x509.AuthorityKeyIdentifier# 809 * @function 810 * @param {Array} param array of {@link KJUR.asn1.x509.X500Name} parameter 811 * @since asn1x509 1.0.8 812 * @description 813 * NOTE: Automatic authorityCertIssuer name setting by an issuer 814 * certificate will be supported in future version. 815 */ 816 this.setCertIssuerByParam = function(param) { 817 this.asn1CertIssuer = new KJUR.asn1.x509.X500Name(param); 818 }; 819 820 /** 821 * set authorityCertSerialNumber value by DERInteger parameter 822 * @name setCertSerialNumberByParam 823 * @memberOf KJUR.asn1.x509.AuthorityKeyIdentifier# 824 * @function 825 * @param {Array} param array of {@link KJUR.asn1.DERInteger} parameter 826 * @since asn1x509 1.0.8 827 * @description 828 * NOTE: Automatic authorityCertSerialNumber setting by an issuer 829 * certificate will be supported in future version. 830 */ 831 this.setCertSNByParam = function(param) { 832 this.asn1CertSN = new KJUR.asn1.DERInteger(param); 833 }; 834 835 this.oid = "2.5.29.35"; 836 if (typeof params != "undefined") { 837 if (typeof params['kid'] != "undefined") { 838 this.setKIDByParam(params['kid']); 839 } 840 if (typeof params['issuer'] != "undefined") { 841 this.setCertIssuerByParam(params['issuer']); 842 } 843 if (typeof params['sn'] != "undefined") { 844 this.setCertSNByParam(params['sn']); 845 } 846 } 847 }; 848 YAHOO.lang.extend(KJUR.asn1.x509.AuthorityKeyIdentifier, KJUR.asn1.x509.Extension); 849 850 /** 851 * AuthorityInfoAccess ASN.1 structure class 852 * @name KJUR.asn1.x509.AuthorityInfoAccess 853 * @class AuthorityInfoAccess ASN.1 structure class 854 * @param {Array} params associative array of parameters 855 * @extends KJUR.asn1.x509.Extension 856 * @since asn1x509 1.0.8 857 * @description 858 * <pre> 859 * id-pe OBJECT IDENTIFIER ::= { id-pkix 1 } 860 * id-pe-authorityInfoAccess OBJECT IDENTIFIER ::= { id-pe 1 } 861 * AuthorityInfoAccessSyntax ::= 862 * SEQUENCE SIZE (1..MAX) OF AccessDescription 863 * AccessDescription ::= SEQUENCE { 864 * accessMethod OBJECT IDENTIFIER, 865 * accessLocation GeneralName } 866 * id-ad OBJECT IDENTIFIER ::= { id-pkix 48 } 867 * id-ad-caIssuers OBJECT IDENTIFIER ::= { id-ad 2 } 868 * id-ad-ocsp OBJECT IDENTIFIER ::= { id-ad 1 } 869 * </pre> 870 * @example 871 * e1 = new KJUR.asn1.x509.AuthorityInfoAccess({ 872 * array: [{ 873 * accessMethod:{'oid': '1.3.6.1.5.5.7.48.1'}, 874 * accessLocation:{'uri': 'http://ocsp.cacert.org'} 875 * }] 876 * }); 877 */ 878 KJUR.asn1.x509.AuthorityInfoAccess = function(params) { 879 KJUR.asn1.x509.AuthorityInfoAccess.superclass.constructor.call(this, params); 880 881 this.setAccessDescriptionArray = function(accessDescriptionArray) { 882 var array = new Array(), 883 _KJUR = KJUR, 884 _KJUR_asn1 = _KJUR.asn1, 885 _DERSequence = _KJUR_asn1.DERSequence; 886 887 for (var i = 0; i < accessDescriptionArray.length; i++) { 888 var o = new _KJUR_asn1.DERObjectIdentifier(accessDescriptionArray[i].accessMethod); 889 var gn = new _KJUR_asn1.x509.GeneralName(accessDescriptionArray[i].accessLocation); 890 var accessDescription = new _DERSequence({'array':[o, gn]}); 891 array.push(accessDescription); 892 } 893 this.asn1ExtnValue = new _DERSequence({'array':array}); 894 }; 895 896 this.getExtnValueHex = function() { 897 return this.asn1ExtnValue.getEncodedHex(); 898 }; 899 900 this.oid = "1.3.6.1.5.5.7.1.1"; 901 if (typeof params != "undefined") { 902 if (typeof params['array'] != "undefined") { 903 this.setAccessDescriptionArray(params['array']); 904 } 905 } 906 }; 907 YAHOO.lang.extend(KJUR.asn1.x509.AuthorityInfoAccess, KJUR.asn1.x509.Extension); 908 909 /** 910 * SubjectAltName ASN.1 structure class<br/> 911 * @name KJUR.asn1.x509.SubjectAltName 912 * @class SubjectAltName ASN.1 structure class 913 * @param {Array} params associative array of parameters 914 * @extends KJUR.asn1.x509.Extension 915 * @since jsrsasign 6.2.3 asn1x509 1.0.19 916 * @see KJUR.asn1.x509.GeneralNames 917 * @see KJUR.asn1.x509.GeneralName 918 * @description 919 * This class provides X.509v3 SubjectAltName extension. 920 * <pre> 921 * id-ce-subjectAltName OBJECT IDENTIFIER ::= { id-ce 17 } 922 * SubjectAltName ::= GeneralNames 923 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName 924 * GeneralName ::= CHOICE { 925 * otherName [0] OtherName, 926 * rfc822Name [1] IA5String, 927 * dNSName [2] IA5String, 928 * x400Address [3] ORAddress, 929 * directoryName [4] Name, 930 * ediPartyName [5] EDIPartyName, 931 * uniformResourceIdentifier [6] IA5String, 932 * iPAddress [7] OCTET STRING, 933 * registeredID [8] OBJECT IDENTIFIER } 934 * </pre> 935 * @example 936 * e1 = new KJUR.asn1.x509.SubjectAltName({ 937 * critical: true, 938 * array: [{uri: 'http://aaa.com/'}, {uri: 'http://bbb.com/'}] 939 * }); 940 */ 941 KJUR.asn1.x509.SubjectAltName = function(params) { 942 KJUR.asn1.x509.SubjectAltName.superclass.constructor.call(this, params) 943 944 this.setNameArray = function(paramsArray) { 945 this.asn1ExtnValue = new KJUR.asn1.x509.GeneralNames(paramsArray); 946 }; 947 948 this.getExtnValueHex = function() { 949 return this.asn1ExtnValue.getEncodedHex(); 950 }; 951 952 this.oid = "2.5.29.17"; 953 if (params !== undefined) { 954 if (params.array !== undefined) { 955 this.setNameArray(params.array); 956 } 957 } 958 }; 959 YAHOO.lang.extend(KJUR.asn1.x509.SubjectAltName, KJUR.asn1.x509.Extension); 960 961 /** 962 * IssuerAltName ASN.1 structure class<br/> 963 * @name KJUR.asn1.x509.IssuerAltName 964 * @class IssuerAltName ASN.1 structure class 965 * @param {Array} params associative array of parameters 966 * @extends KJUR.asn1.x509.Extension 967 * @since jsrsasign 6.2.3 asn1x509 1.0.19 968 * @see KJUR.asn1.x509.GeneralNames 969 * @see KJUR.asn1.x509.GeneralName 970 * @description 971 * This class provides X.509v3 IssuerAltName extension. 972 * <pre> 973 * id-ce-subjectAltName OBJECT IDENTIFIER ::= { id-ce 18 } 974 * IssuerAltName ::= GeneralNames 975 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName 976 * GeneralName ::= CHOICE { 977 * otherName [0] OtherName, 978 * rfc822Name [1] IA5String, 979 * dNSName [2] IA5String, 980 * x400Address [3] ORAddress, 981 * directoryName [4] Name, 982 * ediPartyName [5] EDIPartyName, 983 * uniformResourceIdentifier [6] IA5String, 984 * iPAddress [7] OCTET STRING, 985 * registeredID [8] OBJECT IDENTIFIER } 986 * </pre> 987 * @example 988 * e1 = new KJUR.asn1.x509.IssuerAltName({ 989 * critical: true, 990 * array: [{uri: 'http://aaa.com/'}, {uri: 'http://bbb.com/'}] 991 * }); 992 */ 993 KJUR.asn1.x509.IssuerAltName = function(params) { 994 KJUR.asn1.x509.IssuerAltName.superclass.constructor.call(this, params) 995 996 this.setNameArray = function(paramsArray) { 997 this.asn1ExtnValue = new KJUR.asn1.x509.GeneralNames(paramsArray); 998 }; 999 1000 this.getExtnValueHex = function() { 1001 return this.asn1ExtnValue.getEncodedHex(); 1002 }; 1003 1004 this.oid = "2.5.29.18"; 1005 if (params !== undefined) { 1006 if (params.array !== undefined) { 1007 this.setNameArray(params.array); 1008 } 1009 } 1010 }; 1011 YAHOO.lang.extend(KJUR.asn1.x509.IssuerAltName, KJUR.asn1.x509.Extension); 1012 1013 // === END X.509v3 Extensions Related ======================================= 1014 1015 // === BEGIN CRL Related =================================================== 1016 /** 1017 * X.509 CRL class to sign and generate hex encoded CRL 1018 * @name KJUR.asn1.x509.CRL 1019 * @class X.509 CRL class to sign and generate hex encoded certificate 1020 * @param {Array} params associative array of parameters (ex. {'tbsobj': obj, 'rsaprvkey': key}) 1021 * @extends KJUR.asn1.ASN1Object 1022 * @since 1.0.3 1023 * @description 1024 * <br/> 1025 * As for argument 'params' for constructor, you can specify one of 1026 * following properties: 1027 * <ul> 1028 * <li>tbsobj - specify {@link KJUR.asn1.x509.TBSCertList} object to be signed</li> 1029 * <li>rsaprvkey - specify {@link RSAKey} object CA private key</li> 1030 * </ul> 1031 * NOTE: 'params' can be omitted. 1032 * <h4>EXAMPLE</h4> 1033 * @example 1034 * var prvKey = new RSAKey(); // CA's private key 1035 * prvKey.readPrivateKeyFromASN1HexString("3080..."); 1036 * var crl = new KJUR.asn1x509.CRL({'tbsobj': tbs, 'prvkeyobj': prvKey}); 1037 * crl.sign(); // issue CRL by CA's private key 1038 * var hCRL = crl.getEncodedHex(); 1039 * 1040 * // CertificateList ::= SEQUENCE { 1041 * // tbsCertList TBSCertList, 1042 * // signatureAlgorithm AlgorithmIdentifier, 1043 * // signatureValue BIT STRING } 1044 */ 1045 KJUR.asn1.x509.CRL = function(params) { 1046 KJUR.asn1.x509.CRL.superclass.constructor.call(this); 1047 1048 var asn1TBSCertList = null, 1049 asn1SignatureAlg = null, 1050 asn1Sig = null, 1051 hexSig = null, 1052 prvKey = null; 1053 1054 /** 1055 * sign TBSCertList and set signature value internally 1056 * @name sign 1057 * @memberOf KJUR.asn1.x509.CRL# 1058 * @function 1059 * @description 1060 * @example 1061 * var cert = new KJUR.asn1.x509.CRL({'tbsobj': tbs, 'prvkeyobj': prvKey}); 1062 * cert.sign(); 1063 */ 1064 this.sign = function() { 1065 this.asn1SignatureAlg = this.asn1TBSCertList.asn1SignatureAlg; 1066 1067 sig = new KJUR.crypto.Signature({'alg': 'SHA1withRSA', 'prov': 'cryptojs/jsrsa'}); 1068 sig.initSign(this.prvKey); 1069 sig.updateHex(this.asn1TBSCertList.getEncodedHex()); 1070 this.hexSig = sig.sign(); 1071 1072 this.asn1Sig = new KJUR.asn1.DERBitString({'hex': '00' + this.hexSig}); 1073 1074 var seq = new KJUR.asn1.DERSequence({'array': [this.asn1TBSCertList, 1075 this.asn1SignatureAlg, 1076 this.asn1Sig]}); 1077 this.hTLV = seq.getEncodedHex(); 1078 this.isModified = false; 1079 }; 1080 1081 this.getEncodedHex = function() { 1082 if (this.isModified == false && this.hTLV != null) return this.hTLV; 1083 throw "not signed yet"; 1084 }; 1085 1086 /** 1087 * get PEM formatted CRL string after signed 1088 * @name getPEMString 1089 * @memberOf KJUR.asn1.x509.CRL# 1090 * @function 1091 * @return PEM formatted string of certificate 1092 * @description 1093 * @example 1094 * var cert = new KJUR.asn1.x509.CRL({'tbsobj': tbs, 'rsaprvkey': prvKey}); 1095 * cert.sign(); 1096 * var sPEM = cert.getPEMString(); 1097 */ 1098 this.getPEMString = function() { 1099 var pemBody = hextob64nl(this.getEncodedHex()); 1100 return "-----BEGIN X509 CRL-----\r\n" + 1101 pemBody + 1102 "\r\n-----END X509 CRL-----\r\n"; 1103 }; 1104 1105 if (params !== undefined) { 1106 if (params.tbsobj !== undefined) { 1107 this.asn1TBSCertList = params.tbsobj; 1108 } 1109 if (params.prvkeyobj !== undefined) { 1110 this.prvKey = params.prvkeyobj; 1111 } 1112 } 1113 }; 1114 YAHOO.lang.extend(KJUR.asn1.x509.CRL, KJUR.asn1.ASN1Object); 1115 1116 /** 1117 * ASN.1 TBSCertList structure class for CRL 1118 * @name KJUR.asn1.x509.TBSCertList 1119 * @class ASN.1 TBSCertList structure class for CRL 1120 * @param {Array} params associative array of parameters (ex. {}) 1121 * @extends KJUR.asn1.ASN1Object 1122 * @since 1.0.3 1123 * @description 1124 * <br/> 1125 * <h4>EXAMPLE</h4> 1126 * @example 1127 * var o = new KJUR.asn1.x509.TBSCertList(); 1128 * o.setSignatureAlgByParam({'name': 'SHA1withRSA'}); 1129 * o.setIssuerByParam({'str': '/C=US/O=a'}); 1130 * o.setNotThisUpdateByParam({'str': '130504235959Z'}); 1131 * o.setNotNextUpdateByParam({'str': '140504235959Z'}); 1132 * o.addRevokedCert({'int': 4}, {'str':'130514235959Z'})); 1133 * o.addRevokedCert({'hex': '0f34dd'}, {'str':'130514235959Z'})); 1134 * 1135 * // TBSCertList ::= SEQUENCE { 1136 * // version Version OPTIONAL, 1137 * // -- if present, MUST be v2 1138 * // signature AlgorithmIdentifier, 1139 * // issuer Name, 1140 * // thisUpdate Time, 1141 * // nextUpdate Time OPTIONAL, 1142 * // revokedCertificates SEQUENCE OF SEQUENCE { 1143 * // userCertificate CertificateSerialNumber, 1144 * // revocationDate Time, 1145 * // crlEntryExtensions Extensions OPTIONAL 1146 * // -- if present, version MUST be v2 1147 * // } OPTIONAL, 1148 * // crlExtensions [0] EXPLICIT Extensions OPTIONAL 1149 */ 1150 KJUR.asn1.x509.TBSCertList = function(params) { 1151 KJUR.asn1.x509.TBSCertList.superclass.constructor.call(this); 1152 var aRevokedCert = null, 1153 _KJUR = KJUR, 1154 _KJUR_asn1 = _KJUR.asn1, 1155 _DERSequence = _KJUR_asn1.DERSequence, 1156 _KJUR_asn1_x509 = _KJUR_asn1.x509, 1157 _Time = _KJUR_asn1_x509.Time; 1158 1159 /** 1160 * set signature algorithm field by parameter 1161 * @name setSignatureAlgByParam 1162 * @memberOf KJUR.asn1.x509.TBSCertList# 1163 * @function 1164 * @param {Array} algIdParam AlgorithmIdentifier parameter 1165 * @description 1166 * @example 1167 * tbsc.setSignatureAlgByParam({'name': 'SHA1withRSA'}); 1168 */ 1169 this.setSignatureAlgByParam = function(algIdParam) { 1170 this.asn1SignatureAlg = 1171 new _KJUR_asn1_x509.AlgorithmIdentifier(algIdParam); 1172 }; 1173 1174 /** 1175 * set issuer name field by parameter 1176 * @name setIssuerByParam 1177 * @memberOf KJUR.asn1.x509.TBSCertList# 1178 * @function 1179 * @param {Array} x500NameParam X500Name parameter 1180 * @description 1181 * @example 1182 * tbsc.setIssuerParam({'str': '/C=US/CN=b'}); 1183 * @see KJUR.asn1.x509.X500Name 1184 */ 1185 this.setIssuerByParam = function(x500NameParam) { 1186 this.asn1Issuer = new _KJUR_asn1_x509.X500Name(x500NameParam); 1187 }; 1188 1189 /** 1190 * set thisUpdate field by parameter 1191 * @name setThisUpdateByParam 1192 * @memberOf KJUR.asn1.x509.TBSCertList# 1193 * @function 1194 * @param {Array} timeParam Time parameter 1195 * @description 1196 * @example 1197 * tbsc.setThisUpdateByParam({'str': '130508235959Z'}); 1198 * @see KJUR.asn1.x509.Time 1199 */ 1200 this.setThisUpdateByParam = function(timeParam) { 1201 this.asn1ThisUpdate = new _Time(timeParam); 1202 }; 1203 1204 /** 1205 * set nextUpdate field by parameter 1206 * @name setNextUpdateByParam 1207 * @memberOf KJUR.asn1.x509.TBSCertList# 1208 * @function 1209 * @param {Array} timeParam Time parameter 1210 * @description 1211 * @example 1212 * tbsc.setNextUpdateByParam({'str': '130508235959Z'}); 1213 * @see KJUR.asn1.x509.Time 1214 */ 1215 this.setNextUpdateByParam = function(timeParam) { 1216 this.asn1NextUpdate = new _Time(timeParam); 1217 }; 1218 1219 /** 1220 * add revoked certificate by parameter 1221 * @name addRevokedCert 1222 * @memberOf KJUR.asn1.x509.TBSCertList# 1223 * @function 1224 * @param {Array} snParam DERInteger parameter for certificate serial number 1225 * @param {Array} timeParam Time parameter for revocation date 1226 * @description 1227 * @example 1228 * tbsc.addRevokedCert({'int': 3}, {'str': '130508235959Z'}); 1229 * @see KJUR.asn1.x509.Time 1230 */ 1231 this.addRevokedCert = function(snParam, timeParam) { 1232 var param = {}; 1233 if (snParam != undefined && snParam != null) 1234 param['sn'] = snParam; 1235 if (timeParam != undefined && timeParam != null) 1236 param['time'] = timeParam; 1237 var o = new _KJUR_asn1_x509.CRLEntry(param); 1238 this.aRevokedCert.push(o); 1239 }; 1240 1241 this.getEncodedHex = function() { 1242 this.asn1Array = new Array(); 1243 1244 if (this.asn1Version != null) this.asn1Array.push(this.asn1Version); 1245 this.asn1Array.push(this.asn1SignatureAlg); 1246 this.asn1Array.push(this.asn1Issuer); 1247 this.asn1Array.push(this.asn1ThisUpdate); 1248 if (this.asn1NextUpdate != null) this.asn1Array.push(this.asn1NextUpdate); 1249 1250 if (this.aRevokedCert.length > 0) { 1251 var seq = new _DERSequence({'array': this.aRevokedCert}); 1252 this.asn1Array.push(seq); 1253 } 1254 1255 var o = new _DERSequence({"array": this.asn1Array}); 1256 this.hTLV = o.getEncodedHex(); 1257 this.isModified = false; 1258 return this.hTLV; 1259 }; 1260 1261 this._initialize = function() { 1262 this.asn1Version = null; 1263 this.asn1SignatureAlg = null; 1264 this.asn1Issuer = null; 1265 this.asn1ThisUpdate = null; 1266 this.asn1NextUpdate = null; 1267 this.aRevokedCert = new Array(); 1268 }; 1269 1270 this._initialize(); 1271 }; 1272 YAHOO.lang.extend(KJUR.asn1.x509.TBSCertList, KJUR.asn1.ASN1Object); 1273 1274 /** 1275 * ASN.1 CRLEntry structure class for CRL 1276 * @name KJUR.asn1.x509.CRLEntry 1277 * @class ASN.1 CRLEntry structure class for CRL 1278 * @param {Array} params associative array of parameters (ex. {}) 1279 * @extends KJUR.asn1.ASN1Object 1280 * @since 1.0.3 1281 * @description 1282 * @example 1283 * var e = new KJUR.asn1.x509.CRLEntry({'time': {'str': '130514235959Z'}, 'sn': {'int': 234}}); 1284 * 1285 * // revokedCertificates SEQUENCE OF SEQUENCE { 1286 * // userCertificate CertificateSerialNumber, 1287 * // revocationDate Time, 1288 * // crlEntryExtensions Extensions OPTIONAL 1289 * // -- if present, version MUST be v2 } 1290 */ 1291 KJUR.asn1.x509.CRLEntry = function(params) { 1292 KJUR.asn1.x509.CRLEntry.superclass.constructor.call(this); 1293 var sn = null, 1294 time = null, 1295 _KJUR = KJUR, 1296 _KJUR_asn1 = _KJUR.asn1; 1297 1298 /** 1299 * set DERInteger parameter for serial number of revoked certificate 1300 * @name setCertSerial 1301 * @memberOf KJUR.asn1.x509.CRLEntry 1302 * @function 1303 * @param {Array} intParam DERInteger parameter for certificate serial number 1304 * @description 1305 * @example 1306 * entry.setCertSerial({'int': 3}); 1307 */ 1308 this.setCertSerial = function(intParam) { 1309 this.sn = new _KJUR_asn1.DERInteger(intParam); 1310 }; 1311 1312 /** 1313 * set Time parameter for revocation date 1314 * @name setRevocationDate 1315 * @memberOf KJUR.asn1.x509.CRLEntry 1316 * @function 1317 * @param {Array} timeParam Time parameter for revocation date 1318 * @description 1319 * @example 1320 * entry.setRevocationDate({'str': '130508235959Z'}); 1321 */ 1322 this.setRevocationDate = function(timeParam) { 1323 this.time = new _KJUR_asn1.x509.Time(timeParam); 1324 }; 1325 1326 this.getEncodedHex = function() { 1327 var o = new _KJUR_asn1.DERSequence({"array": [this.sn, this.time]}); 1328 this.TLV = o.getEncodedHex(); 1329 return this.TLV; 1330 }; 1331 1332 if (params !== undefined) { 1333 if (params.time !== undefined) { 1334 this.setRevocationDate(params.time); 1335 } 1336 if (params.sn !== undefined) { 1337 this.setCertSerial(params.sn); 1338 } 1339 } 1340 }; 1341 YAHOO.lang.extend(KJUR.asn1.x509.CRLEntry, KJUR.asn1.ASN1Object); 1342 1343 // === END CRL Related =================================================== 1344 1345 // === BEGIN X500Name Related ================================================= 1346 /** 1347 * X500Name ASN.1 structure class 1348 * @name KJUR.asn1.x509.X500Name 1349 * @class X500Name ASN.1 structure class 1350 * @param {Array} params associative array of parameters (ex. {'str': '/C=US/O=a'}) 1351 * @extends KJUR.asn1.ASN1Object 1352 * @see KJUR.asn1.x509.X500Name 1353 * @see KJUR.asn1.x509.RDN 1354 * @see KJUR.asn1.x509.AttributeTypeAndValue 1355 * @description 1356 * This class provides DistinguishedName ASN.1 class structure 1357 * defined in <a href="https://tools.ietf.org/html/rfc2253#section-2">RFC 2253 section 2</a>. 1358 * <blockquote><pre> 1359 * DistinguishedName ::= RDNSequence 1360 * 1361 * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName 1362 * 1363 * RelativeDistinguishedName ::= SET SIZE (1..MAX) OF 1364 * AttributeTypeAndValue 1365 * 1366 * AttributeTypeAndValue ::= SEQUENCE { 1367 * type AttributeType, 1368 * value AttributeValue } 1369 * </pre></blockquote> 1370 * <br/> 1371 * For string representation of distinguished name in jsrsasign, 1372 * OpenSSL oneline format is used. Please see <a href="https://github.com/kjur/jsrsasign/wiki/NOTE-distinguished-name-representation-in-jsrsasign">wiki article</a> for it. 1373 * <br/> 1374 * NOTE: Multi-valued RDN is supported since jsrsasign 6.2.1 asn1x509 1.0.17. 1375 * @example 1376 * // 1. construct with string 1377 * o = new KJUR.asn1.x509.X500Name({str: "/C=US/O=aaa/OU=bbb/CN=foo@example.com"}); 1378 * o = new KJUR.asn1.x509.X500Name({str: "/C=US/O=aaa+CN=contact@example.com"}); // multi valued 1379 * // 2. construct by object 1380 * o = new KJUR.asn1.x509.X500Name({C: "US", O: "aaa", CN: "http://example.com/"}); 1381 */ 1382 KJUR.asn1.x509.X500Name = function(params) { 1383 KJUR.asn1.x509.X500Name.superclass.constructor.call(this); 1384 this.asn1Array = new Array(); 1385 var _KJUR = KJUR, 1386 _KJUR_asn1 = _KJUR.asn1, 1387 _KJUR_asn1_x509 = _KJUR_asn1.x509, 1388 _pemtohex = pemtohex; 1389 1390 /** 1391 * set DN by OpenSSL oneline distinguished name string<br/> 1392 * @name setByString 1393 * @memberOf KJUR.asn1.x509.X500Name# 1394 * @function 1395 * @param {String} dnStr distinguished name by string (ex. /C=US/O=aaa) 1396 * @description 1397 * @example 1398 * name = new KJUR.asn1.x509.X500Name(); 1399 * name.setByString("/C=US/O=aaa/OU=bbb/CN=foo@example.com"); 1400 */ 1401 this.setByString = function(dnStr) { 1402 var a = dnStr.split('/'); 1403 a.shift(); 1404 for (var i = 0; i < a.length; i++) { 1405 this.asn1Array.push(new _KJUR_asn1_x509.RDN({'str':a[i]})); 1406 } 1407 }; 1408 1409 /** 1410 * set DN by LDAP(RFC 2253) distinguished name string<br/> 1411 * @name setByLdapString 1412 * @memberOf KJUR.asn1.x509.X500Name# 1413 * @function 1414 * @param {String} dnStr distinguished name by LDAP string (ex. O=aaa,C=US) 1415 * @since jsrsasign 6.2.2 asn1x509 1.0.18 1416 * @description 1417 * @example 1418 * name = new KJUR.asn1.x509.X500Name(); 1419 * name.setByLdapString("CN=foo@example.com,OU=bbb,O=aaa,C=US"); 1420 */ 1421 this.setByLdapString = function(dnStr) { 1422 var oneline = _KJUR_asn1_x509.X500Name.ldapToOneline(dnStr); 1423 this.setByString(oneline); 1424 }; 1425 1426 /** 1427 * set DN by associative array<br/> 1428 * @name setByObject 1429 * @memberOf KJUR.asn1.x509.X500Name# 1430 * @function 1431 * @param {Array} dnObj associative array of DN (ex. {C: "US", O: "aaa"}) 1432 * @since jsrsasign 4.9. asn1x509 1.0.13 1433 * @description 1434 * @example 1435 * name = new KJUR.asn1.x509.X500Name(); 1436 * name.setByObject({C: "US", O: "aaa", CN="http://example.com/"1}); 1437 */ 1438 this.setByObject = function(dnObj) { 1439 // Get all the dnObject attributes and stuff them in the ASN.1 array. 1440 for (var x in dnObj) { 1441 if (dnObj.hasOwnProperty(x)) { 1442 var newRDN = new KJUR.asn1.x509.RDN( 1443 {'str': x + '=' + dnObj[x]}); 1444 // Initialize or push into the ANS1 array. 1445 this.asn1Array ? this.asn1Array.push(newRDN) 1446 : this.asn1Array = [newRDN]; 1447 } 1448 } 1449 }; 1450 1451 this.getEncodedHex = function() { 1452 if (typeof this.hTLV == "string") return this.hTLV; 1453 var o = new _KJUR_asn1.DERSequence({"array": this.asn1Array}); 1454 this.hTLV = o.getEncodedHex(); 1455 return this.hTLV; 1456 }; 1457 1458 if (params !== undefined) { 1459 if (params.str !== undefined) { 1460 this.setByString(params.str); 1461 } else if (params.ldapstr !== undefined) { 1462 this.setByLdapString(params.ldapstr); 1463 // If params is an object, then set the ASN1 array just using the object 1464 // attributes. This is nice for fields that have lots of special 1465 // characters (i.e. CN: 'https://www.github.com/kjur//'). 1466 } else if (typeof params === "object") { 1467 this.setByObject(params); 1468 } 1469 1470 if (params.certissuer !== undefined) { 1471 var x = new X509(); 1472 x.hex = _pemtohex(params.certissuer); 1473 this.hTLV = x.getIssuerHex(); 1474 } 1475 if (params.certsubject !== undefined) { 1476 var x = new X509(); 1477 x.hex = _pemtohex(params.certsubject); 1478 this.hTLV = x.getSubjectHex(); 1479 } 1480 } 1481 }; 1482 YAHOO.lang.extend(KJUR.asn1.x509.X500Name, KJUR.asn1.ASN1Object); 1483 1484 /** 1485 * convert OpenSSL oneline distinguished name format string to LDAP(RFC 2253) format<br/> 1486 * @name onelineToLDAP 1487 * @memberOf KJUR.asn1.x509.X500Name 1488 * @function 1489 * @param {String} s distinguished name string in OpenSSL oneline format (ex. /C=US/O=test) 1490 * @return {String} distinguished name string in LDAP(RFC 2253) format (ex. O=test,C=US) 1491 * @since jsrsasign 6.2.2 asn1x509 1.0.18 1492 * @description 1493 * This static method converts a distinguished name string in OpenSSL oneline 1494 * format to LDAP(RFC 2253) format. 1495 * @see <a href="https://github.com/kjur/jsrsasign/wiki/NOTE-distinguished-name-representation-in-jsrsasign">jsrsasign wiki: distinguished name string difference between OpenSSL oneline and LDAP(RFC 2253)</a> 1496 * @example 1497 * KJUR.asn1.x509.X500Name.onelineToLDAP("/C=US/O=test") → 'O=test,C=US' 1498 * KJUR.asn1.x509.X500Name.onelineToLDAP("/C=US/O=a,a") → 'O=a\,a,C=US' 1499 */ 1500 KJUR.asn1.x509.X500Name.onelineToLDAP = function(s) { 1501 if (s.substr(0, 1) !== "/") throw "malformed input"; 1502 1503 var result = ""; 1504 s = s.substr(1); 1505 1506 var a = s.split("/"); 1507 a.reverse(); 1508 a = a.map(function(s) {return s.replace(/,/, "\\,")}); 1509 1510 return a.join(","); 1511 }; 1512 1513 /** 1514 * convert LDAP(RFC 2253) distinguished name format string to OpenSSL oneline format<br/> 1515 * @name ldapToOneline 1516 * @memberOf KJUR.asn1.x509.X500Name 1517 * @function 1518 * @param {String} s distinguished name string in LDAP(RFC 2253) format (ex. O=test,C=US) 1519 * @return {String} distinguished name string in OpenSSL oneline format (ex. /C=US/O=test) 1520 * @since jsrsasign 6.2.2 asn1x509 1.0.18 1521 * @description 1522 * This static method converts a distinguished name string in 1523 * LDAP(RFC 2253) format to OpenSSL oneline format. 1524 * @see <a href="https://github.com/kjur/jsrsasign/wiki/NOTE-distinguished-name-representation-in-jsrsasign">jsrsasign wiki: distinguished name string difference between OpenSSL oneline and LDAP(RFC 2253)</a> 1525 * @example 1526 * KJUR.asn1.x509.X500Name.ldapToOneline('O=test,C=US') → '/C=US/O=test' 1527 * KJUR.asn1.x509.X500Name.ldapToOneline('O=a\,a,C=US') → '/C=US/O=a,a' 1528 * KJUR.asn1.x509.X500Name.ldapToOneline('O=a/a,C=US') → '/C=US/O=a\/a' 1529 */ 1530 KJUR.asn1.x509.X500Name.ldapToOneline = function(s) { 1531 var a = s.split(","); 1532 1533 // join \, 1534 var isBSbefore = false; 1535 var a2 = []; 1536 for (var i = 0; a.length > 0; i++) { 1537 var item = a.shift(); 1538 //console.log("item=" + item); 1539 1540 if (isBSbefore === true) { 1541 var a2last = a2.pop(); 1542 var newitem = (a2last + "," + item).replace(/\\,/g, ","); 1543 a2.push(newitem); 1544 isBSbefore = false; 1545 } else { 1546 a2.push(item); 1547 } 1548 1549 if (item.substr(-1, 1) === "\\") isBSbefore = true; 1550 } 1551 1552 a2 = a2.map(function(s) {return s.replace("/", "\\/")}); 1553 a2.reverse(); 1554 return "/" + a2.join("/"); 1555 }; 1556 1557 /** 1558 * RDN (Relative Distinguished Name) ASN.1 structure class 1559 * @name KJUR.asn1.x509.RDN 1560 * @class RDN (Relative Distinguished Name) ASN.1 structure class 1561 * @param {Array} params associative array of parameters (ex. {'str': 'C=US'}) 1562 * @extends KJUR.asn1.ASN1Object 1563 * @see KJUR.asn1.x509.X500Name 1564 * @see KJUR.asn1.x509.RDN 1565 * @see KJUR.asn1.x509.AttributeTypeAndValue 1566 * @description 1567 * This class provides RelativeDistinguishedName ASN.1 class structure 1568 * defined in <a href="https://tools.ietf.org/html/rfc2253#section-2">RFC 2253 section 2</a>. 1569 * <blockquote><pre> 1570 * RelativeDistinguishedName ::= SET SIZE (1..MAX) OF 1571 * AttributeTypeAndValue 1572 * 1573 * AttributeTypeAndValue ::= SEQUENCE { 1574 * type AttributeType, 1575 * value AttributeValue } 1576 * </pre></blockquote> 1577 * <br/> 1578 * NOTE: Multi-valued RDN is supported since jsrsasign 6.2.1 asn1x509 1.0.17. 1579 * @example 1580 * rdn = new KJUR.asn1.x509.RDN({str: "CN=test"}); 1581 * rdn = new KJUR.asn1.x509.RDN({str: "O=a+O=bb+O=c"}); // multi-valued 1582 * rdn = new KJUR.asn1.x509.RDN({str: "O=a+O=b\\+b+O=c"}); // plus escaped 1583 * rdn = new KJUR.asn1.x509.RDN({str: "O=a+O=\"b+b\"+O=c"}); // double quoted 1584 */ 1585 KJUR.asn1.x509.RDN = function(params) { 1586 KJUR.asn1.x509.RDN.superclass.constructor.call(this); 1587 this.asn1Array = new Array(); 1588 1589 /** 1590 * add one AttributeTypeAndValue by string<br/> 1591 * @name addByString 1592 * @memberOf KJUR.asn1.x509.RDN# 1593 * @function 1594 * @param {String} s string of AttributeTypeAndValue 1595 * @return {Object} unspecified 1596 * @description 1597 * This method add one AttributeTypeAndValue to RDN object. 1598 * @example 1599 * rdn = new KJUR.asn1.x509.RDN(); 1600 * rdn.addByString("CN=john"); 1601 * rdn.addByString("serialNumber=1234"); // for multi-valued RDN 1602 */ 1603 this.addByString = function(s) { 1604 this.asn1Array.push(new KJUR.asn1.x509.AttributeTypeAndValue({'str': s})); 1605 }; 1606 1607 /** 1608 * add one AttributeTypeAndValue by multi-valued string<br/> 1609 * @name addByMultiValuedString 1610 * @memberOf KJUR.asn1.x509.RDN# 1611 * @function 1612 * @param {String} s string of multi-valued RDN 1613 * @return {Object} unspecified 1614 * @since jsrsasign 6.2.1 asn1x509 1.0.17 1615 * @description 1616 * This method add multi-valued RDN to RDN object. 1617 * @example 1618 * rdn = new KJUR.asn1.x509.RDN(); 1619 * rdn.addByMultiValuedString("CN=john+O=test"); 1620 * rdn.addByMultiValuedString("O=a+O=b\+b\+b+O=c"); // multi-valued RDN with quoted plus 1621 * rdn.addByMultiValuedString("O=a+O=\"b+b+b\"+O=c"); // multi-valued RDN with quoted quotation 1622 */ 1623 this.addByMultiValuedString = function(s) { 1624 var a = KJUR.asn1.x509.RDN.parseString(s); 1625 for (var i = 0; i < a.length; i++) { 1626 this.addByString(a[i]); 1627 } 1628 }; 1629 1630 this.getEncodedHex = function() { 1631 var o = new KJUR.asn1.DERSet({"array": this.asn1Array}); 1632 this.TLV = o.getEncodedHex(); 1633 return this.TLV; 1634 }; 1635 1636 if (typeof params != "undefined") { 1637 if (typeof params['str'] != "undefined") { 1638 this.addByMultiValuedString(params['str']); 1639 } 1640 } 1641 }; 1642 YAHOO.lang.extend(KJUR.asn1.x509.RDN, KJUR.asn1.ASN1Object); 1643 1644 /** 1645 * parse multi-valued RDN string and split into array of 'AttributeTypeAndValue'<br/> 1646 * @name parseString 1647 * @memberOf KJUR.asn1.x509.RDN 1648 * @function 1649 * @param {String} s multi-valued string of RDN 1650 * @return {Array} array of string of AttributeTypeAndValue 1651 * @since jsrsasign 6.2.1 asn1x509 1.0.17 1652 * @description 1653 * This static method parses multi-valued RDN string and split into 1654 * array of AttributeTypeAndValue. 1655 * @example 1656 * KJUR.asn1.x509.RDN.parseString("CN=john") → ["CN=john"] 1657 * KJUR.asn1.x509.RDN.parseString("CN=john+OU=test") → ["CN=john", "OU=test"] 1658 * KJUR.asn1.x509.RDN.parseString('CN="jo+hn"+OU=test') → ["CN=jo+hn", "OU=test"] 1659 * KJUR.asn1.x509.RDN.parseString('CN=jo\+hn+OU=test') → ["CN=jo+hn", "OU=test"] 1660 * KJUR.asn1.x509.RDN.parseString("CN=john+OU=test+OU=t1") → ["CN=john", "OU=test", "OU=t1"] 1661 */ 1662 KJUR.asn1.x509.RDN.parseString = function(s) { 1663 var a = s.split(/\+/); 1664 1665 // join \+ 1666 var isBSbefore = false; 1667 var a2 = []; 1668 for (var i = 0; a.length > 0; i++) { 1669 var item = a.shift(); 1670 //console.log("item=" + item); 1671 1672 if (isBSbefore === true) { 1673 var a2last = a2.pop(); 1674 var newitem = (a2last + "+" + item).replace(/\\\+/g, "+"); 1675 a2.push(newitem); 1676 isBSbefore = false; 1677 } else { 1678 a2.push(item); 1679 } 1680 1681 if (item.substr(-1, 1) === "\\") isBSbefore = true; 1682 } 1683 1684 // join quote 1685 var beginQuote = false; 1686 var a3 = []; 1687 for (var i = 0; a2.length > 0; i++) { 1688 var item = a2.shift(); 1689 1690 if (beginQuote === true) { 1691 var a3last = a3.pop(); 1692 if (item.match(/"$/)) { 1693 var newitem = (a3last + "+" + item).replace(/^([^=]+)="(.*)"$/, "$1=$2"); 1694 a3.push(newitem); 1695 beginQuote = false; 1696 } else { 1697 a3.push(a3last + "+" + item); 1698 } 1699 } else { 1700 a3.push(item); 1701 } 1702 1703 if (item.match(/^[^=]+="/)) { 1704 //console.log(i + "=" + item); 1705 beginQuote = true; 1706 } 1707 } 1708 1709 return a3; 1710 }; 1711 1712 /** 1713 * AttributeTypeAndValue ASN.1 structure class 1714 * @name KJUR.asn1.x509.AttributeTypeAndValue 1715 * @class AttributeTypeAndValue ASN.1 structure class 1716 * @param {Array} params associative array of parameters (ex. {'str': 'C=US'}) 1717 * @extends KJUR.asn1.ASN1Object 1718 * @description 1719 * @see KJUR.asn1.x509.X500Name 1720 * @see KJUR.asn1.x509.RDN 1721 * @see KJUR.asn1.x509.AttributeTypeAndValue 1722 * @example 1723 */ 1724 KJUR.asn1.x509.AttributeTypeAndValue = function(params) { 1725 KJUR.asn1.x509.AttributeTypeAndValue.superclass.constructor.call(this); 1726 var typeObj = null, 1727 valueObj = null, 1728 defaultDSType = "utf8", 1729 _KJUR = KJUR, 1730 _KJUR_asn1 = _KJUR.asn1; 1731 1732 this.setByString = function(attrTypeAndValueStr) { 1733 var matchResult = attrTypeAndValueStr.match(/^([^=]+)=(.+)$/); 1734 if (matchResult) { 1735 this.setByAttrTypeAndValueStr(matchResult[1], matchResult[2]); 1736 } else { 1737 throw "malformed attrTypeAndValueStr: " + attrTypeAndValueStr; 1738 } 1739 }; 1740 1741 this.setByAttrTypeAndValueStr = function(shortAttrType, valueStr) { 1742 this.typeObj = KJUR.asn1.x509.OID.atype2obj(shortAttrType); 1743 var dsType = defaultDSType; 1744 if (shortAttrType == "C") dsType = "prn"; 1745 this.valueObj = this.getValueObj(dsType, valueStr); 1746 }; 1747 1748 this.getValueObj = function(dsType, valueStr) { 1749 if (dsType == "utf8") return new _KJUR_asn1.DERUTF8String({"str": valueStr}); 1750 if (dsType == "prn") return new _KJUR_asn1.DERPrintableString({"str": valueStr}); 1751 if (dsType == "tel") return new _KJUR_asn1.DERTeletexString({"str": valueStr}); 1752 if (dsType == "ia5") return new _KJUR_asn1.DERIA5String({"str": valueStr}); 1753 throw "unsupported directory string type: type=" + dsType + " value=" + valueStr; 1754 }; 1755 1756 this.getEncodedHex = function() { 1757 var o = new _KJUR_asn1.DERSequence({"array": [this.typeObj, this.valueObj]}); 1758 this.TLV = o.getEncodedHex(); 1759 return this.TLV; 1760 }; 1761 1762 if (typeof params != "undefined") { 1763 if (typeof params['str'] != "undefined") { 1764 this.setByString(params['str']); 1765 } 1766 } 1767 }; 1768 YAHOO.lang.extend(KJUR.asn1.x509.AttributeTypeAndValue, KJUR.asn1.ASN1Object); 1769 1770 // === END X500Name Related ================================================= 1771 1772 // === BEGIN Other ASN1 structure class ====================================== 1773 1774 /** 1775 * SubjectPublicKeyInfo ASN.1 structure class 1776 * @name KJUR.asn1.x509.SubjectPublicKeyInfo 1777 * @class SubjectPublicKeyInfo ASN.1 structure class 1778 * @param {Object} params parameter for subject public key 1779 * @extends KJUR.asn1.ASN1Object 1780 * @description 1781 * <br/> 1782 * As for argument 'params' for constructor, you can specify one of 1783 * following properties: 1784 * <ul> 1785 * <li>{@link RSAKey} object</li> 1786 * <li>{@link KJUR.crypto.ECDSA} object</li> 1787 * <li>{@link KJUR.crypto.DSA} object</li> 1788 * </ul> 1789 * NOTE1: 'params' can be omitted.<br/> 1790 * NOTE2: DSA/ECDSA key object is also supported since asn1x509 1.0.6.<br/> 1791 * <h4>EXAMPLE</h4> 1792 * @example 1793 * spki = new KJUR.asn1.x509.SubjectPublicKeyInfo(RSAKey_object); 1794 * spki = new KJUR.asn1.x509.SubjectPublicKeyInfo(KJURcryptoECDSA_object); 1795 * spki = new KJUR.asn1.x509.SubjectPublicKeyInfo(KJURcryptoDSA_object); 1796 */ 1797 KJUR.asn1.x509.SubjectPublicKeyInfo = function(params) { 1798 KJUR.asn1.x509.SubjectPublicKeyInfo.superclass.constructor.call(this); 1799 var asn1AlgId = null, 1800 asn1SubjPKey = null, 1801 _KJUR = KJUR, 1802 _KJUR_asn1 = _KJUR.asn1, 1803 _DERInteger = _KJUR_asn1.DERInteger, 1804 _DERBitString = _KJUR_asn1.DERBitString, 1805 _DERObjectIdentifier = _KJUR_asn1.DERObjectIdentifier, 1806 _DERSequence = _KJUR_asn1.DERSequence, 1807 _newObject = _KJUR_asn1.ASN1Util.newObject, 1808 _KJUR_asn1_x509 = _KJUR_asn1.x509, 1809 _AlgorithmIdentifier = _KJUR_asn1_x509.AlgorithmIdentifier, 1810 _KJUR_crypto = _KJUR.crypto, 1811 _KJUR_crypto_ECDSA = _KJUR_crypto.ECDSA, 1812 _KJUR_crypto_DSA = _KJUR_crypto.DSA; 1813 1814 /* 1815 * @since asn1x509 1.0.7 1816 */ 1817 this.getASN1Object = function() { 1818 if (this.asn1AlgId == null || this.asn1SubjPKey == null) 1819 throw "algId and/or subjPubKey not set"; 1820 var o = new _DERSequence({'array': 1821 [this.asn1AlgId, this.asn1SubjPKey]}); 1822 return o; 1823 }; 1824 1825 this.getEncodedHex = function() { 1826 var o = this.getASN1Object(); 1827 this.hTLV = o.getEncodedHex(); 1828 return this.hTLV; 1829 }; 1830 1831 /** 1832 * @name setPubKey 1833 * @memberOf KJUR.asn1.x509.SubjectPublicKeyInfo# 1834 * @function 1835 * @param {Object} {@link RSAKey}, {@link KJUR.crypto.ECDSA} or {@link KJUR.crypto.DSA} object 1836 * @since jsrsasign 8.0.0 asn1x509 1.1.0 1837 * @description 1838 * @example 1839 * spki = new KJUR.asn1.x509.SubjectPublicKeyInfo(); 1840 * pubKey = KEYUTIL.getKey(PKCS8PUBKEYPEM); 1841 * spki.setPubKey(pubKey); 1842 */ 1843 this.setPubKey = function(key) { 1844 try { 1845 if (key instanceof RSAKey) { 1846 var asn1RsaPub = _newObject({ 1847 'seq': [{'int': {'bigint': key.n}}, {'int': {'int': key.e}}] 1848 }); 1849 var rsaKeyHex = asn1RsaPub.getEncodedHex(); 1850 this.asn1AlgId = new _AlgorithmIdentifier({'name':'rsaEncryption'}); 1851 this.asn1SubjPKey = new _DERBitString({'hex':'00'+rsaKeyHex}); 1852 } 1853 } catch(ex) {}; 1854 1855 try { 1856 if (key instanceof KJUR.crypto.ECDSA) { 1857 var asn1Params = new _DERObjectIdentifier({'name': key.curveName}); 1858 this.asn1AlgId = 1859 new _AlgorithmIdentifier({'name': 'ecPublicKey', 1860 'asn1params': asn1Params}); 1861 this.asn1SubjPKey = new _DERBitString({'hex': '00' + key.pubKeyHex}); 1862 } 1863 } catch(ex) {}; 1864 1865 try { 1866 if (key instanceof KJUR.crypto.DSA) { 1867 var asn1Params = new _newObject({ 1868 'seq': [{'int': {'bigint': key.p}}, 1869 {'int': {'bigint': key.q}}, 1870 {'int': {'bigint': key.g}}] 1871 }); 1872 this.asn1AlgId = 1873 new _AlgorithmIdentifier({'name': 'dsa', 1874 'asn1params': asn1Params}); 1875 var pubInt = new _DERInteger({'bigint': key.y}); 1876 this.asn1SubjPKey = 1877 new _DERBitString({'hex': '00' + pubInt.getEncodedHex()}); 1878 } 1879 } catch(ex) {}; 1880 }; 1881 1882 if (params !== undefined) { 1883 this.setPubKey(params); 1884 } 1885 }; 1886 YAHOO.lang.extend(KJUR.asn1.x509.SubjectPublicKeyInfo, KJUR.asn1.ASN1Object); 1887 1888 /** 1889 * Time ASN.1 structure class 1890 * @name KJUR.asn1.x509.Time 1891 * @class Time ASN.1 structure class 1892 * @param {Array} params associative array of parameters (ex. {'str': '130508235959Z'}) 1893 * @extends KJUR.asn1.ASN1Object 1894 * @description 1895 * <br/> 1896 * <h4>EXAMPLES</h4> 1897 * @example 1898 * var t1 = new KJUR.asn1.x509.Time{'str': '130508235959Z'} // UTCTime by default 1899 * var t2 = new KJUR.asn1.x509.Time{'type': 'gen', 'str': '20130508235959Z'} // GeneralizedTime 1900 */ 1901 KJUR.asn1.x509.Time = function(params) { 1902 KJUR.asn1.x509.Time.superclass.constructor.call(this); 1903 var type = null, 1904 timeParams = null, 1905 _KJUR = KJUR, 1906 _KJUR_asn1 = _KJUR.asn1, 1907 _DERUTCTime = _KJUR_asn1.DERUTCTime, 1908 _DERGeneralizedTime = _KJUR_asn1.DERGeneralizedTime; 1909 1910 this.setTimeParams = function(timeParams) { 1911 this.timeParams = timeParams; 1912 } 1913 1914 this.getEncodedHex = function() { 1915 var o = null; 1916 1917 if (this.timeParams != null) { 1918 if (this.type == "utc") { 1919 o = new _DERUTCTime(this.timeParams); 1920 } else { 1921 o = new _DERGeneralizedTime(this.timeParams); 1922 } 1923 } else { 1924 if (this.type == "utc") { 1925 o = new _DERUTCTime(); 1926 } else { 1927 o = new _DERGeneralizedTime(); 1928 } 1929 } 1930 this.TLV = o.getEncodedHex(); 1931 return this.TLV; 1932 }; 1933 1934 this.type = "utc"; 1935 if (params !== undefined) { 1936 if (params.type !== undefined) { 1937 this.type = params.type; 1938 } else { 1939 if (params.str !== undefined) { 1940 if (params.str.match(/^[0-9]{12}Z$/)) this.type = "utc"; 1941 if (params.str.match(/^[0-9]{14}Z$/)) this.type = "gen"; 1942 } 1943 } 1944 this.timeParams = params; 1945 } 1946 }; 1947 YAHOO.lang.extend(KJUR.asn1.x509.Time, KJUR.asn1.ASN1Object); 1948 1949 /** 1950 * AlgorithmIdentifier ASN.1 structure class 1951 * @name KJUR.asn1.x509.AlgorithmIdentifier 1952 * @class AlgorithmIdentifier ASN.1 structure class 1953 * @param {Array} params associative array of parameters (ex. {'name': 'SHA1withRSA'}) 1954 * @extends KJUR.asn1.ASN1Object 1955 * @description 1956 * The 'params' argument is an associative array and has following parameters: 1957 * <ul> 1958 * <li>name: algorithm name (MANDATORY, ex. sha1, SHA256withRSA)</li> 1959 * <li>asn1params: explicitly specify ASN.1 object for algorithm. 1960 * (OPTION)</li> 1961 * <li>paramempty: set algorithm parameter to NULL by force. 1962 * If paramempty is false, algorithm parameter will be set automatically. 1963 * If paramempty is false and algorithm name is "*withDSA" or "withECDSA" parameter field of 1964 * AlgorithmIdentifier will be ommitted otherwise 1965 * it will be NULL by default. 1966 * (OPTION, DEFAULT = false)</li> 1967 * </ul> 1968 * @example 1969 * algId = new KJUR.asn1.x509.AlgorithmIdentifier({name: "sha1"}); 1970 * // set parameter to NULL authomatically if algorithm name is "*withRSA". 1971 * algId = new KJUR.asn1.x509.AlgorithmIdentifier({name: "SHA256withRSA"}); 1972 * // set parameter to NULL authomatically if algorithm name is "rsaEncryption". 1973 * algId = new KJUR.asn1.x509.AlgorithmIdentifier({name: "rsaEncryption"}); 1974 * // SHA256withRSA and set parameter empty by force 1975 * algId = new KJUR.asn1.x509.AlgorithmIdentifier({name: "SHA256withRSA", paramempty: true}); 1976 */ 1977 KJUR.asn1.x509.AlgorithmIdentifier = function(params) { 1978 KJUR.asn1.x509.AlgorithmIdentifier.superclass.constructor.call(this); 1979 this.nameAlg = null; 1980 this.asn1Alg = null; 1981 this.asn1Params = null; 1982 this.paramEmpty = false; 1983 var _KJUR = KJUR, 1984 _KJUR_asn1 = _KJUR.asn1; 1985 1986 this.getEncodedHex = function() { 1987 if (this.nameAlg === null && this.asn1Alg === null) { 1988 throw "algorithm not specified"; 1989 } 1990 if (this.nameAlg !== null && this.asn1Alg === null) { 1991 this.asn1Alg = _KJUR_asn1.x509.OID.name2obj(this.nameAlg); 1992 } 1993 var a = [this.asn1Alg]; 1994 if (this.asn1Params !== null) a.push(this.asn1Params); 1995 1996 var o = new _KJUR_asn1.DERSequence({'array': a}); 1997 this.hTLV = o.getEncodedHex(); 1998 return this.hTLV; 1999 }; 2000 2001 if (params !== undefined) { 2002 if (params.name !== undefined) { 2003 this.nameAlg = params.name; 2004 } 2005 if (params.asn1params !== undefined) { 2006 this.asn1Params = params.asn1params; 2007 } 2008 if (params.paramempty !== undefined) { 2009 this.paramEmpty = params.paramempty; 2010 } 2011 } 2012 2013 // set algorithm parameters will be ommitted for 2014 // "*withDSA" or "*withECDSA" otherwise will be NULL. 2015 if (this.asn1Params === null && 2016 this.paramEmpty === false && 2017 this.nameAlg !== null) { 2018 var lcNameAlg = this.nameAlg.toLowerCase(); 2019 if (lcNameAlg.substr(-7, 7) !== "withdsa" && 2020 lcNameAlg.substr(-9, 9) !== "withecdsa") { 2021 this.asn1Params = new _KJUR_asn1.DERNull(); 2022 } 2023 } 2024 }; 2025 YAHOO.lang.extend(KJUR.asn1.x509.AlgorithmIdentifier, KJUR.asn1.ASN1Object); 2026 2027 /** 2028 * GeneralName ASN.1 structure class<br/> 2029 * @name KJUR.asn1.x509.GeneralName 2030 * @class GeneralName ASN.1 structure class 2031 * @description 2032 * <br/> 2033 * As for argument 'params' for constructor, you can specify one of 2034 * following properties: 2035 * <ul> 2036 * <li>rfc822 - rfc822Name[1] (ex. user1@foo.com)</li> 2037 * <li>dns - dNSName[2] (ex. foo.com)</li> 2038 * <li>uri - uniformResourceIdentifier[6] (ex. http://foo.com/)</li> 2039 * <li>dn - directoryName[4] (ex. /C=US/O=Test)</li> 2040 * <li>ldapdn - directoryName[4] (ex. O=Test,C=US)</li> 2041 * <li>certissuer - directoryName[4] (PEM or hex string of cert)</li> 2042 * <li>certsubj - directoryName[4] (PEM or hex string of cert)</li> 2043 * </ul> 2044 * NOTE1: certissuer and certsubj were supported since asn1x509 1.0.10.<br/> 2045 * NOTE2: dn and ldapdn were supported since jsrsasign 6.2.3 asn1x509 1.0.19.<br/> 2046 * 2047 * Here is definition of the ASN.1 syntax: 2048 * <pre> 2049 * -- NOTE: under the CHOICE, it will always be explicit. 2050 * GeneralName ::= CHOICE { 2051 * otherName [0] OtherName, 2052 * rfc822Name [1] IA5String, 2053 * dNSName [2] IA5String, 2054 * x400Address [3] ORAddress, 2055 * directoryName [4] Name, 2056 * ediPartyName [5] EDIPartyName, 2057 * uniformResourceIdentifier [6] IA5String, 2058 * iPAddress [7] OCTET STRING, 2059 * registeredID [8] OBJECT IDENTIFIER } 2060 * </pre> 2061 * 2062 * @example 2063 * gn = new KJUR.asn1.x509.GeneralName({rfc822: 'test@aaa.com'}); 2064 * gn = new KJUR.asn1.x509.GeneralName({dns: 'aaa.com'}); 2065 * gn = new KJUR.asn1.x509.GeneralName({uri: 'http://aaa.com/'}); 2066 * gn = new KJUR.asn1.x509.GeneralName({dn: '/C=US/O=Test'}); 2067 * gn = new KJUR.asn1.x509.GeneralName({ldapdn: 'O=Test,C=US'}); 2068 * gn = new KJUR.asn1.x509.GeneralName({certissuer: certPEM}); 2069 * gn = new KJUR.asn1.x509.GeneralName({certsubj: certPEM}); 2070 */ 2071 KJUR.asn1.x509.GeneralName = function(params) { 2072 KJUR.asn1.x509.GeneralName.superclass.constructor.call(this); 2073 var asn1Obj = null, 2074 type = null, 2075 pTag = {rfc822: '81', dns: '82', dn: 'a4', uri: '86'}, 2076 _KJUR = KJUR, 2077 _KJUR_asn1 = _KJUR.asn1, 2078 _DERIA5String = _KJUR_asn1.DERIA5String, 2079 _DERTaggedObject = _KJUR_asn1.DERTaggedObject, 2080 _ASN1Object = _KJUR_asn1.ASN1Object, 2081 _X500Name = _KJUR_asn1.x509.X500Name, 2082 _pemtohex = pemtohex; 2083 2084 this.explicit = false; 2085 2086 this.setByParam = function(params) { 2087 var str = null; 2088 var v = null; 2089 2090 if (params === undefined) return; 2091 2092 if (params.rfc822 !== undefined) { 2093 this.type = 'rfc822'; 2094 v = new _DERIA5String({str: params[this.type]}); 2095 } 2096 2097 if (params.dns !== undefined) { 2098 this.type = 'dns'; 2099 v = new _DERIA5String({str: params[this.type]}); 2100 } 2101 2102 if (params.uri !== undefined) { 2103 this.type = 'uri'; 2104 v = new _DERIA5String({str: params[this.type]}); 2105 } 2106 2107 if (params.dn !== undefined) { 2108 this.type = 'dn'; 2109 v = new _X500Name({str: params.dn}); 2110 } 2111 2112 if (params.ldapdn !== undefined) { 2113 this.type = 'dn'; 2114 v = new _X500Name({ldapstr: params.ldapdn}); 2115 } 2116 2117 if (params.certissuer !== undefined) { 2118 this.type = 'dn'; 2119 this.explicit = true; 2120 var certStr = params.certissuer; 2121 var certHex = null; 2122 2123 if (certStr.match(/^[0-9A-Fa-f]+$/)) { 2124 certHex == certStr; 2125 } 2126 2127 if (certStr.indexOf("-----BEGIN ") != -1) { 2128 certHex = _pemtohex(certStr); 2129 } 2130 2131 if (certHex == null) throw "certissuer param not cert"; 2132 var x = new X509(); 2133 x.hex = certHex; 2134 var dnHex = x.getIssuerHex(); 2135 v = new _ASN1Object(); 2136 v.hTLV = dnHex; 2137 } 2138 2139 if (params.certsubj !== undefined) { 2140 this.type = 'dn'; 2141 this.explicit = true; 2142 var certStr = params.certsubj; 2143 var certHex = null; 2144 if (certStr.match(/^[0-9A-Fa-f]+$/)) { 2145 certHex == certStr; 2146 } 2147 if (certStr.indexOf("-----BEGIN ") != -1) { 2148 certHex = _pemtohex(certStr); 2149 } 2150 if (certHex == null) throw "certsubj param not cert"; 2151 var x = new X509(); 2152 x.hex = certHex; 2153 var dnHex = x.getSubjectHex(); 2154 v = new _ASN1Object(); 2155 v.hTLV = dnHex; 2156 } 2157 2158 if (this.type == null) 2159 throw "unsupported type in params=" + params; 2160 this.asn1Obj = new _DERTaggedObject({'explicit': this.explicit, 2161 'tag': pTag[this.type], 2162 'obj': v}); 2163 }; 2164 2165 this.getEncodedHex = function() { 2166 return this.asn1Obj.getEncodedHex(); 2167 } 2168 2169 if (params !== undefined) { 2170 this.setByParam(params); 2171 } 2172 2173 }; 2174 YAHOO.lang.extend(KJUR.asn1.x509.GeneralName, KJUR.asn1.ASN1Object); 2175 2176 /** 2177 * GeneralNames ASN.1 structure class<br/> 2178 * @name KJUR.asn1.x509.GeneralNames 2179 * @class GeneralNames ASN.1 structure class 2180 * @description 2181 * <br/> 2182 * <h4>EXAMPLE AND ASN.1 SYNTAX</h4> 2183 * @example 2184 * gns = new KJUR.asn1.x509.GeneralNames([{'uri': 'http://aaa.com/'}, {'uri': 'http://bbb.com/'}]); 2185 * 2186 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName 2187 */ 2188 KJUR.asn1.x509.GeneralNames = function(paramsArray) { 2189 KJUR.asn1.x509.GeneralNames.superclass.constructor.call(this); 2190 var asn1Array = null, 2191 _KJUR = KJUR, 2192 _KJUR_asn1 = _KJUR.asn1; 2193 2194 /** 2195 * set a array of {@link KJUR.asn1.x509.GeneralName} parameters<br/> 2196 * @name setByParamArray 2197 * @memberOf KJUR.asn1.x509.GeneralNames# 2198 * @function 2199 * @param {Array} paramsArray Array of {@link KJUR.asn1.x509.GeneralNames} 2200 * @description 2201 * <br/> 2202 * <h4>EXAMPLES</h4> 2203 * @example 2204 * gns = new KJUR.asn1.x509.GeneralNames(); 2205 * gns.setByParamArray([{uri: 'http://aaa.com/'}, {uri: 'http://bbb.com/'}]); 2206 */ 2207 this.setByParamArray = function(paramsArray) { 2208 for (var i = 0; i < paramsArray.length; i++) { 2209 var o = new _KJUR_asn1.x509.GeneralName(paramsArray[i]); 2210 this.asn1Array.push(o); 2211 } 2212 }; 2213 2214 this.getEncodedHex = function() { 2215 var o = new _KJUR_asn1.DERSequence({'array': this.asn1Array}); 2216 return o.getEncodedHex(); 2217 }; 2218 2219 this.asn1Array = new Array(); 2220 if (typeof paramsArray != "undefined") { 2221 this.setByParamArray(paramsArray); 2222 } 2223 }; 2224 YAHOO.lang.extend(KJUR.asn1.x509.GeneralNames, KJUR.asn1.ASN1Object); 2225 2226 /** 2227 * DistributionPointName ASN.1 structure class<br/> 2228 * @name KJUR.asn1.x509.DistributionPointName 2229 * @class DistributionPointName ASN.1 structure class 2230 * @description 2231 * <pre> 2232 * DistributionPoint ::= SEQUENCE { 2233 * distributionPoint [0] DistributionPointName OPTIONAL, 2234 * reasons [1] ReasonFlags OPTIONAL, 2235 * cRLIssuer [2] GeneralNames OPTIONAL } 2236 * 2237 * DistributionPointName ::= CHOICE { 2238 * fullName [0] GeneralNames, 2239 * nameRelativeToCRLIssuer [1] RelativeDistinguishedName } 2240 * 2241 * ReasonFlags ::= BIT STRING { 2242 * unused (0), 2243 * keyCompromise (1), 2244 * cACompromise (2), 2245 * affiliationChanged (3), 2246 * superseded (4), 2247 * cessationOfOperation (5), 2248 * certificateHold (6), 2249 * privilegeWithdrawn (7), 2250 * aACompromise (8) } 2251 * </pre> 2252 * @example 2253 */ 2254 KJUR.asn1.x509.DistributionPointName = function(gnOrRdn) { 2255 KJUR.asn1.x509.DistributionPointName.superclass.constructor.call(this); 2256 var asn1Obj = null, 2257 type = null, 2258 tag = null, 2259 asn1V = null, 2260 _KJUR = KJUR, 2261 _KJUR_asn1 = _KJUR.asn1, 2262 _DERTaggedObject = _KJUR_asn1.DERTaggedObject; 2263 2264 this.getEncodedHex = function() { 2265 if (this.type != "full") 2266 throw "currently type shall be 'full': " + this.type; 2267 this.asn1Obj = new _DERTaggedObject({'explicit': false, 2268 'tag': this.tag, 2269 'obj': this.asn1V}); 2270 this.hTLV = this.asn1Obj.getEncodedHex(); 2271 return this.hTLV; 2272 }; 2273 2274 if (gnOrRdn !== undefined) { 2275 if (_KJUR_asn1.x509.GeneralNames.prototype.isPrototypeOf(gnOrRdn)) { 2276 this.type = "full"; 2277 this.tag = "a0"; 2278 this.asn1V = gnOrRdn; 2279 } else { 2280 throw "This class supports GeneralNames only as argument"; 2281 } 2282 } 2283 }; 2284 YAHOO.lang.extend(KJUR.asn1.x509.DistributionPointName, KJUR.asn1.ASN1Object); 2285 2286 /** 2287 * DistributionPoint ASN.1 structure class<br/> 2288 * @name KJUR.asn1.x509.DistributionPoint 2289 * @class DistributionPoint ASN.1 structure class 2290 * @description 2291 * <pre> 2292 * DistributionPoint ::= SEQUENCE { 2293 * distributionPoint [0] DistributionPointName OPTIONAL, 2294 * reasons [1] ReasonFlags OPTIONAL, 2295 * cRLIssuer [2] GeneralNames OPTIONAL } 2296 * 2297 * DistributionPointName ::= CHOICE { 2298 * fullName [0] GeneralNames, 2299 * nameRelativeToCRLIssuer [1] RelativeDistinguishedName } 2300 * 2301 * ReasonFlags ::= BIT STRING { 2302 * unused (0), 2303 * keyCompromise (1), 2304 * cACompromise (2), 2305 * affiliationChanged (3), 2306 * superseded (4), 2307 * cessationOfOperation (5), 2308 * certificateHold (6), 2309 * privilegeWithdrawn (7), 2310 * aACompromise (8) } 2311 * </pre> 2312 * @example 2313 */ 2314 KJUR.asn1.x509.DistributionPoint = function(params) { 2315 KJUR.asn1.x509.DistributionPoint.superclass.constructor.call(this); 2316 var asn1DP = null, 2317 _KJUR = KJUR, 2318 _KJUR_asn1 = _KJUR.asn1; 2319 2320 this.getEncodedHex = function() { 2321 var seq = new _KJUR_asn1.DERSequence(); 2322 if (this.asn1DP != null) { 2323 var o1 = new _KJUR_asn1.DERTaggedObject({'explicit': true, 2324 'tag': 'a0', 2325 'obj': this.asn1DP}); 2326 seq.appendASN1Object(o1); 2327 } 2328 this.hTLV = seq.getEncodedHex(); 2329 return this.hTLV; 2330 }; 2331 2332 if (params !== undefined) { 2333 if (params.dpobj !== undefined) { 2334 this.asn1DP = params.dpobj; 2335 } 2336 } 2337 }; 2338 YAHOO.lang.extend(KJUR.asn1.x509.DistributionPoint, KJUR.asn1.ASN1Object); 2339 2340 /** 2341 * static object for OID 2342 * @name KJUR.asn1.x509.OID 2343 * @class static object for OID 2344 * @property {Assoc Array} atype2oidList for short attribute type name and oid (ex. 'C' and '2.5.4.6') 2345 * @property {Assoc Array} name2oidList for oid name and oid (ex. 'keyUsage' and '2.5.29.15') 2346 * @property {Assoc Array} objCache for caching name and DERObjectIdentifier object 2347 * @description 2348 * This class defines OID name and values. 2349 * AttributeType names registered in OID.atype2oidList are following: 2350 * <table style="border-width: thin; border-style: solid; witdh: 100%"> 2351 * <tr><th>short</th><th>long</th><th>OID</th></tr> 2352 * <tr><td>CN</td>commonName<td></td><td>2.5.4.3</td></tr> 2353 * <tr><td>L</td><td>localityName</td><td>2.5.4.7</td></tr> 2354 * <tr><td>ST</td><td>stateOrProvinceName</td><td>2.5.4.8</td></tr> 2355 * <tr><td>O</td><td>organizationName</td><td>2.5.4.10</td></tr> 2356 * <tr><td>OU</td><td>organizationalUnitName</td><td>2.5.4.11</td></tr> 2357 * <tr><td>C</td><td></td>countryName<td>2.5.4.6</td></tr> 2358 * <tr><td>STREET</td>streetAddress<td></td><td>2.5.4.6</td></tr> 2359 * <tr><td>DC</td><td>domainComponent</td><td>0.9.2342.19200300.100.1.25</td></tr> 2360 * <tr><td>UID</td><td>userId</td><td>0.9.2342.19200300.100.1.1</td></tr> 2361 * <tr><td>SN</td><td>surname</td><td>2.5.4.4</td></tr> 2362 * <tr><td>DN</td><td>distinguishedName</td><td>2.5.4.49</td></tr> 2363 * <tr><td>E</td><td>emailAddress</td><td>1.2.840.113549.1.9.1</td></tr> 2364 * <tr><td></td><td>businessCategory</td><td>2.5.4.15</td></tr> 2365 * <tr><td></td><td>postalCode</td><td>2.5.4.17</td></tr> 2366 * <tr><td></td><td>jurisdictionOfIncorporationL</td><td>1.3.6.1.4.1.311.60.2.1.1</td></tr> 2367 * <tr><td></td><td>jurisdictionOfIncorporationSP</td><td>1.3.6.1.4.1.311.60.2.1.2</td></tr> 2368 * <tr><td></td><td>jurisdictionOfIncorporationC</td><td>1.3.6.1.4.1.311.60.2.1.3</td></tr> 2369 * </table> 2370 * 2371 * @example 2372 */ 2373 KJUR.asn1.x509.OID = new function(params) { 2374 this.atype2oidList = { 2375 // RFC 4514 AttributeType name string (MUST recognized) 2376 'CN': '2.5.4.3', 2377 'L': '2.5.4.7', 2378 'ST': '2.5.4.8', 2379 'O': '2.5.4.10', 2380 'OU': '2.5.4.11', 2381 'C': '2.5.4.6', 2382 'STREET': '2.5.4.9', 2383 'DC': '0.9.2342.19200300.100.1.25', 2384 'UID': '0.9.2342.19200300.100.1.1', 2385 // other AttributeType name string 2386 // http://blog.livedoor.jp/k_urushima/archives/656114.html 2387 'SN': '2.5.4.4', // surname 2388 'DN': '2.5.4.49', // distinguishedName 2389 'E': '1.2.840.113549.1.9.1', // emailAddress in MS.NET or Bouncy 2390 // other AttributeType name string (no short name) 2391 'businessCategory': '2.5.4.15', 2392 'postalCode': '2.5.4.17', 2393 'serialNumber': '2.5.4.5', 2394 'jurisdictionOfIncorporationL': '1.3.6.1.4.1.311.60.2.1.1', 2395 'jurisdictionOfIncorporationSP':'1.3.6.1.4.1.311.60.2.1.2', 2396 'jurisdictionOfIncorporationC': '1.3.6.1.4.1.311.60.2.1.3' 2397 }; 2398 this.name2oidList = { 2399 'sha1': '1.3.14.3.2.26', 2400 'sha256': '2.16.840.1.101.3.4.2.1', 2401 'sha384': '2.16.840.1.101.3.4.2.2', 2402 'sha512': '2.16.840.1.101.3.4.2.3', 2403 'sha224': '2.16.840.1.101.3.4.2.4', 2404 'md5': '1.2.840.113549.2.5', 2405 'md2': '1.3.14.7.2.2.1', 2406 'ripemd160': '1.3.36.3.2.1', 2407 2408 'MD2withRSA': '1.2.840.113549.1.1.2', 2409 'MD4withRSA': '1.2.840.113549.1.1.3', 2410 'MD5withRSA': '1.2.840.113549.1.1.4', 2411 'SHA1withRSA': '1.2.840.113549.1.1.5', 2412 'SHA224withRSA': '1.2.840.113549.1.1.14', 2413 'SHA256withRSA': '1.2.840.113549.1.1.11', 2414 'SHA384withRSA': '1.2.840.113549.1.1.12', 2415 'SHA512withRSA': '1.2.840.113549.1.1.13', 2416 2417 'SHA1withECDSA': '1.2.840.10045.4.1', 2418 'SHA224withECDSA': '1.2.840.10045.4.3.1', 2419 'SHA256withECDSA': '1.2.840.10045.4.3.2', 2420 'SHA384withECDSA': '1.2.840.10045.4.3.3', 2421 'SHA512withECDSA': '1.2.840.10045.4.3.4', 2422 2423 'dsa': '1.2.840.10040.4.1', 2424 'SHA1withDSA': '1.2.840.10040.4.3', 2425 'SHA224withDSA': '2.16.840.1.101.3.4.3.1', 2426 'SHA256withDSA': '2.16.840.1.101.3.4.3.2', 2427 2428 'rsaEncryption': '1.2.840.113549.1.1.1', 2429 2430 // X.500 AttributeType defined in RFC 4514 2431 'commonName': '2.5.4.3', 2432 'localityName': '2.5.4.7', 2433 'stateOrProvinceName': '2.5.4.8', 2434 'organizationName': '2.5.4.10', 2435 'organizationalUnitName': '2.5.4.11', 2436 'countryName': '2.5.4.6', 2437 'streetAddress': '2.5.4.9', 2438 'domainComponent': '0.9.2342.19200300.100.1.25', 2439 'userId': '0.9.2342.19200300.100.1.1', 2440 // other AttributeType name string 2441 'surname': '2.5.4.4', 2442 'distinguishedName': '2.5.4.49', 2443 'emailAddress': '1.2.840.113549.1.9.1', 2444 // other AttributeType name string (no short name) 2445 'businessCategory': '2.5.4.15', 2446 'postalCode': '2.5.4.17', 2447 'jurisdictionOfIncorporationL': '1.3.6.1.4.1.311.60.2.1.1', 2448 'jurisdictionOfIncorporationSP':'1.3.6.1.4.1.311.60.2.1.2', 2449 'jurisdictionOfIncorporationC': '1.3.6.1.4.1.311.60.2.1.3', 2450 2451 'subjectKeyIdentifier': '2.5.29.14', 2452 'keyUsage': '2.5.29.15', 2453 'subjectAltName': '2.5.29.17', 2454 'issuerAltName': '2.5.29.18', 2455 'basicConstraints': '2.5.29.19', 2456 'nameConstraints': '2.5.29.30', 2457 'cRLDistributionPoints':'2.5.29.31', 2458 'certificatePolicies': '2.5.29.32', 2459 'authorityKeyIdentifier':'2.5.29.35', 2460 'policyConstraints': '2.5.29.36', 2461 'extKeyUsage': '2.5.29.37', 2462 'authorityInfoAccess': '1.3.6.1.5.5.7.1.1', 2463 'ocsp': '1.3.6.1.5.5.7.48.1', 2464 'caIssuers': '1.3.6.1.5.5.7.48.2', 2465 2466 'anyExtendedKeyUsage': '2.5.29.37.0', 2467 'serverAuth': '1.3.6.1.5.5.7.3.1', 2468 'clientAuth': '1.3.6.1.5.5.7.3.2', 2469 'codeSigning': '1.3.6.1.5.5.7.3.3', 2470 'emailProtection': '1.3.6.1.5.5.7.3.4', 2471 'timeStamping': '1.3.6.1.5.5.7.3.8', 2472 'ocspSigning': '1.3.6.1.5.5.7.3.9', 2473 2474 'ecPublicKey': '1.2.840.10045.2.1', 2475 'secp256r1': '1.2.840.10045.3.1.7', 2476 'secp256k1': '1.3.132.0.10', 2477 'secp384r1': '1.3.132.0.34', 2478 2479 'pkcs5PBES2': '1.2.840.113549.1.5.13', 2480 'pkcs5PBKDF2': '1.2.840.113549.1.5.12', 2481 2482 'des-EDE3-CBC': '1.2.840.113549.3.7', 2483 2484 'data': '1.2.840.113549.1.7.1', // CMS data 2485 'signed-data': '1.2.840.113549.1.7.2', // CMS signed-data 2486 'enveloped-data': '1.2.840.113549.1.7.3', // CMS enveloped-data 2487 'digested-data': '1.2.840.113549.1.7.5', // CMS digested-data 2488 'encrypted-data': '1.2.840.113549.1.7.6', // CMS encrypted-data 2489 'authenticated-data': '1.2.840.113549.1.9.16.1.2', // CMS authenticated-data 2490 'tstinfo': '1.2.840.113549.1.9.16.1.4', // RFC3161 TSTInfo 2491 'extensionRequest': '1.2.840.113549.1.9.14',// CSR extensionRequest 2492 }; 2493 2494 this.objCache = {}; 2495 2496 /** 2497 * get DERObjectIdentifier by registered OID name 2498 * @name name2obj 2499 * @memberOf KJUR.asn1.x509.OID 2500 * @function 2501 * @param {String} name OID 2502 * @description 2503 * @example 2504 * var asn1ObjOID = OID.name2obj('SHA1withRSA'); 2505 */ 2506 this.name2obj = function(name) { 2507 if (typeof this.objCache[name] != "undefined") 2508 return this.objCache[name]; 2509 if (typeof this.name2oidList[name] == "undefined") 2510 throw "Name of ObjectIdentifier not defined: " + name; 2511 var oid = this.name2oidList[name]; 2512 var obj = new KJUR.asn1.DERObjectIdentifier({'oid': oid}); 2513 this.objCache[name] = obj; 2514 return obj; 2515 }; 2516 2517 /** 2518 * get DERObjectIdentifier by registered attribute type name such like 'C' or 'CN'<br/> 2519 * @name atype2obj 2520 * @memberOf KJUR.asn1.x509.OID 2521 * @function 2522 * @param {String} atype short attribute type name such like 'C' or 'CN' 2523 * @description 2524 * @example 2525 * KJUR.asn1.x509.OID.atype2obj('CN') → 2.5.4.3 2526 * KJUR.asn1.x509.OID.atype2obj('OU') → 2.5.4.11 2527 */ 2528 this.atype2obj = function(atype) { 2529 if (typeof this.objCache[atype] != "undefined") 2530 return this.objCache[atype]; 2531 if (typeof this.atype2oidList[atype] == "undefined") 2532 throw "AttributeType name undefined: " + atype; 2533 var oid = this.atype2oidList[atype]; 2534 var obj = new KJUR.asn1.DERObjectIdentifier({'oid': oid}); 2535 this.objCache[atype] = obj; 2536 return obj; 2537 }; 2538 }; 2539 2540 /** 2541 * convert OID to name<br/> 2542 * @name oid2name 2543 * @memberOf KJUR.asn1.x509.OID 2544 * @function 2545 * @param {String} oid dot noted Object Identifer string (ex. 1.2.3.4) 2546 * @return {String} OID name if registered otherwise empty string 2547 * @since asn1x509 1.0.9 2548 * @description 2549 * This static method converts OID string to its name. 2550 * If OID is undefined then it returns empty string (i.e. ''). 2551 * @example 2552 * KJUR.asn1.x509.OID.oid2name("1.3.6.1.5.5.7.1.1") → 'authorityInfoAccess' 2553 */ 2554 KJUR.asn1.x509.OID.oid2name = function(oid) { 2555 var list = KJUR.asn1.x509.OID.name2oidList; 2556 for (var name in list) { 2557 if (list[name] == oid) return name; 2558 } 2559 return ''; 2560 }; 2561 2562 /** 2563 * convert OID to AttributeType name<br/> 2564 * @name oid2atype 2565 * @memberOf KJUR.asn1.x509.OID 2566 * @function 2567 * @param {String} oid dot noted Object Identifer string (ex. 1.2.3.4) 2568 * @return {String} OID AttributeType name if registered otherwise oid 2569 * @since jsrsasign 6.2.2 asn1x509 1.0.18 2570 * @description 2571 * This static method converts OID string to its AttributeType name. 2572 * If OID is not defined in OID.atype2oidList associative array then it returns OID 2573 * specified as argument. 2574 * @example 2575 * KJUR.asn1.x509.OID.oid2atype("2.5.4.3") → CN 2576 * KJUR.asn1.x509.OID.oid2atype("1.3.6.1.4.1.311.60.2.1.3") → jurisdictionOfIncorporationC 2577 * KJUR.asn1.x509.OID.oid2atype("0.1.2.3.4") → 0.1.2.3.4 // unregistered OID 2578 */ 2579 KJUR.asn1.x509.OID.oid2atype = function(oid) { 2580 var list = KJUR.asn1.x509.OID.atype2oidList; 2581 for (var atype in list) { 2582 if (list[atype] == oid) return atype; 2583 } 2584 return oid; 2585 }; 2586 2587 /** 2588 * convert OID name to OID value<br/> 2589 * @name name2oid 2590 * @memberOf KJUR.asn1.x509.OID 2591 * @function 2592 * @param {String} OID name 2593 * @return {String} dot noted Object Identifer string (ex. 1.2.3.4) 2594 * @since asn1x509 1.0.11 2595 * @description 2596 * This static method converts from OID name to OID string. 2597 * If OID is undefined then it returns empty string (i.e. ''). 2598 * @example 2599 * KJUR.asn1.x509.OID.name2oid("authorityInfoAccess") → 1.3.6.1.5.5.7.1.1 2600 */ 2601 KJUR.asn1.x509.OID.name2oid = function(name) { 2602 var list = KJUR.asn1.x509.OID.name2oidList; 2603 if (list[name] === undefined) return ''; 2604 return list[name]; 2605 }; 2606 2607 /** 2608 * X.509 certificate and CRL utilities class<br/> 2609 * @name KJUR.asn1.x509.X509Util 2610 * @class X.509 certificate and CRL utilities class 2611 */ 2612 KJUR.asn1.x509.X509Util = {}; 2613 2614 /** 2615 * issue a certificate in PEM format 2616 * @name newCertPEM 2617 * @memberOf KJUR.asn1.x509.X509Util 2618 * @function 2619 * @param {Array} param parameter to issue a certificate 2620 * @since asn1x509 1.0.6 2621 * @description 2622 * This method can issue a certificate by a simple 2623 * JSON object. 2624 * Signature value will be provided by signing with 2625 * private key using 'cakey' parameter or 2626 * hexa decimal signature value by 'sighex' parameter. 2627 * <br/> 2628 * NOTE: Algorithm parameter of AlgorithmIdentifier will 2629 * be set automatically by default. (see {@link KJUR.asn1.x509.AlgorithmIdentifier}) 2630 * from jsrsasign 7.1.1 asn1x509 1.0.20. 2631 * 2632 * @example 2633 * var certPEM = KJUR.asn1.x509.X509Util.newCertPEM({ 2634 * serial: {int: 4}, 2635 * sigalg: {name: 'SHA1withECDSA'}, 2636 * issuer: {str: '/C=US/O=a'}, 2637 * notbefore: {'str': '130504235959Z'}, 2638 * notafter: {'str': '140504235959Z'}, 2639 * subject: {str: '/C=US/O=b'}, 2640 * sbjpubkey: pubKeyObj, 2641 * ext: [ 2642 * {basicConstraints: {cA: true, critical: true}}, 2643 * {keyUsage: {bin: '11'}}, 2644 * ], 2645 * cakey: prvKeyObj 2646 * }); 2647 * // -- or -- 2648 * var certPEM = KJUR.asn1.x509.X509Util.newCertPEM({ 2649 * serial: {int: 4}, 2650 * sigalg: {name: 'SHA1withECDSA'}, 2651 * issuer: {str: '/C=US/O=a'}, 2652 * notbefore: {'str': '130504235959Z'}, 2653 * notafter: {'str': '140504235959Z'}, 2654 * subject: {str: '/C=US/O=b'}, 2655 * sbjpubkey: pubKeyPEM, 2656 * ext: [ 2657 * {basicConstraints: {cA: true, critical: true}}, 2658 * {keyUsage: {bin: '11'}}, 2659 * ], 2660 * cakey: [prvkey, pass]} 2661 * ); 2662 * // -- or -- 2663 * var certPEM = KJUR.asn1.x509.X509Util.newCertPEM({ 2664 * serial: {int: 1}, 2665 * sigalg: {name: 'SHA1withRSA'}, 2666 * issuer: {str: '/C=US/O=T1'}, 2667 * notbefore: {'str': '130504235959Z'}, 2668 * notafter: {'str': '140504235959Z'}, 2669 * subject: {str: '/C=US/O=T1'}, 2670 * sbjpubkey: pubKeyObj, 2671 * sighex: '0102030405..' 2672 * }); 2673 * // for the issuer and subject field, another 2674 * // representation is also available 2675 * var certPEM = KJUR.asn1.x509.X509Util.newCertPEM({ 2676 * serial: {int: 1}, 2677 * sigalg: {name: 'SHA256withRSA'}, 2678 * issuer: {C: "US", O: "T1"}, 2679 * notbefore: {'str': '130504235959Z'}, 2680 * notafter: {'str': '140504235959Z'}, 2681 * subject: {C: "US", O: "T1", CN: "http://example.com/"}, 2682 * sbjpubkey: pubKeyObj, 2683 * sighex: '0102030405..' 2684 * }); 2685 */ 2686 KJUR.asn1.x509.X509Util.newCertPEM = function(param) { 2687 var _KJUR_asn1_x509 = KJUR.asn1.x509, 2688 _TBSCertificate = _KJUR_asn1_x509.TBSCertificate, 2689 _Certificate = _KJUR_asn1_x509.Certificate; 2690 var o = new _TBSCertificate(); 2691 2692 if (param.serial !== undefined) 2693 o.setSerialNumberByParam(param.serial); 2694 else 2695 throw "serial number undefined."; 2696 2697 if (typeof param.sigalg.name === 'string') 2698 o.setSignatureAlgByParam(param.sigalg); 2699 else 2700 throw "unproper signature algorithm name"; 2701 2702 if (param.issuer !== undefined) 2703 o.setIssuerByParam(param.issuer); 2704 else 2705 throw "issuer name undefined."; 2706 2707 if (param.notbefore !== undefined) 2708 o.setNotBeforeByParam(param.notbefore); 2709 else 2710 throw "notbefore undefined."; 2711 2712 if (param.notafter !== undefined) 2713 o.setNotAfterByParam(param.notafter); 2714 else 2715 throw "notafter undefined."; 2716 2717 if (param.subject !== undefined) 2718 o.setSubjectByParam(param.subject); 2719 else 2720 throw "subject name undefined."; 2721 2722 if (param.sbjpubkey !== undefined) 2723 o.setSubjectPublicKeyByGetKey(param.sbjpubkey); 2724 else 2725 throw "subject public key undefined."; 2726 2727 if (param.ext !== undefined && param.ext.length !== undefined) { 2728 for (var i = 0; i < param.ext.length; i++) { 2729 for (key in param.ext[i]) { 2730 o.appendExtensionByName(key, param.ext[i][key]); 2731 } 2732 } 2733 } 2734 2735 // set signature 2736 if (param.cakey === undefined && param.sighex === undefined) 2737 throw "param cakey and sighex undefined."; 2738 2739 var caKey = null; 2740 var cert = null; 2741 2742 if (param.cakey) { 2743 if (param.cakey.isPrivate === true) { 2744 caKey = param.cakey; 2745 } else { 2746 caKey = KEYUTIL.getKey.apply(null, param.cakey); 2747 } 2748 cert = new _Certificate({'tbscertobj': o, 'prvkeyobj': caKey}); 2749 cert.sign(); 2750 } 2751 2752 if (param.sighex) { 2753 cert = new _Certificate({'tbscertobj': o}); 2754 cert.setSignatureHex(param.sighex); 2755 } 2756 2757 return cert.getPEMString(); 2758 }; 2759 2760