1 /*! asn1x509-1.0.14.js (c) 2013-2015 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-2015 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.14 (2016-May-10) 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 * </ul> 76 * NOTE: Please ignore method summary and document of this namespace. This caused by a bug of jsdoc2. 77 * @name KJUR.asn1.x509 78 * @namespace 79 */ 80 if (typeof KJUR.asn1.x509 == "undefined" || !KJUR.asn1.x509) KJUR.asn1.x509 = {}; 81 82 // === BEGIN Certificate =================================================== 83 84 /** 85 * X.509 Certificate class to sign and generate hex encoded certificate 86 * @name KJUR.asn1.x509.Certificate 87 * @class X.509 Certificate class to sign and generate hex encoded certificate 88 * @param {Array} params associative array of parameters (ex. {'tbscertobj': obj, 'prvkeyobj': key}) 89 * @extends KJUR.asn1.ASN1Object 90 * @description 91 * <br/> 92 * As for argument 'params' for constructor, you can specify one of 93 * following properties: 94 * <ul> 95 * <li>tbscertobj - specify {@link KJUR.asn1.x509.TBSCertificate} object</li> 96 * <li>prvkeyobj - specify {@link RSAKey}, {@link KJUR.crypto.ECDSA} or {@link KJUR.crypto.DSA} object for CA private key to sign the certificate</li> 97 * <li>(DEPRECATED)rsaprvkey - specify {@link RSAKey} object CA private key</li> 98 * <li>(DEPRECATED)rsaprvpem - specify PEM string of RSA CA private key</li> 99 * </ul> 100 * NOTE1: 'params' can be omitted.<br/> 101 * NOTE2: DSA/ECDSA is also supported for CA signging key from asn1x509 1.0.6. 102 * @example 103 * var caKey = KEYUTIL.getKey(caKeyPEM); // CA's private key 104 * var cert = new KJUR.asn1x509.Certificate({'tbscertobj': tbs, 'prvkeyobj': caKey}); 105 * cert.sign(); // issue certificate by CA's private key 106 * var certPEM = cert.getPEMString(); 107 * 108 * // Certificate ::= SEQUENCE { 109 * // tbsCertificate TBSCertificate, 110 * // signatureAlgorithm AlgorithmIdentifier, 111 * // signature BIT STRING } 112 */ 113 KJUR.asn1.x509.Certificate = function(params) { 114 KJUR.asn1.x509.Certificate.superclass.constructor.call(this); 115 var asn1TBSCert = null; 116 var asn1SignatureAlg = null; 117 var asn1Sig = null; 118 var hexSig = null; 119 var prvKey = null; 120 var rsaPrvKey = null; // DEPRECATED 121 122 123 /** 124 * set PKCS#5 encrypted RSA PEM private key as CA key 125 * @name setRsaPrvKeyByPEMandPass 126 * @memberOf KJUR.asn1.x509.Certificate 127 * @function 128 * @param {String} rsaPEM string of PKCS#5 encrypted RSA PEM private key 129 * @param {String} passPEM passcode string to decrypt private key 130 * @since 1.0.1 131 * @description 132 * <br/> 133 * <h4>EXAMPLES</h4> 134 * @example 135 * var cert = new KJUR.asn1.x509.Certificate({'tbscertobj': tbs}); 136 * cert.setRsaPrvKeyByPEMandPass("-----BEGIN RSA PRIVATE..(snip)", "password"); 137 */ 138 this.setRsaPrvKeyByPEMandPass = function(rsaPEM, passPEM) { 139 var caKeyHex = PKCS5PKEY.getDecryptedKeyHex(rsaPEM, passPEM); 140 var caKey = new RSAKey(); 141 caKey.readPrivateKeyFromASN1HexString(caKeyHex); 142 this.prvKey = caKey; 143 }; 144 145 /** 146 * sign TBSCertificate and set signature value internally 147 * @name sign 148 * @memberOf KJUR.asn1.x509.Certificate 149 * @function 150 * @description 151 * @example 152 * var cert = new KJUR.asn1.x509.Certificate({'tbscertobj': tbs, 'rsaprvkey': prvKey}); 153 * cert.sign(); 154 */ 155 this.sign = function() { 156 this.asn1SignatureAlg = this.asn1TBSCert.asn1SignatureAlg; 157 158 sig = new KJUR.crypto.Signature({'alg': 'SHA1withRSA'}); 159 sig.init(this.prvKey); 160 sig.updateHex(this.asn1TBSCert.getEncodedHex()); 161 this.hexSig = sig.sign(); 162 163 this.asn1Sig = new KJUR.asn1.DERBitString({'hex': '00' + this.hexSig}); 164 165 var seq = new KJUR.asn1.DERSequence({'array': [this.asn1TBSCert, 166 this.asn1SignatureAlg, 167 this.asn1Sig]}); 168 this.hTLV = seq.getEncodedHex(); 169 this.isModified = false; 170 }; 171 172 /** 173 * set signature value internally by hex string 174 * @name setSignatureHex 175 * @memberOf KJUR.asn1.x509.Certificate 176 * @function 177 * @since asn1x509 1.0.8 178 * @description 179 * @example 180 * var cert = new KJUR.asn1.x509.Certificate({'tbscertobj': tbs}); 181 * cert.setSignatureHex('01020304'); 182 */ 183 this.setSignatureHex = function(sigHex) { 184 this.asn1SignatureAlg = this.asn1TBSCert.asn1SignatureAlg; 185 this.hexSig = sigHex; 186 this.asn1Sig = new KJUR.asn1.DERBitString({'hex': '00' + this.hexSig}); 187 188 var seq = new KJUR.asn1.DERSequence({'array': [this.asn1TBSCert, 189 this.asn1SignatureAlg, 190 this.asn1Sig]}); 191 this.hTLV = seq.getEncodedHex(); 192 this.isModified = false; 193 }; 194 195 this.getEncodedHex = function() { 196 if (this.isModified == false && this.hTLV != null) return this.hTLV; 197 throw "not signed yet"; 198 }; 199 200 /** 201 * get PEM formatted certificate string after signed 202 * @name getPEMString 203 * @memberOf KJUR.asn1.x509.Certificate 204 * @function 205 * @return PEM formatted string of certificate 206 * @description 207 * @example 208 * var cert = new KJUR.asn1.x509.Certificate({'tbscertobj': tbs, 'rsaprvkey': prvKey}); 209 * cert.sign(); 210 * var sPEM = cert.getPEMString(); 211 */ 212 this.getPEMString = function() { 213 var hCert = this.getEncodedHex(); 214 var wCert = CryptoJS.enc.Hex.parse(hCert); 215 var b64Cert = CryptoJS.enc.Base64.stringify(wCert); 216 var pemBody = b64Cert.replace(/(.{64})/g, "$1\r\n"); 217 return "-----BEGIN CERTIFICATE-----\r\n" + pemBody + "\r\n-----END CERTIFICATE-----\r\n"; 218 }; 219 220 if (typeof params != "undefined") { 221 if (typeof params['tbscertobj'] != "undefined") { 222 this.asn1TBSCert = params['tbscertobj']; 223 } 224 if (typeof params['prvkeyobj'] != "undefined") { 225 this.prvKey = params['prvkeyobj']; 226 } else if (typeof params['rsaprvkey'] != "undefined") { 227 this.prvKey = params['rsaprvkey']; 228 } else if ((typeof params['rsaprvpem'] != "undefined") && 229 (typeof params['rsaprvpas'] != "undefined")) { 230 this.setRsaPrvKeyByPEMandPass(params['rsaprvpem'], params['rsaprvpas']); 231 } 232 } 233 }; 234 YAHOO.lang.extend(KJUR.asn1.x509.Certificate, KJUR.asn1.ASN1Object); 235 236 /** 237 * ASN.1 TBSCertificate structure class 238 * @name KJUR.asn1.x509.TBSCertificate 239 * @class ASN.1 TBSCertificate structure class 240 * @param {Array} params associative array of parameters (ex. {}) 241 * @extends KJUR.asn1.ASN1Object 242 * @description 243 * <br/> 244 * <h4>EXAMPLE</h4> 245 * @example 246 * var o = new KJUR.asn1.x509.TBSCertificate(); 247 * o.setSerialNumberByParam({'int': 4}); 248 * o.setSignatureAlgByParam({'name': 'SHA1withRSA'}); 249 * o.setIssuerByParam({'str': '/C=US/O=a'}); 250 * o.setNotBeforeByParam({'str': '130504235959Z'}); 251 * o.setNotAfterByParam({'str': '140504235959Z'}); 252 * o.setSubjectByParam({'str': '/C=US/CN=b'}); 253 * o.setSubjectPublicKeyByParam({'rsakey': rsaKey}); 254 * o.appendExtension(new KJUR.asn1.x509.BasicConstraints({'cA':true})); 255 * o.appendExtension(new KJUR.asn1.x509.KeyUsage({'bin':'11'})); 256 */ 257 KJUR.asn1.x509.TBSCertificate = function(params) { 258 KJUR.asn1.x509.TBSCertificate.superclass.constructor.call(this); 259 260 this._initialize = function() { 261 this.asn1Array = new Array(); 262 263 this.asn1Version = 264 new KJUR.asn1.DERTaggedObject({'obj': new KJUR.asn1.DERInteger({'int': 2})}); 265 this.asn1SerialNumber = null; 266 this.asn1SignatureAlg = null; 267 this.asn1Issuer = null; 268 this.asn1NotBefore = null; 269 this.asn1NotAfter = null; 270 this.asn1Subject = null; 271 this.asn1SubjPKey = null; 272 this.extensionsArray = new Array(); 273 }; 274 275 /** 276 * set serial number field by parameter 277 * @name setSerialNumberByParam 278 * @memberOf KJUR.asn1.x509.TBSCertificate 279 * @function 280 * @param {Array} intParam DERInteger param 281 * @description 282 * @example 283 * tbsc.setSerialNumberByParam({'int': 3}); 284 */ 285 this.setSerialNumberByParam = function(intParam) { 286 this.asn1SerialNumber = new KJUR.asn1.DERInteger(intParam); 287 }; 288 289 /** 290 * set signature algorithm field by parameter 291 * @name setSignatureAlgByParam 292 * @memberOf KJUR.asn1.x509.TBSCertificate 293 * @function 294 * @param {Array} algIdParam AlgorithmIdentifier parameter 295 * @description 296 * @example 297 * tbsc.setSignatureAlgByParam({'name': 'SHA1withRSA'}); 298 */ 299 this.setSignatureAlgByParam = function(algIdParam) { 300 this.asn1SignatureAlg = new KJUR.asn1.x509.AlgorithmIdentifier(algIdParam); 301 }; 302 303 /** 304 * set issuer name field by parameter 305 * @name setIssuerByParam 306 * @memberOf KJUR.asn1.x509.TBSCertificate 307 * @function 308 * @param {Array} x500NameParam X500Name parameter 309 * @description 310 * @example 311 * tbsc.setIssuerParam({'str': '/C=US/CN=b'}); 312 * @see KJUR.asn1.x509.X500Name 313 */ 314 this.setIssuerByParam = function(x500NameParam) { 315 this.asn1Issuer = new KJUR.asn1.x509.X500Name(x500NameParam); 316 }; 317 318 /** 319 * set notBefore field by parameter 320 * @name setNotBeforeByParam 321 * @memberOf KJUR.asn1.x509.TBSCertificate 322 * @function 323 * @param {Array} timeParam Time parameter 324 * @description 325 * @example 326 * tbsc.setNotBeforeByParam({'str': '130508235959Z'}); 327 * @see KJUR.asn1.x509.Time 328 */ 329 this.setNotBeforeByParam = function(timeParam) { 330 this.asn1NotBefore = new KJUR.asn1.x509.Time(timeParam); 331 }; 332 333 /** 334 * set notAfter field by parameter 335 * @name setNotAfterByParam 336 * @memberOf KJUR.asn1.x509.TBSCertificate 337 * @function 338 * @param {Array} timeParam Time parameter 339 * @description 340 * @example 341 * tbsc.setNotAfterByParam({'str': '130508235959Z'}); 342 * @see KJUR.asn1.x509.Time 343 */ 344 this.setNotAfterByParam = function(timeParam) { 345 this.asn1NotAfter = new KJUR.asn1.x509.Time(timeParam); 346 }; 347 348 /** 349 * set subject name field by parameter 350 * @name setSubjectByParam 351 * @memberOf KJUR.asn1.x509.TBSCertificate 352 * @function 353 * @param {Array} x500NameParam X500Name parameter 354 * @description 355 * @example 356 * tbsc.setSubjectParam({'str': '/C=US/CN=b'}); 357 * @see KJUR.asn1.x509.X500Name 358 */ 359 this.setSubjectByParam = function(x500NameParam) { 360 this.asn1Subject = new KJUR.asn1.x509.X500Name(x500NameParam); 361 }; 362 363 /** 364 * (DEPRECATED) set subject public key info field by RSA key parameter 365 * @name setSubjectPublicKeyByParam 366 * @memberOf KJUR.asn1.x509.TBSCertificate 367 * @function 368 * @param {Array} subjPKeyParam SubjectPublicKeyInfo parameter of RSA 369 * @deprecated 370 * @description 371 * @example 372 * tbsc.setSubjectPublicKeyByParam({'rsakey': pubKey}); 373 * @see KJUR.asn1.x509.SubjectPublicKeyInfo 374 */ 375 this.setSubjectPublicKeyByParam = function(subjPKeyParam) { 376 this.asn1SubjPKey = new KJUR.asn1.x509.SubjectPublicKeyInfo(subjPKeyParam); 377 }; 378 379 /** 380 * set subject public key info by RSA/ECDSA/DSA key parameter 381 * @name setSubjectPublicKeyByGetKey 382 * @memberOf KJUR.asn1.x509.TBSCertificate 383 * @function 384 * @param {Object} keyParam public key parameter which passed to {@link KEYUTIL.getKey} argument 385 * @description 386 * @example 387 * tbsc.setSubjectPublicKeyByGetKeyParam(certPEMString); // or 388 * tbsc.setSubjectPublicKeyByGetKeyParam(pkcs8PublicKeyPEMString); // or 389 * tbsc.setSubjectPublicKeyByGetKeyParam(kjurCryptoECDSAKeyObject); // et.al. 390 * @see KJUR.asn1.x509.SubjectPublicKeyInfo 391 * @see KEYUTIL.getKey 392 * @since asn1x509 1.0.6 393 */ 394 this.setSubjectPublicKeyByGetKey = function(keyParam) { 395 var keyObj = KEYUTIL.getKey(keyParam); 396 this.asn1SubjPKey = new KJUR.asn1.x509.SubjectPublicKeyInfo(keyObj); 397 }; 398 399 /** 400 * append X.509v3 extension to this object 401 * @name appendExtension 402 * @memberOf KJUR.asn1.x509.TBSCertificate 403 * @function 404 * @param {Extension} extObj X.509v3 Extension object 405 * @description 406 * @example 407 * tbsc.appendExtension(new KJUR.asn1.x509.BasicConstraints({'cA':true, 'critical': true})); 408 * tbsc.appendExtension(new KJUR.asn1.x509.KeyUsage({'bin':'11'})); 409 * @see KJUR.asn1.x509.Extension 410 */ 411 this.appendExtension = function(extObj) { 412 this.extensionsArray.push(extObj); 413 }; 414 415 /** 416 * append X.509v3 extension to this object by name and parameters 417 * @name appendExtensionByName 418 * @memberOf KJUR.asn1.x509.TBSCertificate 419 * @function 420 * @param {name} name name of X.509v3 Extension object 421 * @param {Array} extParams parameters as argument of Extension constructor. 422 * @description 423 * @example 424 * tbsc.appendExtensionByName('BasicConstraints', {'cA':true, 'critical': true}); 425 * tbsc.appendExtensionByName('KeyUsage', {'bin':'11'}); 426 * tbsc.appendExtensionByName('CRLDistributionPoints', {uri: 'http://aaa.com/a.crl'}); 427 * tbsc.appendExtensionByName('ExtKeyUsage', {array: [{name: 'clientAuth'}]}); 428 * tbsc.appendExtensionByName('AuthorityKeyIdentifier', {kid: '1234ab..'}); 429 * @see KJUR.asn1.x509.Extension 430 */ 431 this.appendExtensionByName = function(name, extParams) { 432 if (name.toLowerCase() == "basicconstraints") { 433 var extObj = new KJUR.asn1.x509.BasicConstraints(extParams); 434 this.appendExtension(extObj); 435 } else if (name.toLowerCase() == "keyusage") { 436 var extObj = new KJUR.asn1.x509.KeyUsage(extParams); 437 this.appendExtension(extObj); 438 } else if (name.toLowerCase() == "crldistributionpoints") { 439 var extObj = new KJUR.asn1.x509.CRLDistributionPoints(extParams); 440 this.appendExtension(extObj); 441 } else if (name.toLowerCase() == "extkeyusage") { 442 var extObj = new KJUR.asn1.x509.ExtKeyUsage(extParams); 443 this.appendExtension(extObj); 444 } else if (name.toLowerCase() == "authoritykeyidentifier") { 445 var extObj = new KJUR.asn1.x509.AuthorityKeyIdentifier(extParams); 446 this.appendExtension(extObj); 447 } else { 448 throw "unsupported extension name: " + name; 449 } 450 }; 451 452 this.getEncodedHex = function() { 453 if (this.asn1NotBefore == null || this.asn1NotAfter == null) 454 throw "notBefore and/or notAfter not set"; 455 var asn1Validity = 456 new KJUR.asn1.DERSequence({'array':[this.asn1NotBefore, this.asn1NotAfter]}); 457 458 this.asn1Array = new Array(); 459 460 this.asn1Array.push(this.asn1Version); 461 this.asn1Array.push(this.asn1SerialNumber); 462 this.asn1Array.push(this.asn1SignatureAlg); 463 this.asn1Array.push(this.asn1Issuer); 464 this.asn1Array.push(asn1Validity); 465 this.asn1Array.push(this.asn1Subject); 466 this.asn1Array.push(this.asn1SubjPKey); 467 468 if (this.extensionsArray.length > 0) { 469 var extSeq = new KJUR.asn1.DERSequence({"array": this.extensionsArray}); 470 var extTagObj = new KJUR.asn1.DERTaggedObject({'explicit': true, 471 'tag': 'a3', 472 'obj': extSeq}); 473 this.asn1Array.push(extTagObj); 474 } 475 476 var o = new KJUR.asn1.DERSequence({"array": this.asn1Array}); 477 this.hTLV = o.getEncodedHex(); 478 this.isModified = false; 479 return this.hTLV; 480 }; 481 482 this._initialize(); 483 }; 484 YAHOO.lang.extend(KJUR.asn1.x509.TBSCertificate, KJUR.asn1.ASN1Object); 485 486 // === END TBSCertificate =================================================== 487 488 // === BEGIN X.509v3 Extensions Related ======================================= 489 490 /** 491 * base Extension ASN.1 structure class 492 * @name KJUR.asn1.x509.Extension 493 * @class base Extension ASN.1 structure class 494 * @param {Array} params associative array of parameters (ex. {'critical': true}) 495 * @extends KJUR.asn1.ASN1Object 496 * @description 497 * @example 498 * // Extension ::= SEQUENCE { 499 * // extnID OBJECT IDENTIFIER, 500 * // critical BOOLEAN DEFAULT FALSE, 501 * // extnValue OCTET STRING } 502 */ 503 KJUR.asn1.x509.Extension = function(params) { 504 KJUR.asn1.x509.Extension.superclass.constructor.call(this); 505 var asn1ExtnValue = null; 506 507 this.getEncodedHex = function() { 508 var asn1Oid = new KJUR.asn1.DERObjectIdentifier({'oid': this.oid}); 509 var asn1EncapExtnValue = 510 new KJUR.asn1.DEROctetString({'hex': this.getExtnValueHex()}); 511 512 var asn1Array = new Array(); 513 asn1Array.push(asn1Oid); 514 if (this.critical) asn1Array.push(new KJUR.asn1.DERBoolean()); 515 asn1Array.push(asn1EncapExtnValue); 516 517 var asn1Seq = new KJUR.asn1.DERSequence({'array': asn1Array}); 518 return asn1Seq.getEncodedHex(); 519 }; 520 521 this.critical = false; 522 if (typeof params != "undefined") { 523 if (typeof params['critical'] != "undefined") { 524 this.critical = params['critical']; 525 } 526 } 527 }; 528 YAHOO.lang.extend(KJUR.asn1.x509.Extension, KJUR.asn1.ASN1Object); 529 530 /** 531 * KeyUsage ASN.1 structure class 532 * @name KJUR.asn1.x509.KeyUsage 533 * @class KeyUsage ASN.1 structure class 534 * @param {Array} params associative array of parameters (ex. {'bin': '11', 'critical': true}) 535 * @extends KJUR.asn1.x509.Extension 536 * @description 537 * @example 538 */ 539 KJUR.asn1.x509.KeyUsage = function(params) { 540 KJUR.asn1.x509.KeyUsage.superclass.constructor.call(this, params); 541 542 this.getExtnValueHex = function() { 543 return this.asn1ExtnValue.getEncodedHex(); 544 }; 545 546 this.oid = "2.5.29.15"; 547 if (typeof params != "undefined") { 548 if (typeof params['bin'] != "undefined") { 549 this.asn1ExtnValue = new KJUR.asn1.DERBitString(params); 550 } 551 } 552 }; 553 YAHOO.lang.extend(KJUR.asn1.x509.KeyUsage, KJUR.asn1.x509.Extension); 554 555 /** 556 * BasicConstraints ASN.1 structure class 557 * @name KJUR.asn1.x509.BasicConstraints 558 * @class BasicConstraints ASN.1 structure class 559 * @param {Array} params associative array of parameters (ex. {'cA': true, 'critical': true}) 560 * @extends KJUR.asn1.x509.Extension 561 * @description 562 * @example 563 */ 564 KJUR.asn1.x509.BasicConstraints = function(params) { 565 KJUR.asn1.x509.BasicConstraints.superclass.constructor.call(this, params); 566 var cA = false; 567 var pathLen = -1; 568 569 this.getExtnValueHex = function() { 570 var asn1Array = new Array(); 571 if (this.cA) asn1Array.push(new KJUR.asn1.DERBoolean()); 572 if (this.pathLen > -1) 573 asn1Array.push(new KJUR.asn1.DERInteger({'int': this.pathLen})); 574 var asn1Seq = new KJUR.asn1.DERSequence({'array': asn1Array}); 575 this.asn1ExtnValue = asn1Seq; 576 return this.asn1ExtnValue.getEncodedHex(); 577 }; 578 579 this.oid = "2.5.29.19"; 580 this.cA = false; 581 this.pathLen = -1; 582 if (typeof params != "undefined") { 583 if (typeof params['cA'] != "undefined") { 584 this.cA = params['cA']; 585 } 586 if (typeof params['pathLen'] != "undefined") { 587 this.pathLen = params['pathLen']; 588 } 589 } 590 }; 591 YAHOO.lang.extend(KJUR.asn1.x509.BasicConstraints, KJUR.asn1.x509.Extension); 592 593 /** 594 * CRLDistributionPoints ASN.1 structure class 595 * @name KJUR.asn1.x509.CRLDistributionPoints 596 * @class CRLDistributionPoints ASN.1 structure class 597 * @param {Array} params associative array of parameters (ex. {'uri': 'http://a.com/', 'critical': true}) 598 * @extends KJUR.asn1.x509.Extension 599 * @description 600 * @example 601 */ 602 KJUR.asn1.x509.CRLDistributionPoints = function(params) { 603 KJUR.asn1.x509.CRLDistributionPoints.superclass.constructor.call(this, params); 604 605 this.getExtnValueHex = function() { 606 return this.asn1ExtnValue.getEncodedHex(); 607 }; 608 609 this.setByDPArray = function(dpArray) { 610 this.asn1ExtnValue = new KJUR.asn1.DERSequence({'array': dpArray}); 611 }; 612 613 this.setByOneURI = function(uri) { 614 var gn1 = new KJUR.asn1.x509.GeneralNames([{'uri': uri}]); 615 var dpn1 = new KJUR.asn1.x509.DistributionPointName(gn1); 616 var dp1 = new KJUR.asn1.x509.DistributionPoint({'dpobj': dpn1}); 617 this.setByDPArray([dp1]); 618 }; 619 620 this.oid = "2.5.29.31"; 621 if (typeof params != "undefined") { 622 if (typeof params['array'] != "undefined") { 623 this.setByDPArray(params['array']); 624 } else if (typeof params['uri'] != "undefined") { 625 this.setByOneURI(params['uri']); 626 } 627 } 628 }; 629 YAHOO.lang.extend(KJUR.asn1.x509.CRLDistributionPoints, KJUR.asn1.x509.Extension); 630 631 /** 632 * KeyUsage ASN.1 structure class 633 * @name KJUR.asn1.x509.ExtKeyUsage 634 * @class ExtKeyUsage ASN.1 structure class 635 * @param {Array} params associative array of parameters 636 * @extends KJUR.asn1.x509.Extension 637 * @description 638 * @example 639 * var e1 = 640 * new KJUR.asn1.x509.ExtKeyUsage({'critical': true, 641 * 'array': 642 * [{'oid': '2.5.29.37.0', // anyExtendedKeyUsage 643 * 'name': 'clientAuth'}]}); 644 * 645 * // id-ce-extKeyUsage OBJECT IDENTIFIER ::= { id-ce 37 } 646 * // ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId 647 * // KeyPurposeId ::= OBJECT IDENTIFIER 648 */ 649 KJUR.asn1.x509.ExtKeyUsage = function(params) { 650 KJUR.asn1.x509.ExtKeyUsage.superclass.constructor.call(this, params); 651 652 this.setPurposeArray = function(purposeArray) { 653 this.asn1ExtnValue = new KJUR.asn1.DERSequence(); 654 for (var i = 0; i < purposeArray.length; i++) { 655 var o = new KJUR.asn1.DERObjectIdentifier(purposeArray[i]); 656 this.asn1ExtnValue.appendASN1Object(o); 657 } 658 }; 659 660 this.getExtnValueHex = function() { 661 return this.asn1ExtnValue.getEncodedHex(); 662 }; 663 664 this.oid = "2.5.29.37"; 665 if (typeof params != "undefined") { 666 if (typeof params['array'] != "undefined") { 667 this.setPurposeArray(params['array']); 668 } 669 } 670 }; 671 YAHOO.lang.extend(KJUR.asn1.x509.ExtKeyUsage, KJUR.asn1.x509.Extension); 672 673 /** 674 * AuthorityKeyIdentifier ASN.1 structure class 675 * @name KJUR.asn1.x509.AuthorityKeyIdentifier 676 * @class AuthorityKeyIdentifier ASN.1 structure class 677 * @param {Array} params associative array of parameters (ex. {'uri': 'http://a.com/', 'critical': true}) 678 * @extends KJUR.asn1.x509.Extension 679 * @since asn1x509 1.0.8 680 * @description 681 * <pre> 682 * d-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 35 } 683 * AuthorityKeyIdentifier ::= SEQUENCE { 684 * keyIdentifier [0] KeyIdentifier OPTIONAL, 685 * authorityCertIssuer [1] GeneralNames OPTIONAL, 686 * authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL } 687 * KeyIdentifier ::= OCTET STRING 688 * </pre> 689 * @example 690 * var param = {'kid': {'hex': '89ab'}, 691 * 'issuer': {'str': '/C=US/CN=a'}, 692 * 'sn': {'hex': '1234'}, 693 * 'critical': true}); 694 * var e1 = new KJUR.asn1.x509.AuthorityKeyIdentifier(param); 695 */ 696 KJUR.asn1.x509.AuthorityKeyIdentifier = function(params) { 697 KJUR.asn1.x509.AuthorityKeyIdentifier.superclass.constructor.call(this, params); 698 this.asn1KID = null; 699 this.asn1CertIssuer = null; 700 this.asn1CertSN = null; 701 702 this.getExtnValueHex = function() { 703 var a = new Array(); 704 if (this.asn1KID) 705 a.push(new KJUR.asn1.DERTaggedObject({'explicit': false, 706 'tag': '80', 707 'obj': this.asn1KID})); 708 if (this.asn1CertIssuer) 709 a.push(new KJUR.asn1.DERTaggedObject({'explicit': false, 710 'tag': 'a1', 711 'obj': this.asn1CertIssuer})); 712 if (this.asn1CertSN) 713 a.push(new KJUR.asn1.DERTaggedObject({'explicit': false, 714 'tag': '82', 715 'obj': this.asn1CertSN})); 716 717 var asn1Seq = new KJUR.asn1.DERSequence({'array': a}); 718 this.asn1ExtnValue = asn1Seq; 719 return this.asn1ExtnValue.getEncodedHex(); 720 }; 721 722 /** 723 * set keyIdentifier value by DERInteger parameter 724 * @name setKIDByParam 725 * @memberOf KJUR.asn1.x509.AuthorityKeyIdentifier 726 * @function 727 * @param {Array} param array of {@link KJUR.asn1.DERInteger} parameter 728 * @since asn1x509 1.0.8 729 * @description 730 * NOTE: Automatic keyIdentifier value calculation by an issuer 731 * public key will be supported in future version. 732 */ 733 this.setKIDByParam = function(param) { 734 this.asn1KID = new KJUR.asn1.DEROctetString(param); 735 }; 736 737 /** 738 * set authorityCertIssuer value by X500Name parameter 739 * @name setCertIssuerByParam 740 * @memberOf KJUR.asn1.x509.AuthorityKeyIdentifier 741 * @function 742 * @param {Array} param array of {@link KJUR.asn1.x509.X500Name} parameter 743 * @since asn1x509 1.0.8 744 * @description 745 * NOTE: Automatic authorityCertIssuer name setting by an issuer 746 * certificate will be supported in future version. 747 */ 748 this.setCertIssuerByParam = function(param) { 749 this.asn1CertIssuer = new KJUR.asn1.x509.X500Name(param); 750 }; 751 752 /** 753 * set authorityCertSerialNumber value by DERInteger parameter 754 * @name setCertSerialNumberByParam 755 * @memberOf KJUR.asn1.x509.AuthorityKeyIdentifier 756 * @function 757 * @param {Array} param array of {@link KJUR.asn1.DERInteger} parameter 758 * @since asn1x509 1.0.8 759 * @description 760 * NOTE: Automatic authorityCertSerialNumber setting by an issuer 761 * certificate will be supported in future version. 762 */ 763 this.setCertSNByParam = function(param) { 764 this.asn1CertSN = new KJUR.asn1.DERInteger(param); 765 }; 766 767 this.oid = "2.5.29.35"; 768 if (typeof params != "undefined") { 769 if (typeof params['kid'] != "undefined") { 770 this.setKIDByParam(params['kid']); 771 } 772 if (typeof params['issuer'] != "undefined") { 773 this.setCertIssuerByParam(params['issuer']); 774 } 775 if (typeof params['sn'] != "undefined") { 776 this.setCertSNByParam(params['sn']); 777 } 778 } 779 }; 780 YAHOO.lang.extend(KJUR.asn1.x509.AuthorityKeyIdentifier, KJUR.asn1.x509.Extension); 781 782 // === END X.509v3 Extensions Related ======================================= 783 784 // === BEGIN CRL Related =================================================== 785 /** 786 * X.509 CRL class to sign and generate hex encoded CRL 787 * @name KJUR.asn1.x509.CRL 788 * @class X.509 CRL class to sign and generate hex encoded certificate 789 * @param {Array} params associative array of parameters (ex. {'tbsobj': obj, 'rsaprvkey': key}) 790 * @extends KJUR.asn1.ASN1Object 791 * @since 1.0.3 792 * @description 793 * <br/> 794 * As for argument 'params' for constructor, you can specify one of 795 * following properties: 796 * <ul> 797 * <li>tbsobj - specify {@link KJUR.asn1.x509.TBSCertList} object to be signed</li> 798 * <li>rsaprvkey - specify {@link RSAKey} object CA private key</li> 799 * </ul> 800 * NOTE: 'params' can be omitted. 801 * <h4>EXAMPLE</h4> 802 * @example 803 * var prvKey = new RSAKey(); // CA's private key 804 * prvKey.readPrivateKeyFromASN1HexString("3080..."); 805 * var crl = new KJUR.asn1x509.CRL({'tbsobj': tbs, 'rsaprvkey': prvKey}); 806 * crl.sign(); // issue CRL by CA's private key 807 * var hCRL = crl.getEncodedHex(); 808 * 809 * // CertificateList ::= SEQUENCE { 810 * // tbsCertList TBSCertList, 811 * // signatureAlgorithm AlgorithmIdentifier, 812 * // signatureValue BIT STRING } 813 */ 814 KJUR.asn1.x509.CRL = function(params) { 815 KJUR.asn1.x509.CRL.superclass.constructor.call(this); 816 817 var asn1TBSCertList = null; 818 var asn1SignatureAlg = null; 819 var asn1Sig = null; 820 var hexSig = null; 821 var rsaPrvKey = null; 822 823 /** 824 * set PKCS#5 encrypted RSA PEM private key as CA key 825 * @name setRsaPrvKeyByPEMandPass 826 * @memberOf KJUR.asn1.x509.CRL 827 * @function 828 * @param {String} rsaPEM string of PKCS#5 encrypted RSA PEM private key 829 * @param {String} passPEM passcode string to decrypt private key 830 * @description 831 * <br/> 832 * <h4>EXAMPLES</h4> 833 * @example 834 */ 835 this.setRsaPrvKeyByPEMandPass = function(rsaPEM, passPEM) { 836 var caKeyHex = PKCS5PKEY.getDecryptedKeyHex(rsaPEM, passPEM); 837 var caKey = new RSAKey(); 838 caKey.readPrivateKeyFromASN1HexString(caKeyHex); 839 this.rsaPrvKey = caKey; 840 }; 841 842 /** 843 * sign TBSCertList and set signature value internally 844 * @name sign 845 * @memberOf KJUR.asn1.x509.CRL 846 * @function 847 * @description 848 * @example 849 * var cert = new KJUR.asn1.x509.CRL({'tbsobj': tbs, 'rsaprvkey': prvKey}); 850 * cert.sign(); 851 */ 852 this.sign = function() { 853 this.asn1SignatureAlg = this.asn1TBSCertList.asn1SignatureAlg; 854 855 sig = new KJUR.crypto.Signature({'alg': 'SHA1withRSA', 'prov': 'cryptojs/jsrsa'}); 856 sig.initSign(this.rsaPrvKey); 857 sig.updateHex(this.asn1TBSCertList.getEncodedHex()); 858 this.hexSig = sig.sign(); 859 860 this.asn1Sig = new KJUR.asn1.DERBitString({'hex': '00' + this.hexSig}); 861 862 var seq = new KJUR.asn1.DERSequence({'array': [this.asn1TBSCertList, 863 this.asn1SignatureAlg, 864 this.asn1Sig]}); 865 this.hTLV = seq.getEncodedHex(); 866 this.isModified = false; 867 }; 868 869 this.getEncodedHex = function() { 870 if (this.isModified == false && this.hTLV != null) return this.hTLV; 871 throw "not signed yet"; 872 }; 873 874 /** 875 * get PEM formatted CRL string after signed 876 * @name getPEMString 877 * @memberOf KJUR.asn1.x509.CRL 878 * @function 879 * @return PEM formatted string of certificate 880 * @description 881 * @example 882 * var cert = new KJUR.asn1.x509.CRL({'tbsobj': tbs, 'rsaprvkey': prvKey}); 883 * cert.sign(); 884 * var sPEM = cert.getPEMString(); 885 */ 886 this.getPEMString = function() { 887 var hCert = this.getEncodedHex(); 888 var wCert = CryptoJS.enc.Hex.parse(hCert); 889 var b64Cert = CryptoJS.enc.Base64.stringify(wCert); 890 var pemBody = b64Cert.replace(/(.{64})/g, "$1\r\n"); 891 return "-----BEGIN X509 CRL-----\r\n" + pemBody + "\r\n-----END X509 CRL-----\r\n"; 892 }; 893 894 if (typeof params != "undefined") { 895 if (typeof params['tbsobj'] != "undefined") { 896 this.asn1TBSCertList = params['tbsobj']; 897 } 898 if (typeof params['rsaprvkey'] != "undefined") { 899 this.rsaPrvKey = params['rsaprvkey']; 900 } 901 if ((typeof params['rsaprvpem'] != "undefined") && 902 (typeof params['rsaprvpas'] != "undefined")) { 903 this.setRsaPrvKeyByPEMandPass(params['rsaprvpem'], params['rsaprvpas']); 904 } 905 } 906 }; 907 YAHOO.lang.extend(KJUR.asn1.x509.CRL, KJUR.asn1.ASN1Object); 908 909 /** 910 * ASN.1 TBSCertList structure class for CRL 911 * @name KJUR.asn1.x509.TBSCertList 912 * @class ASN.1 TBSCertList structure class for CRL 913 * @param {Array} params associative array of parameters (ex. {}) 914 * @extends KJUR.asn1.ASN1Object 915 * @since 1.0.3 916 * @description 917 * <br/> 918 * <h4>EXAMPLE</h4> 919 * @example 920 * var o = new KJUR.asn1.x509.TBSCertList(); 921 * o.setSignatureAlgByParam({'name': 'SHA1withRSA'}); 922 * o.setIssuerByParam({'str': '/C=US/O=a'}); 923 * o.setNotThisUpdateByParam({'str': '130504235959Z'}); 924 * o.setNotNextUpdateByParam({'str': '140504235959Z'}); 925 * o.addRevokedCert({'int': 4}, {'str':'130514235959Z'})); 926 * o.addRevokedCert({'hex': '0f34dd'}, {'str':'130514235959Z'})); 927 * 928 * // TBSCertList ::= SEQUENCE { 929 * // version Version OPTIONAL, 930 * // -- if present, MUST be v2 931 * // signature AlgorithmIdentifier, 932 * // issuer Name, 933 * // thisUpdate Time, 934 * // nextUpdate Time OPTIONAL, 935 * // revokedCertificates SEQUENCE OF SEQUENCE { 936 * // userCertificate CertificateSerialNumber, 937 * // revocationDate Time, 938 * // crlEntryExtensions Extensions OPTIONAL 939 * // -- if present, version MUST be v2 940 * // } OPTIONAL, 941 * // crlExtensions [0] EXPLICIT Extensions OPTIONAL 942 */ 943 KJUR.asn1.x509.TBSCertList = function(params) { 944 KJUR.asn1.x509.TBSCertList.superclass.constructor.call(this); 945 var aRevokedCert = null; 946 947 /** 948 * set signature algorithm field by parameter 949 * @name setSignatureAlgByParam 950 * @memberOf KJUR.asn1.x509.TBSCertList 951 * @function 952 * @param {Array} algIdParam AlgorithmIdentifier parameter 953 * @description 954 * @example 955 * tbsc.setSignatureAlgByParam({'name': 'SHA1withRSA'}); 956 */ 957 this.setSignatureAlgByParam = function(algIdParam) { 958 this.asn1SignatureAlg = new KJUR.asn1.x509.AlgorithmIdentifier(algIdParam); 959 }; 960 961 /** 962 * set issuer name field by parameter 963 * @name setIssuerByParam 964 * @memberOf KJUR.asn1.x509.TBSCertList 965 * @function 966 * @param {Array} x500NameParam X500Name parameter 967 * @description 968 * @example 969 * tbsc.setIssuerParam({'str': '/C=US/CN=b'}); 970 * @see KJUR.asn1.x509.X500Name 971 */ 972 this.setIssuerByParam = function(x500NameParam) { 973 this.asn1Issuer = new KJUR.asn1.x509.X500Name(x500NameParam); 974 }; 975 976 /** 977 * set thisUpdate field by parameter 978 * @name setThisUpdateByParam 979 * @memberOf KJUR.asn1.x509.TBSCertList 980 * @function 981 * @param {Array} timeParam Time parameter 982 * @description 983 * @example 984 * tbsc.setThisUpdateByParam({'str': '130508235959Z'}); 985 * @see KJUR.asn1.x509.Time 986 */ 987 this.setThisUpdateByParam = function(timeParam) { 988 this.asn1ThisUpdate = new KJUR.asn1.x509.Time(timeParam); 989 }; 990 991 /** 992 * set nextUpdate field by parameter 993 * @name setNextUpdateByParam 994 * @memberOf KJUR.asn1.x509.TBSCertList 995 * @function 996 * @param {Array} timeParam Time parameter 997 * @description 998 * @example 999 * tbsc.setNextUpdateByParam({'str': '130508235959Z'}); 1000 * @see KJUR.asn1.x509.Time 1001 */ 1002 this.setNextUpdateByParam = function(timeParam) { 1003 this.asn1NextUpdate = new KJUR.asn1.x509.Time(timeParam); 1004 }; 1005 1006 /** 1007 * add revoked certficate by parameter 1008 * @name addRevokedCert 1009 * @memberOf KJUR.asn1.x509.TBSCertList 1010 * @function 1011 * @param {Array} snParam DERInteger parameter for certificate serial number 1012 * @param {Array} timeParam Time parameter for revocation date 1013 * @description 1014 * @example 1015 * tbsc.addRevokedCert({'int': 3}, {'str': '130508235959Z'}); 1016 * @see KJUR.asn1.x509.Time 1017 */ 1018 this.addRevokedCert = function(snParam, timeParam) { 1019 var param = {}; 1020 if (snParam != undefined && snParam != null) param['sn'] = snParam; 1021 if (timeParam != undefined && timeParam != null) param['time'] = timeParam; 1022 var o = new KJUR.asn1.x509.CRLEntry(param); 1023 this.aRevokedCert.push(o); 1024 }; 1025 1026 this.getEncodedHex = function() { 1027 this.asn1Array = new Array(); 1028 1029 if (this.asn1Version != null) this.asn1Array.push(this.asn1Version); 1030 this.asn1Array.push(this.asn1SignatureAlg); 1031 this.asn1Array.push(this.asn1Issuer); 1032 this.asn1Array.push(this.asn1ThisUpdate); 1033 if (this.asn1NextUpdate != null) this.asn1Array.push(this.asn1NextUpdate); 1034 1035 if (this.aRevokedCert.length > 0) { 1036 var seq = new KJUR.asn1.DERSequence({'array': this.aRevokedCert}); 1037 this.asn1Array.push(seq); 1038 } 1039 1040 var o = new KJUR.asn1.DERSequence({"array": this.asn1Array}); 1041 this.hTLV = o.getEncodedHex(); 1042 this.isModified = false; 1043 return this.hTLV; 1044 }; 1045 1046 this._initialize = function() { 1047 this.asn1Version = null; 1048 this.asn1SignatureAlg = null; 1049 this.asn1Issuer = null; 1050 this.asn1ThisUpdate = null; 1051 this.asn1NextUpdate = null; 1052 this.aRevokedCert = new Array(); 1053 }; 1054 1055 this._initialize(); 1056 }; 1057 YAHOO.lang.extend(KJUR.asn1.x509.TBSCertList, KJUR.asn1.ASN1Object); 1058 1059 /** 1060 * ASN.1 CRLEntry structure class for CRL 1061 * @name KJUR.asn1.x509.CRLEntry 1062 * @class ASN.1 CRLEntry structure class for CRL 1063 * @param {Array} params associative array of parameters (ex. {}) 1064 * @extends KJUR.asn1.ASN1Object 1065 * @since 1.0.3 1066 * @description 1067 * @example 1068 * var e = new KJUR.asn1.x509.CRLEntry({'time': {'str': '130514235959Z'}, 'sn': {'int': 234}}); 1069 * 1070 * // revokedCertificates SEQUENCE OF SEQUENCE { 1071 * // userCertificate CertificateSerialNumber, 1072 * // revocationDate Time, 1073 * // crlEntryExtensions Extensions OPTIONAL 1074 * // -- if present, version MUST be v2 } 1075 */ 1076 KJUR.asn1.x509.CRLEntry = function(params) { 1077 KJUR.asn1.x509.CRLEntry.superclass.constructor.call(this); 1078 var sn = null; 1079 var time = null; 1080 1081 /** 1082 * set DERInteger parameter for serial number of revoked certificate 1083 * @name setCertSerial 1084 * @memberOf KJUR.asn1.x509.CRLEntry 1085 * @function 1086 * @param {Array} intParam DERInteger parameter for certificate serial number 1087 * @description 1088 * @example 1089 * entry.setCertSerial({'int': 3}); 1090 */ 1091 this.setCertSerial = function(intParam) { 1092 this.sn = new KJUR.asn1.DERInteger(intParam); 1093 }; 1094 1095 /** 1096 * set Time parameter for revocation date 1097 * @name setRevocationDate 1098 * @memberOf KJUR.asn1.x509.CRLEntry 1099 * @function 1100 * @param {Array} timeParam Time parameter for revocation date 1101 * @description 1102 * @example 1103 * entry.setRevocationDate({'str': '130508235959Z'}); 1104 */ 1105 this.setRevocationDate = function(timeParam) { 1106 this.time = new KJUR.asn1.x509.Time(timeParam); 1107 }; 1108 1109 this.getEncodedHex = function() { 1110 var o = new KJUR.asn1.DERSequence({"array": [this.sn, this.time]}); 1111 this.TLV = o.getEncodedHex(); 1112 return this.TLV; 1113 }; 1114 1115 if (typeof params != "undefined") { 1116 if (typeof params['time'] != "undefined") { 1117 this.setRevocationDate(params['time']); 1118 } 1119 if (typeof params['sn'] != "undefined") { 1120 this.setCertSerial(params['sn']); 1121 } 1122 } 1123 }; 1124 YAHOO.lang.extend(KJUR.asn1.x509.CRLEntry, KJUR.asn1.ASN1Object); 1125 1126 // === END CRL Related =================================================== 1127 1128 // === BEGIN X500Name Related ================================================= 1129 /** 1130 * X500Name ASN.1 structure class 1131 * @name KJUR.asn1.x509.X500Name 1132 * @class X500Name ASN.1 structure class 1133 * @param {Array} params associative array of parameters (ex. {'str': '/C=US/O=a'}) 1134 * @extends KJUR.asn1.ASN1Object 1135 * @description 1136 * @example 1137 * // 1. construct with string 1138 * o = new KJUR.asn1.x509.X500Name({str: "/C=US/O=aaa/OU=bbb/CN=foo@example.com"}); 1139 * // 2. construct by object 1140 * o = new KJUR.asn1.x509.X500Name({C: "US", O: "aaa", CN: "http://example.com/"}); 1141 */ 1142 KJUR.asn1.x509.X500Name = function(params) { 1143 KJUR.asn1.x509.X500Name.superclass.constructor.call(this); 1144 this.asn1Array = new Array(); 1145 1146 /** 1147 * set DN by string 1148 * @name setByString 1149 * @memberOf KJUR.asn1.x509.X500Name 1150 * @function 1151 * @param {Array} dnStr distinguished name by string (ex. /C=US/O=aaa) 1152 * @description 1153 * @example 1154 * name = new KJUR.asn1.x509.X500Name(); 1155 * name.setByString("/C=US/O=aaa/OU=bbb/CN=foo@example.com"); 1156 */ 1157 this.setByString = function(dnStr) { 1158 var a = dnStr.split('/'); 1159 a.shift(); 1160 for (var i = 0; i < a.length; i++) { 1161 this.asn1Array.push(new KJUR.asn1.x509.RDN({'str':a[i]})); 1162 } 1163 }; 1164 1165 /** 1166 * set DN by associative array 1167 * @name setByObject 1168 * @memberOf KJUR.asn1.x509.X500Name 1169 * @function 1170 * @param {Array} dnObj associative array of DN (ex. {C: "US", O: "aaa"}) 1171 * @since jsrsasign 4.9. asn1x509 1.0.13 1172 * @description 1173 * @example 1174 * name = new KJUR.asn1.x509.X500Name(); 1175 * name.setByObject({C: "US", O: "aaa", CN="http://example.com/"1}); 1176 */ 1177 this.setByObject = function(dnObj) { 1178 // Get all the dnObject attributes and stuff them in the ASN.1 array. 1179 for (var x in dnObj) { 1180 if (dnObj.hasOwnProperty(x)) { 1181 var newRDN = new KJUR.asn1.x509.RDN( 1182 {'str': x + '=' + dnObj[x]}); 1183 // Initialize or push into the ANS1 array. 1184 this.asn1Array ? this.asn1Array.push(newRDN) 1185 : this.asn1Array = [newRDN]; 1186 } 1187 } 1188 }; 1189 1190 this.getEncodedHex = function() { 1191 if (typeof this.hTLV == "string") return this.hTLV; 1192 var o = new KJUR.asn1.DERSequence({"array": this.asn1Array}); 1193 this.hTLV = o.getEncodedHex(); 1194 return this.hTLV; 1195 }; 1196 1197 if (typeof params != "undefined") { 1198 if (typeof params['str'] != "undefined") { 1199 this.setByString(params['str']); 1200 // If params is an object, then set the ASN1 array just using the object 1201 // attributes. This is nice for fields that have lots of special 1202 // characters (i.e. CN: 'http://www.github.com/kjur//'). 1203 } else if (typeof params === "object") { 1204 this.setByObject(params); 1205 } 1206 1207 if (typeof params.certissuer != "undefined") { 1208 var x = new X509(); 1209 x.hex = X509.pemToHex(params.certissuer); 1210 this.hTLV = x.getIssuerHex(); 1211 } 1212 if (typeof params.certsubject != "undefined") { 1213 var x = new X509(); 1214 x.hex = X509.pemToHex(params.certsubject); 1215 this.hTLV = x.getSubjectHex(); 1216 } 1217 } 1218 }; 1219 YAHOO.lang.extend(KJUR.asn1.x509.X500Name, KJUR.asn1.ASN1Object); 1220 1221 /** 1222 * RDN (Relative Distinguish Name) ASN.1 structure class 1223 * @name KJUR.asn1.x509.RDN 1224 * @class RDN (Relative Distinguish Name) ASN.1 structure class 1225 * @param {Array} params associative array of parameters (ex. {'str': 'C=US'}) 1226 * @extends KJUR.asn1.ASN1Object 1227 * @description 1228 * @example 1229 */ 1230 KJUR.asn1.x509.RDN = function(params) { 1231 KJUR.asn1.x509.RDN.superclass.constructor.call(this); 1232 this.asn1Array = new Array(); 1233 1234 this.addByString = function(rdnStr) { 1235 this.asn1Array.push(new KJUR.asn1.x509.AttributeTypeAndValue({'str':rdnStr})); 1236 }; 1237 1238 this.getEncodedHex = function() { 1239 var o = new KJUR.asn1.DERSet({"array": this.asn1Array}); 1240 this.TLV = o.getEncodedHex(); 1241 return this.TLV; 1242 }; 1243 1244 if (typeof params != "undefined") { 1245 if (typeof params['str'] != "undefined") { 1246 this.addByString(params['str']); 1247 } 1248 } 1249 }; 1250 YAHOO.lang.extend(KJUR.asn1.x509.RDN, KJUR.asn1.ASN1Object); 1251 1252 /** 1253 * AttributeTypeAndValue ASN.1 structure class 1254 * @name KJUR.asn1.x509.AttributeTypeAndValue 1255 * @class AttributeTypeAndValue ASN.1 structure class 1256 * @param {Array} params associative array of parameters (ex. {'str': 'C=US'}) 1257 * @extends KJUR.asn1.ASN1Object 1258 * @description 1259 * @example 1260 */ 1261 KJUR.asn1.x509.AttributeTypeAndValue = function(params) { 1262 KJUR.asn1.x509.AttributeTypeAndValue.superclass.constructor.call(this); 1263 var typeObj = null; 1264 var valueObj = null; 1265 var defaultDSType = "utf8"; 1266 1267 this.setByString = function(attrTypeAndValueStr) { 1268 if (attrTypeAndValueStr.match(/^([^=]+)=(.+)$/)) { 1269 this.setByAttrTypeAndValueStr(RegExp.$1, RegExp.$2); 1270 } else { 1271 throw "malformed attrTypeAndValueStr: " + attrTypeAndValueStr; 1272 } 1273 }; 1274 1275 this.setByAttrTypeAndValueStr = function(shortAttrType, valueStr) { 1276 this.typeObj = KJUR.asn1.x509.OID.atype2obj(shortAttrType); 1277 var dsType = defaultDSType; 1278 if (shortAttrType == "C") dsType = "prn"; 1279 this.valueObj = this.getValueObj(dsType, valueStr); 1280 }; 1281 1282 this.getValueObj = function(dsType, valueStr) { 1283 if (dsType == "utf8") return new KJUR.asn1.DERUTF8String({"str": valueStr}); 1284 if (dsType == "prn") return new KJUR.asn1.DERPrintableString({"str": valueStr}); 1285 if (dsType == "tel") return new KJUR.asn1.DERTeletexString({"str": valueStr}); 1286 if (dsType == "ia5") return new KJUR.asn1.DERIA5String({"str": valueStr}); 1287 throw "unsupported directory string type: type=" + dsType + " value=" + valueStr; 1288 }; 1289 1290 this.getEncodedHex = function() { 1291 var o = new KJUR.asn1.DERSequence({"array": [this.typeObj, this.valueObj]}); 1292 this.TLV = o.getEncodedHex(); 1293 return this.TLV; 1294 }; 1295 1296 if (typeof params != "undefined") { 1297 if (typeof params['str'] != "undefined") { 1298 this.setByString(params['str']); 1299 } 1300 } 1301 }; 1302 YAHOO.lang.extend(KJUR.asn1.x509.AttributeTypeAndValue, KJUR.asn1.ASN1Object); 1303 1304 // === END X500Name Related ================================================= 1305 1306 // === BEGIN Other ASN1 structure class ====================================== 1307 1308 /** 1309 * SubjectPublicKeyInfo ASN.1 structure class 1310 * @name KJUR.asn1.x509.SubjectPublicKeyInfo 1311 * @class SubjectPublicKeyInfo ASN.1 structure class 1312 * @param {Object} params parameter for subject public key 1313 * @extends KJUR.asn1.ASN1Object 1314 * @description 1315 * <br/> 1316 * As for argument 'params' for constructor, you can specify one of 1317 * following properties: 1318 * <ul> 1319 * <li>{@link RSAKey} object</li> 1320 * <li>{@link KJUR.crypto.ECDSA} object</li> 1321 * <li>{@link KJUR.crypto.DSA} object</li> 1322 * <li>(DEPRECATED)rsakey - specify {@link RSAKey} object of subject public key</li> 1323 * <li>(DEPRECATED)rsapem - specify a string of PEM public key of RSA key</li> 1324 * </ul> 1325 * NOTE1: 'params' can be omitted.<br/> 1326 * NOTE2: DSA/ECDSA key object is also supported since asn1x509 1.0.6.<br/> 1327 * <h4>EXAMPLE</h4> 1328 * @example 1329 * var spki = new KJUR.asn1.x509.SubjectPublicKeyInfo(RSAKey_object); 1330 * var spki = new KJUR.asn1.x509.SubjectPublicKeyInfo(KJURcryptoECDSA_object); 1331 * var spki = new KJUR.asn1.x509.SubjectPublicKeyInfo(KJURcryptoDSA_object); 1332 */ 1333 KJUR.asn1.x509.SubjectPublicKeyInfo = function(params) { 1334 KJUR.asn1.x509.SubjectPublicKeyInfo.superclass.constructor.call(this); 1335 var asn1AlgId = null; 1336 var asn1SubjPKey = null; 1337 var rsaKey = null; 1338 1339 /** 1340 * (DEPRECATED) set RSAKey object as subject public key 1341 * @name setRSAKey 1342 * @memberOf KJUR.asn1.x509.SubjectPublicKeyInfo 1343 * @function 1344 * @param {RSAKey} rsaKey {@link RSAKey} object for RSA public key 1345 * @description 1346 * @deprecated 1347 * @example 1348 * spki.setRSAKey(rsaKey); 1349 */ 1350 this.setRSAKey = function(rsaKey) { 1351 if (! RSAKey.prototype.isPrototypeOf(rsaKey)) 1352 throw "argument is not RSAKey instance"; 1353 this.rsaKey = rsaKey; 1354 var asn1RsaN = new KJUR.asn1.DERInteger({'bigint': rsaKey.n}); 1355 var asn1RsaE = new KJUR.asn1.DERInteger({'int': rsaKey.e}); 1356 var asn1RsaPub = new KJUR.asn1.DERSequence({'array': [asn1RsaN, asn1RsaE]}); 1357 var rsaKeyHex = asn1RsaPub.getEncodedHex(); 1358 this.asn1AlgId = new KJUR.asn1.x509.AlgorithmIdentifier({'name':'rsaEncryption'}); 1359 this.asn1SubjPKey = new KJUR.asn1.DERBitString({'hex':'00'+rsaKeyHex}); 1360 }; 1361 1362 /** 1363 * (DEPRECATED) set a PEM formatted RSA public key string as RSA public key 1364 * @name setRSAPEM 1365 * @memberOf KJUR.asn1.x509.SubjectPublicKeyInfo 1366 * @function 1367 * @param {String} rsaPubPEM PEM formatted RSA public key string 1368 * @deprecated 1369 * @description 1370 * @example 1371 * spki.setRSAPEM(rsaPubPEM); 1372 */ 1373 this.setRSAPEM = function(rsaPubPEM) { 1374 if (rsaPubPEM.match(/-----BEGIN PUBLIC KEY-----/)) { 1375 var s = rsaPubPEM; 1376 s = s.replace(/^-----[^-]+-----/, ''); 1377 s = s.replace(/-----[^-]+-----\s*$/, ''); 1378 var rsaB64 = s.replace(/\s+/g, ''); 1379 var rsaWA = CryptoJS.enc.Base64.parse(rsaB64); 1380 var rsaP8Hex = CryptoJS.enc.Hex.stringify(rsaWA); 1381 var a = _rsapem_getHexValueArrayOfChildrenFromHex(rsaP8Hex); 1382 var hBitStrVal = a[1]; 1383 var rsaHex = hBitStrVal.substr(2); 1384 var a3 = _rsapem_getHexValueArrayOfChildrenFromHex(rsaHex); 1385 var rsaKey = new RSAKey(); 1386 rsaKey.setPublic(a3[0], a3[1]); 1387 this.setRSAKey(rsaKey); 1388 } else { 1389 throw "key not supported"; 1390 } 1391 }; 1392 1393 /* 1394 * @since asn1x509 1.0.7 1395 */ 1396 this.getASN1Object = function() { 1397 if (this.asn1AlgId == null || this.asn1SubjPKey == null) 1398 throw "algId and/or subjPubKey not set"; 1399 var o = new KJUR.asn1.DERSequence({'array': 1400 [this.asn1AlgId, this.asn1SubjPKey]}); 1401 return o; 1402 }; 1403 1404 this.getEncodedHex = function() { 1405 var o = this.getASN1Object(); 1406 this.hTLV = o.getEncodedHex(); 1407 return this.hTLV; 1408 }; 1409 1410 this._setRSAKey = function(key) { 1411 var asn1RsaPub = KJUR.asn1.ASN1Util.newObject({ 1412 'seq': [{'int': {'bigint': key.n}}, {'int': {'int': key.e}}] 1413 }); 1414 var rsaKeyHex = asn1RsaPub.getEncodedHex(); 1415 this.asn1AlgId = new KJUR.asn1.x509.AlgorithmIdentifier({'name':'rsaEncryption'}); 1416 this.asn1SubjPKey = new KJUR.asn1.DERBitString({'hex':'00'+rsaKeyHex}); 1417 }; 1418 1419 this._setEC = function(key) { 1420 var asn1Params = new KJUR.asn1.DERObjectIdentifier({'name': key.curveName}); 1421 this.asn1AlgId = 1422 new KJUR.asn1.x509.AlgorithmIdentifier({'name': 'ecPublicKey', 1423 'asn1params': asn1Params}); 1424 this.asn1SubjPKey = new KJUR.asn1.DERBitString({'hex': '00' + key.pubKeyHex}); 1425 }; 1426 1427 this._setDSA = function(key) { 1428 var asn1Params = new KJUR.asn1.ASN1Util.newObject({ 1429 'seq': [{'int': {'bigint': key.p}}, 1430 {'int': {'bigint': key.q}}, 1431 {'int': {'bigint': key.g}}] 1432 }); 1433 this.asn1AlgId = 1434 new KJUR.asn1.x509.AlgorithmIdentifier({'name': 'dsa', 1435 'asn1params': asn1Params}); 1436 var pubInt = new KJUR.asn1.DERInteger({'bigint': key.y}); 1437 this.asn1SubjPKey = new KJUR.asn1.DERBitString({'hex': '00' + pubInt.getEncodedHex()}); 1438 }; 1439 1440 if (typeof params != "undefined") { 1441 if (typeof RSAKey != 'undefined' && params instanceof RSAKey) { 1442 this._setRSAKey(params); 1443 } else if (typeof KJUR.crypto.ECDSA != 'undefined' && 1444 params instanceof KJUR.crypto.ECDSA) { 1445 this._setEC(params); 1446 } else if (typeof KJUR.crypto.DSA != 'undefined' && 1447 params instanceof KJUR.crypto.DSA) { 1448 this._setDSA(params); 1449 } else if (typeof params['rsakey'] != "undefined") { 1450 this.setRSAKey(params['rsakey']); 1451 } else if (typeof params['rsapem'] != "undefined") { 1452 this.setRSAPEM(params['rsapem']); 1453 } 1454 } 1455 }; 1456 YAHOO.lang.extend(KJUR.asn1.x509.SubjectPublicKeyInfo, KJUR.asn1.ASN1Object); 1457 1458 /** 1459 * Time ASN.1 structure class 1460 * @name KJUR.asn1.x509.Time 1461 * @class Time ASN.1 structure class 1462 * @param {Array} params associative array of parameters (ex. {'str': '130508235959Z'}) 1463 * @extends KJUR.asn1.ASN1Object 1464 * @description 1465 * <br/> 1466 * <h4>EXAMPLES</h4> 1467 * @example 1468 * var t1 = new KJUR.asn1.x509.Time{'str': '130508235959Z'} // UTCTime by default 1469 * var t2 = new KJUR.asn1.x509.Time{'type': 'gen', 'str': '20130508235959Z'} // GeneralizedTime 1470 */ 1471 KJUR.asn1.x509.Time = function(params) { 1472 KJUR.asn1.x509.Time.superclass.constructor.call(this); 1473 var type = null; 1474 var timeParams = null; 1475 1476 this.setTimeParams = function(timeParams) { 1477 this.timeParams = timeParams; 1478 } 1479 1480 this.getEncodedHex = function() { 1481 var o = null; 1482 1483 if (this.timeParams != null) { 1484 if (this.type == "utc") { 1485 o = new KJUR.asn1.DERUTCTime(this.timeParams); 1486 } else { 1487 o = new KJUR.asn1.DERGeneralizedTime(this.timeParams); 1488 } 1489 } else { 1490 if (this.type == "utc") { 1491 o = new KJUR.asn1.DERUTCTime(); 1492 } else { 1493 o = new KJUR.asn1.DERGeneralizedTime(); 1494 } 1495 } 1496 this.TLV = o.getEncodedHex(); 1497 return this.TLV; 1498 }; 1499 1500 this.type = "utc"; 1501 if (typeof params != "undefined") { 1502 if (typeof params.type != "undefined") { 1503 this.type = params.type; 1504 } else { 1505 if (typeof params.str != "undefined") { 1506 if (params.str.match(/^[0-9]{12}Z$/)) this.type = "utc"; 1507 if (params.str.match(/^[0-9]{14}Z$/)) this.type = "gen"; 1508 } 1509 } 1510 this.timeParams = params; 1511 } 1512 }; 1513 YAHOO.lang.extend(KJUR.asn1.x509.Time, KJUR.asn1.ASN1Object); 1514 1515 /** 1516 * AlgorithmIdentifier ASN.1 structure class 1517 * @name KJUR.asn1.x509.AlgorithmIdentifier 1518 * @class AlgorithmIdentifier ASN.1 structure class 1519 * @param {Array} params associative array of parameters (ex. {'name': 'SHA1withRSA'}) 1520 * @extends KJUR.asn1.ASN1Object 1521 * @description 1522 * @example 1523 */ 1524 KJUR.asn1.x509.AlgorithmIdentifier = function(params) { 1525 KJUR.asn1.x509.AlgorithmIdentifier.superclass.constructor.call(this); 1526 var nameAlg = null; 1527 var asn1Alg = null; 1528 var asn1Params = null; 1529 var paramEmpty = false; 1530 1531 this.getEncodedHex = function() { 1532 if (this.nameAlg == null && this.asn1Alg == null) { 1533 throw "algorithm not specified"; 1534 } 1535 if (this.nameAlg != null && this.asn1Alg == null) { 1536 this.asn1Alg = KJUR.asn1.x509.OID.name2obj(this.nameAlg); 1537 } 1538 var a = [this.asn1Alg]; 1539 if (! this.paramEmpty) a.push(this.asn1Params); 1540 var o = new KJUR.asn1.DERSequence({'array': a}); 1541 this.hTLV = o.getEncodedHex(); 1542 return this.hTLV; 1543 }; 1544 1545 if (typeof params != "undefined") { 1546 if (typeof params['name'] != "undefined") { 1547 this.nameAlg = params['name']; 1548 } 1549 if (typeof params['asn1params'] != "undefined") { 1550 this.asn1Params = params['asn1params']; 1551 } 1552 if (typeof params['paramempty'] != "undefined") { 1553 this.paramEmpty = params['paramempty']; 1554 } 1555 } 1556 if (this.asn1Params == null) { 1557 this.asn1Params = new KJUR.asn1.DERNull(); 1558 } 1559 }; 1560 YAHOO.lang.extend(KJUR.asn1.x509.AlgorithmIdentifier, KJUR.asn1.ASN1Object); 1561 1562 /** 1563 * GeneralName ASN.1 structure class 1564 * @name KJUR.asn1.x509.GeneralName 1565 * @class GeneralName ASN.1 structure class 1566 * @description 1567 * <br/> 1568 * As for argument 'params' for constructor, you can specify one of 1569 * following properties: 1570 * <ul> 1571 * <li>rfc822 - rfc822Name[1] (ex. user1@foo.com)</li> 1572 * <li>dns - dNSName[2] (ex. foo.com)</li> 1573 * <li>uri - uniformResourceIdentifier[6] (ex. http://foo.com/)</li> 1574 * <li>certissuer - directoryName[4] (PEM or hex string of cert)</li> 1575 * <li>certsubj - directoryName[4] (PEM or hex string of cert)</li> 1576 * </ul> 1577 * NOTE1: certissuer and certsubj is supported since asn1x509 1.0.10. 1578 * 1579 * Here is definition of the ASN.1 syntax: 1580 * <pre> 1581 * -- NOTE: under the CHOICE, it will always be explicit. 1582 * GeneralName ::= CHOICE { 1583 * otherName [0] OtherName, 1584 * rfc822Name [1] IA5String, 1585 * dNSName [2] IA5String, 1586 * x400Address [3] ORAddress, 1587 * directoryName [4] Name, 1588 * ediPartyName [5] EDIPartyName, 1589 * uniformResourceIdentifier [6] IA5String, 1590 * iPAddress [7] OCTET STRING, 1591 * registeredID [8] OBJECT IDENTIFIER } 1592 * </pre> 1593 * 1594 * 1595 * 1596 * @example 1597 * gn = new KJUR.asn1.x509.GeneralName({rfc822: 'test@aaa.com'}); 1598 * gn = new KJUR.asn1.x509.GeneralName({dns: 'aaa.com'}); 1599 * gn = new KJUR.asn1.x509.GeneralName({uri: 'http://aaa.com/'}); 1600 * gn = new KJUR.asn1.x509.GeneralName({certissuer: certPEM}); 1601 * gn = new KJUR.asn1.x509.GeneralName({certsubj: certPEM}); 1602 */ 1603 KJUR.asn1.x509.GeneralName = function(params) { 1604 KJUR.asn1.x509.GeneralName.superclass.constructor.call(this); 1605 var asn1Obj = null; 1606 var type = null; 1607 var pTag = {rfc822: '81', dns: '82', dn: 'a4', uri: '86'}; 1608 this.explicit = false; 1609 1610 this.setByParam = function(params) { 1611 var str = null; 1612 var v = null; 1613 1614 if (typeof params == "undefined") return; 1615 1616 if (typeof params.rfc822 != "undefined") { 1617 this.type = 'rfc822'; 1618 v = new KJUR.asn1.DERIA5String({'str': params[this.type]}); 1619 } 1620 if (typeof params.dns != "undefined") { 1621 this.type = 'dns'; 1622 v = new KJUR.asn1.DERIA5String({'str': params[this.type]}); 1623 } 1624 if (typeof params.uri != "undefined") { 1625 this.type = 'uri'; 1626 v = new KJUR.asn1.DERIA5String({'str': params[this.type]}); 1627 } 1628 if (typeof params.certissuer != "undefined") { 1629 this.type = 'dn'; 1630 this.explicit = true; 1631 var certStr = params.certissuer; 1632 var certHex = null; 1633 if (certStr.match(/^[0-9A-Fa-f]+$/)) { 1634 certHex == certStr; 1635 } 1636 if (certStr.indexOf("-----BEGIN ") != -1) { 1637 certHex = X509.pemToHex(certStr); 1638 } 1639 if (certHex == null) throw "certissuer param not cert"; 1640 var x = new X509(); 1641 x.hex = certHex; 1642 var dnHex = x.getIssuerHex(); 1643 v = new KJUR.asn1.ASN1Object(); 1644 v.hTLV = dnHex; 1645 } 1646 if (typeof params.certsubj != "undefined") { 1647 this.type = 'dn'; 1648 this.explicit = true; 1649 var certStr = params.certsubj; 1650 var certHex = null; 1651 if (certStr.match(/^[0-9A-Fa-f]+$/)) { 1652 certHex == certStr; 1653 } 1654 if (certStr.indexOf("-----BEGIN ") != -1) { 1655 certHex = X509.pemToHex(certStr); 1656 } 1657 if (certHex == null) throw "certsubj param not cert"; 1658 var x = new X509(); 1659 x.hex = certHex; 1660 var dnHex = x.getSubjectHex(); 1661 v = new KJUR.asn1.ASN1Object(); 1662 v.hTLV = dnHex; 1663 } 1664 1665 if (this.type == null) 1666 throw "unsupported type in params=" + params; 1667 this.asn1Obj = new KJUR.asn1.DERTaggedObject({'explicit': this.explicit, 1668 'tag': pTag[this.type], 1669 'obj': v}); 1670 }; 1671 1672 this.getEncodedHex = function() { 1673 return this.asn1Obj.getEncodedHex(); 1674 } 1675 1676 if (typeof params != "undefined") { 1677 this.setByParam(params); 1678 } 1679 1680 }; 1681 YAHOO.lang.extend(KJUR.asn1.x509.GeneralName, KJUR.asn1.ASN1Object); 1682 1683 /** 1684 * GeneralNames ASN.1 structure class 1685 * @name KJUR.asn1.x509.GeneralNames 1686 * @class GeneralNames ASN.1 structure class 1687 * @description 1688 * <br/> 1689 * <h4>EXAMPLE AND ASN.1 SYNTAX</h4> 1690 * @example 1691 * var gns = new KJUR.asn1.x509.GeneralNames([{'uri': 'http://aaa.com/'}, {'uri': 'http://bbb.com/'}]); 1692 * 1693 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName 1694 */ 1695 KJUR.asn1.x509.GeneralNames = function(paramsArray) { 1696 KJUR.asn1.x509.GeneralNames.superclass.constructor.call(this); 1697 var asn1Array = null; 1698 1699 /** 1700 * set a array of {@link KJUR.asn1.x509.GeneralName} parameters 1701 * @name setByParamArray 1702 * @memberOf KJUR.asn1.x509.GeneralNames 1703 * @function 1704 * @param {Array} paramsArray Array of {@link KJUR.asn1.x509.GeneralNames} 1705 * @description 1706 * <br/> 1707 * <h4>EXAMPLES</h4> 1708 * @example 1709 * var gns = new KJUR.asn1.x509.GeneralNames(); 1710 * gns.setByParamArray([{'uri': 'http://aaa.com/'}, {'uri': 'http://bbb.com/'}]); 1711 */ 1712 this.setByParamArray = function(paramsArray) { 1713 for (var i = 0; i < paramsArray.length; i++) { 1714 var o = new KJUR.asn1.x509.GeneralName(paramsArray[i]); 1715 this.asn1Array.push(o); 1716 } 1717 }; 1718 1719 this.getEncodedHex = function() { 1720 var o = new KJUR.asn1.DERSequence({'array': this.asn1Array}); 1721 return o.getEncodedHex(); 1722 }; 1723 1724 this.asn1Array = new Array(); 1725 if (typeof paramsArray != "undefined") { 1726 this.setByParamArray(paramsArray); 1727 } 1728 }; 1729 YAHOO.lang.extend(KJUR.asn1.x509.GeneralNames, KJUR.asn1.ASN1Object); 1730 1731 /** 1732 * DistributionPointName ASN.1 structure class 1733 * @name KJUR.asn1.x509.DistributionPointName 1734 * @class DistributionPointName ASN.1 structure class 1735 * @description 1736 * @example 1737 */ 1738 KJUR.asn1.x509.DistributionPointName = function(gnOrRdn) { 1739 KJUR.asn1.x509.DistributionPointName.superclass.constructor.call(this); 1740 var asn1Obj = null; 1741 var type = null; 1742 var tag = null; 1743 var asn1V = null; 1744 1745 this.getEncodedHex = function() { 1746 if (this.type != "full") 1747 throw "currently type shall be 'full': " + this.type; 1748 this.asn1Obj = new KJUR.asn1.DERTaggedObject({'explicit': false, 1749 'tag': this.tag, 1750 'obj': this.asn1V}); 1751 this.hTLV = this.asn1Obj.getEncodedHex(); 1752 return this.hTLV; 1753 }; 1754 1755 if (typeof gnOrRdn != "undefined") { 1756 if (KJUR.asn1.x509.GeneralNames.prototype.isPrototypeOf(gnOrRdn)) { 1757 this.type = "full"; 1758 this.tag = "a0"; 1759 this.asn1V = gnOrRdn; 1760 } else { 1761 throw "This class supports GeneralNames only as argument"; 1762 } 1763 } 1764 }; 1765 YAHOO.lang.extend(KJUR.asn1.x509.DistributionPointName, KJUR.asn1.ASN1Object); 1766 1767 /** 1768 * DistributionPoint ASN.1 structure class 1769 * @name KJUR.asn1.x509.DistributionPoint 1770 * @class DistributionPoint ASN.1 structure class 1771 * @description 1772 * @example 1773 */ 1774 KJUR.asn1.x509.DistributionPoint = function(params) { 1775 KJUR.asn1.x509.DistributionPoint.superclass.constructor.call(this); 1776 var asn1DP = null; 1777 1778 this.getEncodedHex = function() { 1779 var seq = new KJUR.asn1.DERSequence(); 1780 if (this.asn1DP != null) { 1781 var o1 = new KJUR.asn1.DERTaggedObject({'explicit': true, 1782 'tag': 'a0', 1783 'obj': this.asn1DP}); 1784 seq.appendASN1Object(o1); 1785 } 1786 this.hTLV = seq.getEncodedHex(); 1787 return this.hTLV; 1788 }; 1789 1790 if (typeof params != "undefined") { 1791 if (typeof params['dpobj'] != "undefined") { 1792 this.asn1DP = params['dpobj']; 1793 } 1794 } 1795 }; 1796 YAHOO.lang.extend(KJUR.asn1.x509.DistributionPoint, KJUR.asn1.ASN1Object); 1797 1798 /** 1799 * static object for OID 1800 * @name KJUR.asn1.x509.OID 1801 * @class static object for OID 1802 * @property {Assoc Array} atype2oidList for short attribyte type name and oid (i.e. 'C' and '2.5.4.6') 1803 * @property {Assoc Array} name2oidList for oid name and oid (i.e. 'keyUsage' and '2.5.29.15') 1804 * @property {Assoc Array} objCache for caching name and DERObjectIdentifier object 1805 * @description 1806 * <dl> 1807 * <dt><b>atype2oidList</b> 1808 * <dd>currently supports 'C', 'O', 'OU', 'ST', 'L' and 'CN' only. 1809 * <dt><b>name2oidList</b> 1810 * <dd>currently supports 'SHA1withRSA', 'rsaEncryption' and some extension OIDs 1811 * </dl> 1812 * @example 1813 */ 1814 KJUR.asn1.x509.OID = new function(params) { 1815 this.atype2oidList = { 1816 'C': '2.5.4.6', 1817 'O': '2.5.4.10', 1818 'OU': '2.5.4.11', 1819 'ST': '2.5.4.8', 1820 'L': '2.5.4.7', 1821 'CN': '2.5.4.3', 1822 'SN': '2.5.4.4', 1823 'DN': '2.5.4.49', 1824 'DC': '0.9.2342.19200300.100.1.25', 1825 }; 1826 this.name2oidList = { 1827 'sha1': '1.3.14.3.2.26', 1828 'sha256': '2.16.840.1.101.3.4.2.1', 1829 'sha384': '2.16.840.1.101.3.4.2.2', 1830 'sha512': '2.16.840.1.101.3.4.2.3', 1831 'sha224': '2.16.840.1.101.3.4.2.4', 1832 'md5': '1.2.840.113549.2.5', 1833 'md2': '1.3.14.7.2.2.1', 1834 'ripemd160': '1.3.36.3.2.1', 1835 1836 'MD2withRSA': '1.2.840.113549.1.1.2', 1837 'MD4withRSA': '1.2.840.113549.1.1.3', 1838 'MD5withRSA': '1.2.840.113549.1.1.4', 1839 'SHA1withRSA': '1.2.840.113549.1.1.5', 1840 'SHA224withRSA': '1.2.840.113549.1.1.14', 1841 'SHA256withRSA': '1.2.840.113549.1.1.11', 1842 'SHA384withRSA': '1.2.840.113549.1.1.12', 1843 'SHA512withRSA': '1.2.840.113549.1.1.13', 1844 1845 'SHA1withECDSA': '1.2.840.10045.4.1', 1846 'SHA224withECDSA': '1.2.840.10045.4.3.1', 1847 'SHA256withECDSA': '1.2.840.10045.4.3.2', 1848 'SHA384withECDSA': '1.2.840.10045.4.3.3', 1849 'SHA512withECDSA': '1.2.840.10045.4.3.4', 1850 1851 'dsa': '1.2.840.10040.4.1', 1852 'SHA1withDSA': '1.2.840.10040.4.3', 1853 'SHA224withDSA': '2.16.840.1.101.3.4.3.1', 1854 'SHA256withDSA': '2.16.840.1.101.3.4.3.2', 1855 1856 'rsaEncryption': '1.2.840.113549.1.1.1', 1857 1858 'countryName': '2.5.4.6', 1859 'organization': '2.5.4.10', 1860 'organizationalUnit': '2.5.4.11', 1861 'stateOrProvinceName': '2.5.4.8', 1862 'locality': '2.5.4.7', 1863 'commonName': '2.5.4.3', 1864 1865 'subjectKeyIdentifier': '2.5.29.14', 1866 'keyUsage': '2.5.29.15', 1867 'subjectAltName': '2.5.29.17', 1868 'basicConstraints': '2.5.29.19', 1869 'nameConstraints': '2.5.29.30', 1870 'cRLDistributionPoints':'2.5.29.31', 1871 'certificatePolicies': '2.5.29.32', 1872 'authorityKeyIdentifier':'2.5.29.35', 1873 'policyConstraints': '2.5.29.36', 1874 'extKeyUsage': '2.5.29.37', 1875 'authorityInfoAccess': '1.3.6.1.5.5.7.1.1', 1876 1877 'anyExtendedKeyUsage': '2.5.29.37.0', 1878 'serverAuth': '1.3.6.1.5.5.7.3.1', 1879 'clientAuth': '1.3.6.1.5.5.7.3.2', 1880 'codeSigning': '1.3.6.1.5.5.7.3.3', 1881 'emailProtection': '1.3.6.1.5.5.7.3.4', 1882 'timeStamping': '1.3.6.1.5.5.7.3.8', 1883 'ocspSigning': '1.3.6.1.5.5.7.3.9', 1884 1885 'ecPublicKey': '1.2.840.10045.2.1', 1886 'secp256r1': '1.2.840.10045.3.1.7', 1887 'secp256k1': '1.3.132.0.10', 1888 'secp384r1': '1.3.132.0.34', 1889 1890 'pkcs5PBES2': '1.2.840.113549.1.5.13', 1891 'pkcs5PBKDF2': '1.2.840.113549.1.5.12', 1892 1893 'des-EDE3-CBC': '1.2.840.113549.3.7', 1894 1895 'data': '1.2.840.113549.1.7.1', // CMS data 1896 'signed-data': '1.2.840.113549.1.7.2', // CMS signed-data 1897 'enveloped-data': '1.2.840.113549.1.7.3', // CMS enveloped-data 1898 'digested-data': '1.2.840.113549.1.7.5', // CMS digested-data 1899 'encrypted-data': '1.2.840.113549.1.7.6', // CMS encrypted-data 1900 'authenticated-data': '1.2.840.113549.1.9.16.1.2', // CMS authenticated-data 1901 'tstinfo': '1.2.840.113549.1.9.16.1.4', // RFC3161 TSTInfo 1902 }; 1903 1904 this.objCache = {}; 1905 1906 /** 1907 * get DERObjectIdentifier by registered OID name 1908 * @name name2obj 1909 * @memberOf KJUR.asn1.x509.OID 1910 * @function 1911 * @param {String} name OID 1912 * @description 1913 * @example 1914 * var asn1ObjOID = OID.name2obj('SHA1withRSA'); 1915 */ 1916 this.name2obj = function(name) { 1917 if (typeof this.objCache[name] != "undefined") 1918 return this.objCache[name]; 1919 if (typeof this.name2oidList[name] == "undefined") 1920 throw "Name of ObjectIdentifier not defined: " + name; 1921 var oid = this.name2oidList[name]; 1922 var obj = new KJUR.asn1.DERObjectIdentifier({'oid': oid}); 1923 this.objCache[name] = obj; 1924 return obj; 1925 }; 1926 1927 /** 1928 * get DERObjectIdentifier by registered attribyte type name such like 'C' or 'CN' 1929 * @name atype2obj 1930 * @memberOf KJUR.asn1.x509.OID 1931 * @function 1932 * @param {String} atype short attribute type name such like 'C' or 'CN' 1933 * @description 1934 * @example 1935 * var asn1ObjOID = OID.atype2obj('CN'); 1936 */ 1937 this.atype2obj = function(atype) { 1938 if (typeof this.objCache[atype] != "undefined") 1939 return this.objCache[atype]; 1940 if (typeof this.atype2oidList[atype] == "undefined") 1941 throw "AttributeType name undefined: " + atype; 1942 var oid = this.atype2oidList[atype]; 1943 var obj = new KJUR.asn1.DERObjectIdentifier({'oid': oid}); 1944 this.objCache[atype] = obj; 1945 return obj; 1946 }; 1947 }; 1948 1949 /* 1950 * convert OID to name 1951 * @name oid2name 1952 * @memberOf KJUR.asn1.x509.OID 1953 * @function 1954 * @param {String} dot noted Object Identifer string (ex. 1.2.3.4) 1955 * @return {String} OID name 1956 * @description 1957 * This static method converts OID string to its name. 1958 * If OID is undefined then it returns empty string (i.e. ''). 1959 * @example 1960 * name = KJUR.asn1.x509.OID.oid2name("1.3.6.1.5.5.7.1.1"); 1961 * // name will be 'authorityInfoAccess'. 1962 * @since asn1x509 1.0.9 1963 */ 1964 KJUR.asn1.x509.OID.oid2name = function(oid) { 1965 var list = KJUR.asn1.x509.OID.name2oidList; 1966 for (var name in list) { 1967 if (list[name] == oid) return name; 1968 } 1969 return ''; 1970 }; 1971 1972 /* 1973 * convert name to OID 1974 * @name name2oid 1975 * @memberOf KJUR.asn1.x509.OID 1976 * @function 1977 * @param {String} OID name 1978 * @return {String} dot noted Object Identifer string (ex. 1.2.3.4) 1979 * @description 1980 * This static method converts from OID name to OID string. 1981 * If OID is undefined then it returns empty string (i.e. ''). 1982 * @example 1983 * name = KJUR.asn1.x509.OID.name2oid("authorityInfoAccess"); 1984 * // name will be '1.3.6.1.5.5.7.1.1'. 1985 * @since asn1x509 1.0.11 1986 */ 1987 KJUR.asn1.x509.OID.name2oid = function(name) { 1988 var list = KJUR.asn1.x509.OID.name2oidList; 1989 if (list[name] === undefined) return ''; 1990 return list[name]; 1991 }; 1992 1993 /** 1994 * X.509 certificate and CRL utilities class 1995 * @name KJUR.asn1.x509.X509Util 1996 * @class X.509 certificate and CRL utilities class 1997 */ 1998 KJUR.asn1.x509.X509Util = new function() { 1999 /** 2000 * get PKCS#8 PEM public key string from RSAKey object 2001 * @name getPKCS8PubKeyPEMfromRSAKey 2002 * @memberOf KJUR.asn1.x509.X509Util 2003 * @function 2004 * @param {RSAKey} rsaKey RSA public key of {@link RSAKey} object 2005 * @description 2006 * @example 2007 * var pem = KJUR.asn1.x509.X509Util.getPKCS8PubKeyPEMfromRSAKey(pubKey); 2008 */ 2009 this.getPKCS8PubKeyPEMfromRSAKey = function(rsaKey) { 2010 var pem = null; 2011 var hN = KJUR.asn1.ASN1Util.bigIntToMinTwosComplementsHex(rsaKey.n); 2012 var hE = KJUR.asn1.ASN1Util.integerToByteHex(rsaKey.e); 2013 var iN = new KJUR.asn1.DERInteger({hex: hN}); 2014 var iE = new KJUR.asn1.DERInteger({hex: hE}); 2015 var asn1PubKey = new KJUR.asn1.DERSequence({array: [iN, iE]}); 2016 var hPubKey = asn1PubKey.getEncodedHex(); 2017 var o1 = new KJUR.asn1.x509.AlgorithmIdentifier({name: 'rsaEncryption'}); 2018 var o2 = new KJUR.asn1.DERBitString({hex: '00' + hPubKey}); 2019 var seq = new KJUR.asn1.DERSequence({array: [o1, o2]}); 2020 var hP8 = seq.getEncodedHex(); 2021 var pem = KJUR.asn1.ASN1Util.getPEMStringFromHex(hP8, "PUBLIC KEY"); 2022 return pem; 2023 }; 2024 }; 2025 /** 2026 * issue a certificate in PEM format 2027 * @name newCertPEM 2028 * @memberOf KJUR.asn1.x509.X509Util 2029 * @function 2030 * @param {Array} param parameter to issue a certificate 2031 * @since asn1x509 1.0.6 2032 * @description 2033 * This method can issue a certificate by a simple 2034 * JSON object. 2035 * Signature value will be provided by signing with 2036 * private key using 'cakey' parameter or 2037 * hexa decimal signature value by 'sighex' parameter. 2038 * 2039 * NOTE: When using DSA or ECDSA CA signing key, 2040 * use 'paramempty' in 'sigalg' to ommit parameter field 2041 * of AlgorithmIdentifer. In case of RSA, parameter 2042 * NULL will be specified by default. 2043 * 2044 * @example 2045 * var certPEM = KJUR.asn1.x509.X509Util.newCertPEM( 2046 * { serial: {int: 4}, 2047 * sigalg: {name: 'SHA1withECDSA', paramempty: true}, 2048 * issuer: {str: '/C=US/O=a'}, 2049 * notbefore: {'str': '130504235959Z'}, 2050 * notafter: {'str': '140504235959Z'}, 2051 * subject: {str: '/C=US/O=b'}, 2052 * sbjpubkey: pubKeyPEM, 2053 * ext: [ 2054 * {basicConstraints: {cA: true, critical: true}}, 2055 * {keyUsage: {bin: '11'}}, 2056 * ], 2057 * cakey: [prvkey, pass]} 2058 * ); 2059 * // -- or -- 2060 * var certPEM = KJUR.asn1.x509.X509Util.newCertPEM( 2061 * { serial: {int: 1}, 2062 * sigalg: {name: 'SHA1withRSA', paramempty: true}, 2063 * issuer: {str: '/C=US/O=T1'}, 2064 * notbefore: {'str': '130504235959Z'}, 2065 * notafter: {'str': '140504235959Z'}, 2066 * subject: {str: '/C=US/O=T1'}, 2067 * sbjpubkey: pubKeyObj, 2068 * sighex: '0102030405..'} 2069 * ); 2070 * // for the issuer and subject field, another 2071 * // representation is also available 2072 * var certPEM = KJUR.asn1.x509.X509Util.newCertPEM( 2073 * { serial: {int: 1}, 2074 * sigalg: {name: 'SHA1withRSA', paramempty: true}, 2075 * issuer: {C: "US", O: "T1"}, 2076 * notbefore: {'str': '130504235959Z'}, 2077 * notafter: {'str': '140504235959Z'}, 2078 * subject: {C: "US", O: "T1", CN: "http://example.com/"}, 2079 * sbjpubkey: pubKeyObj, 2080 * sighex: '0102030405..'} 2081 * ); 2082 */ 2083 KJUR.asn1.x509.X509Util.newCertPEM = function(param) { 2084 var ns1 = KJUR.asn1.x509; 2085 var o = new ns1.TBSCertificate(); 2086 2087 if (param.serial !== undefined) 2088 o.setSerialNumberByParam(param.serial); 2089 else 2090 throw "serial number undefined."; 2091 2092 if (typeof param.sigalg.name == 'string') 2093 o.setSignatureAlgByParam(param.sigalg); 2094 else 2095 throw "unproper signature algorithm name"; 2096 2097 if (param.issuer !== undefined) 2098 o.setIssuerByParam(param.issuer); 2099 else 2100 throw "issuer name undefined."; 2101 2102 if (param.notbefore !== undefined) 2103 o.setNotBeforeByParam(param.notbefore); 2104 else 2105 throw "notbefore undefined."; 2106 2107 if (param.notafter !== undefined) 2108 o.setNotAfterByParam(param.notafter); 2109 else 2110 throw "notafter undefined."; 2111 2112 if (param.subject !== undefined) 2113 o.setSubjectByParam(param.subject); 2114 else 2115 throw "subject name undefined."; 2116 2117 if (param.sbjpubkey !== undefined) 2118 o.setSubjectPublicKeyByGetKey(param.sbjpubkey); 2119 else 2120 throw "subject public key undefined."; 2121 2122 if (param.ext !== undefined && param.ext.length !== undefined) { 2123 for (var i = 0; i < param.ext.length; i++) { 2124 for (key in param.ext[i]) { 2125 o.appendExtensionByName(key, param.ext[i][key]); 2126 } 2127 } 2128 } 2129 2130 // set signature 2131 if (param.cakey === undefined && param.sighex === undefined) 2132 throw "param cakey and sighex undefined."; 2133 2134 var caKey = null; 2135 var cert = null; 2136 2137 if (param.cakey) { 2138 caKey = KEYUTIL.getKey.apply(null, param.cakey); 2139 cert = new ns1.Certificate({'tbscertobj': o, 'prvkeyobj': caKey}); 2140 cert.sign(); 2141 } 2142 2143 if (param.sighex) { 2144 cert = new ns1.Certificate({'tbscertobj': o}); 2145 cert.setSignatureHex(param.sighex); 2146 } 2147 2148 return cert.getPEMString(); 2149 }; 2150 2151 /* 2152 org.bouncycastle.asn1.x500 2153 AttributeTypeAndValue 2154 DirectoryString 2155 RDN 2156 X500Name 2157 X500NameBuilder 2158 2159 org.bouncycastleasn1.x509 2160 TBSCertificate 2161 */ 2162