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