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