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