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