1 /* asn1csr-2.0.7.js (c) 2015-2022 Kenji Urushima | kjur.github.io/jsrsasign/license 2 */ 3 /* 4 * asn1csr.js - ASN.1 DER encoder classes for PKCS#10 CSR 5 * 6 * Copyright (c) 2015-2022 Kenji Urushima (kenji.urushima@gmail.com) 7 * 8 * This software is licensed under the terms of the MIT License. 9 * https://kjur.github.io/jsrsasign/license 10 * 11 * The above copyright and license notice shall be 12 * included in all copies or substantial portions of the Software. 13 */ 14 15 /** 16 * @fileOverview 17 * @name asn1csr-1.0.js 18 * @author Kenji Urushima kenji.urushima@gmail.com 19 * @version jsrsasign 10.5.27 asn1csr 2.0.7 (2022-Aug-19) 20 * @since jsrsasign 4.9.0 21 * @license <a href="https://kjur.github.io/jsrsasign/license/">MIT License</a> 22 */ 23 24 /** 25 * kjur's ASN.1 class for CSR/PKCS#10 name space 26 * <p> 27 * This name space is a sub name space for {@link KJUR.asn1}. 28 * This name space contains classes for 29 * <a href="https://tools.ietf.org/html/rfc2986">RFC 2986</a> 30 * certificate signing request(CSR/PKCS#10) and its utilities 31 * to be issued your certificate from certification authorities. 32 * <h4>PROVIDING ASN.1 STRUCTURES</h4> 33 * <ul> 34 * <li>{@link KJUR.asn1.csr.CertificationRequest}</li> 35 * <li>{@link KJUR.asn1.csr.CertificationRequestInfo}</li> 36 * </ul> 37 * <h4>PROVIDING UTILITY CLASSES</h4> 38 * <ul> 39 * <li>{@link KJUR.asn1.csr.CSRUtil}</li> 40 * </ul> 41 * </p> 42 * @name KJUR.asn1.csr 43 * @namespace 44 */ 45 if (typeof KJUR.asn1.csr == "undefined" || !KJUR.asn1.csr) KJUR.asn1.csr = {}; 46 47 /** 48 * ASN.1 CertificationRequest structure class 49 * @name KJUR.asn1.csr.CertificationRequest 50 * @class ASN.1 CertificationRequest structure class 51 * @param {Array} params associative array of parameters 52 * @extends KJUR.asn1.ASN1Object 53 * @since jsrsasign 4.9.0 asn1csr 1.0.0 54 * @see KJUR.asn1.csr.CertificationRequestInfo 55 * @description 56 * This class provides CertificateRequestInfo ASN.1 structure 57 * defined in 58 * <a href="https://tools.ietf.org/html/rfc2986#page-5"> 59 * RFC 2986 4.2</a>. 60 * <pre> 61 * CertificationRequest ::= SEQUENCE { 62 * certificationRequestInfo CertificationRequestInfo, 63 * signatureAlgorithm AlgorithmIdentifier{{ SignatureAlgorithms }}, 64 * signature BIT STRING } 65 * CertificationRequestInfo ::= SEQUENCE { 66 * version INTEGER { v1(0) } (v1,...), 67 * subject Name, 68 * subjectPKInfo SubjectPublicKeyInfo{{ PKInfoAlgorithms }}, 69 * attributes [0] Attributes{{ CRIAttributes }} } 70 * </pre> 71 * 72 * Argument "params" JSON object can have following keys: 73 * <ul> 74 * <li>{Array}subject - parameter to be passed to {@link KJUR.asn1.x509.X500Name}</li> 75 * <li>{Object}sbjpubkey - PEM string or key object to be passed to {@link KEYUTIL.getKey}</li> 76 * <li>{Array}extreq - array of certificate extension parameters</li> 77 * <li>{String}sigalg - signature algorithm name (ex. SHA256withRSA)</li> 78 * <li>{Object}sbjprvkey - PEM string or key object to be passed to {@link KEYUTIL.getKey} 79 * (OPTION)</li> 80 * <li>{String}sighex - hexadecimal string of signature value. 81 * When this is not defined and 82 * sbjprvkey is specified, sighex will be set automatically 83 * during getEncodedHex() is called. (OPTION)</li> 84 * </ul> 85 * 86 * <br/> 87 * CAUTION: 88 * Argument "params" JSON value format have been changed without 89 * backward compatibility since jsrsasign 9.0.0 asn1csr 2.0.0. 90 * 91 * @example 92 * // sign by private key 93 * csr = new KJUR.asn1.csr.CertificationRequest({ 94 * subject: {str:"/C=US/O=Test"}, 95 * sbjpubkey: "-----BEGIN PUBLIC KEY...", 96 * extreq: [{extname:"subjectAltName",array:[{dns:"example.com"}]}] 97 * sigalg: "SHA256withRSA", 98 * sbjprvkey: "-----BEGIN PRIVATE KEY..." 99 * }); 100 * pem = csr.getPEM(); // signed with sbjprvkey automatically 101 * 102 * // or specifying signature value 103 * csr = new KJUR.asn1.csr.CertificationRequest({ 104 * subject: {str:"/C=US/O=Test"}, 105 * sbjpubkey: "-----BEGIN PUBLIC KEY...", 106 * extreq: [{extname:"subjectAltName",array:[{dns:"example.com"}]}] 107 * sigalg: "SHA256withRSA", 108 * sighex: "1234abcd..." 109 * }); 110 * pem = csr.getPEM(); 111 */ 112 KJUR.asn1.csr.CertificationRequest = function(params) { 113 var _KJUR = KJUR, 114 _KJUR_asn1 = _KJUR.asn1, 115 _DERBitString = _KJUR_asn1.DERBitString, 116 _DERSequence = _KJUR_asn1.DERSequence, 117 _KJUR_asn1_csr = _KJUR_asn1.csr, 118 _KJUR_asn1_x509 = _KJUR_asn1.x509, 119 _CertificationRequestInfo = _KJUR_asn1_csr.CertificationRequestInfo; 120 121 _KJUR_asn1_csr.CertificationRequest.superclass.constructor.call(this); 122 123 /** 124 * set parameter<br/> 125 * @name setByParam 126 * @memberOf KJUR.asn1.csr.CertificationRequest# 127 * @function 128 * @param params {Array} JSON object of CSR parameters 129 * @since jsrsasign 9.0.0 asn1csr 2.0.0 130 * @description 131 * This method will set parameter to this object. 132 * @example 133 * csr = new KJUR.asn1.x509.CertificationRequest(); 134 * csr.setByParam({ 135 * subject: {str: "/C=JP/O=Test"}, 136 * ... 137 * }); 138 */ 139 this.setByParam = function(params) { 140 this.params = params; 141 }; 142 143 /** 144 * sign CertificationRequest and set signature value internally<br/> 145 * @name sign 146 * @memberOf KJUR.asn1.csr.CertificationRequest# 147 * @function 148 * @description 149 * This method self-signs CertificateRequestInfo with a subject's 150 * private key and set signature value internally. 151 * <br/> 152 * @example 153 * csr = new KJUR.asn1.csr.CertificationRequest({ 154 * subject: "/C=JP/O=Test", 155 * sbjpubkey: ... 156 * }); 157 * csr.sign(); 158 */ 159 this.sign = function() { 160 var hCSRI = 161 (new _CertificationRequestInfo(this.params)).tohex(); 162 var sig = new KJUR.crypto.Signature({alg: this.params.sigalg}); 163 sig.init(this.params.sbjprvkey); 164 sig.updateHex(hCSRI); 165 var sighex = sig.sign(); 166 this.params.sighex = sighex; 167 }; 168 169 /** 170 * get PEM formatted certificate signing request (CSR/PKCS#10)<br/> 171 * @name getPEM 172 * @memberOf KJUR.asn1.csr.CertificationRequest# 173 * @function 174 * @return PEM formatted string of CSR/PKCS#10 175 * @description 176 * This method is to a get CSR PEM string 177 * <br/> 178 * @example 179 * csr = new KJUR.asn1.csr.CertificationRequest({ 180 * subject: "/C=JP/O=Test", 181 * sbjpubkey: ... 182 * }); 183 * csr.getPEM() → "-----BEGIN CERTIFICATE REQUEST..." 184 */ 185 this.getPEM = function() { 186 return hextopem(this.tohex(), "CERTIFICATE REQUEST"); 187 }; 188 189 this.tohex = function() { 190 var params = this.params; 191 var csri = new KJUR.asn1.csr.CertificationRequestInfo(this.params); 192 var algid = 193 new KJUR.asn1.x509.AlgorithmIdentifier({name: params.sigalg}); 194 195 if (params.sighex == undefined && params.sbjprvkey != undefined) { 196 this.sign(); 197 } 198 199 if (params.sighex == undefined) { 200 throw new Error("sighex or sbjprvkey parameter not defined"); 201 } 202 203 var asn1Sig = new _DERBitString({hex: "00" + params.sighex}); 204 205 var seq = new _DERSequence({array: [csri, algid, asn1Sig]}); 206 return seq.tohex(); 207 }; 208 this.getEncodedHex = function() { return this.tohex(); }; 209 210 if (params !== undefined) this.setByParam(params); 211 }; 212 extendClass(KJUR.asn1.csr.CertificationRequest, KJUR.asn1.ASN1Object); 213 214 /** 215 * ASN.1 CertificationRequestInfo structure class 216 * @name KJUR.asn1.csr.CertificationRequestInfo 217 * @class ASN.1 CertificationRequestInfo structure class 218 * @param {Array} params associative array of parameters (ex. {}) 219 * @extends KJUR.asn1.ASN1Object 220 * @since jsrsasign 4.9.0 asn1csr 1.0.0 221 * @see KJUR.asn1.csr.CertificationRequest 222 * @see KJUR.asn1.x509.Extensions 223 * @description 224 * This class provides CertificateRequestInfo ASN.1 structure 225 * defined in 226 * <a href="https://tools.ietf.org/html/rfc2986#page-5"> 227 * RFC 2986 4.1</a>. 228 * <pre> 229 * CertificationRequestInfo ::= SEQUENCE { 230 * version INTEGER { v1(0) } (v1,...), 231 * subject Name, 232 * subjectPKInfo SubjectPublicKeyInfo{{ PKInfoAlgorithms }}, 233 * attributes [0] Attributes {{ CRIAttributes }} } 234 * </pre> 235 * <br/> 236 * <br/> 237 * NOTE1: 238 * Argument "params" JSON value format have been changed without 239 * backward compatibility since jsrsasign 9.0.0 asn1csr 2.0.0.<br/> 240 * NOTE2: 241 * From jsrsasign 10.5.27, "attrs" member in the constructor argument 242 * object have been supported to support more Attributes type. 243 * Currently following Attribute types are supported: 244 * <ul> 245 * <li>challengePassword</li> 246 * <li>unstructuredName - member "names" will be array of 247 * DirectoryStrings. (ex. [{prnstr: "aaa"},{utf8str: "bbb"}]</li> 248 * <li>extensionRequest - any {@link KJUR.asn1.x509.Extensions} 249 * constructor argument can be specified for "ext" member value.</li> 250 * </ul> 251 * 252 * @example 253 * csri = new KJUR.asn1.csr.CertificationRequestInfo({ 254 * subject: {str: '/C=US/CN=b'}, 255 * sbjpubkey: <<PUBLIC KEY PEM>>, 256 * extreq: [ 257 * {extname:"subjectAltName", array:[{dns:"example.com"}]} 258 * ]}); 259 * csri.tohex() → "30..." 260 * 261 * // From jsrsasign 10.5.27, "attrs" supported 262 * csri = new KJUR.asn1.csr.CertificationRequestInfo({ 263 * subject: {str: '/C=US/CN=b'}, 264 * sbjpubkey: <<PUBLIC KEY PEM>>, 265 * attrs: [ 266 * {attr: "challengePassword", password: "secret"}, 267 * {attr: "unstructuredName", names: [{utf8str:"aaa"},{ia5str:"bbb"}]}, 268 * {attr: "extensionRequest", ext: [ 269 * {extname: "basicConstraints", cA: true}, 270 * {extname: "subjectKeyIdentifier", kid: "1a2b..."} 271 * ]} 272 * ]}); 273 * csri.tohex() → "30..." 274 */ 275 KJUR.asn1.csr.CertificationRequestInfo = function(params) { 276 var _KJUR = KJUR, 277 _KJUR_asn1 = _KJUR.asn1, 278 _DERBitString = _KJUR_asn1.DERBitString, 279 _DERSequence = _KJUR_asn1.DERSequence, 280 _DERInteger = _KJUR_asn1.DERInteger, 281 _DERUTF8String = _KJUR_asn1.DERUTF8String, 282 _DERTaggedObject = _KJUR_asn1.DERTaggedObject, 283 _newObject = _KJUR_asn1.ASN1Util.newObject, 284 _KJUR_asn1_csr = _KJUR_asn1.csr, 285 _KJUR_asn1_x509 = _KJUR_asn1.x509, 286 _X500Name = _KJUR_asn1_x509.X500Name, 287 _Extensions = _KJUR_asn1_x509.Extensions, 288 _SubjectPublicKeyInfo = _KJUR_asn1_x509.SubjectPublicKeyInfo, 289 _AttributeList = _KJUR_asn1_csr.AttributeList; 290 291 _KJUR_asn1_csr.CertificationRequestInfo.superclass.constructor.call(this); 292 293 this.params = null; 294 295 this.setByParam = function(params) { 296 if (params != undefined) this.params = params; 297 }; 298 299 this.tohex = function() { 300 var params = this.params; 301 var a = []; 302 a.push(new _DERInteger({'int': 0})); // version 303 a.push(new _X500Name(params.subject)); 304 a.push(new _SubjectPublicKeyInfo(KEYUTIL.getKey(params.sbjpubkey))); 305 if (params.attrs != undefined) { 306 var asn1Param = _conv(params.attrs); 307 var tagobj = _newObject({tag: {tage: "a0", obj: asn1Param}}); 308 a.push(tagobj); 309 } else if (params.extreq != undefined) { 310 var extseq = new _Extensions(params.extreq); 311 var tagobj = _newObject({ 312 tag: { 313 tage:'a0', 314 obj:{seq: [{oid: "1.2.840.113549.1.9.14"}, 315 {set: [extseq]}]} 316 } 317 }); 318 a.push(tagobj); 319 } else { 320 a.push(new _DERTaggedObject({tag:"a0", 321 explicit:false, 322 obj:new _DERUTF8String({str:''})})); 323 } 324 var seq = new _DERSequence({array: a}); 325 return seq.tohex(); 326 }; 327 this.getEncodedHex = function() { return this.tohex(); }; 328 329 /* 330 * converter from attrs member value to newObject acceptable data 331 */ 332 function _conv(aAttrParam) { 333 var _Error = Error, 334 _Extensions = KJUR.asn1.x509.Extensions; 335 var a = []; 336 for (var i = 0; i < aAttrParam.length; i++) { 337 var pAttr = aAttrParam[i]; 338 var attrName = pAttr.attr; 339 if (attrName == "extensionRequest") { 340 var oExt = new _Extensions(pAttr.ext); 341 var p = {seq: [{oid: "1.2.840.113549.1.9.14"},{set: [oExt]}]}; 342 a.push(p); 343 } else if (attrName == "unstructuredName") { 344 var p = {seq: [{oid: "1.2.840.113549.1.9.2"},{set: pAttr.names}]}; 345 a.push(p); 346 } else if (attrName == "challengePassword") { 347 var p = {seq: [{oid: "1.2.840.113549.1.9.7"}, 348 {set: [{utf8str: pAttr.password}]}]}; 349 a.push(p); 350 } else { 351 throw new _Error("unknown CSR attribute"); 352 } 353 } 354 return {set: a}; 355 } 356 357 if (params != undefined) this.setByParam(params); 358 }; 359 extendClass(KJUR.asn1.csr.CertificationRequestInfo, KJUR.asn1.ASN1Object); 360 361 KJUR.asn1.csr.AttributeList = function(aParam) { 362 function _paramToASN1Param(aParam) { 363 } 364 }; 365 extendClass(KJUR.asn1.csr.AttributeList, KJUR.asn1.ASN1Object); 366 367 368 /** 369 * Certification Request (CSR/PKCS#10) utilities class<br/> 370 * @name KJUR.asn1.csr.CSRUtil 371 * @class Certification Request (CSR/PKCS#10) utilities class 372 * @description 373 * This class provides utility static methods for CSR/PKCS#10. 374 * Here is a list of methods: 375 * <ul> 376 * <li>{@link KJUR.asn1.csr.CSRUtil.newCSRPEM} (DEPRECATED)</li> 377 * <li>{@link KJUR.asn1.csr.CSRUtil.getParam}</li> 378 * </ul> 379 * <br/> 380 */ 381 KJUR.asn1.csr.CSRUtil = new function() { 382 }; 383 384 /** 385 * generate a PEM format of CSR/PKCS#10 certificate signing request (DEPRECATED)<br/> 386 * @name newCSRPEM 387 * @memberOf KJUR.asn1.csr.CSRUtil 388 * @function 389 * @param {Array} param parameter to generate CSR 390 * @since jsrsasign 4.9.0 asn1csr 1.0.0 391 * @deprecated since jsrsasign 9.0.0 asn1csr 2.0.0. please use {@link KJUR.asn1.csr.CertificationRequest} constructor. 392 * @description 393 * This method can generate a CSR certificate signing. 394 * 395 * @example 396 * // 1) by key object 397 * pem = KJUR.asn1.csr.CSRUtil.newCSRPEM({ 398 * subject: {str: '/C=US/O=Test/CN=example.com'}, 399 * sbjpubkey: pubKeyObj, 400 * sigalg: "SHA256withRSA", 401 * sbjprvkey: prvKeyObj, 402 * extreq: [{ 403 * extname: "subjectAltName", 404 * array: [{dns:"example.com"}] 405 * }] 406 * }); 407 * 408 * // 2) by private/public key PEM 409 * pem = KJUR.asn1.csr.CSRUtil.newCSRPEM({ 410 * subject: {str: '/C=US/O=Test/CN=example.com'}, 411 * sbjpubkey: pubKeyPEM, 412 * sigalg: "SHA256withRSA", 413 * sbjprvkey: prvKeyPEM 414 * }); 415 * 416 * // 3) with generateKeypair 417 * kp = KEYUTIL.generateKeypair("RSA", 2048); 418 * pem = KJUR.asn1.csr.CSRUtil.newCSRPEM({ 419 * subject: {str: '/C=US/O=Test/CN=example.com'}, 420 * sbjpubkey: kp.pubKeyObj, 421 * sigalg: "SHA256withRSA", 422 * sbjprvkey: kp.prvKeyObj 423 * }); 424 * 425 * // 4) by private/public key PEM with extension 426 * pem = KJUR.asn1.csr.CSRUtil.newCSRPEM({ 427 * subject: {str: '/C=US/O=Test/CN=example.com'}, 428 * ext: [ 429 * {subjectAltName: {array: [{dns: 'example.net'}]}} 430 * ], 431 * sbjpubkey: pubKeyPEM, 432 * sigalg: "SHA256withRSA", 433 * sbjprvkey: prvKeyPEM 434 * }); 435 */ 436 KJUR.asn1.csr.CSRUtil.newCSRPEM = function(param) { 437 var _KEYUTIL = KEYUTIL, 438 _KJUR_asn1_csr = KJUR.asn1.csr; 439 440 var csr = new _KJUR_asn1_csr.CertificationRequest(param); 441 var pem = csr.getPEM(); 442 return pem; 443 }; 444 445 /** 446 * get field values from CSR/PKCS#10 PEM string<br/> 447 * @name getParam 448 * @memberOf KJUR.asn1.csr.CSRUtil 449 * @function 450 * @param {string} sPEM PEM string of CSR/PKCS#10 451 * @param {boolean} flagTBS result object also concludes CertificationRequestInfo (OPTION, DEFAULT=false) 452 * @returns {Array} JSON object with parsed parameters such as name or public key 453 * @since jsrsasign 9.0.0 asn1csr 2.0.0 454 * @see KJUR.asn1.csr.CertificationRequest 455 * @see KJUR.asn1.csr.CertificationRequestInfo 456 * @see KJUR.asn1.x509.X500Name 457 * @see X509#getExtParamArray 458 * @description 459 * This method parses PEM CSR/PKCS#1 string and retrieves 460 * fields such as subject name and public key. 461 * Following parameters are available in the 462 * resulted JSON object. 463 * <ul> 464 * <li>{X500Name}subject - subject name parameters </li> 465 * <li>{String}sbjpubkey - PEM string of subject public key</li> 466 * <li>{Array}extreq - array of extensionRequest parameters</li> 467 * <li>{String}sigalg - name of signature algorithm field</li> 468 * <li>{String}sighex - hexadecimal string of signature value</li> 469 * <li>{String}tbs - a hexadecimal string of CertificationRequestInfo as to be signed(OPTION)</li> 470 * </ul> 471 * Returned JSON object can be passed to 472 * {@link KJUR.asn1.csr.CertificationRequest} class constructor. 473 * <br/> 474 * CAUTION: 475 * Returned JSON value format have been changed without 476 * backward compatibility since jsrsasign 9.0.0 asn1csr 2.0.0. 477 * <br/> 478 * NOTE: 479 * The "flagTBS" supported since jsrsasign 10.5.26. 480 * 481 * @example 482 * KJUR.asn1.csr.CSRUtil.getParam("-----BEGIN CERTIFICATE REQUEST...") → 483 * { 484 * subject: { array:[[{type:"C",value:"JP",ds:"prn"}],...], 485 * str: "/C=JP/O=Test"}, 486 * sbjpubkey: "-----BEGIN PUBLIC KEY...", 487 * extreq: [{extname:"subjectAltName",array:[{dns:"example.com"}]}] 488 * sigalg: "SHA256withRSA", 489 * sighex: "1ab3df.." 490 * } 491 * 492 * KJUR.asn1.csr.CSRUtil.getParam("-----BEGIN CERTIFICATE REQUEST...", true) → 493 * result will also have a member "tbs" in the object. 494 */ 495 KJUR.asn1.csr.CSRUtil.getParam = function(sPEM, flagTBS) { 496 var _ASN1HEX = ASN1HEX, 497 _getV = _ASN1HEX.getV, 498 _getIdxbyList = _ASN1HEX.getIdxbyList, 499 _getTLVbyList = _ASN1HEX.getTLVbyList, 500 _getTLVbyListEx = _ASN1HEX.getTLVbyListEx, 501 _getVbyListEx = _ASN1HEX.getVbyListEx; 502 503 /* 504 * get a hexadecimal string of sequence of extension request attribute value 505 * @param {String} h hexadecimal string of whole CSR 506 * @return {String} hexadecimal string of SEQUENCE of extension request attribute value 507 */ 508 var _getExtReqSeqHex = function(h) { 509 var idx1 = _getIdxbyList(h, 0, [0, 3, 0, 0], "06"); // extreq attr OID idx 510 if (_getV(h, idx1) != "2a864886f70d01090e") { 511 return null; 512 } 513 514 return _getTLVbyList(h, 0, [0, 3, 0, 1, 0], "30"); // ext seq idx 515 }; 516 517 var result = {}; 518 519 if (sPEM.indexOf("-----BEGIN CERTIFICATE REQUEST") == -1) 520 throw new Error("argument is not PEM file"); 521 522 var hex = pemtohex(sPEM, "CERTIFICATE REQUEST"); 523 524 if (flagTBS) { 525 result.tbs = _getTLVbyList(hex, 0, [0]); 526 } 527 528 try { 529 var hSubject = _getTLVbyListEx(hex, 0, [0, 1]); 530 if (hSubject == "3000") { 531 result.subject = {}; 532 } else { 533 var x = new X509(); 534 result.subject = x.getX500Name(hSubject); 535 } 536 } catch (ex) {}; 537 538 var hPubKey = _getTLVbyListEx(hex, 0, [0, 2]); 539 var pubkeyobj = KEYUTIL.getKey(hPubKey, null, "pkcs8pub"); 540 result.sbjpubkey = KEYUTIL.getPEM(pubkeyobj, "PKCS8PUB"); 541 542 var hExtReqSeq = _getExtReqSeqHex(hex); 543 var x = new X509(); 544 if (hExtReqSeq != null) { 545 result.extreq = x.getExtParamArray(hExtReqSeq); 546 } 547 548 try { 549 var hSigAlg = _getTLVbyListEx(hex, 0, [1], "30"); 550 var x = new X509(); 551 result.sigalg = x.getAlgorithmIdentifierName(hSigAlg); 552 } catch (ex) {}; 553 554 try { 555 var hSig = _getVbyListEx(hex, 0, [2]); 556 result.sighex = hSig; 557 } catch (ex) {}; 558 559 return result; 560 }; 561 562 /** 563 * verify self-signed CSR/PKCS#10 signature<br/> 564 * @name verifySignature 565 * @memberOf KJUR.asn1.csr.CSRUtil 566 * @function 567 * @param {object} csr PEM CSR string or parsed JSON object of CSR 568 * @returns {boolean} true if self-signed signature is valid otherwise false 569 * @since jsrsasign 10.5.26 asn1csr 2.0.6 570 * @see KJUR.asn1.csr.CertificationRequest 571 * @see KJUR.asn1.csr.CertificationRequestInfo 572 * @see KJUR.asn1.csr.CSRUtil#getParam 573 * @description 574 * This method verifies self-signed signature of CSR/PKCS#10 575 * with its public key which is concluded in the CSR. 576 * 577 * @example 578 * KJUR.asn1.csr.CSRUtil.verifySignatrue("-----BEGIN CERTIFICATE REQUEST...") → true or false 579 * 580 * p = KJUR.asn1.csr.CSRUtil.getParam("-----BEGIN CERTIFICATE REQUEST-----", true); // with tbs 581 * KJUR.asn1.csr.CSRUtil.verifySignatrue(p) → true or false 582 */ 583 KJUR.asn1.csr.CSRUtil.verifySignature = function(csr) { 584 try { 585 var pCSR = null; 586 if (typeof csr == "string" && 587 csr.indexOf("-----BEGIN CERTIFICATE REQUEST") != -1) { 588 pCSR = KJUR.asn1.csr.CSRUtil.getParam(csr, true); 589 } else if (typeof csr == "object" && 590 csr.sbjpubkey != undefined && 591 csr.sigalg != undefined && 592 csr.sighex != undefined && 593 csr.tbs != undefined) { 594 pCSR = csr; 595 } 596 if (pCSR == null) return false; 597 598 // verify self-signed signature 599 var sig = new KJUR.crypto.Signature({alg: pCSR.sigalg}); 600 sig.init(pCSR.sbjpubkey); 601 sig.updateHex(pCSR.tbs); 602 return sig.verify(pCSR.sighex); 603 } catch(ex) { 604 alert(ex); 605 return false; 606 } 607 }; 608 609 610