diff --git a/ChangeLog.txt b/ChangeLog.txt index 048dfdc5..76b27532 100755 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,6 +1,14 @@ ChangeLog for jsrsasign +extend CertificationRequestInfo class for challengePassword and unstructuredName +* Changes from 10.5.26 to 10.5.27 (2022-Aug-19) + - src/asn1csr.js + - CertificationRequestInfo class + - add support for challengePassword and unstructuredName (#522) + - "attrs" member support in constructure argument + - test/qunit-do-asn1csr.html + CSRUtil class enhancement * Changes from 10.5.25 to 10.5.26 (2022-Jul-14) - src/asn1csr.js diff --git a/api/files.html b/api/files.html index 545d93c3..4cf8c7c5 100644 --- a/api/files.html +++ b/api/files.html @@ -586,7 +586,7 @@
Attributes ::= SET OF Attribute Attribute ::= SEQUENCE { diff --git a/api/symbols/KJUR.asn1.csr.CertificationRequestInfo.html b/api/symbols/KJUR.asn1.csr.CertificationRequestInfo.html index 2873ed3c..330a6453 100644 --- a/api/symbols/KJUR.asn1.csr.CertificationRequestInfo.html +++ b/api/symbols/KJUR.asn1.csr.CertificationRequestInfo.html @@ -617,13 +617,24 @@version INTEGER { v1(0) } (v1,...), subject Name, subjectPKInfo SubjectPublicKeyInfo{{ PKInfoAlgorithms }}, - attributes [0] Attributes{{ CRIAttributes }} } + attributes [0] Attributes {{ CRIAttributes }} }
1 /* asn1csr-2.0.6.js (c) 2015-2022 Kenji Urushima | kjur.github.io/jsrsasign/license +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 @@ -23,7 +23,7 @@ 16 * @fileOverview 17 * @name asn1csr-1.0.js 18 * @author Kenji Urushima kenji.urushima@gmail.com - 19 * @version jsrsasign 10.5.26 asn1csr 2.0.6 (2022-Jul-14) + 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 */ @@ -226,328 +226,392 @@ 219 * @extends KJUR.asn1.ASN1Object 220 * @since jsrsasign 4.9.0 asn1csr 1.0.0 221 * @see KJUR.asn1.csr.CertificationRequest -222 * @description -223 * This class provides CertificateRequestInfo ASN.1 structure -224 * defined in -225 * <a href="https://tools.ietf.org/html/rfc2986#page-5"> -226 * RFC 2986 4.1</a>. -227 * <pre> -228 * CertificationRequestInfo ::= SEQUENCE { -229 * version INTEGER { v1(0) } (v1,...), -230 * subject Name, -231 * subjectPKInfo SubjectPublicKeyInfo{{ PKInfoAlgorithms }}, -232 * attributes [0] Attributes{{ CRIAttributes }} } -233 * </pre> -234 * <br/> +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 * CAUTION: -237 * Argument "params" JSON value format have been changed without -238 * backward compatibility since jsrsasign 9.0.0 asn1csr 2.0.0. -239 * -240 * @example -241 * csri = new KJUR.asn1.csr.CertificationRequestInfo({ -242 * subject: {str: '/C=US/CN=b'}, -243 * sbjpubkey: <<PUBLIC KEY PEM>>, -244 * extreq: [ -245 * {extname:"subjectAltName", array:[{dns:"example.com"}]} -246 * ]}); -247 * csri.tohex() → "30..." -248 */ -249 KJUR.asn1.csr.CertificationRequestInfo = function(params) { -250 var _KJUR = KJUR, -251 _KJUR_asn1 = _KJUR.asn1, -252 _DERBitString = _KJUR_asn1.DERBitString, -253 _DERSequence = _KJUR_asn1.DERSequence, -254 _DERInteger = _KJUR_asn1.DERInteger, -255 _DERUTF8String = _KJUR_asn1.DERUTF8String, -256 _DERTaggedObject = _KJUR_asn1.DERTaggedObject, -257 _newObject = _KJUR_asn1.ASN1Util.newObject, -258 _KJUR_asn1_csr = _KJUR_asn1.csr, -259 _KJUR_asn1_x509 = _KJUR_asn1.x509, -260 _X500Name = _KJUR_asn1_x509.X500Name, -261 _Extensions = _KJUR_asn1_x509.Extensions, -262 _SubjectPublicKeyInfo = _KJUR_asn1_x509.SubjectPublicKeyInfo; -263 -264 _KJUR_asn1_csr.CertificationRequestInfo.superclass.constructor.call(this); -265 -266 this.params = null; -267 -268 this.setByParam = function(params) { -269 if (params != undefined) this.params = params; -270 }; -271 -272 this.tohex = function() { -273 var params = this.params; -274 var a = []; -275 a.push(new _DERInteger({'int': 0})); // version -276 a.push(new _X500Name(params.subject)); -277 a.push(new _SubjectPublicKeyInfo(KEYUTIL.getKey(params.sbjpubkey))); -278 if (params.extreq != undefined) { -279 var extseq = new _Extensions(params.extreq); -280 var tagobj = _newObject({ -281 tag: { -282 tag:'a0', -283 explict:true, -284 obj:{seq: [{oid: "1.2.840.113549.1.9.14"}, -285 {set: [extseq]}]} -286 } -287 }); -288 a.push(tagobj); -289 } else { -290 a.push(new _DERTaggedObject({tag:"a0", -291 explicit:false, -292 obj:new _DERUTF8String({str:''})})); -293 } -294 var seq = new _DERSequence({array: a}); -295 return seq.tohex(); -296 }; -297 this.getEncodedHex = function() { return this.tohex(); }; +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 if (params != undefined) this.setByParam(params); -300 }; -301 -302 extendClass(KJUR.asn1.csr.CertificationRequestInfo, KJUR.asn1.ASN1Object); -303 -304 /** -305 * Certification Request (CSR/PKCS#10) utilities class<br/> -306 * @name KJUR.asn1.csr.CSRUtil -307 * @class Certification Request (CSR/PKCS#10) utilities class -308 * @description -309 * This class provides utility static methods for CSR/PKCS#10. -310 * Here is a list of methods: -311 * <ul> -312 * <li>{@link KJUR.asn1.csr.CSRUtil.newCSRPEM} (DEPRECATED)</li> -313 * <li>{@link KJUR.asn1.csr.CSRUtil.getParam}</li> -314 * </ul> -315 * <br/> -316 */ -317 KJUR.asn1.csr.CSRUtil = new function() { -318 }; -319 -320 /** -321 * generate a PEM format of CSR/PKCS#10 certificate signing request (DEPRECATED)<br/> -322 * @name newCSRPEM -323 * @memberOf KJUR.asn1.csr.CSRUtil -324 * @function -325 * @param {Array} param parameter to generate CSR -326 * @since jsrsasign 4.9.0 asn1csr 1.0.0 -327 * @deprecated since jsrsasign 9.0.0 asn1csr 2.0.0. please use {@link KJUR.asn1.csr.CertificationRequest} constructor. -328 * @description -329 * This method can generate a CSR certificate signing. -330 * -331 * @example -332 * // 1) by key object -333 * pem = KJUR.asn1.csr.CSRUtil.newCSRPEM({ -334 * subject: {str: '/C=US/O=Test/CN=example.com'}, -335 * sbjpubkey: pubKeyObj, -336 * sigalg: "SHA256withRSA", -337 * sbjprvkey: prvKeyObj, -338 * extreq: [{ -339 * extname: "subjectAltName", -340 * array: [{dns:"example.com"}] -341 * }] -342 * }); -343 * -344 * // 2) by private/public key PEM -345 * pem = KJUR.asn1.csr.CSRUtil.newCSRPEM({ -346 * subject: {str: '/C=US/O=Test/CN=example.com'}, -347 * sbjpubkey: pubKeyPEM, -348 * sigalg: "SHA256withRSA", -349 * sbjprvkey: prvKeyPEM -350 * }); -351 * -352 * // 3) with generateKeypair -353 * kp = KEYUTIL.generateKeypair("RSA", 2048); -354 * pem = KJUR.asn1.csr.CSRUtil.newCSRPEM({ -355 * subject: {str: '/C=US/O=Test/CN=example.com'}, -356 * sbjpubkey: kp.pubKeyObj, -357 * sigalg: "SHA256withRSA", -358 * sbjprvkey: kp.prvKeyObj -359 * }); -360 * -361 * // 4) by private/public key PEM with extension -362 * pem = KJUR.asn1.csr.CSRUtil.newCSRPEM({ -363 * subject: {str: '/C=US/O=Test/CN=example.com'}, -364 * ext: [ -365 * {subjectAltName: {array: [{dns: 'example.net'}]}} -366 * ], -367 * sbjpubkey: pubKeyPEM, -368 * sigalg: "SHA256withRSA", -369 * sbjprvkey: prvKeyPEM -370 * }); -371 */ -372 KJUR.asn1.csr.CSRUtil.newCSRPEM = function(param) { -373 var _KEYUTIL = KEYUTIL, -374 _KJUR_asn1_csr = KJUR.asn1.csr; -375 -376 var csr = new _KJUR_asn1_csr.CertificationRequest(param); -377 var pem = csr.getPEM(); -378 return pem; -379 }; -380 -381 /** -382 * get field values from CSR/PKCS#10 PEM string<br/> -383 * @name getParam -384 * @memberOf KJUR.asn1.csr.CSRUtil -385 * @function -386 * @param {string} sPEM PEM string of CSR/PKCS#10 -387 * @param {boolean} flagTBS result object also concludes CertificationRequestInfo (OPTION, DEFAULT=false) -388 * @returns {Array} JSON object with parsed parameters such as name or public key -389 * @since jsrsasign 9.0.0 asn1csr 2.0.0 -390 * @see KJUR.asn1.csr.CertificationRequest -391 * @see KJUR.asn1.csr.CertificationRequestInfo -392 * @see KJUR.asn1.x509.X500Name -393 * @see X509#getExtParamArray -394 * @description -395 * This method parses PEM CSR/PKCS#1 string and retrieves -396 * fields such as subject name and public key. -397 * Following parameters are available in the -398 * resulted JSON object. -399 * <ul> -400 * <li>{X500Name}subject - subject name parameters </li> -401 * <li>{String}sbjpubkey - PEM string of subject public key</li> -402 * <li>{Array}extreq - array of extensionRequest parameters</li> -403 * <li>{String}sigalg - name of signature algorithm field</li> -404 * <li>{String}sighex - hexadecimal string of signature value</li> -405 * <li>{String}tbs - a hexadecimal string of CertificationRequestInfo as to be signed(OPTION)</li> -406 * </ul> -407 * Returned JSON object can be passed to -408 * {@link KJUR.asn1.csr.CertificationRequest} class constructor. -409 * <br/> -410 * CAUTION: -411 * Returned JSON value format have been changed without -412 * backward compatibility since jsrsasign 9.0.0 asn1csr 2.0.0. -413 * <br/> -414 * NOTE: -415 * The "flagTBS" supported since jsrsasign 10.5.26. -416 * -417 * @example -418 * KJUR.asn1.csr.CSRUtil.getParam("-----BEGIN CERTIFICATE REQUEST...") → -419 * { -420 * subject: { array:[[{type:"C",value:"JP",ds:"prn"}],...], -421 * str: "/C=JP/O=Test"}, -422 * sbjpubkey: "-----BEGIN PUBLIC KEY...", -423 * extreq: [{extname:"subjectAltName",array:[{dns:"example.com"}]}] -424 * sigalg: "SHA256withRSA", -425 * sighex: "1ab3df.." -426 * } -427 * -428 * KJUR.asn1.csr.CSRUtil.getParam("-----BEGIN CERTIFICATE REQUEST...", true) → -429 * result will also have a member "tbs" in the object. -430 */ -431 KJUR.asn1.csr.CSRUtil.getParam = function(sPEM, flagTBS) { -432 var _ASN1HEX = ASN1HEX, -433 _getV = _ASN1HEX.getV, -434 _getIdxbyList = _ASN1HEX.getIdxbyList, -435 _getTLVbyList = _ASN1HEX.getTLVbyList, -436 _getTLVbyListEx = _ASN1HEX.getTLVbyListEx, -437 _getVbyListEx = _ASN1HEX.getVbyListEx; -438 -439 /* -440 * get a hexadecimal string of sequence of extension request attribute value -441 * @param {String} h hexadecimal string of whole CSR -442 * @return {String} hexadecimal string of SEQUENCE of extension request attribute value -443 */ -444 var _getExtReqSeqHex = function(h) { -445 var idx1 = _getIdxbyList(h, 0, [0, 3, 0, 0], "06"); // extreq attr OID idx -446 if (_getV(h, idx1) != "2a864886f70d01090e") { -447 return null; -448 } -449 -450 return _getTLVbyList(h, 0, [0, 3, 0, 1, 0], "30"); // ext seq idx -451 }; -452 -453 var result = {}; -454 -455 if (sPEM.indexOf("-----BEGIN CERTIFICATE REQUEST") == -1) -456 throw new Error("argument is not PEM file"); -457 -458 var hex = pemtohex(sPEM, "CERTIFICATE REQUEST"); -459 -460 if (flagTBS) { -461 result.tbs = _getTLVbyList(hex, 0, [0]); -462 } -463 -464 try { -465 var hSubject = _getTLVbyListEx(hex, 0, [0, 1]); -466 if (hSubject == "3000") { -467 result.subject = {}; -468 } else { -469 var x = new X509(); -470 result.subject = x.getX500Name(hSubject); -471 } -472 } catch (ex) {}; -473 -474 var hPubKey = _getTLVbyListEx(hex, 0, [0, 2]); -475 var pubkeyobj = KEYUTIL.getKey(hPubKey, null, "pkcs8pub"); -476 result.sbjpubkey = KEYUTIL.getPEM(pubkeyobj, "PKCS8PUB"); -477 -478 var hExtReqSeq = _getExtReqSeqHex(hex); -479 var x = new X509(); -480 if (hExtReqSeq != null) { -481 result.extreq = x.getExtParamArray(hExtReqSeq); -482 } -483 -484 try { -485 var hSigAlg = _getTLVbyListEx(hex, 0, [1], "30"); -486 var x = new X509(); -487 result.sigalg = x.getAlgorithmIdentifierName(hSigAlg); -488 } catch (ex) {}; -489 -490 try { -491 var hSig = _getVbyListEx(hex, 0, [2]); -492 result.sighex = hSig; -493 } catch (ex) {}; -494 -495 return result; -496 }; -497 -498 /** -499 * verify self-signed CSR/PKCS#10 signature<br/> -500 * @name verifySignature -501 * @memberOf KJUR.asn1.csr.CSRUtil -502 * @function -503 * @param {object} csr PEM CSR string or parsed JSON object of CSR -504 * @returns {boolean} true if self-signed signature is valid otherwise false -505 * @since jsrsasign 10.5.26 asn1csr 2.0.6 -506 * @see KJUR.asn1.csr.CertificationRequest -507 * @see KJUR.asn1.csr.CertificationRequestInfo -508 * @see KJUR.asn1.csr.CSRUtil#getParam -509 * @description -510 * This method verifies self-signed signature of CSR/PKCS#10 -511 * with its public key which is concluded in the CSR. -512 * -513 * @example -514 * KJUR.asn1.csr.CSRUtil.verifySignatrue("-----BEGIN CERTIFICATE REQUEST...") → true or false -515 * -516 * p = KJUR.asn1.csr.CSRUtil.getParam("-----BEGIN CERTIFICATE REQUEST-----", true); // with tbs -517 * KJUR.asn1.csr.CSRUtil.verifySignatrue(p) → true or false -518 */ -519 KJUR.asn1.csr.CSRUtil.verifySignature = function(csr) { -520 try { -521 var pCSR = null; -522 if (typeof csr == "string" && -523 csr.indexOf("-----BEGIN CERTIFICATE REQUEST") != -1) { -524 pCSR = KJUR.asn1.csr.CSRUtil.getParam(csr, true); -525 } else if (typeof csr == "object" && -526 csr.sbjpubkey != undefined && -527 csr.sigalg != undefined && -528 csr.sighex != undefined && -529 csr.tbs != undefined) { -530 pCSR = csr; -531 } -532 if (pCSR == null) return false; -533 -534 // verify self-signed signature -535 var sig = new KJUR.crypto.Signature({alg: pCSR.sigalg}); -536 sig.init(pCSR.sbjpubkey); -537 sig.updateHex(pCSR.tbs); -538 return sig.verify(pCSR.sighex); -539 } catch(ex) { -540 alert(ex); -541 return false; -542 } -543 }; -544 -545 -546