1 /*! asn1x509-1.0.8.js (c) 2013-2014 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-2014 Kenji Urushima (kenji.urushima@gmail.com) 7 * 8 * This software is licensed under the terms of the MIT License. 9 * http://kjur.github.com/jsrsasign/license 10 * 11 * The above copyright and license notice shall be 12 * included in all copies or substantial portions of the Software. 13 */ 14 15 /** 16 * @fileOverview 17 * @name asn1x509-1.0.js 18 * @author Kenji Urushima kenji.urushima@gmail.com 19 * @version 1.0.8 (2014-Apr-16) 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 */ 1138 KJUR.asn1.x509.X500Name = function(params) { 1139 KJUR.asn1.x509.X500Name.superclass.constructor.call(this); 1140 this.asn1Array = new Array(); 1141 1142 this.setByString = function(dnStr) { 1143 var a = dnStr.split('/'); 1144 a.shift(); 1145 for (var i = 0; i < a.length; i++) { 1146 this.asn1Array.push(new KJUR.asn1.x509.RDN({'str':a[i]})); 1147 } 1148 }; 1149 1150 this.getEncodedHex = function() { 1151 var o = new KJUR.asn1.DERSequence({"array": this.asn1Array}); 1152 this.TLV = o.getEncodedHex(); 1153 return this.TLV; 1154 }; 1155 1156 if (typeof params != "undefined") { 1157 if (typeof params['str'] != "undefined") { 1158 this.setByString(params['str']); 1159 } 1160 } 1161 1162 }; 1163 YAHOO.lang.extend(KJUR.asn1.x509.X500Name, KJUR.asn1.ASN1Object); 1164 1165 /** 1166 * RDN (Relative Distinguish Name) ASN.1 structure class 1167 * @name KJUR.asn1.x509.RDN 1168 * @class RDN (Relative Distinguish Name) ASN.1 structure class 1169 * @param {Array} params associative array of parameters (ex. {'str': 'C=US'}) 1170 * @extends KJUR.asn1.ASN1Object 1171 * @description 1172 * @example 1173 */ 1174 KJUR.asn1.x509.RDN = function(params) { 1175 KJUR.asn1.x509.RDN.superclass.constructor.call(this); 1176 this.asn1Array = new Array(); 1177 1178 this.addByString = function(rdnStr) { 1179 this.asn1Array.push(new KJUR.asn1.x509.AttributeTypeAndValue({'str':rdnStr})); 1180 }; 1181 1182 this.getEncodedHex = function() { 1183 var o = new KJUR.asn1.DERSet({"array": this.asn1Array}); 1184 this.TLV = o.getEncodedHex(); 1185 return this.TLV; 1186 }; 1187 1188 if (typeof params != "undefined") { 1189 if (typeof params['str'] != "undefined") { 1190 this.addByString(params['str']); 1191 } 1192 } 1193 }; 1194 YAHOO.lang.extend(KJUR.asn1.x509.RDN, KJUR.asn1.ASN1Object); 1195 1196 /** 1197 * AttributeTypeAndValue ASN.1 structure class 1198 * @name KJUR.asn1.x509.AttributeTypeAndValue 1199 * @class AttributeTypeAndValue ASN.1 structure class 1200 * @param {Array} params associative array of parameters (ex. {'str': 'C=US'}) 1201 * @extends KJUR.asn1.ASN1Object 1202 * @description 1203 * @example 1204 */ 1205 KJUR.asn1.x509.AttributeTypeAndValue = function(params) { 1206 KJUR.asn1.x509.AttributeTypeAndValue.superclass.constructor.call(this); 1207 var typeObj = null; 1208 var valueObj = null; 1209 var defaultDSType = "utf8"; 1210 1211 this.setByString = function(attrTypeAndValueStr) { 1212 if (attrTypeAndValueStr.match(/^([^=]+)=(.+)$/)) { 1213 this.setByAttrTypeAndValueStr(RegExp.$1, RegExp.$2); 1214 } else { 1215 throw "malformed attrTypeAndValueStr: " + attrTypeAndValueStr; 1216 } 1217 }; 1218 1219 this.setByAttrTypeAndValueStr = function(shortAttrType, valueStr) { 1220 this.typeObj = KJUR.asn1.x509.OID.atype2obj(shortAttrType); 1221 var dsType = defaultDSType; 1222 if (shortAttrType == "C") dsType = "prn"; 1223 this.valueObj = this.getValueObj(dsType, valueStr); 1224 }; 1225 1226 this.getValueObj = function(dsType, valueStr) { 1227 if (dsType == "utf8") return new KJUR.asn1.DERUTF8String({"str": valueStr}); 1228 if (dsType == "prn") return new KJUR.asn1.DERPrintableString({"str": valueStr}); 1229 if (dsType == "tel") return new KJUR.asn1.DERTeletexString({"str": valueStr}); 1230 if (dsType == "ia5") return new KJUR.asn1.DERIA5String({"str": valueStr}); 1231 throw "unsupported directory string type: type=" + dsType + " value=" + valueStr; 1232 }; 1233 1234 this.getEncodedHex = function() { 1235 var o = new KJUR.asn1.DERSequence({"array": [this.typeObj, this.valueObj]}); 1236 this.TLV = o.getEncodedHex(); 1237 return this.TLV; 1238 }; 1239 1240 if (typeof params != "undefined") { 1241 if (typeof params['str'] != "undefined") { 1242 this.setByString(params['str']); 1243 } 1244 } 1245 }; 1246 YAHOO.lang.extend(KJUR.asn1.x509.AttributeTypeAndValue, KJUR.asn1.ASN1Object); 1247 1248 // === END X500Name Related ================================================= 1249 1250 // === BEGIN Other ASN1 structure class ====================================== 1251 1252 /** 1253 * SubjectPublicKeyInfo ASN.1 structure class 1254 * @name KJUR.asn1.x509.SubjectPublicKeyInfo 1255 * @class SubjectPublicKeyInfo ASN.1 structure class 1256 * @param {Object} params parameter for subject public key 1257 * @extends KJUR.asn1.ASN1Object 1258 * @description 1259 * <br/> 1260 * As for argument 'params' for constructor, you can specify one of 1261 * following properties: 1262 * <ul> 1263 * <li>{@link RSAKey} object</li> 1264 * <li>{@link KJUR.crypto.ECDSA} object</li> 1265 * <li>{@link KJUR.crypto.DSA} object</li> 1266 * <li>(DEPRECATED)rsakey - specify {@link RSAKey} object of subject public key</li> 1267 * <li>(DEPRECATED)rsapem - specify a string of PEM public key of RSA key</li> 1268 * </ul> 1269 * NOTE1: 'params' can be omitted.<br/> 1270 * NOTE2: DSA/ECDSA key object is also supported since asn1x509 1.0.6.<br/> 1271 * <h4>EXAMPLE</h4> 1272 * @example 1273 * var spki = new KJUR.asn1.x509.SubjectPublicKeyInfo(RSAKey_object); 1274 * var spki = new KJUR.asn1.x509.SubjectPublicKeyInfo(KJURcryptoECDSA_object); 1275 * var spki = new KJUR.asn1.x509.SubjectPublicKeyInfo(KJURcryptoDSA_object); 1276 */ 1277 KJUR.asn1.x509.SubjectPublicKeyInfo = function(params) { 1278 KJUR.asn1.x509.SubjectPublicKeyInfo.superclass.constructor.call(this); 1279 var asn1AlgId = null; 1280 var asn1SubjPKey = null; 1281 var rsaKey = null; 1282 1283 /** 1284 * (DEPRECATED) set RSAKey object as subject public key 1285 * @name setRSAKey 1286 * @memberOf KJUR.asn1.x509.SubjectPublicKeyInfo 1287 * @function 1288 * @param {RSAKey} rsaKey {@link RSAKey} object for RSA public key 1289 * @description 1290 * @deprecated 1291 * @example 1292 * spki.setRSAKey(rsaKey); 1293 */ 1294 this.setRSAKey = function(rsaKey) { 1295 if (! RSAKey.prototype.isPrototypeOf(rsaKey)) 1296 throw "argument is not RSAKey instance"; 1297 this.rsaKey = rsaKey; 1298 var asn1RsaN = new KJUR.asn1.DERInteger({'bigint': rsaKey.n}); 1299 var asn1RsaE = new KJUR.asn1.DERInteger({'int': rsaKey.e}); 1300 var asn1RsaPub = new KJUR.asn1.DERSequence({'array': [asn1RsaN, asn1RsaE]}); 1301 var rsaKeyHex = asn1RsaPub.getEncodedHex(); 1302 this.asn1AlgId = new KJUR.asn1.x509.AlgorithmIdentifier({'name':'rsaEncryption'}); 1303 this.asn1SubjPKey = new KJUR.asn1.DERBitString({'hex':'00'+rsaKeyHex}); 1304 }; 1305 1306 /** 1307 * (DEPRECATED) set a PEM formatted RSA public key string as RSA public key 1308 * @name setRSAPEM 1309 * @memberOf KJUR.asn1.x509.SubjectPublicKeyInfo 1310 * @function 1311 * @param {String} rsaPubPEM PEM formatted RSA public key string 1312 * @deprecated 1313 * @description 1314 * @example 1315 * spki.setRSAPEM(rsaPubPEM); 1316 */ 1317 this.setRSAPEM = function(rsaPubPEM) { 1318 if (rsaPubPEM.match(/-----BEGIN PUBLIC KEY-----/)) { 1319 var s = rsaPubPEM; 1320 s = s.replace(/^-----[^-]+-----/, ''); 1321 s = s.replace(/-----[^-]+-----\s*$/, ''); 1322 var rsaB64 = s.replace(/\s+/g, ''); 1323 var rsaWA = CryptoJS.enc.Base64.parse(rsaB64); 1324 var rsaP8Hex = CryptoJS.enc.Hex.stringify(rsaWA); 1325 var a = _rsapem_getHexValueArrayOfChildrenFromHex(rsaP8Hex); 1326 var hBitStrVal = a[1]; 1327 var rsaHex = hBitStrVal.substr(2); 1328 var a3 = _rsapem_getHexValueArrayOfChildrenFromHex(rsaHex); 1329 var rsaKey = new RSAKey(); 1330 rsaKey.setPublic(a3[0], a3[1]); 1331 this.setRSAKey(rsaKey); 1332 } else { 1333 throw "key not supported"; 1334 } 1335 }; 1336 1337 /* 1338 * @since asn1x509 1.0.7 1339 */ 1340 this.getASN1Object = function() { 1341 if (this.asn1AlgId == null || this.asn1SubjPKey == null) 1342 throw "algId and/or subjPubKey not set"; 1343 var o = new KJUR.asn1.DERSequence({'array': 1344 [this.asn1AlgId, this.asn1SubjPKey]}); 1345 return o; 1346 }; 1347 1348 this.getEncodedHex = function() { 1349 var o = this.getASN1Object(); 1350 this.hTLV = o.getEncodedHex(); 1351 return this.hTLV; 1352 }; 1353 1354 this._setRSAKey = function(key) { 1355 var asn1RsaPub = KJUR.asn1.ASN1Util.newObject({ 1356 'seq': [{'int': {'bigint': key.n}}, {'int': {'int': key.e}}] 1357 }); 1358 var rsaKeyHex = asn1RsaPub.getEncodedHex(); 1359 this.asn1AlgId = new KJUR.asn1.x509.AlgorithmIdentifier({'name':'rsaEncryption'}); 1360 this.asn1SubjPKey = new KJUR.asn1.DERBitString({'hex':'00'+rsaKeyHex}); 1361 }; 1362 1363 this._setEC = function(key) { 1364 var asn1Params = new KJUR.asn1.DERObjectIdentifier({'name': key.curveName}); 1365 this.asn1AlgId = 1366 new KJUR.asn1.x509.AlgorithmIdentifier({'name': 'ecPublicKey', 1367 'asn1params': asn1Params}); 1368 this.asn1SubjPKey = new KJUR.asn1.DERBitString({'hex': '00' + key.pubKeyHex}); 1369 }; 1370 1371 this._setDSA = function(key) { 1372 var asn1Params = new KJUR.asn1.ASN1Util.newObject({ 1373 'seq': [{'int': {'bigint': key.p}}, 1374 {'int': {'bigint': key.q}}, 1375 {'int': {'bigint': key.g}}] 1376 }); 1377 this.asn1AlgId = 1378 new KJUR.asn1.x509.AlgorithmIdentifier({'name': 'dsa', 1379 'asn1params': asn1Params}); 1380 var pubInt = new KJUR.asn1.DERInteger({'bigint': key.y}); 1381 this.asn1SubjPKey = new KJUR.asn1.DERBitString({'hex': '00' + pubInt.getEncodedHex()}); 1382 }; 1383 1384 if (typeof params != "undefined") { 1385 if (typeof RSAKey != 'undefined' && params instanceof RSAKey) { 1386 this._setRSAKey(params); 1387 } else if (typeof KJUR.crypto.ECDSA != 'undefined' && 1388 params instanceof KJUR.crypto.ECDSA) { 1389 this._setEC(params); 1390 } else if (typeof KJUR.crypto.DSA != 'undefined' && 1391 params instanceof KJUR.crypto.DSA) { 1392 this._setDSA(params); 1393 } else if (typeof params['rsakey'] != "undefined") { 1394 this.setRSAKey(params['rsakey']); 1395 } else if (typeof params['rsapem'] != "undefined") { 1396 this.setRSAPEM(params['rsapem']); 1397 } 1398 } 1399 }; 1400 YAHOO.lang.extend(KJUR.asn1.x509.SubjectPublicKeyInfo, KJUR.asn1.ASN1Object); 1401 1402 /** 1403 * Time ASN.1 structure class 1404 * @name KJUR.asn1.x509.Time 1405 * @class Time ASN.1 structure class 1406 * @param {Array} params associative array of parameters (ex. {'str': '130508235959Z'}) 1407 * @extends KJUR.asn1.ASN1Object 1408 * @description 1409 * <br/> 1410 * <h4>EXAMPLES</h4> 1411 * @example 1412 * var t1 = new KJUR.asn1.x509.Time{'str': '130508235959Z'} // UTCTime by default 1413 * var t2 = new KJUR.asn1.x509.Time{'type': 'gen', 'str': '20130508235959Z'} // GeneralizedTime 1414 */ 1415 KJUR.asn1.x509.Time = function(params) { 1416 KJUR.asn1.x509.Time.superclass.constructor.call(this); 1417 var type = null; 1418 var timeParams = null; 1419 1420 this.setTimeParams = function(timeParams) { 1421 this.timeParams = timeParams; 1422 } 1423 1424 this.getEncodedHex = function() { 1425 if (this.timeParams == null) { 1426 throw "timeParams shall be specified. ({'str':'130403235959Z'}}"; 1427 } 1428 var o = null; 1429 if (this.type == "utc") { 1430 o = new KJUR.asn1.DERUTCTime(this.timeParams); 1431 } else { 1432 o = new KJUR.asn1.DERGeneralizedTime(this.timeParams); 1433 } 1434 this.TLV = o.getEncodedHex(); 1435 return this.TLV; 1436 }; 1437 1438 this.type = "utc"; 1439 if (typeof params != "undefined") { 1440 if (typeof params['type'] != "undefined") { 1441 this.type = params['type']; 1442 } 1443 this.timeParams = params; 1444 } 1445 }; 1446 YAHOO.lang.extend(KJUR.asn1.x509.Time, KJUR.asn1.ASN1Object); 1447 1448 /** 1449 * AlgorithmIdentifier ASN.1 structure class 1450 * @name KJUR.asn1.x509.AlgorithmIdentifier 1451 * @class AlgorithmIdentifier ASN.1 structure class 1452 * @param {Array} params associative array of parameters (ex. {'name': 'SHA1withRSA'}) 1453 * @extends KJUR.asn1.ASN1Object 1454 * @description 1455 * @example 1456 */ 1457 KJUR.asn1.x509.AlgorithmIdentifier = function(params) { 1458 KJUR.asn1.x509.AlgorithmIdentifier.superclass.constructor.call(this); 1459 var nameAlg = null; 1460 var asn1Alg = null; 1461 var asn1Params = null; 1462 var paramEmpty = false; 1463 1464 this.getEncodedHex = function() { 1465 if (this.nameAlg == null && this.asn1Alg == null) { 1466 throw "algorithm not specified"; 1467 } 1468 if (this.nameAlg != null && this.asn1Alg == null) { 1469 this.asn1Alg = KJUR.asn1.x509.OID.name2obj(this.nameAlg); 1470 } 1471 var a = [this.asn1Alg]; 1472 if (! this.paramEmpty) a.push(this.asn1Params); 1473 var o = new KJUR.asn1.DERSequence({'array': a}); 1474 this.hTLV = o.getEncodedHex(); 1475 return this.hTLV; 1476 }; 1477 1478 if (typeof params != "undefined") { 1479 if (typeof params['name'] != "undefined") { 1480 this.nameAlg = params['name']; 1481 } 1482 if (typeof params['asn1params'] != "undefined") { 1483 this.asn1Params = params['asn1params']; 1484 } 1485 if (typeof params['paramempty'] != "undefined") { 1486 this.paramEmpty = params['paramempty']; 1487 } 1488 } 1489 if (this.asn1Params == null) { 1490 this.asn1Params = new KJUR.asn1.DERNull(); 1491 } 1492 }; 1493 YAHOO.lang.extend(KJUR.asn1.x509.AlgorithmIdentifier, KJUR.asn1.ASN1Object); 1494 1495 /** 1496 * GeneralName ASN.1 structure class 1497 * @name KJUR.asn1.x509.GeneralName 1498 * @class GeneralName ASN.1 structure class 1499 * @description 1500 * <br/> 1501 * As for argument 'params' for constructor, you can specify one of 1502 * following properties: 1503 * <ul> 1504 * <li>rfc822 - rfc822Name[1] (ex. user1@foo.com)</li> 1505 * <li>dns - dNSName[2] (ex. foo.com)</li> 1506 * <li>uri - uniformResourceIdentifier[6] (ex. http://foo.com/)</li> 1507 * </ul> 1508 * NOTE: Currently this only supports 'uniformResourceIdentifier'. 1509 * <h4>EXAMPLE AND ASN.1 SYNTAX</h4> 1510 * @example 1511 * var gn = new KJUR.asn1.x509.GeneralName({'uri': 'http://aaa.com/'}); 1512 * 1513 * GeneralName ::= CHOICE { 1514 * otherName [0] OtherName, 1515 * rfc822Name [1] IA5String, 1516 * dNSName [2] IA5String, 1517 * x400Address [3] ORAddress, 1518 * directoryName [4] Name, 1519 * ediPartyName [5] EDIPartyName, 1520 * uniformResourceIdentifier [6] IA5String, 1521 * iPAddress [7] OCTET STRING, 1522 * registeredID [8] OBJECT IDENTIFIER } 1523 */ 1524 KJUR.asn1.x509.GeneralName = function(params) { 1525 KJUR.asn1.x509.GeneralName.superclass.constructor.call(this); 1526 var asn1Obj = null; 1527 var type = null; 1528 var pTag = {'rfc822': '81', 'dns': '82', 'uri': '86'}; 1529 1530 this.setByParam = function(params) { 1531 var str = null; 1532 var v = null; 1533 1534 if (typeof params['rfc822'] != "undefined") { 1535 this.type = 'rfc822'; 1536 v = new KJUR.asn1.DERIA5String({'str': params[this.type]}); 1537 } 1538 if (typeof params['dns'] != "undefined") { 1539 this.type = 'dns'; 1540 v = new KJUR.asn1.DERIA5String({'str': params[this.type]}); 1541 } 1542 if (typeof params['uri'] != "undefined") { 1543 this.type = 'uri'; 1544 v = new KJUR.asn1.DERIA5String({'str': params[this.type]}); 1545 } 1546 1547 if (this.type == null) 1548 throw "unsupported type in params=" + params; 1549 this.asn1Obj = new KJUR.asn1.DERTaggedObject({'explicit': false, 1550 'tag': pTag[this.type], 1551 'obj': v}); 1552 }; 1553 1554 this.getEncodedHex = function() { 1555 return this.asn1Obj.getEncodedHex(); 1556 } 1557 1558 if (typeof params != "undefined") { 1559 this.setByParam(params); 1560 } 1561 1562 }; 1563 YAHOO.lang.extend(KJUR.asn1.x509.GeneralName, KJUR.asn1.ASN1Object); 1564 1565 /** 1566 * GeneralNames ASN.1 structure class 1567 * @name KJUR.asn1.x509.GeneralNames 1568 * @class GeneralNames ASN.1 structure class 1569 * @description 1570 * <br/> 1571 * <h4>EXAMPLE AND ASN.1 SYNTAX</h4> 1572 * @example 1573 * var gns = new KJUR.asn1.x509.GeneralNames([{'uri': 'http://aaa.com/'}, {'uri': 'http://bbb.com/'}]); 1574 * 1575 * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName 1576 */ 1577 KJUR.asn1.x509.GeneralNames = function(paramsArray) { 1578 KJUR.asn1.x509.GeneralNames.superclass.constructor.call(this); 1579 var asn1Array = null; 1580 1581 /** 1582 * set a array of {@link KJUR.asn1.x509.GeneralName} parameters 1583 * @name setByParamArray 1584 * @memberOf KJUR.asn1.x509.GeneralNames 1585 * @function 1586 * @param {Array} paramsArray Array of {@link KJUR.asn1.x509.GeneralNames} 1587 * @description 1588 * <br/> 1589 * <h4>EXAMPLES</h4> 1590 * @example 1591 * var gns = new KJUR.asn1.x509.GeneralNames(); 1592 * gns.setByParamArray([{'uri': 'http://aaa.com/'}, {'uri': 'http://bbb.com/'}]); 1593 */ 1594 this.setByParamArray = function(paramsArray) { 1595 for (var i = 0; i < paramsArray.length; i++) { 1596 var o = new KJUR.asn1.x509.GeneralName(paramsArray[i]); 1597 this.asn1Array.push(o); 1598 } 1599 }; 1600 1601 this.getEncodedHex = function() { 1602 var o = new KJUR.asn1.DERSequence({'array': this.asn1Array}); 1603 return o.getEncodedHex(); 1604 }; 1605 1606 this.asn1Array = new Array(); 1607 if (typeof paramsArray != "undefined") { 1608 this.setByParamArray(paramsArray); 1609 } 1610 }; 1611 YAHOO.lang.extend(KJUR.asn1.x509.GeneralNames, KJUR.asn1.ASN1Object); 1612 1613 /** 1614 * DistributionPointName ASN.1 structure class 1615 * @name KJUR.asn1.x509.DistributionPointName 1616 * @class DistributionPointName ASN.1 structure class 1617 * @description 1618 * @example 1619 */ 1620 KJUR.asn1.x509.DistributionPointName = function(gnOrRdn) { 1621 KJUR.asn1.x509.DistributionPointName.superclass.constructor.call(this); 1622 var asn1Obj = null; 1623 var type = null; 1624 var tag = null; 1625 var asn1V = null; 1626 1627 this.getEncodedHex = function() { 1628 if (this.type != "full") 1629 throw "currently type shall be 'full': " + this.type; 1630 this.asn1Obj = new KJUR.asn1.DERTaggedObject({'explicit': false, 1631 'tag': this.tag, 1632 'obj': this.asn1V}); 1633 this.hTLV = this.asn1Obj.getEncodedHex(); 1634 return this.hTLV; 1635 }; 1636 1637 if (typeof gnOrRdn != "undefined") { 1638 if (KJUR.asn1.x509.GeneralNames.prototype.isPrototypeOf(gnOrRdn)) { 1639 this.type = "full"; 1640 this.tag = "a0"; 1641 this.asn1V = gnOrRdn; 1642 } else { 1643 throw "This class supports GeneralNames only as argument"; 1644 } 1645 } 1646 }; 1647 YAHOO.lang.extend(KJUR.asn1.x509.DistributionPointName, KJUR.asn1.ASN1Object); 1648 1649 /** 1650 * DistributionPoint ASN.1 structure class 1651 * @name KJUR.asn1.x509.DistributionPoint 1652 * @class DistributionPoint ASN.1 structure class 1653 * @description 1654 * @example 1655 */ 1656 KJUR.asn1.x509.DistributionPoint = function(params) { 1657 KJUR.asn1.x509.DistributionPoint.superclass.constructor.call(this); 1658 var asn1DP = null; 1659 1660 this.getEncodedHex = function() { 1661 var seq = new KJUR.asn1.DERSequence(); 1662 if (this.asn1DP != null) { 1663 var o1 = new KJUR.asn1.DERTaggedObject({'explicit': true, 1664 'tag': 'a0', 1665 'obj': this.asn1DP}); 1666 seq.appendASN1Object(o1); 1667 } 1668 this.hTLV = seq.getEncodedHex(); 1669 return this.hTLV; 1670 }; 1671 1672 if (typeof params != "undefined") { 1673 if (typeof params['dpobj'] != "undefined") { 1674 this.asn1DP = params['dpobj']; 1675 } 1676 } 1677 }; 1678 YAHOO.lang.extend(KJUR.asn1.x509.DistributionPoint, KJUR.asn1.ASN1Object); 1679 1680 /** 1681 * static object for OID 1682 * @name KJUR.asn1.x509.OID 1683 * @class static object for OID 1684 * @property {Assoc Array} atype2oidList for short attribyte type name and oid (i.e. 'C' and '2.5.4.6') 1685 * @property {Assoc Array} name2oidList for oid name and oid (i.e. 'keyUsage' and '2.5.29.15') 1686 * @property {Assoc Array} objCache for caching name and DERObjectIdentifier object 1687 * @description 1688 * <dl> 1689 * <dt><b>atype2oidList</b> 1690 * <dd>currently supports 'C', 'O', 'OU', 'ST', 'L' and 'CN' only. 1691 * <dt><b>name2oidList</b> 1692 * <dd>currently supports 'SHA1withRSA', 'rsaEncryption' and some extension OIDs 1693 * </dl> 1694 * @example 1695 */ 1696 KJUR.asn1.x509.OID = new function(params) { 1697 this.atype2oidList = { 1698 'C': '2.5.4.6', 1699 'O': '2.5.4.10', 1700 'OU': '2.5.4.11', 1701 'ST': '2.5.4.8', 1702 'L': '2.5.4.7', 1703 'CN': '2.5.4.3', 1704 }; 1705 this.name2oidList = { 1706 'sha384': '2.16.840.1.101.3.4.2.2', 1707 'sha224': '2.16.840.1.101.3.4.2.4', 1708 1709 'MD2withRSA': '1.2.840.113549.1.1.2', 1710 'MD4withRSA': '1.2.840.113549.1.1.3', 1711 'MD5withRSA': '1.2.840.113549.1.1.4', 1712 'SHA1withRSA': '1.2.840.113549.1.1.5', 1713 'SHA224withRSA': '1.2.840.113549.1.1.14', 1714 'SHA256withRSA': '1.2.840.113549.1.1.11', 1715 'SHA384withRSA': '1.2.840.113549.1.1.12', 1716 'SHA512withRSA': '1.2.840.113549.1.1.13', 1717 1718 'SHA1withECDSA': '1.2.840.10045.4.1', 1719 'SHA224withECDSA': '1.2.840.10045.4.3.1', 1720 'SHA256withECDSA': '1.2.840.10045.4.3.2', 1721 'SHA384withECDSA': '1.2.840.10045.4.3.3', 1722 'SHA512withECDSA': '1.2.840.10045.4.3.4', 1723 1724 'dsa': '1.2.840.10040.4.1', 1725 'SHA1withDSA': '1.2.840.10040.4.3', 1726 'SHA224withDSA': '2.16.840.1.101.3.4.3.1', 1727 'SHA256withDSA': '2.16.840.1.101.3.4.3.2', 1728 1729 'rsaEncryption': '1.2.840.113549.1.1.1', 1730 'subjectKeyIdentifier': '2.5.29.14', 1731 1732 'countryName': '2.5.4.6', 1733 'organization': '2.5.4.10', 1734 'organizationalUnit': '2.5.4.11', 1735 'stateOrProvinceName': '2.5.4.8', 1736 'locality': '2.5.4.7', 1737 'commonName': '2.5.4.3', 1738 1739 'keyUsage': '2.5.29.15', 1740 'basicConstraints': '2.5.29.19', 1741 'cRLDistributionPoints': '2.5.29.31', 1742 'certificatePolicies': '2.5.29.32', 1743 'authorityKeyIdentifier': '2.5.29.35', 1744 'extKeyUsage': '2.5.29.37', 1745 1746 'anyExtendedKeyUsage': '2.5.29.37.0', 1747 'serverAuth': '1.3.6.1.5.5.7.3.1', 1748 'clientAuth': '1.3.6.1.5.5.7.3.2', 1749 'codeSigning': '1.3.6.1.5.5.7.3.3', 1750 'emailProtection': '1.3.6.1.5.5.7.3.4', 1751 'timeStamping': '1.3.6.1.5.5.7.3.8', 1752 'ocspSigning': '1.3.6.1.5.5.7.3.9', 1753 1754 'ecPublicKey': '1.2.840.10045.2.1', 1755 'secp256r1': '1.2.840.10045.3.1.7', 1756 'secp256k1': '1.3.132.0.10', 1757 'secp384r1': '1.3.132.0.34', 1758 1759 'pkcs5PBES2': '1.2.840.113549.1.5.13', 1760 'pkcs5PBKDF2': '1.2.840.113549.1.5.12', 1761 1762 'des-EDE3-CBC': '1.2.840.113549.3.7', 1763 }; 1764 1765 this.objCache = {}; 1766 1767 /** 1768 * get DERObjectIdentifier by registered OID name 1769 * @name name2obj 1770 * @memberOf KJUR.asn1.x509.OID 1771 * @function 1772 * @param {String} name OID 1773 * @description 1774 * @example 1775 * var asn1ObjOID = OID.name2obj('SHA1withRSA'); 1776 */ 1777 this.name2obj = function(name) { 1778 if (typeof this.objCache[name] != "undefined") 1779 return this.objCache[name]; 1780 if (typeof this.name2oidList[name] == "undefined") 1781 throw "Name of ObjectIdentifier not defined: " + name; 1782 var oid = this.name2oidList[name]; 1783 var obj = new KJUR.asn1.DERObjectIdentifier({'oid': oid}); 1784 this.objCache[name] = obj; 1785 return obj; 1786 }; 1787 1788 /** 1789 * get DERObjectIdentifier by registered attribyte type name such like 'C' or 'CN' 1790 * @name atype2obj 1791 * @memberOf KJUR.asn1.x509.OID 1792 * @function 1793 * @param {String} atype short attribute type name such like 'C' or 'CN' 1794 * @description 1795 * @example 1796 * var asn1ObjOID = OID.atype2obj('CN'); 1797 */ 1798 this.atype2obj = function(atype) { 1799 if (typeof this.objCache[atype] != "undefined") 1800 return this.objCache[atype]; 1801 if (typeof this.atype2oidList[atype] == "undefined") 1802 throw "AttributeType name undefined: " + atype; 1803 var oid = this.atype2oidList[atype]; 1804 var obj = new KJUR.asn1.DERObjectIdentifier({'oid': oid}); 1805 this.objCache[atype] = obj; 1806 return obj; 1807 }; 1808 }; 1809 1810 /** 1811 * X.509 certificate and CRL utilities class 1812 * @name KJUR.asn1.x509.X509Util 1813 * @class X.509 certificate and CRL utilities class 1814 */ 1815 KJUR.asn1.x509.X509Util = new function() { 1816 /** 1817 * get PKCS#8 PEM public key string from RSAKey object 1818 * @name getPKCS8PubKeyPEMfromRSAKey 1819 * @memberOf KJUR.asn1.x509.X509Util 1820 * @function 1821 * @param {RSAKey} rsaKey RSA public key of {@link RSAKey} object 1822 * @description 1823 * @example 1824 * var pem = KJUR.asn1.x509.X509Util.getPKCS8PubKeyPEMfromRSAKey(pubKey); 1825 */ 1826 this.getPKCS8PubKeyPEMfromRSAKey = function(rsaKey) { 1827 var pem = null; 1828 var hN = KJUR.asn1.ASN1Util.bigIntToMinTwosComplementsHex(rsaKey.n); 1829 var hE = KJUR.asn1.ASN1Util.integerToByteHex(rsaKey.e); 1830 var iN = new KJUR.asn1.DERInteger({hex: hN}); 1831 var iE = new KJUR.asn1.DERInteger({hex: hE}); 1832 var asn1PubKey = new KJUR.asn1.DERSequence({array: [iN, iE]}); 1833 var hPubKey = asn1PubKey.getEncodedHex(); 1834 var o1 = new KJUR.asn1.x509.AlgorithmIdentifier({name: 'rsaEncryption'}); 1835 var o2 = new KJUR.asn1.DERBitString({hex: '00' + hPubKey}); 1836 var seq = new KJUR.asn1.DERSequence({array: [o1, o2]}); 1837 var hP8 = seq.getEncodedHex(); 1838 var pem = KJUR.asn1.ASN1Util.getPEMStringFromHex(hP8, "PUBLIC KEY"); 1839 return pem; 1840 }; 1841 }; 1842 /** 1843 * issue a certificate in PEM format 1844 * @name newCertPEM 1845 * @memberOf KJUR.asn1.x509.X509Util 1846 * @function 1847 * @param {Array} param parameter to issue a certificate 1848 * @since asn1x509 1.0.6 1849 * @description 1850 * This method can issue a certificate by a simple 1851 * JSON object. 1852 * Signature value will be provided by signing with 1853 * private key using 'cakey' parameter or 1854 * hexa decimal signature value by 'sighex' parameter. 1855 * 1856 * NOTE: When using DSA or ECDSA CA signing key, 1857 * use 'paramempty' in 'sigalg' to ommit parameter field 1858 * of AlgorithmIdentifer. In case of RSA, parameter 1859 * NULL will be specified by default. 1860 * 1861 * @example 1862 * var certPEM = KJUR.asn1.x509.X509Util.newCertPEM( 1863 * { serial: {int: 4}, 1864 * sigalg: {name: 'SHA1withECDSA', paramempty: true}, 1865 * issuer: {str: '/C=US/O=a'}, 1866 * notbefore: {'str': '130504235959Z'}, 1867 * notafter: {'str': '140504235959Z'}, 1868 * subject: {str: '/C=US/O=b'}, 1869 * sbjpubkey: pubKeyPEM, 1870 * ext: [ 1871 * {basicConstraints: {cA: true, critical: true}}, 1872 * {keyUsage: {bin: '11'}}, 1873 * ], 1874 * cakey: [prvkey, pass]} 1875 * ); 1876 * // -- or -- 1877 * var certPEM = KJUR.asn1.x509.X509Util.newCertPEM( 1878 * { serial: {int: 1}, 1879 * sigalg: {name: 'SHA1withRSA', paramempty: true}, 1880 * issuer: {str: '/C=US/O=T1'}, 1881 * notbefore: {'str': '130504235959Z'}, 1882 * notafter: {'str': '140504235959Z'}, 1883 * subject: {str: '/C=US/O=T1'}, 1884 * sbjpubkey: pubKeyObj, 1885 * sighex: '0102030405..'} 1886 * ); 1887 */ 1888 KJUR.asn1.x509.X509Util.newCertPEM = function(param) { 1889 var ns1 = KJUR.asn1.x509; 1890 var o = new ns1.TBSCertificate(); 1891 1892 if (param.serial !== undefined) 1893 o.setSerialNumberByParam(param.serial); 1894 else 1895 throw "serial number undefined."; 1896 1897 if (typeof param.sigalg.name == 'string') 1898 o.setSignatureAlgByParam(param.sigalg); 1899 else 1900 throw "unproper signature algorithm name"; 1901 1902 if (param.issuer !== undefined) 1903 o.setIssuerByParam(param.issuer); 1904 else 1905 throw "issuer name undefined."; 1906 1907 if (param.notbefore !== undefined) 1908 o.setNotBeforeByParam(param.notbefore); 1909 else 1910 throw "notbefore undefined."; 1911 1912 if (param.notafter !== undefined) 1913 o.setNotAfterByParam(param.notafter); 1914 else 1915 throw "notafter undefined."; 1916 1917 if (param.subject !== undefined) 1918 o.setSubjectByParam(param.subject); 1919 else 1920 throw "subject name undefined."; 1921 1922 if (param.sbjpubkey !== undefined) 1923 o.setSubjectPublicKeyByGetKey(param.sbjpubkey); 1924 else 1925 throw "subject public key undefined."; 1926 1927 if (param.ext !== undefined && param.ext.length !== undefined) { 1928 for (var i = 0; i < param.ext.length; i++) { 1929 for (key in param.ext[i]) { 1930 o.appendExtensionByName(key, param.ext[i][key]); 1931 } 1932 } 1933 } 1934 1935 // set signature 1936 if (param.cakey === undefined && param.sighex === undefined) 1937 throw "param cakey and sighex undefined."; 1938 1939 var caKey = null; 1940 var cert = null; 1941 1942 if (param.cakey) { 1943 caKey = KEYUTIL.getKey.apply(null, param.cakey); 1944 cert = new ns1.Certificate({'tbscertobj': o, 'prvkeyobj': caKey}); 1945 cert.sign(); 1946 } 1947 1948 if (param.sighex) { 1949 cert = new ns1.Certificate({'tbscertobj': o}); 1950 cert.setSignatureHex(param.sighex); 1951 } 1952 1953 return cert.getPEMString(); 1954 }; 1955 1956 /* 1957 org.bouncycastle.asn1.x500 1958 AttributeTypeAndValue 1959 DirectoryString 1960 RDN 1961 X500Name 1962 X500NameBuilder 1963 1964 org.bouncycastleasn1.x509 1965 TBSCertificate 1966 */ 1967