diff --git a/ChangeLog.txt b/ChangeLog.txt index 7df39af5..11f13112 100755 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,6 +1,18 @@ ChangeLog for jsrsasign +fix for wrong UTF-8 encoding in distinguished name parser +* Changes from 10.1.11 to 10.1.12 (2021-02-25) + - src/x509.js + - fix X509.getAttrTypeValue (#473) + - attribute value is converted by hextoutf8 not hextorstr + - X509.getIssuerString update to use getIssuer + - X509.getSubjectString update to use getSubject + - X509.dnarraytostr fix to escape "+" and "/" + - X509.hex2dn update to use getX500Name + - test/qunit-do-x509-ext.html + - updated to follow above + update X509.getVersion and add jsrsasign-util saveFileJSON * Changes from 10.1.10 to 10.1.11 (2021-02-19) - src/x509.js diff --git a/api/files.html b/api/files.html index 9679213d..a4cb8640 100644 --- a/api/files.html +++ b/api/files.html @@ -884,7 +884,7 @@

x509-1.1.js

Version:
-
jsrsasign 10.1.0 x509 2.0.9 (2020-Nov-18)
+
jsrsasign 10.1.12 x509 2.0.10 (2021-Feb-25)
diff --git a/api/symbols/X509.html b/api/symbols/X509.html index 58ab13a6..f57e82e8 100644 --- a/api/symbols/X509.html +++ b/api/symbols/X509.html @@ -4365,6 +4365,13 @@

+
+
See:
+ +
X509#getIssuer
+ +
+
@@ -5394,6 +5401,13 @@

+
+
See:
+ +
X509#getSubject
+ +
+
diff --git a/api/symbols/src/x509-1.1.js.html b/api/symbols/src/x509-1.1.js.html index 36759347..c2605abb 100644 --- a/api/symbols/src/x509-1.1.js.html +++ b/api/symbols/src/x509-1.1.js.html @@ -5,12 +5,12 @@ .STRN {color: #393;} .REGX {color: #339;} .line {border-right: 1px dotted #666; color: #666; font-style: normal;} -
  1 /* x509-2.0.9.js (c) 2012-2021 Kenji Urushima | kjur.github.io/jsrsasign/license
+	
  1 /* x509-2.0.10.js (c) 2012-2021 Kenji Urushima | kjur.github.io/jsrsasign/license
   2  */
   3 /*
   4  * x509.js - X509 class to read subject public key from certificate.
   5  *
-  6  * Copyright (c) 2010-2020 Kenji Urushima (kenji.urushima@gmail.com)
+  6  * Copyright (c) 2010-2021 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
@@ -23,7 +23,7 @@
  16  * @fileOverview
  17  * @name x509-1.1.js
  18  * @author Kenji Urushima kenji.urushima@gmail.com
- 19  * @version jsrsasign 10.1.0 x509 2.0.9 (2020-Nov-18)
+ 19  * @version jsrsasign 10.1.12 x509 2.0.10 (2021-Feb-25)
  20  * @since jsrsasign 1.x.x
  21  * @license <a href="https://kjur.github.io/jsrsasign/license/">MIT License</a>
  22  */
@@ -278,2766 +278,2763 @@
 271      * @memberOf X509#
 272      * @function
 273      * @return {String} issuer DN string
-274      * @example
-275      * var x = new X509();
-276      * x.readCertPEM(sCertPEM);
-277      * var dn1 = x.getIssuerString(); // return string like "/C=US/O=TEST"
-278      * var dn2 = KJUR.asn1.x509.X500Name.compatToLDAP(dn1); // returns "O=TEST, C=US"
-279      */
-280     this.getIssuerString = function() {
-281         return _X509.hex2dn(this.getIssuerHex());
-282     };
-283 
-284     /**
-285      * get JSON object of subject field<br/>
-286      * @name getSubject
-287      * @memberOf X509#
-288      * @function
-289      * @return {Array} JSON object of subject field
-290      * @since jsrsasign 9.0.0 x509 2.0.0
-291      * @see X509#getX500Name
-292      * @description
-293      * @example
-294      * var x = new X509(sCertPEM);
-295      * x.getSubject() →
-296      * { array: [[{type:'C',value:'JP',ds:'prn'}],...],
-297      *   str: "/C=JP/..." }
-298      */
-299     this.getSubject = function() {
-300 	return this.getX500Name(this.getSubjectHex());
-301     };
-302 
-303     /**
-304      * get hexadecimal string of subject field of certificate.<br/>
-305      * @name getSubjectHex
-306      * @memberOf X509#
-307      * @function
-308      * @return {String} hexadecial string of subject DN ASN.1
-309      * @example
-310      * var x = new X509();
-311      * x.readCertPEM(sCertPEM);
-312      * var subject = x.getSubjectHex(); // return string like "3013..."
-313      */
-314     this.getSubjectHex = function() {
-315 	return _getTLVbyList(this.hex, 0, [0, 5 + this.foffset], "30");
-316     };
-317 
-318     /**
-319      * get string of subject field of certificate.<br/>
-320      * @name getSubjectString
-321      * @memberOf X509#
-322      * @function
-323      * @return {String} subject DN string
-324      * @example
-325      * var x = new X509();
-326      * x.readCertPEM(sCertPEM);
-327      * var dn1 = x.getSubjectString(); // return string like "/C=US/O=TEST"
-328      * var dn2 = KJUR.asn1.x509.X500Name.compatToLDAP(dn1); // returns "O=TEST, C=US"
-329      */
-330     this.getSubjectString = function() {
-331         return _X509.hex2dn(this.getSubjectHex());
-332     };
-333 
-334     /**
-335      * get notBefore field string of certificate.<br/>
-336      * @name getNotBefore
-337      * @memberOf X509#
-338      * @function
-339      * @return {String} not before time value (ex. "151231235959Z")
-340      * @example
-341      * var x = new X509();
-342      * x.readCertPEM(sCertPEM);
-343      * var notBefore = x.getNotBefore(); // return string like "151231235959Z"
-344      */
-345     this.getNotBefore = function() {
-346         var s = _getVbyList(this.hex, 0, [0, 4 + this.foffset, 0]);
-347         s = s.replace(/(..)/g, "%$1");
-348         s = decodeURIComponent(s);
-349         return s;
-350     };
-351 
-352     /**
-353      * get notAfter field string of certificate.<br/>
-354      * @name getNotAfter
-355      * @memberOf X509#
-356      * @function
-357      * @return {String} not after time value (ex. "151231235959Z")
-358      * @example
-359      * var x = new X509();
-360      * x.readCertPEM(sCertPEM);
-361      * var notAfter = x.getNotAfter(); // return string like "151231235959Z"
-362      */
-363     this.getNotAfter = function() {
-364 	var s = _getVbyList(this.hex, 0, [0, 4 + this.foffset, 1]);
-365         s = s.replace(/(..)/g, "%$1");
-366         s = decodeURIComponent(s);
-367         return s;
-368     };
-369 
-370     /**
-371      * get a hexadecimal string of subjectPublicKeyInfo field.<br/>
-372      * @name getPublicKeyHex
-373      * @memberOf X509#
-374      * @function
-375      * @return {String} ASN.1 SEQUENCE hexadecimal string of subjectPublicKeyInfo field
-376      * @since jsrsasign 7.1.4 x509 1.1.13
-377      * @example
-378      * x = new X509();
-379      * x.readCertPEM(sCertPEM);
-380      * hSPKI = x.getPublicKeyHex(); // return string like "30820122..."
-381      */
-382     this.getPublicKeyHex = function() {
-383 	return _ASN1HEX.getTLVbyList(this.hex, 0, [0, 6 + this.foffset], "30");
-384     };
-385 
-386     /**
-387      * get a string index of subjectPublicKeyInfo field for hexadecimal string certificate.<br/>
-388      * @name getPublicKeyIdx
-389      * @memberOf X509#
-390      * @function
-391      * @return {Number} string index of subjectPublicKeyInfo field for hexadecimal string certificate.
-392      * @since jsrsasign 7.1.4 x509 1.1.13
-393      * @example
-394      * x = new X509();
-395      * x.readCertPEM(sCertPEM);
-396      * idx = x.getPublicKeyIdx(); // return string index in x.hex parameter
-397      */
-398     this.getPublicKeyIdx = function() {
-399 	return _getIdxbyList(this.hex, 0, [0, 6 + this.foffset], "30");
-400     };
-401 
-402     /**
-403      * get a string index of contents of subjectPublicKeyInfo BITSTRING value from hexadecimal certificate<br/>
-404      * @name getPublicKeyContentIdx
-405      * @memberOf X509#
-406      * @function
-407      * @return {Integer} string index of key contents
-408      * @since jsrsasign 8.0.0 x509 1.2.0
-409      * @example
-410      * x = new X509();
-411      * x.readCertPEM(sCertPEM);
-412      * idx = x.getPublicKeyContentIdx(); // return string index in x.hex parameter
-413      */
-414     // NOTE: Without BITSTRING encapsulation.
-415     this.getPublicKeyContentIdx = function() {
-416 	var idx = this.getPublicKeyIdx();
-417 	return _getIdxbyList(this.hex, idx, [1, 0], "30");
-418     };
-419 
-420     /**
-421      * get a RSAKey/ECDSA/DSA public key object of subjectPublicKeyInfo field.<br/>
-422      * @name getPublicKey
-423      * @memberOf X509#
-424      * @function
-425      * @return {Object} RSAKey/ECDSA/DSA public key object of subjectPublicKeyInfo field
-426      * @since jsrsasign 7.1.4 x509 1.1.13
-427      * @example
-428      * x = new X509();
-429      * x.readCertPEM(sCertPEM);
-430      * pubkey= x.getPublicKey();
-431      */
-432     this.getPublicKey = function() {
-433 	return KEYUTIL.getKey(this.getPublicKeyHex(), null, "pkcs8pub");
-434     };
-435 
-436     /**
-437      * get signature algorithm name from hexadecimal certificate data
-438      * @name getSignatureAlgorithmName
-439      * @memberOf X509#
-440      * @function
-441      * @return {String} signature algorithm name (ex. SHA1withRSA, SHA256withECDSA)
-442      * @since jsrsasign 7.2.0 x509 1.1.14
-443      * @see X509#getAlgorithmIdentifierName
-444      * @description
-445      * This method will get signature algorithm name of certificate:
-446      * @example
-447      * var x = new X509();
-448      * x.readCertPEM(sCertPEM);
-449      * x.getSignatureAlgorithmName() → "SHA256withRSA"
-450      */
-451     this.getSignatureAlgorithmName = function() {
-452 	var hTLV = _getTLVbyList(this.hex, 0, [1], "30");
-453 	return this.getAlgorithmIdentifierName(hTLV);
-454     };
-455 
-456     /**
-457      * get signature value as hexadecimal string<br/>
-458      * @name getSignatureValueHex
-459      * @memberOf X509#
-460      * @function
-461      * @return {String} signature value hexadecimal string without BitString unused bits
-462      * @since jsrsasign 7.2.0 x509 1.1.14
-463      *
-464      * @description
-465      * This method will get signature value of certificate:
-466      *
-467      * @example
-468      * var x = new X509();
-469      * x.readCertPEM(sCertPEM);
-470      * x.getSignatureValueHex() &rarr "8a4c47913..."
-471      */
-472     this.getSignatureValueHex = function() {
-473 	return _getVbyList(this.hex, 0, [2], "03", true);
-474     };
-475 
-476     /**
-477      * verifies signature value by public key<br/>
-478      * @name verifySignature
-479      * @memberOf X509#
-480      * @function
-481      * @param {Object} pubKey public key object
-482      * @return {Boolean} true if signature value is valid otherwise false
-483      * @since jsrsasign 7.2.0 x509 1.1.14
-484      *
-485      * @description
-486      * This method verifies signature value of hexadecimal string of 
-487      * X.509 certificate by specified public key object.
-488      * The signature algorithm used to verify will refer
-489      * signatureAlgorithm field. (See {@link X509#getSignatureAlgorithmField})
-490      * RSA-PSS signature algorithms (SHA{,256,384,512}withRSAandMGF1)
-491      * are available.
-492      *
-493      * @example
-494      * pubKey = KEYUTIL.getKey(pemPublicKey); // or certificate
-495      * x = new X509();
-496      * x.readCertPEM(pemCert);
-497      * x.verifySignature(pubKey) → true, false or raising exception
-498      */
-499     this.verifySignature = function(pubKey) {
-500 	var algName = this.getSignatureAlgorithmField();
-501 	var hSigVal = this.getSignatureValueHex();
-502 	var hTbsCert = _getTLVbyList(this.hex, 0, [0], "30");
-503 	
-504 	var sig = new KJUR.crypto.Signature({alg: algName});
-505 	sig.init(pubKey);
-506 	sig.updateHex(hTbsCert);
-507 	return sig.verify(hSigVal);
-508     };
-509 
-510     // ===== parse extension ======================================
-511     /**
-512      * set array of X.509v3 and CSR extesion information such as extension OID, criticality and value index. (DEPRECATED)<br/>
-513      * @name parseExt
-514      * @memberOf X509#
-515      * @function
-516      * @param {String} hCSR - PEM string of certificate signing requrest(CSR) (OPTION)
-517      * @since jsrsasign 7.2.0 x509 1.1.14
-518      * @deprecated jsrsasign 9.1.1 x509 2.0.1
-519      *
-520      * @description
-521      * This method will set an array of X.509v3 extension information having 
-522      * following parameters:
-523      * <ul>
-524      * <li>oid - extension OID (ex. 2.5.29.19)</li>
-525      * <li>critical - true or false</li>
-526      * <li>vidx - string index for extension value</li>
-527      * <br/>
-528      * When you want to parse extensionRequest of CSR,
-529      * argument 'hCSR' shall be specified.
-530      * <br/>
-531      * NOTE: CSR is supported from jsrsasign 8.0.20 x509 1.1.22.
-532      * <br/>
-533      * This method and X509.aExtInfo property
-534      * have been *deprecated* since jsrsasign 9.1.1.
-535      * All extension parser method such as X509.getExt* shall be
-536      * call with argument "hExtV" and "critical" explicitly.
-537      *
-538      * @example
-539      * x = new X509();
-540      * x.readCertPEM(sCertPEM); // parseExt() will also be called internally.
+274      * @see X509#getIssuer
+275      * @example
+276      * var x = new X509();
+277      * x.readCertPEM(sCertPEM);
+278      * var dn1 = x.getIssuerString(); // return string like "/C=US/O=TEST"
+279      * var dn2 = KJUR.asn1.x509.X500Name.compatToLDAP(dn1); // returns "O=TEST, C=US"
+280      */
+281     this.getIssuerString = function() {
+282 	var pIssuer = this.getIssuer();
+283 	return pIssuer.str;
+284     };
+285 
+286     /**
+287      * get JSON object of subject field<br/>
+288      * @name getSubject
+289      * @memberOf X509#
+290      * @function
+291      * @return {Array} JSON object of subject field
+292      * @since jsrsasign 9.0.0 x509 2.0.0
+293      * @see X509#getX500Name
+294      * @description
+295      * @example
+296      * var x = new X509(sCertPEM);
+297      * x.getSubject() →
+298      * { array: [[{type:'C',value:'JP',ds:'prn'}],...],
+299      *   str: "/C=JP/..." }
+300      */
+301     this.getSubject = function() {
+302 	return this.getX500Name(this.getSubjectHex());
+303     };
+304 
+305     /**
+306      * get hexadecimal string of subject field of certificate.<br/>
+307      * @name getSubjectHex
+308      * @memberOf X509#
+309      * @function
+310      * @return {String} hexadecial string of subject DN ASN.1
+311      * @example
+312      * var x = new X509();
+313      * x.readCertPEM(sCertPEM);
+314      * var subject = x.getSubjectHex(); // return string like "3013..."
+315      */
+316     this.getSubjectHex = function() {
+317 	return _getTLVbyList(this.hex, 0, [0, 5 + this.foffset], "30");
+318     };
+319 
+320     /**
+321      * get string of subject field of certificate.<br/>
+322      * @name getSubjectString
+323      * @memberOf X509#
+324      * @function
+325      * @return {String} subject DN string
+326      * @see X509#getSubject
+327      * @example
+328      * var x = new X509();
+329      * x.readCertPEM(sCertPEM);
+330      * var dn1 = x.getSubjectString(); // return string like "/C=US/O=TEST"
+331      * var dn2 = KJUR.asn1.x509.X500Name.compatToLDAP(dn1); // returns "O=TEST, C=US"
+332      */
+333     this.getSubjectString = function() {
+334 	var pSubject = this.getSubject();
+335 	return pSubject.str;
+336     };
+337 
+338     /**
+339      * get notBefore field string of certificate.<br/>
+340      * @name getNotBefore
+341      * @memberOf X509#
+342      * @function
+343      * @return {String} not before time value (ex. "151231235959Z")
+344      * @example
+345      * var x = new X509();
+346      * x.readCertPEM(sCertPEM);
+347      * var notBefore = x.getNotBefore(); // return string like "151231235959Z"
+348      */
+349     this.getNotBefore = function() {
+350         var s = _getVbyList(this.hex, 0, [0, 4 + this.foffset, 0]);
+351         s = s.replace(/(..)/g, "%$1");
+352         s = decodeURIComponent(s);
+353         return s;
+354     };
+355 
+356     /**
+357      * get notAfter field string of certificate.<br/>
+358      * @name getNotAfter
+359      * @memberOf X509#
+360      * @function
+361      * @return {String} not after time value (ex. "151231235959Z")
+362      * @example
+363      * var x = new X509();
+364      * x.readCertPEM(sCertPEM);
+365      * var notAfter = x.getNotAfter(); // return string like "151231235959Z"
+366      */
+367     this.getNotAfter = function() {
+368 	var s = _getVbyList(this.hex, 0, [0, 4 + this.foffset, 1]);
+369         s = s.replace(/(..)/g, "%$1");
+370         s = decodeURIComponent(s);
+371         return s;
+372     };
+373 
+374     /**
+375      * get a hexadecimal string of subjectPublicKeyInfo field.<br/>
+376      * @name getPublicKeyHex
+377      * @memberOf X509#
+378      * @function
+379      * @return {String} ASN.1 SEQUENCE hexadecimal string of subjectPublicKeyInfo field
+380      * @since jsrsasign 7.1.4 x509 1.1.13
+381      * @example
+382      * x = new X509();
+383      * x.readCertPEM(sCertPEM);
+384      * hSPKI = x.getPublicKeyHex(); // return string like "30820122..."
+385      */
+386     this.getPublicKeyHex = function() {
+387 	return _ASN1HEX.getTLVbyList(this.hex, 0, [0, 6 + this.foffset], "30");
+388     };
+389 
+390     /**
+391      * get a string index of subjectPublicKeyInfo field for hexadecimal string certificate.<br/>
+392      * @name getPublicKeyIdx
+393      * @memberOf X509#
+394      * @function
+395      * @return {Number} string index of subjectPublicKeyInfo field for hexadecimal string certificate.
+396      * @since jsrsasign 7.1.4 x509 1.1.13
+397      * @example
+398      * x = new X509();
+399      * x.readCertPEM(sCertPEM);
+400      * idx = x.getPublicKeyIdx(); // return string index in x.hex parameter
+401      */
+402     this.getPublicKeyIdx = function() {
+403 	return _getIdxbyList(this.hex, 0, [0, 6 + this.foffset], "30");
+404     };
+405 
+406     /**
+407      * get a string index of contents of subjectPublicKeyInfo BITSTRING value from hexadecimal certificate<br/>
+408      * @name getPublicKeyContentIdx
+409      * @memberOf X509#
+410      * @function
+411      * @return {Integer} string index of key contents
+412      * @since jsrsasign 8.0.0 x509 1.2.0
+413      * @example
+414      * x = new X509();
+415      * x.readCertPEM(sCertPEM);
+416      * idx = x.getPublicKeyContentIdx(); // return string index in x.hex parameter
+417      */
+418     // NOTE: Without BITSTRING encapsulation.
+419     this.getPublicKeyContentIdx = function() {
+420 	var idx = this.getPublicKeyIdx();
+421 	return _getIdxbyList(this.hex, idx, [1, 0], "30");
+422     };
+423 
+424     /**
+425      * get a RSAKey/ECDSA/DSA public key object of subjectPublicKeyInfo field.<br/>
+426      * @name getPublicKey
+427      * @memberOf X509#
+428      * @function
+429      * @return {Object} RSAKey/ECDSA/DSA public key object of subjectPublicKeyInfo field
+430      * @since jsrsasign 7.1.4 x509 1.1.13
+431      * @example
+432      * x = new X509();
+433      * x.readCertPEM(sCertPEM);
+434      * pubkey= x.getPublicKey();
+435      */
+436     this.getPublicKey = function() {
+437 	return KEYUTIL.getKey(this.getPublicKeyHex(), null, "pkcs8pub");
+438     };
+439 
+440     /**
+441      * get signature algorithm name from hexadecimal certificate data
+442      * @name getSignatureAlgorithmName
+443      * @memberOf X509#
+444      * @function
+445      * @return {String} signature algorithm name (ex. SHA1withRSA, SHA256withECDSA)
+446      * @since jsrsasign 7.2.0 x509 1.1.14
+447      * @see X509#getAlgorithmIdentifierName
+448      * @description
+449      * This method will get signature algorithm name of certificate:
+450      * @example
+451      * var x = new X509();
+452      * x.readCertPEM(sCertPEM);
+453      * x.getSignatureAlgorithmName() → "SHA256withRSA"
+454      */
+455     this.getSignatureAlgorithmName = function() {
+456 	var hTLV = _getTLVbyList(this.hex, 0, [1], "30");
+457 	return this.getAlgorithmIdentifierName(hTLV);
+458     };
+459 
+460     /**
+461      * get signature value as hexadecimal string<br/>
+462      * @name getSignatureValueHex
+463      * @memberOf X509#
+464      * @function
+465      * @return {String} signature value hexadecimal string without BitString unused bits
+466      * @since jsrsasign 7.2.0 x509 1.1.14
+467      *
+468      * @description
+469      * This method will get signature value of certificate:
+470      *
+471      * @example
+472      * var x = new X509();
+473      * x.readCertPEM(sCertPEM);
+474      * x.getSignatureValueHex() &rarr "8a4c47913..."
+475      */
+476     this.getSignatureValueHex = function() {
+477 	return _getVbyList(this.hex, 0, [2], "03", true);
+478     };
+479 
+480     /**
+481      * verifies signature value by public key<br/>
+482      * @name verifySignature
+483      * @memberOf X509#
+484      * @function
+485      * @param {Object} pubKey public key object
+486      * @return {Boolean} true if signature value is valid otherwise false
+487      * @since jsrsasign 7.2.0 x509 1.1.14
+488      *
+489      * @description
+490      * This method verifies signature value of hexadecimal string of 
+491      * X.509 certificate by specified public key object.
+492      * The signature algorithm used to verify will refer
+493      * signatureAlgorithm field. (See {@link X509#getSignatureAlgorithmField})
+494      * RSA-PSS signature algorithms (SHA{,256,384,512}withRSAandMGF1)
+495      * are available.
+496      *
+497      * @example
+498      * pubKey = KEYUTIL.getKey(pemPublicKey); // or certificate
+499      * x = new X509();
+500      * x.readCertPEM(pemCert);
+501      * x.verifySignature(pubKey) → true, false or raising exception
+502      */
+503     this.verifySignature = function(pubKey) {
+504 	var algName = this.getSignatureAlgorithmField();
+505 	var hSigVal = this.getSignatureValueHex();
+506 	var hTbsCert = _getTLVbyList(this.hex, 0, [0], "30");
+507 	
+508 	var sig = new KJUR.crypto.Signature({alg: algName});
+509 	sig.init(pubKey);
+510 	sig.updateHex(hTbsCert);
+511 	return sig.verify(hSigVal);
+512     };
+513 
+514     // ===== parse extension ======================================
+515     /**
+516      * set array of X.509v3 and CSR extesion information such as extension OID, criticality and value index. (DEPRECATED)<br/>
+517      * @name parseExt
+518      * @memberOf X509#
+519      * @function
+520      * @param {String} hCSR - PEM string of certificate signing requrest(CSR) (OPTION)
+521      * @since jsrsasign 7.2.0 x509 1.1.14
+522      * @deprecated jsrsasign 9.1.1 x509 2.0.1
+523      *
+524      * @description
+525      * This method will set an array of X.509v3 extension information having 
+526      * following parameters:
+527      * <ul>
+528      * <li>oid - extension OID (ex. 2.5.29.19)</li>
+529      * <li>critical - true or false</li>
+530      * <li>vidx - string index for extension value</li>
+531      * <br/>
+532      * When you want to parse extensionRequest of CSR,
+533      * argument 'hCSR' shall be specified.
+534      * <br/>
+535      * NOTE: CSR is supported from jsrsasign 8.0.20 x509 1.1.22.
+536      * <br/>
+537      * This method and X509.aExtInfo property
+538      * have been *deprecated* since jsrsasign 9.1.1.
+539      * All extension parser method such as X509.getExt* shall be
+540      * call with argument "hExtV" and "critical" explicitly.
 541      *
-542      * x.aExtInfo →
-543      * [ { oid: "2.5.29,19", critical: true, vidx: 2504 }, ... ]
-544      *
-545      * // to parse CSR
-546      * X = new X509()
-547      * x.parseExt("-----BEGIN CERTIFICATE REQUEST-----...");
-548      * x.aExtInfo →
-549      * [ { oid: "2.5.29,19", critical: true, vidx: 2504 }, ... ]
-550      */
-551     this.parseExt = function(hCSR) {
-552 	var iExtSeq, aExtIdx, h;
-553 
-554 	if (hCSR === undefined) {
-555 	    h = this.hex;
-556 	    if (this.version !== 3) return -1;
-557 	    iExtSeq = _getIdxbyList(h, 0, [0, 7, 0], "30");
-558 	    aExtIdx = _getChildIdx(h, iExtSeq);
-559 	} else {
-560 	    h = pemtohex(hCSR);
-561 	    var idx1 = _getIdxbyList(h, 0, [0, 3, 0, 0], "06");
-562 
-563 	    if (_getV(h, idx1) != "2a864886f70d01090e") {
-564 		this.aExtInfo = new Array();
-565 		return;
-566 	    }
-567 
-568 	    iExtSeq = _getIdxbyList(h, 0, [0, 3, 0, 1, 0], "30");
-569 	    aExtIdx = _getChildIdx(h, iExtSeq);
-570 
-571 	    this.hex = h;
-572 	}
-573 	    
-574 	this.aExtInfo = new Array();
-575 	for (var i = 0; i < aExtIdx.length; i++) {
-576 	    var item = {};
-577 	    item.critical = false;
-578 	    var a = _getChildIdx(h, aExtIdx[i]);
-579 	    var offset = 0;
-580 
-581 	    if (a.length === 3) {
-582 		item.critical = true;
-583 		offset = 1;
-584 	    }
-585 
-586 	    item.oid = _ASN1HEX.hextooidstr(_getVbyList(h, aExtIdx[i], [0], "06"));
-587 	    var octidx = _getIdxbyList(h, aExtIdx[i], [1 + offset]);
-588 	    item.vidx = _getVidx(h, octidx);
-589 	    this.aExtInfo.push(item);
-590 	}
-591     };
-592 
-593     /**
-594      * get a X.509v3 extesion information such as extension OID, criticality and value index for specified oid or name.<br/>
-595      * @name getExtInfo
-596      * @memberOf X509#
-597      * @function
-598      * @param {String} oidOrName X.509 extension oid or name (ex. keyUsage or 2.5.29.19)
-599      * @return X.509 extension information such as extension OID or value indx (see {@link X509#parseExt})
-600      * @since jsrsasign 7.2.0 x509 1.1.14
-601      * @description
-602      * This method will get an X.509v3 extension information JSON object
-603      * having extension OID, criticality and value idx for specified
-604      * extension OID or name.
-605      * If there is no such extension, this returns undefined.
-606      * @example
-607      * x = new X509();
-608      * x.readCertPEM(sCertPEM); // parseExt() will also be called internally.
-609      *
-610      * x.getExtInfo("keyUsage") → { oid: "2.5.29.15", critical: true, vidx: 1714 }
-611      * x.getExtInfo("unknownExt") → undefined
-612      */
-613     this.getExtInfo = function(oidOrName) {
-614 	var a = this.aExtInfo;
-615 	var oid = oidOrName;
-616 	if (! oidOrName.match(/^[0-9.]+$/)) {
-617 	    oid = KJUR.asn1.x509.OID.name2oid(oidOrName);
-618 	}
-619 	if (oid === '') return undefined;
-620 
-621 	for (var i = 0; i < a.length; i++) {
-622 	    if (a[i].oid === oid) return a[i];
-623 	}
-624 	return undefined;
-625     };
-626 
-627     /**
-628      * get BasicConstraints extension value as object in the certificate
-629      * @name getExtBasicConstraints
-630      * @memberOf X509#
-631      * @function
-632      * @param {String} hExtV hexadecimal string of extension value (OPTIONAL)
-633      * @param {Boolean} critical flag (OPTIONAL)
-634      * @return {Array} JSON object of BasicConstraints parameter or undefined
-635      * @since jsrsasign 7.2.0 x509 1.1.14
-636      * @see KJUR.asn1.x509.BasicConstraints
-637      * @description
-638      * This method will get basic constraints extension value as object with following paramters.
-639      * <ul>
-640      * <li>{Boolean}cA - CA flag whether CA or not</li>
-641      * <li>{Integer}pathLen - maximum intermediate certificate length</li>
-642      * <li>{Boolean}critical - critical flag</li>
-643      * </ul>
-644      * There are use cases for return values:
-645      * <ul>
-646      * <li>{cA:true,pathLen:3,critical:true} - cA flag is true and pathLen is 3</li>
-647      * <li>{cA:true,critical:true} - cA flag is true and no pathLen</li>
-648      * <li>{} - basic constraints has no value in case of end entity certificate</li>
-649      * <li>undefined - there is no basic constraints extension</li>
-650      * </ul>
-651      * @example
-652      * x = new X509();
-653      * x.readCertPEM(sCertPEM); // parseExt() will also be called internally.
-654      * x.getExtBasicConstraints() → {cA:true,pathLen:3,critical:true}
-655      */
-656     this.getExtBasicConstraints = function(hExtV, critical) {
-657 	if (hExtV === undefined && critical === undefined) {
-658 	    var info = this.getExtInfo("basicConstraints");
-659 	    if (info === undefined) return undefined;
-660 	    hExtV = _getTLV(this.hex, info.vidx);
-661 	    critical = info.critical;
-662 	}
-663 
-664 	var result = {extname:"basicConstraints"};
-665 	if (critical) result.critical = true;
-666 
-667 	if (hExtV === '3000') return result;
-668 	if (hExtV === '30030101ff') {
-669 	    result.cA = true;
-670 	    return result;
-671 	}
-672 	if (hExtV.substr(0, 12) === '30060101ff02') {
-673 	    var pathLexHex = _getV(hExtV, 10);
-674 	    var pathLen = parseInt(pathLexHex, 16);
-675 	    result.cA = true;
-676 	    result.pathLen = pathLen;
-677 	    return result;
-678 	}
-679 	throw new Error("hExtV parse error: " + hExtV);
-680     };
-681 
-682     /**
-683      * get KeyUsage extension value as JSON object
-684      * @memberOf X509#
-685      * @function
-686      * @name getExtKeyUsage
-687      * @param {String} hExtV hexadecimal string of extension value (OPTIONAL)
-688      * @param {Boolean} critical flag (OPTIONAL)
-689      * @return {Array} JSON object of KeyUsage parameter or undefined
-690      * @since jsrsasign 9.0.0 x509 2.0.0
-691      * @see KJUR.asn1.x509.KeyUsage
-692      * @see X509#getExtKeyUsageString
-693      * @description
-694      * This method parse keyUsage extension. When arguments are
-695      * not specified, its extension in X509 object will be parsed.
-696      * Result of this method can be passed to 
-697      * {@link KJUR.asn1.x509.KeyUsage} constructor.
-698      * <br>
-699      * When hExtV and critical specified as arguments, return value
-700      * will be generated from them.
-701      * <pre>
-702      * id-ce-keyUsage OBJECT IDENTIFIER ::=  { id-ce 15 }
-703      * KeyUsage ::= BIT STRING {
-704      *      digitalSignature        (0),
-705      *      nonRepudiation          (1),
-706      *      keyEncipherment         (2),
-707      *      dataEncipherment        (3),
-708      *      keyAgreement            (4),
-709      *      keyCertSign             (5),
-710      *      cRLSign                 (6),
-711      *      encipherOnly            (7),
-712      *      decipherOnly            (8) }     
-713      * </pre>
-714      * @example
-715      * x = new X509();
-716      * x.readCertPEM(sCertPEM); // parseExt() will also be called internally.
-717      * x.getExtKeyUsage() →
-718      * {
-719      *   critial: true,
-720      *   names: ["digitalSignature", "decipherOnly"]
-721      * }
-722      *
-723      * x = new X509();
-724      * x.getExtKeyUsage("306230...") 
-725      * x.getExtKeyUsage("306230...", true) 
-726      */
-727     this.getExtKeyUsage = function(hExtV, critical) {
-728 	if (hExtV === undefined && critical === undefined) {
-729 	    var info = this.getExtInfo("keyUsage");
-730 	    if (info === undefined) return undefined;
-731 	    hExtV = _getTLV(this.hex, info.vidx);
-732 	    critical = info.critical;
-733 	}
-734 
-735 	var result = {extname:"keyUsage"};
-736 	if (critical) result.critical = true;
-737 
-738 	result.names = this.getExtKeyUsageString(hExtV).split(",");
-739 
-740 	return result;
-741     };
-742 
-743     /**
-744      * get KeyUsage extension value as binary string in the certificate<br/>
-745      * @name getExtKeyUsageBin
-746      * @memberOf X509#
-747      * @function
-748      * @param {String} hExtV hexadecimal string of extension value (OPTIONAL)
-749      * @return {String} binary string of key usage bits (ex. '101')
-750      * @since jsrsasign 7.2.0 x509 1.1.14
-751      * @see X509#getExtKeyUsage
-752      * @description
-753      * This method will get key usage extension value
-754      * as binary string such like '101'.
-755      * Key usage bits definition is in the RFC 5280.
-756      * If there is no key usage extension in the certificate,
-757      * it returns empty string (i.e. '').
-758      * <br/>
-759      * NOTE: argument 'hExtV' supported since jsrsasign 9.0.0 x509 2.0.0.
-760      * @example
-761      * x = new X509();
-762      * x.readCertPEM(sCertPEM); // parseExt() will also be called internally.
-763      * x.getExtKeyUsageBin() → '101'
-764      * // 1 - digitalSignature
-765      * // 0 - nonRepudiation
-766      * // 1 - keyEncipherment
-767      */
-768     this.getExtKeyUsageBin = function(hExtV) {
-769 	if (hExtV === undefined) {
-770 	    var info = this.getExtInfo("keyUsage");
-771 	    if (info === undefined) return '';
-772 	    hExtV = _getTLV(this.hex, info.vidx);
-773 	}
-774 	
-775 	if (hExtV.length != 8 && hExtV.length != 10)
-776 	    throw new Error("malformed key usage value: " + hExtV);
-777 
-778 	var s = "000000000000000" + parseInt(hExtV.substr(6), 16).toString(2);
-779 	if (hExtV.length == 8) s = s.slice(-8);
-780 	if (hExtV.length == 10) s = s.slice(-16);
-781 	s = s.replace(/0+$/, '');
-782 	if (s == '') s = '0';
-783 	return s;
-784     };
-785 
-786     /**
-787      * get KeyUsage extension value as names in the certificate<br/>
-788      * @name getExtKeyUsageString
-789      * @memberOf X509#
-790      * @function
-791      * @param {String} hExtV hexadecimal string of extension value (OPTIONAL)
-792      * @return {String} comma separated string of key usage
-793      * @since jsrsasign 7.2.0 x509 1.1.14
-794      * @see X509#getExtKeyUsage
-795      * @description
-796      * This method will get key usage extension value
-797      * as comma separated string of usage names.
-798      * If there is no key usage extension in the certificate,
-799      * it returns empty string (i.e. '').
-800      * <br/>
-801      * NOTE: argument 'hExtV' supported since jsrsasign 9.0.0 x509 2.0.0.
-802      * @example
-803      * x = new X509();
-804      * x.readCertPEM(sCertPEM); // parseExt() will also be called internally.
-805      * x.getExtKeyUsageString() → "digitalSignature,keyEncipherment"
-806      */
-807     this.getExtKeyUsageString = function(hExtV) {
-808 	var bKeyUsage = this.getExtKeyUsageBin(hExtV);
-809 	var a = new Array();
-810 	for (var i = 0; i < bKeyUsage.length; i++) {
-811 	    if (bKeyUsage.substr(i, 1) == "1") a.push(X509.KEYUSAGE_NAME[i]);
-812 	}
-813 	return a.join(",");
-814     };
-815 
-816     /**
-817      * get subjectKeyIdentifier value as hexadecimal string in the certificate<br/>
-818      * @name getExtSubjectKeyIdentifier
-819      * @memberOf X509#
-820      * @function
-821      * @param {String} hExtV hexadecimal string of extension value (OPTIONAL)
-822      * @param {Boolean} critical flag (OPTIONAL)
-823      * @return {Array} JSON object of SubjectKeyIdentifier parameter or undefined
-824      * @since jsrsasign 7.2.0 x509 1.1.14
-825      * @description
-826      * This method will get 
-827      * <a href="https://tools.ietf.org/html/rfc5280#section-4.2.1.2">
-828      * SubjectKeyIdentifier extension</a> value as JSON object.
-829      * <br>
-830      * When hExtV and critical specified as arguments, return value
-831      * will be generated from them.
-832      * If there is no such extension in the certificate, it returns undefined.
+542      * @example
+543      * x = new X509();
+544      * x.readCertPEM(sCertPEM); // parseExt() will also be called internally.
+545      *
+546      * x.aExtInfo →
+547      * [ { oid: "2.5.29,19", critical: true, vidx: 2504 }, ... ]
+548      *
+549      * // to parse CSR
+550      * X = new X509()
+551      * x.parseExt("-----BEGIN CERTIFICATE REQUEST-----...");
+552      * x.aExtInfo →
+553      * [ { oid: "2.5.29,19", critical: true, vidx: 2504 }, ... ]
+554      */
+555     this.parseExt = function(hCSR) {
+556 	var iExtSeq, aExtIdx, h;
+557 
+558 	if (hCSR === undefined) {
+559 	    h = this.hex;
+560 	    if (this.version !== 3) return -1;
+561 	    iExtSeq = _getIdxbyList(h, 0, [0, 7, 0], "30");
+562 	    aExtIdx = _getChildIdx(h, iExtSeq);
+563 	} else {
+564 	    h = pemtohex(hCSR);
+565 	    var idx1 = _getIdxbyList(h, 0, [0, 3, 0, 0], "06");
+566 
+567 	    if (_getV(h, idx1) != "2a864886f70d01090e") {
+568 		this.aExtInfo = new Array();
+569 		return;
+570 	    }
+571 
+572 	    iExtSeq = _getIdxbyList(h, 0, [0, 3, 0, 1, 0], "30");
+573 	    aExtIdx = _getChildIdx(h, iExtSeq);
+574 
+575 	    this.hex = h;
+576 	}
+577 	    
+578 	this.aExtInfo = new Array();
+579 	for (var i = 0; i < aExtIdx.length; i++) {
+580 	    var item = {};
+581 	    item.critical = false;
+582 	    var a = _getChildIdx(h, aExtIdx[i]);
+583 	    var offset = 0;
+584 
+585 	    if (a.length === 3) {
+586 		item.critical = true;
+587 		offset = 1;
+588 	    }
+589 
+590 	    item.oid = _ASN1HEX.hextooidstr(_getVbyList(h, aExtIdx[i], [0], "06"));
+591 	    var octidx = _getIdxbyList(h, aExtIdx[i], [1 + offset]);
+592 	    item.vidx = _getVidx(h, octidx);
+593 	    this.aExtInfo.push(item);
+594 	}
+595     };
+596 
+597     /**
+598      * get a X.509v3 extesion information such as extension OID, criticality and value index for specified oid or name.<br/>
+599      * @name getExtInfo
+600      * @memberOf X509#
+601      * @function
+602      * @param {String} oidOrName X.509 extension oid or name (ex. keyUsage or 2.5.29.19)
+603      * @return X.509 extension information such as extension OID or value indx (see {@link X509#parseExt})
+604      * @since jsrsasign 7.2.0 x509 1.1.14
+605      * @description
+606      * This method will get an X.509v3 extension information JSON object
+607      * having extension OID, criticality and value idx for specified
+608      * extension OID or name.
+609      * If there is no such extension, this returns undefined.
+610      * @example
+611      * x = new X509();
+612      * x.readCertPEM(sCertPEM); // parseExt() will also be called internally.
+613      *
+614      * x.getExtInfo("keyUsage") → { oid: "2.5.29.15", critical: true, vidx: 1714 }
+615      * x.getExtInfo("unknownExt") → undefined
+616      */
+617     this.getExtInfo = function(oidOrName) {
+618 	var a = this.aExtInfo;
+619 	var oid = oidOrName;
+620 	if (! oidOrName.match(/^[0-9.]+$/)) {
+621 	    oid = KJUR.asn1.x509.OID.name2oid(oidOrName);
+622 	}
+623 	if (oid === '') return undefined;
+624 
+625 	for (var i = 0; i < a.length; i++) {
+626 	    if (a[i].oid === oid) return a[i];
+627 	}
+628 	return undefined;
+629     };
+630 
+631     /**
+632      * get BasicConstraints extension value as object in the certificate
+633      * @name getExtBasicConstraints
+634      * @memberOf X509#
+635      * @function
+636      * @param {String} hExtV hexadecimal string of extension value (OPTIONAL)
+637      * @param {Boolean} critical flag (OPTIONAL)
+638      * @return {Array} JSON object of BasicConstraints parameter or undefined
+639      * @since jsrsasign 7.2.0 x509 1.1.14
+640      * @see KJUR.asn1.x509.BasicConstraints
+641      * @description
+642      * This method will get basic constraints extension value as object with following paramters.
+643      * <ul>
+644      * <li>{Boolean}cA - CA flag whether CA or not</li>
+645      * <li>{Integer}pathLen - maximum intermediate certificate length</li>
+646      * <li>{Boolean}critical - critical flag</li>
+647      * </ul>
+648      * There are use cases for return values:
+649      * <ul>
+650      * <li>{cA:true,pathLen:3,critical:true} - cA flag is true and pathLen is 3</li>
+651      * <li>{cA:true,critical:true} - cA flag is true and no pathLen</li>
+652      * <li>{} - basic constraints has no value in case of end entity certificate</li>
+653      * <li>undefined - there is no basic constraints extension</li>
+654      * </ul>
+655      * @example
+656      * x = new X509();
+657      * x.readCertPEM(sCertPEM); // parseExt() will also be called internally.
+658      * x.getExtBasicConstraints() → {cA:true,pathLen:3,critical:true}
+659      */
+660     this.getExtBasicConstraints = function(hExtV, critical) {
+661 	if (hExtV === undefined && critical === undefined) {
+662 	    var info = this.getExtInfo("basicConstraints");
+663 	    if (info === undefined) return undefined;
+664 	    hExtV = _getTLV(this.hex, info.vidx);
+665 	    critical = info.critical;
+666 	}
+667 
+668 	var result = {extname:"basicConstraints"};
+669 	if (critical) result.critical = true;
+670 
+671 	if (hExtV === '3000') return result;
+672 	if (hExtV === '30030101ff') {
+673 	    result.cA = true;
+674 	    return result;
+675 	}
+676 	if (hExtV.substr(0, 12) === '30060101ff02') {
+677 	    var pathLexHex = _getV(hExtV, 10);
+678 	    var pathLen = parseInt(pathLexHex, 16);
+679 	    result.cA = true;
+680 	    result.pathLen = pathLen;
+681 	    return result;
+682 	}
+683 	throw new Error("hExtV parse error: " + hExtV);
+684     };
+685 
+686     /**
+687      * get KeyUsage extension value as JSON object
+688      * @memberOf X509#
+689      * @function
+690      * @name getExtKeyUsage
+691      * @param {String} hExtV hexadecimal string of extension value (OPTIONAL)
+692      * @param {Boolean} critical flag (OPTIONAL)
+693      * @return {Array} JSON object of KeyUsage parameter or undefined
+694      * @since jsrsasign 9.0.0 x509 2.0.0
+695      * @see KJUR.asn1.x509.KeyUsage
+696      * @see X509#getExtKeyUsageString
+697      * @description
+698      * This method parse keyUsage extension. When arguments are
+699      * not specified, its extension in X509 object will be parsed.
+700      * Result of this method can be passed to 
+701      * {@link KJUR.asn1.x509.KeyUsage} constructor.
+702      * <br>
+703      * When hExtV and critical specified as arguments, return value
+704      * will be generated from them.
+705      * <pre>
+706      * id-ce-keyUsage OBJECT IDENTIFIER ::=  { id-ce 15 }
+707      * KeyUsage ::= BIT STRING {
+708      *      digitalSignature        (0),
+709      *      nonRepudiation          (1),
+710      *      keyEncipherment         (2),
+711      *      dataEncipherment        (3),
+712      *      keyAgreement            (4),
+713      *      keyCertSign             (5),
+714      *      cRLSign                 (6),
+715      *      encipherOnly            (7),
+716      *      decipherOnly            (8) }     
+717      * </pre>
+718      * @example
+719      * x = new X509();
+720      * x.readCertPEM(sCertPEM); // parseExt() will also be called internally.
+721      * x.getExtKeyUsage() →
+722      * {
+723      *   critial: true,
+724      *   names: ["digitalSignature", "decipherOnly"]
+725      * }
+726      *
+727      * x = new X509();
+728      * x.getExtKeyUsage("306230...") 
+729      * x.getExtKeyUsage("306230...", true) 
+730      */
+731     this.getExtKeyUsage = function(hExtV, critical) {
+732 	if (hExtV === undefined && critical === undefined) {
+733 	    var info = this.getExtInfo("keyUsage");
+734 	    if (info === undefined) return undefined;
+735 	    hExtV = _getTLV(this.hex, info.vidx);
+736 	    critical = info.critical;
+737 	}
+738 
+739 	var result = {extname:"keyUsage"};
+740 	if (critical) result.critical = true;
+741 
+742 	result.names = this.getExtKeyUsageString(hExtV).split(",");
+743 
+744 	return result;
+745     };
+746 
+747     /**
+748      * get KeyUsage extension value as binary string in the certificate<br/>
+749      * @name getExtKeyUsageBin
+750      * @memberOf X509#
+751      * @function
+752      * @param {String} hExtV hexadecimal string of extension value (OPTIONAL)
+753      * @return {String} binary string of key usage bits (ex. '101')
+754      * @since jsrsasign 7.2.0 x509 1.1.14
+755      * @see X509#getExtKeyUsage
+756      * @description
+757      * This method will get key usage extension value
+758      * as binary string such like '101'.
+759      * Key usage bits definition is in the RFC 5280.
+760      * If there is no key usage extension in the certificate,
+761      * it returns empty string (i.e. '').
+762      * <br/>
+763      * NOTE: argument 'hExtV' supported since jsrsasign 9.0.0 x509 2.0.0.
+764      * @example
+765      * x = new X509();
+766      * x.readCertPEM(sCertPEM); // parseExt() will also be called internally.
+767      * x.getExtKeyUsageBin() → '101'
+768      * // 1 - digitalSignature
+769      * // 0 - nonRepudiation
+770      * // 1 - keyEncipherment
+771      */
+772     this.getExtKeyUsageBin = function(hExtV) {
+773 	if (hExtV === undefined) {
+774 	    var info = this.getExtInfo("keyUsage");
+775 	    if (info === undefined) return '';
+776 	    hExtV = _getTLV(this.hex, info.vidx);
+777 	}
+778 	
+779 	if (hExtV.length != 8 && hExtV.length != 10)
+780 	    throw new Error("malformed key usage value: " + hExtV);
+781 
+782 	var s = "000000000000000" + parseInt(hExtV.substr(6), 16).toString(2);
+783 	if (hExtV.length == 8) s = s.slice(-8);
+784 	if (hExtV.length == 10) s = s.slice(-16);
+785 	s = s.replace(/0+$/, '');
+786 	if (s == '') s = '0';
+787 	return s;
+788     };
+789 
+790     /**
+791      * get KeyUsage extension value as names in the certificate<br/>
+792      * @name getExtKeyUsageString
+793      * @memberOf X509#
+794      * @function
+795      * @param {String} hExtV hexadecimal string of extension value (OPTIONAL)
+796      * @return {String} comma separated string of key usage
+797      * @since jsrsasign 7.2.0 x509 1.1.14
+798      * @see X509#getExtKeyUsage
+799      * @description
+800      * This method will get key usage extension value
+801      * as comma separated string of usage names.
+802      * If there is no key usage extension in the certificate,
+803      * it returns empty string (i.e. '').
+804      * <br/>
+805      * NOTE: argument 'hExtV' supported since jsrsasign 9.0.0 x509 2.0.0.
+806      * @example
+807      * x = new X509();
+808      * x.readCertPEM(sCertPEM); // parseExt() will also be called internally.
+809      * x.getExtKeyUsageString() → "digitalSignature,keyEncipherment"
+810      */
+811     this.getExtKeyUsageString = function(hExtV) {
+812 	var bKeyUsage = this.getExtKeyUsageBin(hExtV);
+813 	var a = new Array();
+814 	for (var i = 0; i < bKeyUsage.length; i++) {
+815 	    if (bKeyUsage.substr(i, 1) == "1") a.push(X509.KEYUSAGE_NAME[i]);
+816 	}
+817 	return a.join(",");
+818     };
+819 
+820     /**
+821      * get subjectKeyIdentifier value as hexadecimal string in the certificate<br/>
+822      * @name getExtSubjectKeyIdentifier
+823      * @memberOf X509#
+824      * @function
+825      * @param {String} hExtV hexadecimal string of extension value (OPTIONAL)
+826      * @param {Boolean} critical flag (OPTIONAL)
+827      * @return {Array} JSON object of SubjectKeyIdentifier parameter or undefined
+828      * @since jsrsasign 7.2.0 x509 1.1.14
+829      * @description
+830      * This method will get 
+831      * <a href="https://tools.ietf.org/html/rfc5280#section-4.2.1.2">
+832      * SubjectKeyIdentifier extension</a> value as JSON object.
 833      * <br>
-834      * Result of this method can be passed to 
-835      * {@link KJUR.asn1.x509.SubjectKeyIdentifier} constructor.
-836      * <pre>
-837      * id-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::=  { id-ce 14 }
-838      * SubjectKeyIdentifier ::= KeyIdentifier
-839      * </pre>
-840      * <br>
-841      * CAUTION:
-842      * Returned JSON value format have been changed without 
-843      * backward compatibility since jsrsasign 9.0.0 x509 2.0.0.
-844      *
-845      * @example
-846      * x = new X509();
-847      * x.readCertPEM(sCertPEM); // parseExt() will also be called internally.
-848      * x.getExtSubjectKeyIdentifier() → 
-849      * { kid: {hex: "1b3347ab..."}, critical: true };
-850      */
-851     this.getExtSubjectKeyIdentifier = function(hExtV, critical) {
-852 	if (hExtV === undefined && critical === undefined) {
-853 	    var info = this.getExtInfo("subjectKeyIdentifier");
-854 	    if (info === undefined) return undefined;
-855 	    hExtV = _getTLV(this.hex, info.vidx);
-856 	    critical = info.critical;
-857 	}
-858 
-859 	var result = {extname:"subjectKeyIdentifier"};
-860 	if (critical) result.critical = true;
-861 
-862 	var hKID = _getV(hExtV, 0);
-863 	result.kid = {hex: hKID};
-864 
-865 	return result;
-866     };
-867 
-868     /**
-869      * get authorityKeyIdentifier value as JSON object in the certificate<br/>
-870      * @name getExtAuthorityKeyIdentifier
-871      * @memberOf X509#
-872      * @function
-873      * @param {String} hExtV hexadecimal string of extension value (OPTIONAL)
-874      * @param {Boolean} critical flag (OPTIONAL)
-875      * @return {Array} JSON object of AuthorityKeyIdentifier parameter or undefined
-876      * @since jsrsasign 7.2.0 x509 1.1.14
-877      * @see KJUR.asn1.x509.AuthorityKeyIdentifier
-878      * @description
-879      * This method will get 
-880      * <a href="https://tools.ietf.org/html/rfc5280#section-4.2.1.1">
-881      * AuthorityKeyIdentifier extension</a> value as JSON object.
-882      * <br>
-883      * When hExtV and critical specified as arguments, return value
-884      * will be generated from them.
-885      * If there is no such extension in the certificate, it returns undefined.
-886      * <br/>
-887      * Result of this method can be passed to 
-888      * {@link KJUR.asn1.x509.AuthorityKeyIdentifier} constructor.
-889      * <pre>
-890      *    id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::=  { id-ce 35 }
-891      *    AuthorityKeyIdentifier ::= SEQUENCE {
-892      *       keyIdentifier             [0] KeyIdentifier           OPTIONAL,
-893      *       authorityCertIssuer       [1] GeneralNames            OPTIONAL,
-894      *       authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL  }
-895      *    KeyIdentifier ::= OCTET STRING
-896      * </pre>
-897      * Constructor may have following parameters:
-898      * <ul>
-899      * <li>{Array}kid - JSON object of {@link KJUR.asn1.DEROctetString} parameters</li>
-900      * <li>{Array}issuer - JSON object of {@link KJUR.asn1.x509.X500Name} parameters</li>
-901      * <li>{Array}sn - JSON object of {@link KJUR.asn1.DERInteger} parameters</li>
-902      * <li>{Boolean}critical - critical flag</li>
-903      * </ul>
-904      * <br>
-905      * NOTE: The 'authorityCertIssuer' and 'authorityCertSerialNumber'
-906      * supported since jsrsasign 9.0.0 x509 2.0.0.
-907      * @example
-908      * x = new X509();
-909      * x.readCertPEM(sCertPEM); // parseExt() will also be called internally.
-910      * x.getExtAuthorityKeyIdentifier() → 
-911      * { kid: {hex: "1234abcd..."},
-912      *   issuer: {hex: "30..."},
-913      *   sn: {hex: "1234..."},
-914      *   critical: true}
-915      */
-916     this.getExtAuthorityKeyIdentifier = function(hExtV, critical) {
-917 	if (hExtV === undefined && critical === undefined) {
-918 	    var info = this.getExtInfo("authorityKeyIdentifier");
-919 	    if (info === undefined) return undefined;
-920 	    hExtV = _getTLV(this.hex, info.vidx);
-921 	    critical = info.critical;
-922 	}
-923 
-924 	var result = {extname:"authorityKeyIdentifier"};
-925 	if (critical) result.critical = true;
-926 
-927 	var a = _getChildIdx(hExtV, 0);
-928 	for (var i = 0; i < a.length; i++) {
-929 	    var tag = hExtV.substr(a[i], 2);
-930 	    if (tag === "80") {
-931 		result.kid = {hex: _getV(hExtV, a[i])};
-932 	    }
-933 	    if (tag === "a1") {
-934 		var hGNS = _getTLV(hExtV, a[i]);
-935 		var gnsParam = this.getGeneralNames(hGNS);
-936 		result.issuer = gnsParam[0]["dn"];
-937 	    }
-938 	    if (tag === "82") {
-939 		result.sn = {hex: _getV(hExtV, a[i])};
-940 	    }
-941 	}
-942 	return result;
-943     };
-944 
-945     /**
-946      * get extKeyUsage value as JSON object
-947      * @name getExtExtKeyUsage
-948      * @memberOf X509#
-949      * @function
-950      * @param {String} hExtV hexadecimal string of extension value (OPTIONAL)
-951      * @param {Boolean} critical flag (OPTIONAL)
-952      * @return {Array} JSON object of ExtKeyUsage parameter or undefined
-953      * @return {Object} JSONarray of extended key usage ID name or oid
-954      * @since jsrsasign 9.0.0 x509 2.0.0
-955      * @see KJUR.asn1.x509.ExtKeyUsage
-956      * @description
-957      * This method parse extKeyUsage extension. When arguments are
-958      * not specified, its extension in X509 object will be parsed.
-959      * Result of this method can be passed to 
-960      * {@link KJUR.asn1.x509.ExtKeyUsage} constructor.
-961      * <br>
-962      * When hExtV and critical specified as arguments, return value
-963      * will be generated from them.
-964      * @example
-965      * x = new X509();
-966      * x.readCertPEM(sCertPEM); // parseExt() will also be called internally.
-967      * x.getExtExtKeyUsage() →
-968      * { array: ["clientAuth", "emailProtection", "1.3.6.1.4.1.311.10.3.4"], 
-969      *   critical: true},
-970      */
-971     this.getExtExtKeyUsage = function(hExtV, critical) {
-972 	if (hExtV === undefined && critical === undefined) {
-973 	    var info = this.getExtInfo("extKeyUsage");
-974 	    if (info === undefined) return undefined;
-975 	    hExtV = _getTLV(this.hex, info.vidx);
-976 	    critical = info.critical;
-977 	}
-978 
-979 	var result = {extname:"extKeyUsage",array:[]};
-980 	if (critical) result.critical = true;
-981 
-982 	var a = _getChildIdx(hExtV, 0);
-983 
-984 	for (var i = 0; i < a.length; i++) {
-985 	    result.array.push(_oidname(_getV(hExtV, a[i])));
-986 	}
+834      * When hExtV and critical specified as arguments, return value
+835      * will be generated from them.
+836      * If there is no such extension in the certificate, it returns undefined.
+837      * <br>
+838      * Result of this method can be passed to 
+839      * {@link KJUR.asn1.x509.SubjectKeyIdentifier} constructor.
+840      * <pre>
+841      * id-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::=  { id-ce 14 }
+842      * SubjectKeyIdentifier ::= KeyIdentifier
+843      * </pre>
+844      * <br>
+845      * CAUTION:
+846      * Returned JSON value format have been changed without 
+847      * backward compatibility since jsrsasign 9.0.0 x509 2.0.0.
+848      *
+849      * @example
+850      * x = new X509();
+851      * x.readCertPEM(sCertPEM); // parseExt() will also be called internally.
+852      * x.getExtSubjectKeyIdentifier() → 
+853      * { kid: {hex: "1b3347ab..."}, critical: true };
+854      */
+855     this.getExtSubjectKeyIdentifier = function(hExtV, critical) {
+856 	if (hExtV === undefined && critical === undefined) {
+857 	    var info = this.getExtInfo("subjectKeyIdentifier");
+858 	    if (info === undefined) return undefined;
+859 	    hExtV = _getTLV(this.hex, info.vidx);
+860 	    critical = info.critical;
+861 	}
+862 
+863 	var result = {extname:"subjectKeyIdentifier"};
+864 	if (critical) result.critical = true;
+865 
+866 	var hKID = _getV(hExtV, 0);
+867 	result.kid = {hex: hKID};
+868 
+869 	return result;
+870     };
+871 
+872     /**
+873      * get authorityKeyIdentifier value as JSON object in the certificate<br/>
+874      * @name getExtAuthorityKeyIdentifier
+875      * @memberOf X509#
+876      * @function
+877      * @param {String} hExtV hexadecimal string of extension value (OPTIONAL)
+878      * @param {Boolean} critical flag (OPTIONAL)
+879      * @return {Array} JSON object of AuthorityKeyIdentifier parameter or undefined
+880      * @since jsrsasign 7.2.0 x509 1.1.14
+881      * @see KJUR.asn1.x509.AuthorityKeyIdentifier
+882      * @description
+883      * This method will get 
+884      * <a href="https://tools.ietf.org/html/rfc5280#section-4.2.1.1">
+885      * AuthorityKeyIdentifier extension</a> value as JSON object.
+886      * <br>
+887      * When hExtV and critical specified as arguments, return value
+888      * will be generated from them.
+889      * If there is no such extension in the certificate, it returns undefined.
+890      * <br/>
+891      * Result of this method can be passed to 
+892      * {@link KJUR.asn1.x509.AuthorityKeyIdentifier} constructor.
+893      * <pre>
+894      *    id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::=  { id-ce 35 }
+895      *    AuthorityKeyIdentifier ::= SEQUENCE {
+896      *       keyIdentifier             [0] KeyIdentifier           OPTIONAL,
+897      *       authorityCertIssuer       [1] GeneralNames            OPTIONAL,
+898      *       authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL  }
+899      *    KeyIdentifier ::= OCTET STRING
+900      * </pre>
+901      * Constructor may have following parameters:
+902      * <ul>
+903      * <li>{Array}kid - JSON object of {@link KJUR.asn1.DEROctetString} parameters</li>
+904      * <li>{Array}issuer - JSON object of {@link KJUR.asn1.x509.X500Name} parameters</li>
+905      * <li>{Array}sn - JSON object of {@link KJUR.asn1.DERInteger} parameters</li>
+906      * <li>{Boolean}critical - critical flag</li>
+907      * </ul>
+908      * <br>
+909      * NOTE: The 'authorityCertIssuer' and 'authorityCertSerialNumber'
+910      * supported since jsrsasign 9.0.0 x509 2.0.0.
+911      * @example
+912      * x = new X509();
+913      * x.readCertPEM(sCertPEM); // parseExt() will also be called internally.
+914      * x.getExtAuthorityKeyIdentifier() → 
+915      * { kid: {hex: "1234abcd..."},
+916      *   issuer: {hex: "30..."},
+917      *   sn: {hex: "1234..."},
+918      *   critical: true}
+919      */
+920     this.getExtAuthorityKeyIdentifier = function(hExtV, critical) {
+921 	if (hExtV === undefined && critical === undefined) {
+922 	    var info = this.getExtInfo("authorityKeyIdentifier");
+923 	    if (info === undefined) return undefined;
+924 	    hExtV = _getTLV(this.hex, info.vidx);
+925 	    critical = info.critical;
+926 	}
+927 
+928 	var result = {extname:"authorityKeyIdentifier"};
+929 	if (critical) result.critical = true;
+930 
+931 	var a = _getChildIdx(hExtV, 0);
+932 	for (var i = 0; i < a.length; i++) {
+933 	    var tag = hExtV.substr(a[i], 2);
+934 	    if (tag === "80") {
+935 		result.kid = {hex: _getV(hExtV, a[i])};
+936 	    }
+937 	    if (tag === "a1") {
+938 		var hGNS = _getTLV(hExtV, a[i]);
+939 		var gnsParam = this.getGeneralNames(hGNS);
+940 		result.issuer = gnsParam[0]["dn"];
+941 	    }
+942 	    if (tag === "82") {
+943 		result.sn = {hex: _getV(hExtV, a[i])};
+944 	    }
+945 	}
+946 	return result;
+947     };
+948 
+949     /**
+950      * get extKeyUsage value as JSON object
+951      * @name getExtExtKeyUsage
+952      * @memberOf X509#
+953      * @function
+954      * @param {String} hExtV hexadecimal string of extension value (OPTIONAL)
+955      * @param {Boolean} critical flag (OPTIONAL)
+956      * @return {Array} JSON object of ExtKeyUsage parameter or undefined
+957      * @return {Object} JSONarray of extended key usage ID name or oid
+958      * @since jsrsasign 9.0.0 x509 2.0.0
+959      * @see KJUR.asn1.x509.ExtKeyUsage
+960      * @description
+961      * This method parse extKeyUsage extension. When arguments are
+962      * not specified, its extension in X509 object will be parsed.
+963      * Result of this method can be passed to 
+964      * {@link KJUR.asn1.x509.ExtKeyUsage} constructor.
+965      * <br>
+966      * When hExtV and critical specified as arguments, return value
+967      * will be generated from them.
+968      * @example
+969      * x = new X509();
+970      * x.readCertPEM(sCertPEM); // parseExt() will also be called internally.
+971      * x.getExtExtKeyUsage() →
+972      * { array: ["clientAuth", "emailProtection", "1.3.6.1.4.1.311.10.3.4"], 
+973      *   critical: true},
+974      */
+975     this.getExtExtKeyUsage = function(hExtV, critical) {
+976 	if (hExtV === undefined && critical === undefined) {
+977 	    var info = this.getExtInfo("extKeyUsage");
+978 	    if (info === undefined) return undefined;
+979 	    hExtV = _getTLV(this.hex, info.vidx);
+980 	    critical = info.critical;
+981 	}
+982 
+983 	var result = {extname:"extKeyUsage",array:[]};
+984 	if (critical) result.critical = true;
+985 
+986 	var a = _getChildIdx(hExtV, 0);
 987 
-988 	return result;
-989     };
-990 
-991     /**
-992      * get extKeyUsage value as array of name string in the certificate(DEPRECATED)<br/>
-993      * @name getExtExtKeyUsageName
-994      * @memberOf X509#
-995      * @function
-996      * @return {Object} array of extended key usage ID name or oid
-997      * @since jsrsasign 7.2.0 x509 1.1.14
-998      * @deprecated since jsrsasign 9.0.0 x509 2.0.0
-999      * @description
-1000      * This method will get extended key usage extension value
-1001      * as array of name or OID string.
-1002      * If there is this in the certificate, it returns undefined;
-1003      * <br>
-1004      * NOTE: Supported extended key usage ID names are defined in
-1005      * name2oidList parameter in asn1x509.js file.
-1006      * @example
-1007      * x = new X509();
-1008      * x.readCertPEM(sCertPEM); // parseExt() will also be called internally.
-1009      * x.getExtExtKeyUsageName() → ["serverAuth", "clientAuth", "0.1.2.3.4.5"]
-1010      */
-1011     this.getExtExtKeyUsageName = function() {
-1012 	var info = this.getExtInfo("extKeyUsage");
-1013 	if (info === undefined) return info;
-1014 
-1015 	var result = new Array();
-1016 	
-1017 	var h = _getTLV(this.hex, info.vidx);
-1018 	if (h === '') return result;
-1019 
-1020 	var a = _getChildIdx(h, 0);
-1021 	for (var i = 0; i < a.length; i++) {
-1022 	    result.push(_oidname(_getV(h, a[i])));
-1023 	}
-1024 
-1025 	return result;
-1026     };
-1027 
-1028     /**
-1029      * get subjectAltName value as array of string in the certificate
-1030      * @name getExtSubjectAltName
-1031      * @memberOf X509#
-1032      * @function
-1033      * @param {String} hExtV hexadecimal string of extension value (OPTIONAL)
-1034      * @param {Boolean} critical flag (OPTIONAL)
-1035      * @return {Array} JSON object of SubjectAltName parameters or undefined
-1036      * @since jsrsasign 7.2.0 x509 1.1.14
-1037      * @see KJUR.asn1.x509.SubjectAltName
-1038      * @see X509#getExtIssuerAltName
-1039      * @description
-1040      * This method will get subjectAltName value
-1041      * as an array of JSON object which has properties defined
-1042      * in {@link KJUR.asn1.x509.SubjectAltName}.
-1043      * Result of this method can be passed to 
-1044      * {@link KJUR.asn1.x509.SubjectAltName} constructor.
-1045      * If there is no this extension in the certificate,
-1046      * it returns undefined.
-1047      * <br>
-1048      * When hExtV and critical specified as arguments, return value
-1049      * will be generated from them.
-1050      * <br>
-1051      * CAUTION: return value of JSON object format have been changed
-1052      * from jsrsasign 9.0.0 x509 2.0.0 without backword compatibility.
-1053      * @example
-1054      * x = new X509();
-1055      * x.readCertPEM(sCertPEM); // parseExt() will also be called internally.
-1056      * x.getExtSubjectAltName() → 
-1057      * { array: [
-1058      *     {uri: "http://example.com/"},
-1059      *     {rfc822: "user1@example.com"},
-1060      *     {dns: "example.com"}
-1061      *   ],
-1062      *   critical: true
-1063      * }
-1064      *
-1065      * x.getExtSubjectAltName("3026...") →
-1066      * { array: [{ip: "192.168.1.1"}] }
-1067      */
-1068     this.getExtSubjectAltName = function(hExtV, critical) {
-1069 	if (hExtV === undefined && critical === undefined) {
-1070 	    var info = this.getExtInfo("subjectAltName");
-1071 	    if (info === undefined) return undefined;
-1072 	    hExtV = _getTLV(this.hex, info.vidx);
-1073 	    critical = info.critical;
-1074 	}
-1075 
-1076 	var result = {extname:"subjectAltName",array:[]};
-1077 	if (critical) result.critical = true;
-1078 
-1079 	result.array = this.getGeneralNames(hExtV);
-1080 
-1081 	return result;
-1082     };
-1083 
-1084     /**
-1085      * get issuerAltName value as array of string in the certificate
-1086      * @name getExtIssuerAltName
-1087      * @memberOf X509#
-1088      * @function
-1089      * @param {String} hExtV hexadecimal string of extension value (OPTIONAL)
-1090      * @param {Boolean} critical flag (OPTIONAL)
-1091      * @return {Array} JSON object of IssuerAltName parameters
-1092      * @since jsrsasign 9.0.0 x509 2.0.0
-1093      * @see KJUR.asn1.x509.IssuerAltName
-1094      * @see X509#getExtSubjectAltName
-1095      * @description
-1096      * This method will get issuerAltName value
-1097      * as an array of JSON object which has properties defined
-1098      * in {@link KJUR.asn1.x509.IssuerAltName}.
-1099      * Result of this method can be passed to 
-1100      * {@link KJUR.asn1.x509.IssuerAltName} constructor.
-1101      * If there is no this extension in the certificate,
-1102      * it returns undefined.
-1103      * <br>
-1104      * When hExtV and critical specified as arguments, return value
-1105      * will be generated from them.
-1106      * @example
-1107      * x = new X509();
-1108      * x.readCertPEM(sCertPEM); // parseExt() will also be called internally.
-1109      * x.getExtIssuerAltName() → 
-1110      * { array: [
-1111      *     {uri: "http://example.com/"},
-1112      *     {rfc822: "user1@example.com"},
-1113      *     {dns: "example.com"}
-1114      *   ],
-1115      *   critical: true
-1116      * }
-1117      *
-1118      * x.getExtIssuerAltName("3026...") →
-1119      * { array: [{ip: "192.168.1.1"}] }
-1120      */
-1121     this.getExtIssuerAltName = function(hExtV, critical) {
-1122 	if (hExtV === undefined && critical === undefined) {
-1123 	    var info = this.getExtInfo("issuerAltName");
-1124 	    if (info === undefined) return undefined;
-1125 	    hExtV = _getTLV(this.hex, info.vidx);
-1126 	    critical = info.critical;
-1127 	}
-1128 
-1129 	var result = {extname:"issuerAltName",array:[]};
-1130 	if (critical) result.critical = true;
-1131 
-1132 	result.array = this.getGeneralNames(hExtV);
-1133 
-1134 	return result;
-1135     };
-1136 
-1137     /**
-1138      * get GeneralNames ASN.1 structure parameter as JSON object
-1139      * @name getGeneralNames
-1140      * @memberOf X509#
-1141      * @function
-1142      * @param {String} h hexadecimal string of GeneralNames
-1143      * @return {Array} array of GeneralNames parameters
-1144      * @see KJUR.asn1.x509.GeneralNames
-1145      * @see KJUR.asn1.x509.GeneralName
-1146      * @see X509#getGeneralNames
-1147      * @since jsrsasign 9.0.0 x509 2.0.0
-1148      * @description
-1149      * This method will get GeneralNames parameters defined in
-1150      * <a href="https://tools.ietf.org/html/rfc5280#section-4.2.1.6">
-1151      * RFC 5280 4.2.1.6</a>.
-1152      * <pre>
-1153      * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
-1154      * </pre>
-1155      * Result of this method can be passed to
-1156      * {@link KJUR.asn1.x509.GeneralNames} constructor.
-1157      * @example
-1158      * x = new X509();
-1159      * x.getGeneralNames("3011860f687474703a2f2f6161612e636f6d2f")
-1160      * → [{uri: "http://aaa.com/"}]
-1161      *
-1162      * x.getGeneralNames("301ea41c30...") →
-1163      * [{ dn: {
-1164      *     array: [
-1165      *       [{type:"C", value:"JP", ds:"prn"}],
-1166      *       [{type:"O", value:"T1", ds:"utf8"}]
-1167      *     ],
-1168      *     str: "/C=JP/O=T1" } }]
-1169      */
-1170     this.getGeneralNames = function(h) {
-1171 	var aIdx = _getChildIdx(h, 0);
-1172 	var result = [];
-1173 	for (var i = 0; i < aIdx.length; i++) {
-1174 	    var gnParam = this.getGeneralName(_getTLV(h, aIdx[i]));
-1175 	    if (gnParam !== undefined) result.push(gnParam);
-1176 	}
-1177 	return result;
-1178     };
-1179 
-1180     /**
-1181      * get GeneralName ASN.1 structure parameter as JSON object
-1182      * @name getGeneralName
-1183      * @memberOf X509#
-1184      * @function
-1185      * @param {String} h hexadecimal string of GeneralName
-1186      * @return {Array} JSON object of GeneralName parameters or undefined
-1187      * @see KJUR.asn1.x509.GeneralNames
-1188      * @see X509#getGeneralName
-1189      * @since jsrsasign 9.0.0 x509 2.0.0
-1190      * @description
-1191      * This method will get GeneralName parameters defined in
-1192      * <a href="https://tools.ietf.org/html/rfc5280#section-4.2.1.6">
-1193      * RFC 5280 4.2.1.6</a>.
-1194      * <pre>
-1195      * GeneralName ::= CHOICE {
-1196      *      otherName                       [0]     OtherName,
-1197      *      rfc822Name                      [1]     IA5String,
-1198      *      dNSName                         [2]     IA5String,
-1199      *      x400Address                     [3]     ORAddress,
-1200      *      directoryName                   [4]     Name,
-1201      *      ediPartyName                    [5]     EDIPartyName,
-1202      *      uniformResourceIdentifier       [6]     IA5String,
-1203      *      iPAddress                       [7]     OCTET STRING,
-1204      *      registeredID                    [8]     OBJECT IDENTIFIER }
-1205      * </pre>
-1206      * Result of this method can be passed to
-1207      * {@link KJUR.asn1.x509.GeneralName} constructor.
-1208      * @example
-1209      * x = new X509();
-1210      * x.getGeneralName("860f687474703a2f2f6161612e636f6d2f") 
-1211      * → {uri: "http://aaa.com/"}
-1212      * x.getGeneralName("a41c30...") →
-1213      * { dn: {
-1214      *     array: [
-1215      *       [{type:"C", value:"JP", ds:"prn"}],
-1216      *       [{type:"O", value:"T1", ds:"utf8"}]
-1217      *     ],
-1218      *     str: "/C=JP/O=T1" } }
-1219      */
-1220     this.getGeneralName = function(h) {
-1221 	var tag = h.substr(0, 2);
-1222 	var hValue = _getV(h, 0);
-1223 	var sValue = hextorstr(hValue);
-1224 	if (tag == "81") return {rfc822: sValue};
-1225 	if (tag == "82") return {dns: sValue};
-1226 	if (tag == "86") return {uri: sValue};
-1227 	if (tag == "87") return {ip: hextoip(hValue)};
-1228 	if (tag == "a4") return {dn: this.getX500Name(hValue)};
-1229 	return undefined;
-1230     };
-1231 
-1232     /**
-1233      * get subjectAltName value as array of string in the certificate (DEPRECATED)
-1234      * @name getExtSubjectAltName2
-1235      * @memberOf X509#
-1236      * @function
-1237      * @return {Object} array of alt name array
-1238      * @since jsrsasign 8.0.1 x509 1.1.17
-1239      * @deprecated jsrsasign 9.0.0 x509 2.0.0
-1240      * @description
-1241      * This method will get subject alt name extension value
-1242      * as array of type and name.
-1243      * If there is this in the certificate, it returns undefined;
-1244      * Type of GeneralName will be shown as following:
-1245      * <ul>
-1246      * <li>"MAIL" - [1]rfc822Name</li>
-1247      * <li>"DNS"  - [2]dNSName</li>
-1248      * <li>"DN"   - [4]directoryName</li>
-1249      * <li>"URI"  - [6]uniformResourceIdentifier</li>
-1250      * <li>"IP"   - [7]iPAddress</li>
-1251      * </ul>
-1252      * @example
-1253      * x = new X509();
-1254      * x.readCertPEM(sCertPEM); // parseExt() will also be called internally.
-1255      * x.getExtSubjectAltName2() →
-1256      * [["DNS",  "example.com"],
-1257      *  ["DNS",  "example.org"],
-1258      *  ["MAIL", "foo@example.com"],
-1259      *  ["IP",   "192.168.1.1"],
-1260      *  ["IP",   "2001:db8::2:1"],
-1261      *  ["DN",   "/C=US/O=TEST1"]]
-1262      */
-1263     this.getExtSubjectAltName2 = function() {
-1264 	var gnValueHex, gnValueStr, gnTag;
-1265 	var info = this.getExtInfo("subjectAltName");
-1266 	if (info === undefined) return info;
-1267 
-1268 	var result = new Array();
-1269 	var h = _getTLV(this.hex, info.vidx);
-1270 
-1271 	var a = _getChildIdx(h, 0);
-1272 	for (var i = 0; i < a.length; i++) {
-1273 	    gnTag = h.substr(a[i], 2);
-1274 	    gnValueHex = _getV(h, a[i]);
-1275 	    
-1276 	    if (gnTag === "81") { // rfc822Name [1]
-1277 		gnValueStr = hextoutf8(gnValueHex);
-1278 		result.push(["MAIL", gnValueStr]);
-1279 	    }
-1280 	    if (gnTag === "82") { // dNSName [2]
+988 	for (var i = 0; i < a.length; i++) {
+989 	    result.array.push(_oidname(_getV(hExtV, a[i])));
+990 	}
+991 
+992 	return result;
+993     };
+994 
+995     /**
+996      * get extKeyUsage value as array of name string in the certificate(DEPRECATED)<br/>
+997      * @name getExtExtKeyUsageName
+998      * @memberOf X509#
+999      * @function
+1000      * @return {Object} array of extended key usage ID name or oid
+1001      * @since jsrsasign 7.2.0 x509 1.1.14
+1002      * @deprecated since jsrsasign 9.0.0 x509 2.0.0
+1003      * @description
+1004      * This method will get extended key usage extension value
+1005      * as array of name or OID string.
+1006      * If there is this in the certificate, it returns undefined;
+1007      * <br>
+1008      * NOTE: Supported extended key usage ID names are defined in
+1009      * name2oidList parameter in asn1x509.js file.
+1010      * @example
+1011      * x = new X509();
+1012      * x.readCertPEM(sCertPEM); // parseExt() will also be called internally.
+1013      * x.getExtExtKeyUsageName() → ["serverAuth", "clientAuth", "0.1.2.3.4.5"]
+1014      */
+1015     this.getExtExtKeyUsageName = function() {
+1016 	var info = this.getExtInfo("extKeyUsage");
+1017 	if (info === undefined) return info;
+1018 
+1019 	var result = new Array();
+1020 	
+1021 	var h = _getTLV(this.hex, info.vidx);
+1022 	if (h === '') return result;
+1023 
+1024 	var a = _getChildIdx(h, 0);
+1025 	for (var i = 0; i < a.length; i++) {
+1026 	    result.push(_oidname(_getV(h, a[i])));
+1027 	}
+1028 
+1029 	return result;
+1030     };
+1031 
+1032     /**
+1033      * get subjectAltName value as array of string in the certificate
+1034      * @name getExtSubjectAltName
+1035      * @memberOf X509#
+1036      * @function
+1037      * @param {String} hExtV hexadecimal string of extension value (OPTIONAL)
+1038      * @param {Boolean} critical flag (OPTIONAL)
+1039      * @return {Array} JSON object of SubjectAltName parameters or undefined
+1040      * @since jsrsasign 7.2.0 x509 1.1.14
+1041      * @see KJUR.asn1.x509.SubjectAltName
+1042      * @see X509#getExtIssuerAltName
+1043      * @description
+1044      * This method will get subjectAltName value
+1045      * as an array of JSON object which has properties defined
+1046      * in {@link KJUR.asn1.x509.SubjectAltName}.
+1047      * Result of this method can be passed to 
+1048      * {@link KJUR.asn1.x509.SubjectAltName} constructor.
+1049      * If there is no this extension in the certificate,
+1050      * it returns undefined.
+1051      * <br>
+1052      * When hExtV and critical specified as arguments, return value
+1053      * will be generated from them.
+1054      * <br>
+1055      * CAUTION: return value of JSON object format have been changed
+1056      * from jsrsasign 9.0.0 x509 2.0.0 without backword compatibility.
+1057      * @example
+1058      * x = new X509();
+1059      * x.readCertPEM(sCertPEM); // parseExt() will also be called internally.
+1060      * x.getExtSubjectAltName() → 
+1061      * { array: [
+1062      *     {uri: "http://example.com/"},
+1063      *     {rfc822: "user1@example.com"},
+1064      *     {dns: "example.com"}
+1065      *   ],
+1066      *   critical: true
+1067      * }
+1068      *
+1069      * x.getExtSubjectAltName("3026...") →
+1070      * { array: [{ip: "192.168.1.1"}] }
+1071      */
+1072     this.getExtSubjectAltName = function(hExtV, critical) {
+1073 	if (hExtV === undefined && critical === undefined) {
+1074 	    var info = this.getExtInfo("subjectAltName");
+1075 	    if (info === undefined) return undefined;
+1076 	    hExtV = _getTLV(this.hex, info.vidx);
+1077 	    critical = info.critical;
+1078 	}
+1079 
+1080 	var result = {extname:"subjectAltName",array:[]};
+1081 	if (critical) result.critical = true;
+1082 
+1083 	result.array = this.getGeneralNames(hExtV);
+1084 
+1085 	return result;
+1086     };
+1087 
+1088     /**
+1089      * get issuerAltName value as array of string in the certificate
+1090      * @name getExtIssuerAltName
+1091      * @memberOf X509#
+1092      * @function
+1093      * @param {String} hExtV hexadecimal string of extension value (OPTIONAL)
+1094      * @param {Boolean} critical flag (OPTIONAL)
+1095      * @return {Array} JSON object of IssuerAltName parameters
+1096      * @since jsrsasign 9.0.0 x509 2.0.0
+1097      * @see KJUR.asn1.x509.IssuerAltName
+1098      * @see X509#getExtSubjectAltName
+1099      * @description
+1100      * This method will get issuerAltName value
+1101      * as an array of JSON object which has properties defined
+1102      * in {@link KJUR.asn1.x509.IssuerAltName}.
+1103      * Result of this method can be passed to 
+1104      * {@link KJUR.asn1.x509.IssuerAltName} constructor.
+1105      * If there is no this extension in the certificate,
+1106      * it returns undefined.
+1107      * <br>
+1108      * When hExtV and critical specified as arguments, return value
+1109      * will be generated from them.
+1110      * @example
+1111      * x = new X509();
+1112      * x.readCertPEM(sCertPEM); // parseExt() will also be called internally.
+1113      * x.getExtIssuerAltName() → 
+1114      * { array: [
+1115      *     {uri: "http://example.com/"},
+1116      *     {rfc822: "user1@example.com"},
+1117      *     {dns: "example.com"}
+1118      *   ],
+1119      *   critical: true
+1120      * }
+1121      *
+1122      * x.getExtIssuerAltName("3026...") →
+1123      * { array: [{ip: "192.168.1.1"}] }
+1124      */
+1125     this.getExtIssuerAltName = function(hExtV, critical) {
+1126 	if (hExtV === undefined && critical === undefined) {
+1127 	    var info = this.getExtInfo("issuerAltName");
+1128 	    if (info === undefined) return undefined;
+1129 	    hExtV = _getTLV(this.hex, info.vidx);
+1130 	    critical = info.critical;
+1131 	}
+1132 
+1133 	var result = {extname:"issuerAltName",array:[]};
+1134 	if (critical) result.critical = true;
+1135 
+1136 	result.array = this.getGeneralNames(hExtV);
+1137 
+1138 	return result;
+1139     };
+1140 
+1141     /**
+1142      * get GeneralNames ASN.1 structure parameter as JSON object
+1143      * @name getGeneralNames
+1144      * @memberOf X509#
+1145      * @function
+1146      * @param {String} h hexadecimal string of GeneralNames
+1147      * @return {Array} array of GeneralNames parameters
+1148      * @see KJUR.asn1.x509.GeneralNames
+1149      * @see KJUR.asn1.x509.GeneralName
+1150      * @see X509#getGeneralNames
+1151      * @since jsrsasign 9.0.0 x509 2.0.0
+1152      * @description
+1153      * This method will get GeneralNames parameters defined in
+1154      * <a href="https://tools.ietf.org/html/rfc5280#section-4.2.1.6">
+1155      * RFC 5280 4.2.1.6</a>.
+1156      * <pre>
+1157      * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
+1158      * </pre>
+1159      * Result of this method can be passed to
+1160      * {@link KJUR.asn1.x509.GeneralNames} constructor.
+1161      * @example
+1162      * x = new X509();
+1163      * x.getGeneralNames("3011860f687474703a2f2f6161612e636f6d2f")
+1164      * → [{uri: "http://aaa.com/"}]
+1165      *
+1166      * x.getGeneralNames("301ea41c30...") →
+1167      * [{ dn: {
+1168      *     array: [
+1169      *       [{type:"C", value:"JP", ds:"prn"}],
+1170      *       [{type:"O", value:"T1", ds:"utf8"}]
+1171      *     ],
+1172      *     str: "/C=JP/O=T1" } }]
+1173      */
+1174     this.getGeneralNames = function(h) {
+1175 	var aIdx = _getChildIdx(h, 0);
+1176 	var result = [];
+1177 	for (var i = 0; i < aIdx.length; i++) {
+1178 	    var gnParam = this.getGeneralName(_getTLV(h, aIdx[i]));
+1179 	    if (gnParam !== undefined) result.push(gnParam);
+1180 	}
+1181 	return result;
+1182     };
+1183 
+1184     /**
+1185      * get GeneralName ASN.1 structure parameter as JSON object
+1186      * @name getGeneralName
+1187      * @memberOf X509#
+1188      * @function
+1189      * @param {String} h hexadecimal string of GeneralName
+1190      * @return {Array} JSON object of GeneralName parameters or undefined
+1191      * @see KJUR.asn1.x509.GeneralNames
+1192      * @see X509#getGeneralName
+1193      * @since jsrsasign 9.0.0 x509 2.0.0
+1194      * @description
+1195      * This method will get GeneralName parameters defined in
+1196      * <a href="https://tools.ietf.org/html/rfc5280#section-4.2.1.6">
+1197      * RFC 5280 4.2.1.6</a>.
+1198      * <pre>
+1199      * GeneralName ::= CHOICE {
+1200      *      otherName                       [0]     OtherName,
+1201      *      rfc822Name                      [1]     IA5String,
+1202      *      dNSName                         [2]     IA5String,
+1203      *      x400Address                     [3]     ORAddress,
+1204      *      directoryName                   [4]     Name,
+1205      *      ediPartyName                    [5]     EDIPartyName,
+1206      *      uniformResourceIdentifier       [6]     IA5String,
+1207      *      iPAddress                       [7]     OCTET STRING,
+1208      *      registeredID                    [8]     OBJECT IDENTIFIER }
+1209      * </pre>
+1210      * Result of this method can be passed to
+1211      * {@link KJUR.asn1.x509.GeneralName} constructor.
+1212      * @example
+1213      * x = new X509();
+1214      * x.getGeneralName("860f687474703a2f2f6161612e636f6d2f") 
+1215      * → {uri: "http://aaa.com/"}
+1216      * x.getGeneralName("a41c30...") →
+1217      * { dn: {
+1218      *     array: [
+1219      *       [{type:"C", value:"JP", ds:"prn"}],
+1220      *       [{type:"O", value:"T1", ds:"utf8"}]
+1221      *     ],
+1222      *     str: "/C=JP/O=T1" } }
+1223      */
+1224     this.getGeneralName = function(h) {
+1225 	var tag = h.substr(0, 2);
+1226 	var hValue = _getV(h, 0);
+1227 	var sValue = hextorstr(hValue);
+1228 	if (tag == "81") return {rfc822: sValue};
+1229 	if (tag == "82") return {dns: sValue};
+1230 	if (tag == "86") return {uri: sValue};
+1231 	if (tag == "87") return {ip: hextoip(hValue)};
+1232 	if (tag == "a4") return {dn: this.getX500Name(hValue)};
+1233 	return undefined;
+1234     };
+1235 
+1236     /**
+1237      * get subjectAltName value as array of string in the certificate (DEPRECATED)
+1238      * @name getExtSubjectAltName2
+1239      * @memberOf X509#
+1240      * @function
+1241      * @return {Object} array of alt name array
+1242      * @since jsrsasign 8.0.1 x509 1.1.17
+1243      * @deprecated jsrsasign 9.0.0 x509 2.0.0
+1244      * @description
+1245      * This method will get subject alt name extension value
+1246      * as array of type and name.
+1247      * If there is this in the certificate, it returns undefined;
+1248      * Type of GeneralName will be shown as following:
+1249      * <ul>
+1250      * <li>"MAIL" - [1]rfc822Name</li>
+1251      * <li>"DNS"  - [2]dNSName</li>
+1252      * <li>"DN"   - [4]directoryName</li>
+1253      * <li>"URI"  - [6]uniformResourceIdentifier</li>
+1254      * <li>"IP"   - [7]iPAddress</li>
+1255      * </ul>
+1256      * @example
+1257      * x = new X509();
+1258      * x.readCertPEM(sCertPEM); // parseExt() will also be called internally.
+1259      * x.getExtSubjectAltName2() →
+1260      * [["DNS",  "example.com"],
+1261      *  ["DNS",  "example.org"],
+1262      *  ["MAIL", "foo@example.com"],
+1263      *  ["IP",   "192.168.1.1"],
+1264      *  ["IP",   "2001:db8::2:1"],
+1265      *  ["DN",   "/C=US/O=TEST1"]]
+1266      */
+1267     this.getExtSubjectAltName2 = function() {
+1268 	var gnValueHex, gnValueStr, gnTag;
+1269 	var info = this.getExtInfo("subjectAltName");
+1270 	if (info === undefined) return info;
+1271 
+1272 	var result = new Array();
+1273 	var h = _getTLV(this.hex, info.vidx);
+1274 
+1275 	var a = _getChildIdx(h, 0);
+1276 	for (var i = 0; i < a.length; i++) {
+1277 	    gnTag = h.substr(a[i], 2);
+1278 	    gnValueHex = _getV(h, a[i]);
+1279 	    
+1280 	    if (gnTag === "81") { // rfc822Name [1]
 1281 		gnValueStr = hextoutf8(gnValueHex);
-1282 		result.push(["DNS", gnValueStr]);
+1282 		result.push(["MAIL", gnValueStr]);
 1283 	    }
-1284 	    if (gnTag === "84") { // directoryName [4]
-1285 		gnValueStr = X509.hex2dn(gnValueHex, 0);
-1286 		result.push(["DN", gnValueStr]);
+1284 	    if (gnTag === "82") { // dNSName [2]
+1285 		gnValueStr = hextoutf8(gnValueHex);
+1286 		result.push(["DNS", gnValueStr]);
 1287 	    }
-1288 	    if (gnTag === "86") { // uniformResourceIdentifier [6]
-1289 		gnValueStr = hextoutf8(gnValueHex);
-1290 		result.push(["URI", gnValueStr]);
+1288 	    if (gnTag === "84") { // directoryName [4]
+1289 		gnValueStr = X509.hex2dn(gnValueHex, 0);
+1290 		result.push(["DN", gnValueStr]);
 1291 	    }
-1292 	    if (gnTag === "87") { // iPAddress [7]
-1293 		gnValueStr = hextoip(gnValueHex);
-1294 		result.push(["IP", gnValueStr]);
+1292 	    if (gnTag === "86") { // uniformResourceIdentifier [6]
+1293 		gnValueStr = hextoutf8(gnValueHex);
+1294 		result.push(["URI", gnValueStr]);
 1295 	    }
-1296 	}
-1297 	return result;
-1298     };
-1299 
-1300     /**
-1301      * get CRLDistributionPoints extension value as JSON object
-1302      * @name getExtCRLDistributionPoints
-1303      * @memberOf X509#
-1304      * @function
-1305      * @param {String} hExtV hexadecimal string of extension value (OPTIONAL)
-1306      * @param {Boolean} critical flag (OPTIONAL)
-1307      * @return {Object} JSON object of CRLDistributionPoints parameters or undefined
-1308      * @since jsrsasign 9.0.0 x509 2.0.0
-1309      * @see KJUR.asn1.x509.CRLDistributionPoints
-1310      * @see X509#getDistributionPoint
-1311      * @see X509#getDistributionPointName
-1312      * @see X509#getGeneralNames
-1313      * @see X509#getGeneralName
-1314      * @description
-1315      * This method will get certificate policies value
-1316      * as an array of JSON object which has properties defined
-1317      * in {@link KJUR.asn1.x509.CRLDistributionPoints}.
-1318      * Result of this method can be passed to 
-1319      * {@link KJUR.asn1.x509.CRLDistributionPoints} constructor.
-1320      * If there is no this extension in the certificate,
-1321      * it returns undefined.
-1322      * @example
-1323      * x = new X509();
-1324      * x.readCertPEM(sCertPEM); // parseExt() will also be called internally.
-1325      * x.getExtCRLDistributionPoints() → 
-1326      * {array: [
-1327      *   {dpname: {full: [{uri: "http://example.com/"}]}},
-1328      *   {dpname: {full: [{uri: "ldap://example.com/"}]}}
-1329      *  ],
-1330      *  critical: true}
-1331      */
-1332     this.getExtCRLDistributionPoints = function(hExtV, critical) {
-1333 	if (hExtV === undefined && critical === undefined) {
-1334 	    var info = this.getExtInfo("cRLDistributionPoints");
-1335 	    if (info === undefined) return undefined;
-1336 	    hExtV = _getTLV(this.hex, info.vidx);
-1337 	    critical = info.critical;
-1338 	}
-1339 
-1340 	var result = {extname:"cRLDistributionPoints",array:[]};
-1341 	if (critical) result.critical = true;
-1342 
-1343 	var a = _getChildIdx(hExtV, 0);
-1344 	for (var i = 0; i < a.length; i++) {
-1345 	    var hTLV = _getTLV(hExtV, a[i]);
-1346 	    result.array.push(this.getDistributionPoint(hTLV));
-1347 	}
-1348 
-1349 	return result;
-1350     };
-1351 
-1352     /**
-1353      * get DistributionPoint ASN.1 structure parameter as JSON object
-1354      * @name getDistributionPoint
-1355      * @memberOf X509#
-1356      * @function
-1357      * @param {String} h hexadecimal string of DistributionPoint
-1358      * @return {Object} JSON object of DistributionPoint parameters
-1359      * @since jsrsasign 9.0.0 x509 2.0.0
-1360      * @see X509#getExtCRLDistributionPoints
-1361      * @see X509#getDistributionPointName
-1362      * @see X509#getGeneralNames
-1363      * @see X509#getGeneralName
-1364      * @description
-1365      * This method will get DistributionPoint parameters.
-1366      * Result of this method can be passed to
-1367      * {@link KJUR.asn1.x509.DistributionPoint} constructor.
-1368      * <br/>
-1369      * NOTE: reasons[1] and CRLIssuer[2] field not supported
-1370      * @example
-1371      * x = new X509();
-1372      * x.getDistributionPoint("30...") →
-1373      * {dpname: {full: [{uri: "http://aaa.com/"}]}}
-1374      */
-1375     this.getDistributionPoint = function(h) {
-1376 	var result = {};
-1377 	var a = _getChildIdx(h, 0);
-1378 	for (var i = 0; i < a.length; i++) {
-1379 	    var tag = h.substr(a[i], 2);
-1380 	    var hTLV = _getTLV(h, a[i]);
-1381 	    if (tag == "a0") {
-1382 		result.dpname = this.getDistributionPointName(hTLV);
-1383 	    }
-1384 	}
-1385 	return result;
-1386     };
-1387 
-1388     /**
-1389      * get DistributionPointName ASN.1 structure parameter as JSON object
-1390      * @name getDistributionPointName
-1391      * @memberOf X509#
-1392      * @function
-1393      * @param {String} h hexadecimal string of DistributionPointName
-1394      * @return {Object} JSON object of DistributionPointName parameters
-1395      * @since jsrsasign 9.0.0 x509 2.0.0
-1396      * @see X509#getExtCRLDistributionPoints
-1397      * @see X509#getDistributionPoint
-1398      * @see X509#getGeneralNames
-1399      * @see X509#getGeneralName
-1400      * @description
-1401      * This method will get DistributionPointName parameters.
-1402      * Result of this method can be passed to
-1403      * {@link KJUR.asn1.x509.DistributionPointName} constructor.
-1404      * <br/>
-1405      * NOTE: nameRelativeToCRLIssuer[1] not supported
-1406      * @example
-1407      * x = new X509();
-1408      * x.getDistributionPointName("a0...") →
-1409      * {full: [{uri: "http://aaa.com/"}]}
-1410      */
-1411     this.getDistributionPointName = function(h) {
-1412 	var result = {};
-1413 	var a = _getChildIdx(h, 0);
-1414 	for (var i = 0; i < a.length; i++) {
-1415 	    var tag = h.substr(a[i], 2);
-1416 	    var hTLV = _getTLV(h, a[i]);
-1417 	    if (tag == "a0") {
-1418 		result.full = this.getGeneralNames(hTLV);
-1419 	    }
-1420 	}
-1421 	return result;
-1422     };
-1423 
-1424     /**
-1425      * get array of string for fullName URIs in cRLDistributionPoints(CDP) in the certificate (DEPRECATED)
-1426      * @name getExtCRLDistributionPointsURI
-1427      * @memberOf X509#
-1428      * @function
-1429      * @return {Object} array of fullName URIs of CDP of the certificate
-1430      * @since jsrsasign 7.2.0 x509 1.1.14
-1431      * @description
-1432      * This method will get all fullName URIs of cRLDistributionPoints extension
-1433      * in the certificate as array of URI string.
-1434      * If there is this in the certificate, it returns undefined;
-1435      * <br>
-1436      * NOTE: Currently this method supports only fullName URI so that
-1437      * other parameters will not be returned.
-1438      * @example
-1439      * x = new X509();
-1440      * x.readCertPEM(sCertPEM); // parseExt() will also be called internally.
-1441      * x.getExtCRLDistributionPointsURI() →
-1442      * ["http://example.com/aaa.crl", "http://example.org/aaa.crl"]
-1443      */
-1444     this.getExtCRLDistributionPointsURI = function() {
-1445 	var info = this.getExtInfo("cRLDistributionPoints");
-1446 	if (info === undefined) return info;
-1447 
-1448 	var result = new Array();
-1449 	var a = _getChildIdx(this.hex, info.vidx);
-1450 	for (var i = 0; i < a.length; i++) {
-1451 	    try {
-1452 		var hURI = _getVbyList(this.hex, a[i], [0, 0, 0], "86");
-1453 		var uri = hextoutf8(hURI);
-1454 		result.push(uri);
-1455 	    } catch(ex) {};
-1456 	}
-1457 
-1458 	return result;
-1459     };
-1460 
-1461     /**
-1462      * get AuthorityInfoAccess extension value in the certificate as associative array
-1463      * @name getExtAIAInfo
-1464      * @memberOf X509#
-1465      * @function
-1466      * @return {Object} associative array of AIA extension properties
-1467      * @since jsrsasign 7.2.0 x509 1.1.14
-1468      * @description
-1469      * This method will get authority info access value
-1470      * as associate array which has following properties:
-1471      * <ul>
-1472      * <li>ocsp - array of string for OCSP responder URL</li>
-1473      * <li>caissuer - array of string for caIssuer value (i.e. CA certificates URL)</li>
-1474      * </ul>
-1475      * If there is this in the certificate, it returns undefined;
-1476      * @example
-1477      * x = new X509();
-1478      * x.readCertPEM(sCertPEM); // parseExt() will also be called internally.
-1479      * x.getExtAIAInfo(hCert) → 
-1480      * { ocsp:     ["http://ocsp.foo.com"],
-1481      *   caissuer: ["http://rep.foo.com/aaa.p8m"] }
-1482      */
-1483     this.getExtAIAInfo = function() {
-1484 	var info = this.getExtInfo("authorityInfoAccess");
-1485 	if (info === undefined) return info;
-1486 
-1487 	var result = { ocsp: [], caissuer: [] };
-1488 	var a = _getChildIdx(this.hex, info.vidx);
-1489 	for (var i = 0; i < a.length; i++) {
-1490 	    var hOID = _getVbyList(this.hex, a[i], [0], "06");
-1491 	    var hName = _getVbyList(this.hex, a[i], [1], "86");
-1492 	    if (hOID === "2b06010505073001") {
-1493 		result.ocsp.push(hextoutf8(hName));
-1494 	    }
-1495 	    if (hOID === "2b06010505073002") {
-1496 		result.caissuer.push(hextoutf8(hName));
-1497 	    }
-1498 	}
-1499 
-1500 	return result;
-1501     };
-1502 
-1503     /**
-1504      * get AuthorityInfoAccess extension value as JSON object
-1505      * @name getExtAuthorityInfoAccess
-1506      * @memberOf X509#
-1507      * @function
-1508      * @param {String} hExtV hexadecimal string of extension value (OPTIONAL)
-1509      * @param {Boolean} critical flag (OPTIONAL)
-1510      * @return {Array} JSON object of AuthorityInfoAccess parameters or undefined
-1511      * @since jsrsasign 9.0.0 x509 2.0.0
-1512      * @see KJUR.asn1.x509.AuthorityInfoAccess
-1513      * @description
-1514      * This method parse authorityInfoAccess extension. When arguments are
-1515      * not specified, its extension in X509 object will be parsed.
-1516      * Result of this method can be passed to 
-1517      * {@link KJUR.asn1.x509.AuthorityInfoAccess} constructor.
-1518      * <br>
-1519      * When hExtV and critical specified as arguments, return value
-1520      * will be generated from them.
-1521      * @example
-1522      * x = new X509();
-1523      * x.readCertPEM(sCertPEM); // parseExt() will also be called internally.
-1524      * x.getExtAuthorityInfoAccess() →
-1525      * {
-1526      *   critial: true, // 
-1527      *   array: [{ocsp: http://ocsp.example.com/},
-1528      *           {caissuer: https://repository.example.com/}]
-1529      * }
-1530      *
-1531      * x = new X509();
-1532      * x.getExtAuthorityInfoAccesss("306230...") 
-1533      * x.getExtAuthorityInfoAccesss("306230...", true) 
-1534      */
-1535     this.getExtAuthorityInfoAccess = function(hExtV, critical) {
-1536 	if (hExtV === undefined && critical === undefined) {
-1537 	    var info = this.getExtInfo("authorityInfoAccess");
-1538 	    if (info === undefined) return undefined;
-1539 	    hExtV = _getTLV(this.hex, info.vidx);
-1540 	    critical = info.critical;
-1541 	}
-1542 
-1543 	var result = {extname:"authorityInfoAccess",array:[]};
-1544 	if (critical) result.critical = true;
-1545 
-1546 	var a = _getChildIdx(hExtV, 0);
-1547 	for (var i = 0; i < a.length; i++) {
-1548 	    var hMethod = _getVbyListEx(hExtV, a[i], [0], "06");
-1549 	    var hLoc = _getVbyList(hExtV, a[i], [1], "86");
-1550 	    var sLoc = hextoutf8(hLoc);
-1551 	    if (hMethod == "2b06010505073001") {
-1552 		result.array.push({ocsp: sLoc});
-1553 	    } else if (hMethod == "2b06010505073002") {
-1554 		result.array.push({caissuer: sLoc});
-1555 	    } else {
-1556 		throw new Error("unknown method: " + hMethod);
-1557 	    }
-1558 	}
-1559 
-1560 	return result;
-1561     }
-1562 
-1563     /**
-1564      * get CertificatePolicies extension value as JSON object
-1565      * @name getExtCertificatePolicies
-1566      * @memberOf X509#
-1567      * @function
-1568      * @param {String} hExtV hexadecimal string of extension value (OPTIONAL)
-1569      * @param {Boolean} critical flag (OPTIONAL)
-1570      * @return {Object} JSON object of CertificatePolicies parameters or undefined
-1571      * @since jsrsasign 7.2.0 x509 1.1.14
-1572      * @description
-1573      * This method will get certificate policies value
-1574      * as an array of JSON object which has properties defined
-1575      * in {@link KJUR.asn1.x509.CertificatePolicies}.
-1576      * Result of this method can be passed to 
-1577      * {@link KJUR.asn1.x509.CertificatePolicies} constructor.
-1578      * If there is no this extension in the certificate,
-1579      * it returns undefined.
-1580      * <br>
-1581      * CAUTION: return value of JSON object format have been changed
-1582      * from jsrsasign 9.0.0 without backword compatibility.
-1583      * <br>
-1584      * When hExtV and critical specified as arguments, return value
-1585      * will be generated from them.
-1586      * @example
-1587      * x = new X509();
-1588      * x.readCertPEM(sCertPEM); // parseExt() will also be called internally.
-1589      * x.getExtCertificatePolicies() → 
-1590      * { array: [
-1591      *   { policyoid: "1.2.3.4" }
-1592      *   { policyoid: "1.2.3.5",
-1593      *     array: [
-1594      *       { cps: "https://example.com/" },
-1595      *       { unotice: { exptext: { type: "bmp", str: "sample text" } } }
-1596      *     ] 
-1597      *   }
-1598      * ]}
-1599      */
-1600     this.getExtCertificatePolicies = function(hExtV, critical) {
-1601 	if (hExtV === undefined && critical === undefined) {
-1602 	    var info = this.getExtInfo("certificatePolicies");
-1603 	    if (info === undefined) return undefined;
-1604 	    hExtV = _getTLV(this.hex, info.vidx);
-1605 	    critical = info.critical;
-1606 	}
-1607 	var result = {extname:"certificatePolicies",array:[]};
-1608 	if (critical) result.critical = true;
-1609 
-1610 	var aIdxPI = _getChildIdx(hExtV, 0); // PolicyInformation list index
-1611 	for (var i = 0; i < aIdxPI.length; i++) {
-1612 	    var hPolicyInformation = _getTLV(hExtV, aIdxPI[i]);
-1613 	    var polinfo = this.getPolicyInformation(hPolicyInformation);
-1614 	    result.array.push(polinfo);
-1615 	}
-1616 	return result;
-1617     }
-1618 
-1619     /**
-1620      * get PolicyInformation ASN.1 structure parameter as JSON object
-1621      * @name getPolicyInformation
-1622      * @memberOf X509#
-1623      * @function
-1624      * @param {String} h hexadecimal string of PolicyInformation
-1625      * @return {Object} JSON object of PolicyInformation parameters
-1626      * @since jsrsasign 9.0.0 x509 2.0.0
-1627      * @description
-1628      * This method will get PolicyInformation parameters defined in
-1629      * <a href="https://tools.ietf.org/html/rfc5280#section-4.2.1.4">
-1630      * RFC 5280 4.2.1.4</a>.
-1631      * <pre>
-1632      * PolicyInformation ::= SEQUENCE {
-1633      *      policyIdentifier   CertPolicyId,
-1634      *      policyQualifiers   SEQUENCE SIZE (1..MAX) OF
-1635      *                              PolicyQualifierInfo OPTIONAL }
-1636      * </pre>
-1637      * Result of this method can be passed to
-1638      * {@link KJUR.asn1.x509.PolicyInformation} constructor.
-1639      * @example
-1640      * x = new X509();
-1641      * x.getPolicyInformation("30...") →
-1642      * {
-1643      *     policyoid: "2.16.840.1.114412.2.1",
-1644      *     array: [{cps: "https://www.digicert.com/CPS"}]
-1645      * }
-1646      */
-1647     this.getPolicyInformation = function(h) {
-1648 	var result = {};
-1649 
-1650 	var hPOLICYOID = _getVbyList(h, 0, [0], "06");
-1651 	result.policyoid = _oidname(hPOLICYOID);
-1652 	
-1653 	var idxPQSEQ = _getIdxbyListEx(h, 0, [1], "30");
-1654 	if (idxPQSEQ != -1) {
-1655 	    result.array = [];
-1656 	    var aIdx = _getChildIdx(h, idxPQSEQ);
-1657 	    for (var j = 0; j < aIdx.length; j++) {
-1658 		var hPQI = _getTLV(h, aIdx[j]);
-1659 		var pqinfo = this.getPolicyQualifierInfo(hPQI);
-1660 		result.array.push(pqinfo);
-1661 	    }
-1662 	}
-1663 
-1664 	return result;
-1665     };
-1666 
-1667     /**
-1668      * get PolicyQualifierInfo ASN.1 structure parameter as JSON object
-1669      * @name getPolicyQualifierInfo
-1670      * @memberOf X509#
-1671      * @function
-1672      * @param {String} h hexadecimal string of PolicyQualifierInfo
-1673      * @return {Object} JSON object of PolicyQualifierInfo parameters
-1674      * @since jsrsasign 9.0.0 x509 2.0.0
-1675      * @see X509#getExtCertificatePolicies
-1676      * @see X509#getPolicyInformation
-1677      * @description
-1678      * This method will get 
-1679      * <a href="https://tools.ietf.org/html/rfc5280#section-4.2.1.4">
-1680      * PolicyQualifierInfo</a> parameters.
-1681      * <pre>
-1682      * PolicyQualifierInfo ::= SEQUENCE {
-1683      *      policyQualifierId  PolicyQualifierId,
-1684      *      qualifier          ANY DEFINED BY policyQualifierId }
-1685      * id-qt          OBJECT IDENTIFIER ::=  { id-pkix 2 }
-1686      * id-qt-cps      OBJECT IDENTIFIER ::=  { id-qt 1 }
-1687      * id-qt-unotice  OBJECT IDENTIFIER ::=  { id-qt 2 }
-1688      * PolicyQualifierId ::= OBJECT IDENTIFIER ( id-qt-cps | id-qt-unotice )
-1689      * Qualifier ::= CHOICE {
-1690      *      cPSuri           CPSuri,
-1691      *      userNotice       UserNotice }
-1692      * CPSuri ::= IA5String
-1693      * </pre>
-1694      * Result of this method can be passed to 
-1695      * {@link KJUR.asn1.x509.PolicyQualifierInfo} constructor.
-1696      * @example
-1697      * x = new X509();
-1698      * x.getPolicyQualifierInfo("30...") 
-1699      * → {unotice: {exptext: {type: 'utf8', str: 'aaa'}}}
-1700      * x.getPolicyQualifierInfo("30...") 
-1701      * → {cps: "https://repository.example.com/"}
-1702      */
-1703     this.getPolicyQualifierInfo = function(h) {
-1704 	var result = {};
-1705 	var hPQOID = _getVbyList(h, 0, [0], "06");
-1706 	if (hPQOID === "2b06010505070201") { // cps
-1707 	    var hCPSURI = _getVbyListEx(h, 0, [1], "16");
-1708 	    result.cps = hextorstr(hCPSURI);
-1709 	} else if (hPQOID === "2b06010505070202") { // unotice
-1710 	    var hUserNotice = _getTLVbyList(h, 0, [1], "30");
-1711 	    result.unotice = this.getUserNotice(hUserNotice);
-1712 	}
-1713 	return result;
-1714     };
-1715 
-1716     /**
-1717      * get UserNotice ASN.1 structure parameter as JSON object
-1718      * @name getUserNotice
-1719      * @memberOf X509#
-1720      * @function
-1721      * @param {String} h hexadecimal string of UserNotice
-1722      * @return {Object} JSON object of UserNotice parameters
-1723      * @since jsrsasign 9.0.0 x509 2.0.0
-1724      * @see X509#getExtCertificatePolicies
-1725      * @see X509#getPolicyInformation
-1726      * @see X509#getPolicyQualifierInfo
-1727      * @description
-1728      * This method will get 
-1729      * <a href="https://tools.ietf.org/html/rfc5280#section-4.2.1.4">
-1730      * UserNotice</a> parameters.
-1731      * <pre>
-1732      * UserNotice ::= SEQUENCE {
-1733      *      noticeRef        NoticeReference OPTIONAL,
-1734      *      explicitText     DisplayText OPTIONAL }
-1735      * </pre>
-1736      * Result of this method can be passed to 
-1737      * {@link KJUR.asn1.x509.NoticeReference} constructor.
-1738      * <br/>
-1739      * NOTE: NoticeReference parsing is currently not supported and
-1740      * it will be ignored.
-1741      * @example
-1742      * x = new X509();
-1743      * x.getUserNotice("30...") → {exptext: {type: 'utf8', str: 'aaa'}}
-1744      */
-1745     this.getUserNotice = function(h) {
-1746 	var result = {};
-1747 	var a = _getChildIdx(h, 0);
-1748 	for (var i = 0; i < a.length; i++) {
-1749 	    var hItem = _getTLV(h, a[i]);
-1750 	    if (hItem.substr(0, 2) != "30") {
-1751 		result.exptext = this.getDisplayText(hItem);
-1752 	    }
-1753 	}
-1754 	return result;
-1755     };
-1756 
-1757     /**
-1758      * get DisplayText ASN.1 structure parameter as JSON object
-1759      * @name getDisplayText
-1760      * @memberOf X509#
-1761      * @function
-1762      * @param {String} h hexadecimal string of DisplayText
-1763      * @return {Object} JSON object of DisplayText parameters
-1764      * @since jsrsasign 9.0.0 x509 2.0.0
-1765      * @see X509#getExtCertificatePolicies
-1766      * @see X509#getPolicyInformation
-1767      * @description
-1768      * This method will get 
-1769      * <a href="https://tools.ietf.org/html/rfc5280#section-4.2.1.4">
-1770      * DisplayText</a> parameters.
-1771      * <pre>
-1772      * DisplayText ::= CHOICE {
-1773      *      ia5String        IA5String      (SIZE (1..200)),
-1774      *      visibleString    VisibleString  (SIZE (1..200)),
-1775      *      bmpString        BMPString      (SIZE (1..200)),
-1776      *      utf8String       UTF8String     (SIZE (1..200)) }     
-1777      * </pre>
-1778      * Result of this method can be passed to 
-1779      * {@link KJUR.asn1.x509.DisplayText} constructor.
-1780      * @example
-1781      * x = new X509();
-1782      * x.getDisplayText("0c03616161") &rarr {type: 'utf8', str: 'aaa'}
-1783      * x.getDisplayText("1e03616161") &rarr {type: 'bmp',  str: 'aaa'}
-1784      */
-1785     this.getDisplayText = function(h) {
-1786 	var _DISPLAYTEXTTAG = {"0c": "utf8", "16": "ia5", "1a": "vis" , "1e": "bmp"};
-1787 	var result = {};
-1788 	result.type = _DISPLAYTEXTTAG[h.substr(0, 2)];
-1789 	result.str = hextorstr(_getV(h, 0));
-1790 	return result;
-1791     };
-1792 
-1793     /**
-1794      * parse cRLNumber CRL extension as JSON object<br/>
-1795      * @name getExtCRLNumber
-1796      * @memberOf X509#
-1797      * @function
-1798      * @param {String} hExtV hexadecimal string of extension value
-1799      * @param {Boolean} critical flag
-1800      * @since jsrsasign 9.1.1 x509 2.0.1
-1801      * @see KJUR.asn1.x509.CRLNumber
-1802      * @see X509#getExtParamArray
-1803      * @description
-1804      * This method parses
-1805      * CRLNumber CRL extension value defined in
-1806      * <a href="https://tools.ietf.org/html/rfc5280#section-5.2.3">
-1807      * RFC 5280 5.2.3</a> as JSON object.
-1808      * <pre>
-1809      * id-ce-cRLNumber OBJECT IDENTIFIER ::= { id-ce 20 }
-1810      * CRLNumber ::= INTEGER (0..MAX)
-1811      * </pre>
-1812      * <br/>
-1813      * Result of this method can be passed to 
-1814      * {@link KJUR.asn1.x509.CRLNumber} constructor.
-1815      * @example
-1816      * crl = X509CRL("-----BEGIN X509 CRL...");
-1817      * ... get hExtV and critical flag ...
-1818      * crl.getExtCRLNumber("02...", false) →
-1819      * {extname: "cRLNumber", num: {hex: "12af"}}
-1820      */
-1821     this.getExtCRLNumber = function(hExtV, critical) {
-1822 	var result = {extname:"cRLNumber"};
-1823 	if (critical) result.critical = true;
-1824 
-1825 	if (hExtV.substr(0, 2) == "02") {
-1826 	    result.num = {hex: _getV(hExtV, 0)};
-1827 	    return result;
-1828 	}
-1829 	throw new Error("hExtV parse error: " + hExtV);
-1830     };
-1831 
-1832     /**
-1833      * parse cRLReason CRL entry extension as JSON object<br/>
-1834      * @name getExtCRLReason
-1835      * @memberOf X509#
-1836      * @function
-1837      * @param {String} hExtV hexadecimal string of extension value
-1838      * @param {Boolean} critical flag
-1839      * @since jsrsasign 9.1.1 x509 2.0.1
-1840      * @see KJUR.asn1.x509.CRLReason
-1841      * @see X509#getExtParamArray
-1842      * @description
-1843      * This method parses
-1844      * CRLReason CRL entry extension value defined in
-1845      * <a href="https://tools.ietf.org/html/rfc5280#section-5.3.1">
-1846      * RFC 5280 5.3.1</a> as JSON object.
-1847      * <pre>
-1848      * id-ce-cRLReasons OBJECT IDENTIFIER ::= { id-ce 21 }
-1849      * -- reasonCode ::= { CRLReason }
-1850      * CRLReason ::= ENUMERATED {
-1851      *      unspecified             (0),
-1852      *      keyCompromise           (1),
-1853      *      cACompromise            (2),
-1854      *      affiliationChanged      (3),
-1855      *      superseded              (4),
-1856      *      cessationOfOperation    (5),
-1857      *      certificateHold         (6),
-1858      *      removeFromCRL           (8),
-1859      *      privilegeWithdrawn      (9),
-1860      *      aACompromise           (10) }
-1861      * </pre>
-1862      * <br/>
-1863      * Result of this method can be passed to 
-1864      * {@link KJUR.asn1.x509.CRLReason} constructor.
-1865      * @example
-1866      * crl = X509CRL("-----BEGIN X509 CRL...");
-1867      * ... get hExtV and critical flag ...
-1868      * crl.getExtCRLReason("02...", false) →
-1869      * {extname: "cRLReason", code: 3}
-1870      */
-1871     this.getExtCRLReason = function(hExtV, critical) {
-1872 	var result = {extname:"cRLReason"};
-1873 	if (critical) result.critical = true;
-1874 
-1875 	if (hExtV.substr(0, 2) == "0a") {
-1876 	    result.code = parseInt(_getV(hExtV, 0), 16);
-1877 	    return result;
-1878 	}
-1879 	throw new Error("hExtV parse error: " + hExtV);
-1880     };
-1881 
-1882     /**
-1883      * parse OCSPNonce OCSP extension as JSON object<br/>
-1884      * @name getExtOCSPNonce
-1885      * @memberOf X509#
-1886      * @function
-1887      * @param {String} hExtV hexadecimal string of extension value
-1888      * @param {Boolean} critical flag
-1889      * @return {Array} JSON object of parsed OCSPNonce extension
-1890      * @since jsrsasign 9.1.6 x509 2.0.3
-1891      * @see KJUR.asn1.x509.OCSPNonce
-1892      * @see X509#getExtParamArray
-1893      * @see X509#getExtParam
-1894      * @description
-1895      * This method parses
-1896      * Nonce OCSP extension value defined in
-1897      * <a href="https://tools.ietf.org/html/rfc6960#section-4.4.1">
-1898      * RFC 6960 4.4.1</a> as JSON object.
-1899      * <pre>
-1900      * id-pkix-ocsp           OBJECT IDENTIFIER ::= { id-ad-ocsp }
-1901      * id-pkix-ocsp-nonce     OBJECT IDENTIFIER ::= { id-pkix-ocsp 2 }
-1902      * Nonce ::= OCTET STRING
-1903      * </pre>
-1904      * <br/>
-1905      * Result of this method can be passed to 
-1906      * {@link KJUR.asn1.x509.OCSPNonce} constructor.
-1907      * @example
-1908      * x = new X509();
-1909      * x.getExtOCSPNonce(<<extn hex value >>) →
-1910      * { extname: "ocspNonce", hex: "1a2b..." }
-1911      */
-1912     this.getExtOcspNonce = function(hExtV, critical) {
-1913 	var result = {extname:"ocspNonce"};
-1914 	if (critical) result.critical = true;
-1915 
-1916 	var hNonce = _getV(hExtV, 0);
-1917 	result.hex = hNonce;
-1918 
-1919 	return result;
-1920     };
-1921 
-1922     /**
-1923      * parse OCSPNoCheck OCSP extension as JSON object<br/>
-1924      * @name getExtOCSPNoCheck
-1925      * @memberOf X509#
-1926      * @function
-1927      * @param {String} hExtV hexadecimal string of extension value
-1928      * @param {Boolean} critical flag
-1929      * @return {Array} JSON object of parsed OCSPNoCheck extension
-1930      * @since jsrsasign 9.1.6 x509 2.0.3
-1931      * @see KJUR.asn1.x509.OCSPNoCheck
-1932      * @see X509#getExtParamArray
-1933      * @see X509#getExtParam
-1934      * @description
-1935      * This method parses
-1936      * OCSPNoCheck extension value defined in
-1937      * <a href="https://tools.ietf.org/html/rfc6960#section-4.2.2.2.1">
-1938      * RFC 6960 4.2.2.2.1</a> as JSON object.
-1939      * <pre>
-1940      * id-pkix-ocsp-nocheck OBJECT IDENTIFIER ::= { id-pkix-ocsp 5 }
-1941      * </pre>
-1942      * <br/>
-1943      * Result of this method can be passed to 
-1944      * {@link KJUR.asn1.x509.OCSPNoCheck} constructor.
-1945      * @example
-1946      * x = new X509();
-1947      * x.getExtOCSPNoCheck(<<extn hex value >>) →
-1948      * { extname: "ocspNoCheck" }
-1949      */
-1950     this.getExtOcspNoCheck = function(hExtV, critical) {
-1951 	var result = {extname:"ocspNoCheck"};
-1952 	if (critical) result.critical = true;
-1953 
-1954 	return result;
-1955     };
-1956 
-1957     /**
-1958      * parse AdobeTimeStamp extension as JSON object<br/>
-1959      * @name getExtAdobeTimeStamp
-1960      * @memberOf X509#
-1961      * @function
-1962      * @param {String} hExtV hexadecimal string of extension value
-1963      * @param {Boolean} critical flag
-1964      * @return {Array} JSON object of parsed AdobeTimeStamp extension
-1965      * @since jsrsasign 10.0.1 x509 2.0.5
-1966      * @see KJUR.asn1.x509.AdobeTimeStamp
-1967      * @see X509#getExtParamArray
-1968      * @see X509#getExtParam
-1969      * @description
-1970      * This method parses
-1971      * X.509v3 AdobeTimeStamp private extension value defined in the
-1972      * <a href="https://www.adobe.com/devnet-docs/acrobatetk/tools/DigSigDC/oids.html">
-1973      * Adobe site</a> as JSON object.
-1974      * This extension provides the URL location for time stamp service.
-1975      * <pre>
-1976      * adbe- OBJECT IDENTIFIER ::=  { adbe(1.2.840.113583) acrobat(1) security(1) x509Ext(9) 1 }
-1977      *  ::= SEQUENCE {
-1978      *     version INTEGER  { v1(1) }, -- extension version
-1979      *     location GeneralName (In v1 GeneralName can be only uniformResourceIdentifier)
-1980      *     requiresAuth        boolean (default false), OPTIONAL }
-1981      * </pre>
-1982      * <br/>
-1983      * Result of this method can be passed to 
-1984      * {@link KJUR.asn1.x509.AdobeTimeStamp} constructor.
-1985      * <br/>
-1986      * NOTE: This extesion doesn't seem to have official name. This may be called as "pdfTimeStamp".
-1987      * @example
-1988      * x.getExtAdobeTimeStamp(<<extn hex value >>) →
-1989      * { extname: "adobeTimeStamp", uri: "http://tsa.example.com/" reqauth: true }
-1990      */
-1991     this.getExtAdobeTimeStamp = function(hExtV, critical) {
-1992 	if (hExtV === undefined && critical === undefined) {
-1993 	    var info = this.getExtInfo("adobeTimeStamp");
-1994 	    if (info === undefined) return undefined;
-1995 	    hExtV = _getTLV(this.hex, info.vidx);
-1996 	    critical = info.critical;
-1997 	}
-1998 
-1999 	var result = {extname:"adobeTimeStamp"};
-2000 	if (critical) result.critical = true;
-2001 
-2002 	var a = _getChildIdx(hExtV, 0);
-2003 	if (a.length > 1) {
-2004 	    var hGN = _getTLV(hExtV, a[1])
-2005 	    var gnParam = this.getGeneralName(hGN);
-2006 	    if (gnParam.uri != undefined) {
-2007 		result.uri = gnParam.uri;
-2008 	    }
-2009 	}
-2010 	if (a.length > 2) {
-2011 	    var hBool = _getTLV(hExtV, a[2]);
-2012 	    if (hBool == "0101ff") result.reqauth = true;
-2013 	    if (hBool == "010100") result.reqauth = false;
-2014 	}
-2015 
-2016 	return result;
-2017     };
-2018 
-2019     // ===== BEGIN X500Name related =====================================
-2020 
-2021     this.getX500NameRule = function(aDN) {
-2022 	var isPRNRule = true;
-2023 	var isUTF8Rule = true;
-2024 	var isMixedRule = false;
-2025 	var logfull = "";
-2026 	var logcheck = "";
-2027 	var lasttag = null;
-2028 
-2029 	var a = [];
-2030 	for (var i = 0; i < aDN.length; i++) {
-2031 	    var aRDN = aDN[i];
-2032 	    for (var j = 0; j < aRDN.length; j++) {
-2033 		a.push(aRDN[j]);
-2034 	    }
-2035 	}
-2036 
-2037 	for (var i = 0; i < a.length; i++) {
-2038 	    var item = a[i];
-2039 	    var tag = item.ds;
-2040 	    var value = item.value;
-2041 	    var type = item.type;
-2042 	    logfull += ":" + tag;
-2043 	    
-2044 	    if (tag != "prn" && tag != "utf8" && tag != "ia5") {
-2045 		return "mixed";
-2046 	    }
-2047 	    if (tag == "ia5") {
-2048 		if (type != "CN") {
-2049 		    return "mixed";
-2050 		} else {
-2051 		    if (! KJUR.lang.String.isMail(value)) {
-2052 			return "mixed";
-2053 		    } else {
-2054 			continue;
-2055 		    }
-2056 		}
-2057 	    }
-2058 	    if (type == "C") {
-2059 		if (tag == "prn") {
-2060 		    continue;
-2061 		} else {
-2062 		    return "mixed";
-2063 		}
-2064 	    }
-2065 	    logcheck += ":" + tag;
-2066 	    if (lasttag == null) {
-2067 		lasttag = tag;
-2068 	    } else {
-2069 		if (lasttag !== tag) return "mixed";
-2070 	    }
-2071 	}
-2072 	if (lasttag == null) {
-2073 	    return "prn";
-2074 	} else {
-2075 	    return lasttag;
-2076 	}
-2077     };
-2078 
-2079     /**
-2080      * get Name ASN.1 structure parameter array<br/>
-2081      * @name getX500Name
-2082      * @memberOf X509#
-2083      * @function
-2084      * @param {String} h hexadecimal string of Name
-2085      * @return {Array} array of RDN parameter array
-2086      * @since jsrsasign 9.0.0 x509 2.0.0
-2087      * @see X509#getX500NameArray
-2088      * @see X509#getRDN
-2089      * @see X509#getAttrTypeAndValue
-2090      * @see KJUR.asn1.x509.X500Name
-2091      * @see KJUR.asn1.x509.GeneralName
-2092      * @see KJUR.asn1.x509.GeneralNames
-2093      * @description
-2094      * This method will get Name parameter defined in
-2095      * <a href="https://tools.ietf.org/html/rfc5280#section-4.1.2.4">
-2096      * RFC 5280 4.1.2.4</a>.
-2097      * <pre>
-2098      * Name ::= CHOICE { -- only one possibility for now --
-2099      *   rdnSequence  RDNSequence }
-2100      * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
-2101      * </pre>
-2102      * @example
-2103      * x = new X509();
-2104      * x.getX500Name("30...") →
-2105      * { array: [
-2106      *     [{type:"C",value:"US",ds:"prn"}],
-2107      *     [{type:"O",value:"Sample Corp.",ds:"utf8"}],
-2108      *     [{type:"CN",value:"john.smith@example.com",ds:"ia5"}]
-2109      *   ],
-2110      *   str: "/C=US/O=Sample Corp./CN=john.smith@example.com",
-2111      *   hex: "30..."
-2112      * }
-2113      */
-2114     this.getX500Name = function(h) {
-2115 	var a = this.getX500NameArray(h);
-2116 	var s = this.dnarraytostr(a);
-2117 	return { array: a, str: s };
-2118     };
-2119 
-2120     /**
-2121      * get X.500 Name ASN.1 structure parameter array<br/>
-2122      * @name getX500NameArray
-2123      * @memberOf X509#
-2124      * @function
-2125      * @param {String} h hexadecimal string of Name
-2126      * @return {Array} array of RDN parameter array
-2127      * @since jsrsasign 10.0.6 x509 2.0.9
-2128      * @see X509#getX500Name
-2129      * @see X509#getRDN
-2130      * @see X509#getAttrTypeAndValue
-2131      * @description
-2132      * This method will get Name parameter defined in
-2133      * <a href="https://tools.ietf.org/html/rfc5280#section-4.1.2.4">
-2134      * RFC 5280 4.1.2.4</a>.
-2135      * <pre>
-2136      * Name ::= CHOICE { -- only one possibility for now --
-2137      *   rdnSequence  RDNSequence }
-2138      * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
-2139      * </pre>
-2140      * @example
-2141      * x = new X509();
-2142      * x.getX500NameArray("30...") →
-2143      * [[{type:"C",value:"US",ds:"prn"}],
-2144      *  [{type:"O",value:"Sample Corp.",ds:"utf8"}],
-2145      *  [{type:"CN",value:"john.smith@example.com",ds:"ia5"}]]
-2146      */
-2147     this.getX500NameArray = function(h) {
-2148 	var result = [];
-2149 	var a = _getChildIdx(h, 0);
-2150 	for (var i = 0; i < a.length; i++) {
-2151 	    result.push(this.getRDN(_getTLV(h, a[i])));
-2152 	}
-2153 	return result;
-2154     };
-2155     
-2156     /**
-2157      * get RelativeDistinguishedName ASN.1 structure parameter array<br/>
-2158      * @name getRDN
-2159      * @memberOf X509#
-2160      * @function
-2161      * @param {String} h hexadecimal string of RDN
-2162      * @return {Array} array of AttrTypeAndValue parameters
-2163      * @since jsrsasign 9.0.0 x509 2.0.0
-2164      * @see X509#getX500Name
-2165      * @see X509#getRDN
-2166      * @see X509#getAttrTypeAndValue
-2167      * @description
-2168      * This method will get RelativeDistinguishedName parameters defined in
-2169      * <a href="https://tools.ietf.org/html/rfc5280#section-4.1.2.4">
-2170      * RFC 5280 4.1.2.4</a>.
-2171      * <pre>
-2172      * RelativeDistinguishedName ::=
-2173      *   SET SIZE (1..MAX) OF AttributeTypeAndValue
-2174      * </pre>
-2175      * @example
-2176      * x = new X509();
-2177      * x.getRDN("31...") →
-2178      * [{type:"C",value:"US",ds:"prn"}] or
-2179      * [{type:"O",value:"Sample Corp.",ds:"prn"}] or
-2180      * [{type:"CN",value:"john.smith@example.com",ds:"ia5"}]
-2181      */
-2182     this.getRDN = function(h) {
-2183 	var result = [];
-2184 	var a = _getChildIdx(h, 0);
-2185 	for (var i = 0; i < a.length; i++) {
-2186 	    result.push(this.getAttrTypeAndValue(_getTLV(h, a[i])));
-2187 	}
-2188 	return result;
-2189     };
-2190 
-2191     /**
-2192      * get AttributeTypeAndValue ASN.1 structure parameter as JSON object<br/>
-2193      * @name getAttrTypeAndValue
-2194      * @memberOf X509#
-2195      * @function
-2196      * @param {String} h hexadecimal string of AttributeTypeAndValue
-2197      * @return {Object} JSON object of AttributeTypeAndValue parameters
-2198      * @since jsrsasign 9.0.0 x509 2.0.0
-2199      * @see X509#getX500Name
-2200      * @see X509#getRDN
-2201      * @description
-2202      * This method will get AttributeTypeAndValue parameters defined in
-2203      * <a href="https://tools.ietf.org/html/rfc5280#section-4.1.2.4">
-2204      * RFC 5280 4.1.2.4</a>.
-2205      * <pre>
-2206      * AttributeTypeAndValue ::= SEQUENCE {
-2207      *   type     AttributeType,
-2208      *   value    AttributeValue }
-2209      * AttributeType ::= OBJECT IDENTIFIER
-2210      * AttributeValue ::= ANY -- DEFINED BY AttributeType
-2211      * </pre>
-2212      * <ul>
-2213      * <li>{String}type - AttributeType name or OID(ex. C,O,CN)</li>
-2214      * <li>{String}value - raw string of ASN.1 value of AttributeValue</li>
-2215      * <li>{String}ds - DirectoryString type of AttributeValue</li>
-2216      * </ul>
-2217      * "ds" has one of following value:
-2218      * <ul>
-2219      * <li>utf8 - (0x0c) UTF8String</li>
-2220      * <li>prn  - (0x13) PrintableString</li>
-2221      * <li>ia5  - (0x16) IA5String</li>
-2222      * <li>vis  - (0x1a) VisibleString</li>
-2223      * <li>bmp  - (0x1e) BMPString</li>
-2224      * </ul>
-2225      * @example
-2226      * x = new X509();
-2227      * x.getAttrTypeAndValue("30...") →
-2228      * {type:"CN",value:"john.smith@example.com",ds:"ia5"} or
-2229      * {type:"O",value:"Sample Corp.",ds:"prn"}
-2230      */
-2231     // tel  - (0x14) TeletexString ... for future
-2232     // num  - (0x12) NumericString ... for future
-2233     // unv  - (0x1c??) UniversalString ... for future
-2234     this.getAttrTypeAndValue = function(h) {
-2235 	var result = {type: null, value: null, ds: null};
-2236 	var a = _getChildIdx(h, 0);
-2237 	var hOID = _getVbyList(h, a[0], [], "06");
-2238 	var hValue = _getVbyList(h, a[1], []);
-2239 	var oid = KJUR.asn1.ASN1Util.oidHexToInt(hOID);
-2240 	result.type = KJUR.asn1.x509.OID.oid2atype(oid);
-2241 	result.value = hextorstr(hValue);
-2242 	result.ds = this.HEX2STAG[h.substr(a[1], 2)];
-2243 	return result;
-2244     };
-2245 
-2246     // ===== END X500Name related =====================================
-2247 
-2248     // ===== BEGIN read certificate =====================================
-2249     /**
-2250      * read PEM formatted X.509 certificate from string.<br/>
-2251      * @name readCertPEM
-2252      * @memberOf X509#
-2253      * @function
-2254      * @param {String} sCertPEM string for PEM formatted X.509 certificate
-2255      * @example
-2256      * x = new X509();
-2257      * x.readCertPEM(sCertPEM); // read certificate
-2258      */
-2259     this.readCertPEM = function(sCertPEM) {
-2260         this.readCertHex(_pemtohex(sCertPEM));
-2261     };
-2262 
-2263     /**
-2264      * read a hexadecimal string of X.509 certificate<br/>
-2265      * @name readCertHex
-2266      * @memberOf X509#
-2267      * @function
-2268      * @param {String} sCertHex hexadecimal string of X.509 certificate
-2269      * @since jsrsasign 7.1.4 x509 1.1.13
-2270      * @description
-2271      * NOTE: {@link X509#parseExt} will called internally since jsrsasign 7.2.0.
-2272      * @example
-2273      * x = new X509();
-2274      * x.readCertHex("3082..."); // read certificate
-2275      */
-2276     this.readCertHex = function(sCertHex) {
-2277         this.hex = sCertHex;
-2278 	this.getVersion(); // set version parameter
-2279 
-2280 	try {
-2281 	    _getIdxbyList(this.hex, 0, [0, 7], "a3"); // has [3] v3ext
-2282 	    this.parseExt();
-2283 	} catch(ex) {};
-2284     };
-2285 
-2286     // ===== END read certificate =====================================
-2287 
-2288     /**
-2289      * get JSON object of certificate parameters<br/>
-2290      * @name getParam
-2291      * @memberOf X509#
-2292      * @function
-2293      * @return {Array} JSON object of certificate parameters
-2294      * @since jsrsasign 9.0.0 x509 2.0.0
-2295      * @see KJUR.asn1.x509.X509Util.newCertPEM
-2296      * @description
-2297      * This method returns a JSON object of the certificate
-2298      * parameters. Return value can be passed to
-2299      * {@link KJUR.asn1.x509.X509Util.newCertPEM}.
-2300      * @example
-2301      * x = new X509();
-2302      * x.readCertPEM("-----BEGIN CERTIFICATE...");
-2303      * x.getParam() →
-2304      * {version:3,
-2305      *  serial:{hex:"12ab"},
-2306      *  sigalg:"SHA256withRSA",
-2307      *  issuer: {array:[[{type:'CN',value:'CA1',ds:'prn'}]],str:"/O=CA1"},
-2308      *  notbefore:"160403023700Z",
-2309      *  notafter:"160702023700Z",
-2310      *  subject: {array:[[{type:'CN',value:'Test1',ds:'prn'}]],str:"/CN=Test1"},
-2311      *  sbjpubkey:"-----BEGIN PUBLIC KEY...",
-2312      *  ext:[
-2313      *   {extname:"keyUsage",critical:true,names:["digitalSignature"]},
-2314      *   {extname:"basicConstraints",critical:true},
-2315      *   {extname:"subjectKeyIdentifier",kid:{hex:"f2eb..."}},
-2316      *   {extname:"authorityKeyIdentifier",kid:{hex:"12ab..."}},
-2317      *   {extname:"authorityInfoAccess",array:[{ocsp:"http://ocsp.example.com/"}]},
-2318      *   {extname:"certificatePolicies",array:[{policyoid:"2.23.140.1.2.1"}]}
-2319      *  ],
-2320      *  sighex:"0b76...8"
-2321      * };
-2322      */
-2323     this.getParam = function() {
-2324 	var result = {};
-2325 	result.version = this.getVersion();
-2326 	result.serial = {hex: this.getSerialNumberHex()};
-2327 	result.sigalg = this.getSignatureAlgorithmField();
-2328 	result.issuer = this.getIssuer();
-2329 	result.notbefore = this.getNotBefore();
-2330 	result.notafter = this.getNotAfter();
-2331 	result.subject = this.getSubject();
-2332 	result.sbjpubkey = hextopem(this.getPublicKeyHex(), "PUBLIC KEY");
-2333 	if (this.aExtInfo.length > 0) {
-2334 	    result.ext = this.getExtParamArray();
-2335 	}
-2336 	result.sighex = this.getSignatureValueHex();
-2337 	return result;
-2338     };
-2339 
-2340     /** 
-2341      * get array of certificate extension parameter JSON object<br/>
-2342      * @name getExtParamArray
-2343      * @memberOf X509#
-2344      * @function
-2345      * @param {String} hExtSeq hexadecimal string of SEQUENCE of Extension
-2346      * @return {Array} array of certificate extension parameter JSON object
-2347      * @since jsrsasign 9.0.0 x509 2.0.0
-2348      * @see KJUR.asn1.x509.X509Util.newCertPEM
-2349      * @see X509#getParam
-2350      * @see X509#getExtParam
-2351      * @see X509CRL#getParam
-2352      * @see KJUR.asn1.csr.CSRUtil.getParam
-2353      *
-2354      * @description
-2355      * This method returns an array of certificate extension
-2356      * parameters. 
-2357      * <br/>
-2358      * NOTE: Argument "hExtSeq" have been supported since jsrsasign 9.1.1.
-2359      *
-2360      * @example
-2361      * x = new X509();
-2362      * x.readCertPEM("-----BEGIN CERTIFICATE...");
-2363      * x.getExtParamArray() →
-2364      * [ {extname:"keyUsage",critical:true,names:["digitalSignature"]},
-2365      *   {extname:"basicConstraints",critical:true},
-2366      *   {extname:"subjectKeyIdentifier",kid:{hex:"f2eb..."}},
-2367      *   {extname:"authorityKeyIdentifier",kid:{hex:"12ab..."}},
-2368      *   {extname:"authorityInfoAccess",array:[{ocsp:"http://ocsp.example.com/"}]},
-2369      *   {extname:"certificatePolicies",array:[{policyoid:"2.23.140.1.2.1"}]}]
-2370      */
-2371     this.getExtParamArray = function(hExtSeq) {
-2372 	if (hExtSeq == undefined) {
-2373 	    // for X.509v3 certificate
-2374 	    var idx1 = _getIdxbyListEx(this.hex, 0, [0, "[3]"]);
-2375 	    if (idx1 != -1) {
-2376 		hExtSeq = _getTLVbyListEx(this.hex, 0, [0, "[3]", 0], "30");
-2377 	    }
-2378 	}
-2379 	var result = [];
-2380 	var aIdx = _getChildIdx(hExtSeq, 0);
-2381 
-2382 	for (var i = 0; i < aIdx.length; i++) {
-2383 	    var hExt = _getTLV(hExtSeq, aIdx[i]);
-2384 	    var extParam = this.getExtParam(hExt);
-2385 	    if (extParam != null) result.push(extParam);
-2386 	}
-2387 
-2388 	return result;
-2389     };
-2390 
-2391     /** 
-2392      * get a extension parameter JSON object<br/>
-2393      * @name getExtParam
-2394      * @memberOf X509#
-2395      * @function
-2396      * @param {String} hExt hexadecimal string of Extension
-2397      * @return {Array} Extension parameter JSON object
-2398      * @since jsrsasign 9.1.1 x509 2.0.1
-2399      * @see KJUR.asn1.x509.X509Util.newCertPEM
-2400      * @see X509#getParam
-2401      * @see X509#getExtParamArray
-2402      * @see X509CRL#getParam
-2403      * @see KJUR.asn1.csr.CSRUtil.getParam
-2404      *
-2405      * @description
-2406      * This method returns a extension parameters as JSON object. 
-2407      *
-2408      * @example
-2409      * x = new X509();
-2410      * ...
-2411      * x.getExtParam("30...") →
-2412      * {extname:"keyUsage",critical:true,names:["digitalSignature"]}
-2413      */
-2414     this.getExtParam = function(hExt) {
-2415 	var result = {};
-2416 	var aIdx = _getChildIdx(hExt, 0);
-2417 	var aIdxLen = aIdx.length;
-2418 	if (aIdxLen != 2 && aIdxLen != 3)
-2419 	    throw new Error("wrong number elements in Extension: " + 
-2420 			    aIdxLen + " " + hExt);
-2421 
-2422 	var oid = _hextooidstr(_getVbyList(hExt, 0, [0], "06"));
-2423 
-2424 	var critical = false;
-2425 	if (aIdxLen == 3 && _getTLVbyList(hExt, 0, [1]) == "0101ff")
-2426 	    critical = true;
+1296 	    if (gnTag === "87") { // iPAddress [7]
+1297 		gnValueStr = hextoip(gnValueHex);
+1298 		result.push(["IP", gnValueStr]);
+1299 	    }
+1300 	}
+1301 	return result;
+1302     };
+1303 
+1304     /**
+1305      * get CRLDistributionPoints extension value as JSON object
+1306      * @name getExtCRLDistributionPoints
+1307      * @memberOf X509#
+1308      * @function
+1309      * @param {String} hExtV hexadecimal string of extension value (OPTIONAL)
+1310      * @param {Boolean} critical flag (OPTIONAL)
+1311      * @return {Object} JSON object of CRLDistributionPoints parameters or undefined
+1312      * @since jsrsasign 9.0.0 x509 2.0.0
+1313      * @see KJUR.asn1.x509.CRLDistributionPoints
+1314      * @see X509#getDistributionPoint
+1315      * @see X509#getDistributionPointName
+1316      * @see X509#getGeneralNames
+1317      * @see X509#getGeneralName
+1318      * @description
+1319      * This method will get certificate policies value
+1320      * as an array of JSON object which has properties defined
+1321      * in {@link KJUR.asn1.x509.CRLDistributionPoints}.
+1322      * Result of this method can be passed to 
+1323      * {@link KJUR.asn1.x509.CRLDistributionPoints} constructor.
+1324      * If there is no this extension in the certificate,
+1325      * it returns undefined.
+1326      * @example
+1327      * x = new X509();
+1328      * x.readCertPEM(sCertPEM); // parseExt() will also be called internally.
+1329      * x.getExtCRLDistributionPoints() → 
+1330      * {array: [
+1331      *   {dpname: {full: [{uri: "http://example.com/"}]}},
+1332      *   {dpname: {full: [{uri: "ldap://example.com/"}]}}
+1333      *  ],
+1334      *  critical: true}
+1335      */
+1336     this.getExtCRLDistributionPoints = function(hExtV, critical) {
+1337 	if (hExtV === undefined && critical === undefined) {
+1338 	    var info = this.getExtInfo("cRLDistributionPoints");
+1339 	    if (info === undefined) return undefined;
+1340 	    hExtV = _getTLV(this.hex, info.vidx);
+1341 	    critical = info.critical;
+1342 	}
+1343 
+1344 	var result = {extname:"cRLDistributionPoints",array:[]};
+1345 	if (critical) result.critical = true;
+1346 
+1347 	var a = _getChildIdx(hExtV, 0);
+1348 	for (var i = 0; i < a.length; i++) {
+1349 	    var hTLV = _getTLV(hExtV, a[i]);
+1350 	    result.array.push(this.getDistributionPoint(hTLV));
+1351 	}
+1352 
+1353 	return result;
+1354     };
+1355 
+1356     /**
+1357      * get DistributionPoint ASN.1 structure parameter as JSON object
+1358      * @name getDistributionPoint
+1359      * @memberOf X509#
+1360      * @function
+1361      * @param {String} h hexadecimal string of DistributionPoint
+1362      * @return {Object} JSON object of DistributionPoint parameters
+1363      * @since jsrsasign 9.0.0 x509 2.0.0
+1364      * @see X509#getExtCRLDistributionPoints
+1365      * @see X509#getDistributionPointName
+1366      * @see X509#getGeneralNames
+1367      * @see X509#getGeneralName
+1368      * @description
+1369      * This method will get DistributionPoint parameters.
+1370      * Result of this method can be passed to
+1371      * {@link KJUR.asn1.x509.DistributionPoint} constructor.
+1372      * <br/>
+1373      * NOTE: reasons[1] and CRLIssuer[2] field not supported
+1374      * @example
+1375      * x = new X509();
+1376      * x.getDistributionPoint("30...") →
+1377      * {dpname: {full: [{uri: "http://aaa.com/"}]}}
+1378      */
+1379     this.getDistributionPoint = function(h) {
+1380 	var result = {};
+1381 	var a = _getChildIdx(h, 0);
+1382 	for (var i = 0; i < a.length; i++) {
+1383 	    var tag = h.substr(a[i], 2);
+1384 	    var hTLV = _getTLV(h, a[i]);
+1385 	    if (tag == "a0") {
+1386 		result.dpname = this.getDistributionPointName(hTLV);
+1387 	    }
+1388 	}
+1389 	return result;
+1390     };
+1391 
+1392     /**
+1393      * get DistributionPointName ASN.1 structure parameter as JSON object
+1394      * @name getDistributionPointName
+1395      * @memberOf X509#
+1396      * @function
+1397      * @param {String} h hexadecimal string of DistributionPointName
+1398      * @return {Object} JSON object of DistributionPointName parameters
+1399      * @since jsrsasign 9.0.0 x509 2.0.0
+1400      * @see X509#getExtCRLDistributionPoints
+1401      * @see X509#getDistributionPoint
+1402      * @see X509#getGeneralNames
+1403      * @see X509#getGeneralName
+1404      * @description
+1405      * This method will get DistributionPointName parameters.
+1406      * Result of this method can be passed to
+1407      * {@link KJUR.asn1.x509.DistributionPointName} constructor.
+1408      * <br/>
+1409      * NOTE: nameRelativeToCRLIssuer[1] not supported
+1410      * @example
+1411      * x = new X509();
+1412      * x.getDistributionPointName("a0...") →
+1413      * {full: [{uri: "http://aaa.com/"}]}
+1414      */
+1415     this.getDistributionPointName = function(h) {
+1416 	var result = {};
+1417 	var a = _getChildIdx(h, 0);
+1418 	for (var i = 0; i < a.length; i++) {
+1419 	    var tag = h.substr(a[i], 2);
+1420 	    var hTLV = _getTLV(h, a[i]);
+1421 	    if (tag == "a0") {
+1422 		result.full = this.getGeneralNames(hTLV);
+1423 	    }
+1424 	}
+1425 	return result;
+1426     };
+1427 
+1428     /**
+1429      * get array of string for fullName URIs in cRLDistributionPoints(CDP) in the certificate (DEPRECATED)
+1430      * @name getExtCRLDistributionPointsURI
+1431      * @memberOf X509#
+1432      * @function
+1433      * @return {Object} array of fullName URIs of CDP of the certificate
+1434      * @since jsrsasign 7.2.0 x509 1.1.14
+1435      * @description
+1436      * This method will get all fullName URIs of cRLDistributionPoints extension
+1437      * in the certificate as array of URI string.
+1438      * If there is this in the certificate, it returns undefined;
+1439      * <br>
+1440      * NOTE: Currently this method supports only fullName URI so that
+1441      * other parameters will not be returned.
+1442      * @example
+1443      * x = new X509();
+1444      * x.readCertPEM(sCertPEM); // parseExt() will also be called internally.
+1445      * x.getExtCRLDistributionPointsURI() →
+1446      * ["http://example.com/aaa.crl", "http://example.org/aaa.crl"]
+1447      */
+1448     this.getExtCRLDistributionPointsURI = function() {
+1449 	var info = this.getExtInfo("cRLDistributionPoints");
+1450 	if (info === undefined) return info;
+1451 
+1452 	var result = new Array();
+1453 	var a = _getChildIdx(this.hex, info.vidx);
+1454 	for (var i = 0; i < a.length; i++) {
+1455 	    try {
+1456 		var hURI = _getVbyList(this.hex, a[i], [0, 0, 0], "86");
+1457 		var uri = hextoutf8(hURI);
+1458 		result.push(uri);
+1459 	    } catch(ex) {};
+1460 	}
+1461 
+1462 	return result;
+1463     };
+1464 
+1465     /**
+1466      * get AuthorityInfoAccess extension value in the certificate as associative array
+1467      * @name getExtAIAInfo
+1468      * @memberOf X509#
+1469      * @function
+1470      * @return {Object} associative array of AIA extension properties
+1471      * @since jsrsasign 7.2.0 x509 1.1.14
+1472      * @description
+1473      * This method will get authority info access value
+1474      * as associate array which has following properties:
+1475      * <ul>
+1476      * <li>ocsp - array of string for OCSP responder URL</li>
+1477      * <li>caissuer - array of string for caIssuer value (i.e. CA certificates URL)</li>
+1478      * </ul>
+1479      * If there is this in the certificate, it returns undefined;
+1480      * @example
+1481      * x = new X509();
+1482      * x.readCertPEM(sCertPEM); // parseExt() will also be called internally.
+1483      * x.getExtAIAInfo(hCert) → 
+1484      * { ocsp:     ["http://ocsp.foo.com"],
+1485      *   caissuer: ["http://rep.foo.com/aaa.p8m"] }
+1486      */
+1487     this.getExtAIAInfo = function() {
+1488 	var info = this.getExtInfo("authorityInfoAccess");
+1489 	if (info === undefined) return info;
+1490 
+1491 	var result = { ocsp: [], caissuer: [] };
+1492 	var a = _getChildIdx(this.hex, info.vidx);
+1493 	for (var i = 0; i < a.length; i++) {
+1494 	    var hOID = _getVbyList(this.hex, a[i], [0], "06");
+1495 	    var hName = _getVbyList(this.hex, a[i], [1], "86");
+1496 	    if (hOID === "2b06010505073001") {
+1497 		result.ocsp.push(hextoutf8(hName));
+1498 	    }
+1499 	    if (hOID === "2b06010505073002") {
+1500 		result.caissuer.push(hextoutf8(hName));
+1501 	    }
+1502 	}
+1503 
+1504 	return result;
+1505     };
+1506 
+1507     /**
+1508      * get AuthorityInfoAccess extension value as JSON object
+1509      * @name getExtAuthorityInfoAccess
+1510      * @memberOf X509#
+1511      * @function
+1512      * @param {String} hExtV hexadecimal string of extension value (OPTIONAL)
+1513      * @param {Boolean} critical flag (OPTIONAL)
+1514      * @return {Array} JSON object of AuthorityInfoAccess parameters or undefined
+1515      * @since jsrsasign 9.0.0 x509 2.0.0
+1516      * @see KJUR.asn1.x509.AuthorityInfoAccess
+1517      * @description
+1518      * This method parse authorityInfoAccess extension. When arguments are
+1519      * not specified, its extension in X509 object will be parsed.
+1520      * Result of this method can be passed to 
+1521      * {@link KJUR.asn1.x509.AuthorityInfoAccess} constructor.
+1522      * <br>
+1523      * When hExtV and critical specified as arguments, return value
+1524      * will be generated from them.
+1525      * @example
+1526      * x = new X509();
+1527      * x.readCertPEM(sCertPEM); // parseExt() will also be called internally.
+1528      * x.getExtAuthorityInfoAccess() →
+1529      * {
+1530      *   critial: true, // 
+1531      *   array: [{ocsp: http://ocsp.example.com/},
+1532      *           {caissuer: https://repository.example.com/}]
+1533      * }
+1534      *
+1535      * x = new X509();
+1536      * x.getExtAuthorityInfoAccesss("306230...") 
+1537      * x.getExtAuthorityInfoAccesss("306230...", true) 
+1538      */
+1539     this.getExtAuthorityInfoAccess = function(hExtV, critical) {
+1540 	if (hExtV === undefined && critical === undefined) {
+1541 	    var info = this.getExtInfo("authorityInfoAccess");
+1542 	    if (info === undefined) return undefined;
+1543 	    hExtV = _getTLV(this.hex, info.vidx);
+1544 	    critical = info.critical;
+1545 	}
+1546 
+1547 	var result = {extname:"authorityInfoAccess",array:[]};
+1548 	if (critical) result.critical = true;
+1549 
+1550 	var a = _getChildIdx(hExtV, 0);
+1551 	for (var i = 0; i < a.length; i++) {
+1552 	    var hMethod = _getVbyListEx(hExtV, a[i], [0], "06");
+1553 	    var hLoc = _getVbyList(hExtV, a[i], [1], "86");
+1554 	    var sLoc = hextoutf8(hLoc);
+1555 	    if (hMethod == "2b06010505073001") {
+1556 		result.array.push({ocsp: sLoc});
+1557 	    } else if (hMethod == "2b06010505073002") {
+1558 		result.array.push({caissuer: sLoc});
+1559 	    } else {
+1560 		throw new Error("unknown method: " + hMethod);
+1561 	    }
+1562 	}
+1563 
+1564 	return result;
+1565     }
+1566 
+1567     /**
+1568      * get CertificatePolicies extension value as JSON object
+1569      * @name getExtCertificatePolicies
+1570      * @memberOf X509#
+1571      * @function
+1572      * @param {String} hExtV hexadecimal string of extension value (OPTIONAL)
+1573      * @param {Boolean} critical flag (OPTIONAL)
+1574      * @return {Object} JSON object of CertificatePolicies parameters or undefined
+1575      * @since jsrsasign 7.2.0 x509 1.1.14
+1576      * @description
+1577      * This method will get certificate policies value
+1578      * as an array of JSON object which has properties defined
+1579      * in {@link KJUR.asn1.x509.CertificatePolicies}.
+1580      * Result of this method can be passed to 
+1581      * {@link KJUR.asn1.x509.CertificatePolicies} constructor.
+1582      * If there is no this extension in the certificate,
+1583      * it returns undefined.
+1584      * <br>
+1585      * CAUTION: return value of JSON object format have been changed
+1586      * from jsrsasign 9.0.0 without backword compatibility.
+1587      * <br>
+1588      * When hExtV and critical specified as arguments, return value
+1589      * will be generated from them.
+1590      * @example
+1591      * x = new X509();
+1592      * x.readCertPEM(sCertPEM); // parseExt() will also be called internally.
+1593      * x.getExtCertificatePolicies() → 
+1594      * { array: [
+1595      *   { policyoid: "1.2.3.4" }
+1596      *   { policyoid: "1.2.3.5",
+1597      *     array: [
+1598      *       { cps: "https://example.com/" },
+1599      *       { unotice: { exptext: { type: "bmp", str: "sample text" } } }
+1600      *     ] 
+1601      *   }
+1602      * ]}
+1603      */
+1604     this.getExtCertificatePolicies = function(hExtV, critical) {
+1605 	if (hExtV === undefined && critical === undefined) {
+1606 	    var info = this.getExtInfo("certificatePolicies");
+1607 	    if (info === undefined) return undefined;
+1608 	    hExtV = _getTLV(this.hex, info.vidx);
+1609 	    critical = info.critical;
+1610 	}
+1611 	var result = {extname:"certificatePolicies",array:[]};
+1612 	if (critical) result.critical = true;
+1613 
+1614 	var aIdxPI = _getChildIdx(hExtV, 0); // PolicyInformation list index
+1615 	for (var i = 0; i < aIdxPI.length; i++) {
+1616 	    var hPolicyInformation = _getTLV(hExtV, aIdxPI[i]);
+1617 	    var polinfo = this.getPolicyInformation(hPolicyInformation);
+1618 	    result.array.push(polinfo);
+1619 	}
+1620 	return result;
+1621     }
+1622 
+1623     /**
+1624      * get PolicyInformation ASN.1 structure parameter as JSON object
+1625      * @name getPolicyInformation
+1626      * @memberOf X509#
+1627      * @function
+1628      * @param {String} h hexadecimal string of PolicyInformation
+1629      * @return {Object} JSON object of PolicyInformation parameters
+1630      * @since jsrsasign 9.0.0 x509 2.0.0
+1631      * @description
+1632      * This method will get PolicyInformation parameters defined in
+1633      * <a href="https://tools.ietf.org/html/rfc5280#section-4.2.1.4">
+1634      * RFC 5280 4.2.1.4</a>.
+1635      * <pre>
+1636      * PolicyInformation ::= SEQUENCE {
+1637      *      policyIdentifier   CertPolicyId,
+1638      *      policyQualifiers   SEQUENCE SIZE (1..MAX) OF
+1639      *                              PolicyQualifierInfo OPTIONAL }
+1640      * </pre>
+1641      * Result of this method can be passed to
+1642      * {@link KJUR.asn1.x509.PolicyInformation} constructor.
+1643      * @example
+1644      * x = new X509();
+1645      * x.getPolicyInformation("30...") →
+1646      * {
+1647      *     policyoid: "2.16.840.1.114412.2.1",
+1648      *     array: [{cps: "https://www.digicert.com/CPS"}]
+1649      * }
+1650      */
+1651     this.getPolicyInformation = function(h) {
+1652 	var result = {};
+1653 
+1654 	var hPOLICYOID = _getVbyList(h, 0, [0], "06");
+1655 	result.policyoid = _oidname(hPOLICYOID);
+1656 	
+1657 	var idxPQSEQ = _getIdxbyListEx(h, 0, [1], "30");
+1658 	if (idxPQSEQ != -1) {
+1659 	    result.array = [];
+1660 	    var aIdx = _getChildIdx(h, idxPQSEQ);
+1661 	    for (var j = 0; j < aIdx.length; j++) {
+1662 		var hPQI = _getTLV(h, aIdx[j]);
+1663 		var pqinfo = this.getPolicyQualifierInfo(hPQI);
+1664 		result.array.push(pqinfo);
+1665 	    }
+1666 	}
+1667 
+1668 	return result;
+1669     };
+1670 
+1671     /**
+1672      * get PolicyQualifierInfo ASN.1 structure parameter as JSON object
+1673      * @name getPolicyQualifierInfo
+1674      * @memberOf X509#
+1675      * @function
+1676      * @param {String} h hexadecimal string of PolicyQualifierInfo
+1677      * @return {Object} JSON object of PolicyQualifierInfo parameters
+1678      * @since jsrsasign 9.0.0 x509 2.0.0
+1679      * @see X509#getExtCertificatePolicies
+1680      * @see X509#getPolicyInformation
+1681      * @description
+1682      * This method will get 
+1683      * <a href="https://tools.ietf.org/html/rfc5280#section-4.2.1.4">
+1684      * PolicyQualifierInfo</a> parameters.
+1685      * <pre>
+1686      * PolicyQualifierInfo ::= SEQUENCE {
+1687      *      policyQualifierId  PolicyQualifierId,
+1688      *      qualifier          ANY DEFINED BY policyQualifierId }
+1689      * id-qt          OBJECT IDENTIFIER ::=  { id-pkix 2 }
+1690      * id-qt-cps      OBJECT IDENTIFIER ::=  { id-qt 1 }
+1691      * id-qt-unotice  OBJECT IDENTIFIER ::=  { id-qt 2 }
+1692      * PolicyQualifierId ::= OBJECT IDENTIFIER ( id-qt-cps | id-qt-unotice )
+1693      * Qualifier ::= CHOICE {
+1694      *      cPSuri           CPSuri,
+1695      *      userNotice       UserNotice }
+1696      * CPSuri ::= IA5String
+1697      * </pre>
+1698      * Result of this method can be passed to 
+1699      * {@link KJUR.asn1.x509.PolicyQualifierInfo} constructor.
+1700      * @example
+1701      * x = new X509();
+1702      * x.getPolicyQualifierInfo("30...") 
+1703      * → {unotice: {exptext: {type: 'utf8', str: 'aaa'}}}
+1704      * x.getPolicyQualifierInfo("30...") 
+1705      * → {cps: "https://repository.example.com/"}
+1706      */
+1707     this.getPolicyQualifierInfo = function(h) {
+1708 	var result = {};
+1709 	var hPQOID = _getVbyList(h, 0, [0], "06");
+1710 	if (hPQOID === "2b06010505070201") { // cps
+1711 	    var hCPSURI = _getVbyListEx(h, 0, [1], "16");
+1712 	    result.cps = hextorstr(hCPSURI);
+1713 	} else if (hPQOID === "2b06010505070202") { // unotice
+1714 	    var hUserNotice = _getTLVbyList(h, 0, [1], "30");
+1715 	    result.unotice = this.getUserNotice(hUserNotice);
+1716 	}
+1717 	return result;
+1718     };
+1719 
+1720     /**
+1721      * get UserNotice ASN.1 structure parameter as JSON object
+1722      * @name getUserNotice
+1723      * @memberOf X509#
+1724      * @function
+1725      * @param {String} h hexadecimal string of UserNotice
+1726      * @return {Object} JSON object of UserNotice parameters
+1727      * @since jsrsasign 9.0.0 x509 2.0.0
+1728      * @see X509#getExtCertificatePolicies
+1729      * @see X509#getPolicyInformation
+1730      * @see X509#getPolicyQualifierInfo
+1731      * @description
+1732      * This method will get 
+1733      * <a href="https://tools.ietf.org/html/rfc5280#section-4.2.1.4">
+1734      * UserNotice</a> parameters.
+1735      * <pre>
+1736      * UserNotice ::= SEQUENCE {
+1737      *      noticeRef        NoticeReference OPTIONAL,
+1738      *      explicitText     DisplayText OPTIONAL }
+1739      * </pre>
+1740      * Result of this method can be passed to 
+1741      * {@link KJUR.asn1.x509.NoticeReference} constructor.
+1742      * <br/>
+1743      * NOTE: NoticeReference parsing is currently not supported and
+1744      * it will be ignored.
+1745      * @example
+1746      * x = new X509();
+1747      * x.getUserNotice("30...") → {exptext: {type: 'utf8', str: 'aaa'}}
+1748      */
+1749     this.getUserNotice = function(h) {
+1750 	var result = {};
+1751 	var a = _getChildIdx(h, 0);
+1752 	for (var i = 0; i < a.length; i++) {
+1753 	    var hItem = _getTLV(h, a[i]);
+1754 	    if (hItem.substr(0, 2) != "30") {
+1755 		result.exptext = this.getDisplayText(hItem);
+1756 	    }
+1757 	}
+1758 	return result;
+1759     };
+1760 
+1761     /**
+1762      * get DisplayText ASN.1 structure parameter as JSON object
+1763      * @name getDisplayText
+1764      * @memberOf X509#
+1765      * @function
+1766      * @param {String} h hexadecimal string of DisplayText
+1767      * @return {Object} JSON object of DisplayText parameters
+1768      * @since jsrsasign 9.0.0 x509 2.0.0
+1769      * @see X509#getExtCertificatePolicies
+1770      * @see X509#getPolicyInformation
+1771      * @description
+1772      * This method will get 
+1773      * <a href="https://tools.ietf.org/html/rfc5280#section-4.2.1.4">
+1774      * DisplayText</a> parameters.
+1775      * <pre>
+1776      * DisplayText ::= CHOICE {
+1777      *      ia5String        IA5String      (SIZE (1..200)),
+1778      *      visibleString    VisibleString  (SIZE (1..200)),
+1779      *      bmpString        BMPString      (SIZE (1..200)),
+1780      *      utf8String       UTF8String     (SIZE (1..200)) }     
+1781      * </pre>
+1782      * Result of this method can be passed to 
+1783      * {@link KJUR.asn1.x509.DisplayText} constructor.
+1784      * @example
+1785      * x = new X509();
+1786      * x.getDisplayText("0c03616161") &rarr {type: 'utf8', str: 'aaa'}
+1787      * x.getDisplayText("1e03616161") &rarr {type: 'bmp',  str: 'aaa'}
+1788      */
+1789     this.getDisplayText = function(h) {
+1790 	var _DISPLAYTEXTTAG = {"0c": "utf8", "16": "ia5", "1a": "vis" , "1e": "bmp"};
+1791 	var result = {};
+1792 	result.type = _DISPLAYTEXTTAG[h.substr(0, 2)];
+1793 	result.str = hextorstr(_getV(h, 0));
+1794 	return result;
+1795     };
+1796 
+1797     /**
+1798      * parse cRLNumber CRL extension as JSON object<br/>
+1799      * @name getExtCRLNumber
+1800      * @memberOf X509#
+1801      * @function
+1802      * @param {String} hExtV hexadecimal string of extension value
+1803      * @param {Boolean} critical flag
+1804      * @since jsrsasign 9.1.1 x509 2.0.1
+1805      * @see KJUR.asn1.x509.CRLNumber
+1806      * @see X509#getExtParamArray
+1807      * @description
+1808      * This method parses
+1809      * CRLNumber CRL extension value defined in
+1810      * <a href="https://tools.ietf.org/html/rfc5280#section-5.2.3">
+1811      * RFC 5280 5.2.3</a> as JSON object.
+1812      * <pre>
+1813      * id-ce-cRLNumber OBJECT IDENTIFIER ::= { id-ce 20 }
+1814      * CRLNumber ::= INTEGER (0..MAX)
+1815      * </pre>
+1816      * <br/>
+1817      * Result of this method can be passed to 
+1818      * {@link KJUR.asn1.x509.CRLNumber} constructor.
+1819      * @example
+1820      * crl = X509CRL("-----BEGIN X509 CRL...");
+1821      * ... get hExtV and critical flag ...
+1822      * crl.getExtCRLNumber("02...", false) →
+1823      * {extname: "cRLNumber", num: {hex: "12af"}}
+1824      */
+1825     this.getExtCRLNumber = function(hExtV, critical) {
+1826 	var result = {extname:"cRLNumber"};
+1827 	if (critical) result.critical = true;
+1828 
+1829 	if (hExtV.substr(0, 2) == "02") {
+1830 	    result.num = {hex: _getV(hExtV, 0)};
+1831 	    return result;
+1832 	}
+1833 	throw new Error("hExtV parse error: " + hExtV);
+1834     };
+1835 
+1836     /**
+1837      * parse cRLReason CRL entry extension as JSON object<br/>
+1838      * @name getExtCRLReason
+1839      * @memberOf X509#
+1840      * @function
+1841      * @param {String} hExtV hexadecimal string of extension value
+1842      * @param {Boolean} critical flag
+1843      * @since jsrsasign 9.1.1 x509 2.0.1
+1844      * @see KJUR.asn1.x509.CRLReason
+1845      * @see X509#getExtParamArray
+1846      * @description
+1847      * This method parses
+1848      * CRLReason CRL entry extension value defined in
+1849      * <a href="https://tools.ietf.org/html/rfc5280#section-5.3.1">
+1850      * RFC 5280 5.3.1</a> as JSON object.
+1851      * <pre>
+1852      * id-ce-cRLReasons OBJECT IDENTIFIER ::= { id-ce 21 }
+1853      * -- reasonCode ::= { CRLReason }
+1854      * CRLReason ::= ENUMERATED {
+1855      *      unspecified             (0),
+1856      *      keyCompromise           (1),
+1857      *      cACompromise            (2),
+1858      *      affiliationChanged      (3),
+1859      *      superseded              (4),
+1860      *      cessationOfOperation    (5),
+1861      *      certificateHold         (6),
+1862      *      removeFromCRL           (8),
+1863      *      privilegeWithdrawn      (9),
+1864      *      aACompromise           (10) }
+1865      * </pre>
+1866      * <br/>
+1867      * Result of this method can be passed to 
+1868      * {@link KJUR.asn1.x509.CRLReason} constructor.
+1869      * @example
+1870      * crl = X509CRL("-----BEGIN X509 CRL...");
+1871      * ... get hExtV and critical flag ...
+1872      * crl.getExtCRLReason("02...", false) →
+1873      * {extname: "cRLReason", code: 3}
+1874      */
+1875     this.getExtCRLReason = function(hExtV, critical) {
+1876 	var result = {extname:"cRLReason"};
+1877 	if (critical) result.critical = true;
+1878 
+1879 	if (hExtV.substr(0, 2) == "0a") {
+1880 	    result.code = parseInt(_getV(hExtV, 0), 16);
+1881 	    return result;
+1882 	}
+1883 	throw new Error("hExtV parse error: " + hExtV);
+1884     };
+1885 
+1886     /**
+1887      * parse OCSPNonce OCSP extension as JSON object<br/>
+1888      * @name getExtOCSPNonce
+1889      * @memberOf X509#
+1890      * @function
+1891      * @param {String} hExtV hexadecimal string of extension value
+1892      * @param {Boolean} critical flag
+1893      * @return {Array} JSON object of parsed OCSPNonce extension
+1894      * @since jsrsasign 9.1.6 x509 2.0.3
+1895      * @see KJUR.asn1.x509.OCSPNonce
+1896      * @see X509#getExtParamArray
+1897      * @see X509#getExtParam
+1898      * @description
+1899      * This method parses
+1900      * Nonce OCSP extension value defined in
+1901      * <a href="https://tools.ietf.org/html/rfc6960#section-4.4.1">
+1902      * RFC 6960 4.4.1</a> as JSON object.
+1903      * <pre>
+1904      * id-pkix-ocsp           OBJECT IDENTIFIER ::= { id-ad-ocsp }
+1905      * id-pkix-ocsp-nonce     OBJECT IDENTIFIER ::= { id-pkix-ocsp 2 }
+1906      * Nonce ::= OCTET STRING
+1907      * </pre>
+1908      * <br/>
+1909      * Result of this method can be passed to 
+1910      * {@link KJUR.asn1.x509.OCSPNonce} constructor.
+1911      * @example
+1912      * x = new X509();
+1913      * x.getExtOCSPNonce(<<extn hex value >>) →
+1914      * { extname: "ocspNonce", hex: "1a2b..." }
+1915      */
+1916     this.getExtOcspNonce = function(hExtV, critical) {
+1917 	var result = {extname:"ocspNonce"};
+1918 	if (critical) result.critical = true;
+1919 
+1920 	var hNonce = _getV(hExtV, 0);
+1921 	result.hex = hNonce;
+1922 
+1923 	return result;
+1924     };
+1925 
+1926     /**
+1927      * parse OCSPNoCheck OCSP extension as JSON object<br/>
+1928      * @name getExtOCSPNoCheck
+1929      * @memberOf X509#
+1930      * @function
+1931      * @param {String} hExtV hexadecimal string of extension value
+1932      * @param {Boolean} critical flag
+1933      * @return {Array} JSON object of parsed OCSPNoCheck extension
+1934      * @since jsrsasign 9.1.6 x509 2.0.3
+1935      * @see KJUR.asn1.x509.OCSPNoCheck
+1936      * @see X509#getExtParamArray
+1937      * @see X509#getExtParam
+1938      * @description
+1939      * This method parses
+1940      * OCSPNoCheck extension value defined in
+1941      * <a href="https://tools.ietf.org/html/rfc6960#section-4.2.2.2.1">
+1942      * RFC 6960 4.2.2.2.1</a> as JSON object.
+1943      * <pre>
+1944      * id-pkix-ocsp-nocheck OBJECT IDENTIFIER ::= { id-pkix-ocsp 5 }
+1945      * </pre>
+1946      * <br/>
+1947      * Result of this method can be passed to 
+1948      * {@link KJUR.asn1.x509.OCSPNoCheck} constructor.
+1949      * @example
+1950      * x = new X509();
+1951      * x.getExtOCSPNoCheck(<<extn hex value >>) →
+1952      * { extname: "ocspNoCheck" }
+1953      */
+1954     this.getExtOcspNoCheck = function(hExtV, critical) {
+1955 	var result = {extname:"ocspNoCheck"};
+1956 	if (critical) result.critical = true;
+1957 
+1958 	return result;
+1959     };
+1960 
+1961     /**
+1962      * parse AdobeTimeStamp extension as JSON object<br/>
+1963      * @name getExtAdobeTimeStamp
+1964      * @memberOf X509#
+1965      * @function
+1966      * @param {String} hExtV hexadecimal string of extension value
+1967      * @param {Boolean} critical flag
+1968      * @return {Array} JSON object of parsed AdobeTimeStamp extension
+1969      * @since jsrsasign 10.0.1 x509 2.0.5
+1970      * @see KJUR.asn1.x509.AdobeTimeStamp
+1971      * @see X509#getExtParamArray
+1972      * @see X509#getExtParam
+1973      * @description
+1974      * This method parses
+1975      * X.509v3 AdobeTimeStamp private extension value defined in the
+1976      * <a href="https://www.adobe.com/devnet-docs/acrobatetk/tools/DigSigDC/oids.html">
+1977      * Adobe site</a> as JSON object.
+1978      * This extension provides the URL location for time stamp service.
+1979      * <pre>
+1980      * adbe- OBJECT IDENTIFIER ::=  { adbe(1.2.840.113583) acrobat(1) security(1) x509Ext(9) 1 }
+1981      *  ::= SEQUENCE {
+1982      *     version INTEGER  { v1(1) }, -- extension version
+1983      *     location GeneralName (In v1 GeneralName can be only uniformResourceIdentifier)
+1984      *     requiresAuth        boolean (default false), OPTIONAL }
+1985      * </pre>
+1986      * <br/>
+1987      * Result of this method can be passed to 
+1988      * {@link KJUR.asn1.x509.AdobeTimeStamp} constructor.
+1989      * <br/>
+1990      * NOTE: This extesion doesn't seem to have official name. This may be called as "pdfTimeStamp".
+1991      * @example
+1992      * x.getExtAdobeTimeStamp(<<extn hex value >>) →
+1993      * { extname: "adobeTimeStamp", uri: "http://tsa.example.com/" reqauth: true }
+1994      */
+1995     this.getExtAdobeTimeStamp = function(hExtV, critical) {
+1996 	if (hExtV === undefined && critical === undefined) {
+1997 	    var info = this.getExtInfo("adobeTimeStamp");
+1998 	    if (info === undefined) return undefined;
+1999 	    hExtV = _getTLV(this.hex, info.vidx);
+2000 	    critical = info.critical;
+2001 	}
+2002 
+2003 	var result = {extname:"adobeTimeStamp"};
+2004 	if (critical) result.critical = true;
+2005 
+2006 	var a = _getChildIdx(hExtV, 0);
+2007 	if (a.length > 1) {
+2008 	    var hGN = _getTLV(hExtV, a[1])
+2009 	    var gnParam = this.getGeneralName(hGN);
+2010 	    if (gnParam.uri != undefined) {
+2011 		result.uri = gnParam.uri;
+2012 	    }
+2013 	}
+2014 	if (a.length > 2) {
+2015 	    var hBool = _getTLV(hExtV, a[2]);
+2016 	    if (hBool == "0101ff") result.reqauth = true;
+2017 	    if (hBool == "010100") result.reqauth = false;
+2018 	}
+2019 
+2020 	return result;
+2021     };
+2022 
+2023     // ===== BEGIN X500Name related =====================================
+2024 
+2025     this.getX500NameRule = function(aDN) {
+2026 	var isPRNRule = true;
+2027 	var isUTF8Rule = true;
+2028 	var isMixedRule = false;
+2029 	var logfull = "";
+2030 	var logcheck = "";
+2031 	var lasttag = null;
+2032 
+2033 	var a = [];
+2034 	for (var i = 0; i < aDN.length; i++) {
+2035 	    var aRDN = aDN[i];
+2036 	    for (var j = 0; j < aRDN.length; j++) {
+2037 		a.push(aRDN[j]);
+2038 	    }
+2039 	}
+2040 
+2041 	for (var i = 0; i < a.length; i++) {
+2042 	    var item = a[i];
+2043 	    var tag = item.ds;
+2044 	    var value = item.value;
+2045 	    var type = item.type;
+2046 	    logfull += ":" + tag;
+2047 	    
+2048 	    if (tag != "prn" && tag != "utf8" && tag != "ia5") {
+2049 		return "mixed";
+2050 	    }
+2051 	    if (tag == "ia5") {
+2052 		if (type != "CN") {
+2053 		    return "mixed";
+2054 		} else {
+2055 		    if (! KJUR.lang.String.isMail(value)) {
+2056 			return "mixed";
+2057 		    } else {
+2058 			continue;
+2059 		    }
+2060 		}
+2061 	    }
+2062 	    if (type == "C") {
+2063 		if (tag == "prn") {
+2064 		    continue;
+2065 		} else {
+2066 		    return "mixed";
+2067 		}
+2068 	    }
+2069 	    logcheck += ":" + tag;
+2070 	    if (lasttag == null) {
+2071 		lasttag = tag;
+2072 	    } else {
+2073 		if (lasttag !== tag) return "mixed";
+2074 	    }
+2075 	}
+2076 	if (lasttag == null) {
+2077 	    return "prn";
+2078 	} else {
+2079 	    return lasttag;
+2080 	}
+2081     };
+2082 
+2083     /**
+2084      * get Name ASN.1 structure parameter array<br/>
+2085      * @name getX500Name
+2086      * @memberOf X509#
+2087      * @function
+2088      * @param {String} h hexadecimal string of Name
+2089      * @return {Array} array of RDN parameter array
+2090      * @since jsrsasign 9.0.0 x509 2.0.0
+2091      * @see X509#getX500NameArray
+2092      * @see X509#getRDN
+2093      * @see X509#getAttrTypeAndValue
+2094      * @see KJUR.asn1.x509.X500Name
+2095      * @see KJUR.asn1.x509.GeneralName
+2096      * @see KJUR.asn1.x509.GeneralNames
+2097      * @description
+2098      * This method will get Name parameter defined in
+2099      * <a href="https://tools.ietf.org/html/rfc5280#section-4.1.2.4">
+2100      * RFC 5280 4.1.2.4</a>.
+2101      * <pre>
+2102      * Name ::= CHOICE { -- only one possibility for now --
+2103      *   rdnSequence  RDNSequence }
+2104      * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
+2105      * </pre>
+2106      * @example
+2107      * x = new X509();
+2108      * x.getX500Name("30...") →
+2109      * { array: [
+2110      *     [{type:"C",value:"US",ds:"prn"}],
+2111      *     [{type:"O",value:"Sample Corp.",ds:"utf8"}],
+2112      *     [{type:"CN",value:"john.smith@example.com",ds:"ia5"}]
+2113      *   ],
+2114      *   str: "/C=US/O=Sample Corp./CN=john.smith@example.com",
+2115      *   hex: "30..."
+2116      * }
+2117      */
+2118     this.getX500Name = function(h) {
+2119 	var a = this.getX500NameArray(h);
+2120 	var s = this.dnarraytostr(a);
+2121 	return { array: a, str: s };
+2122     };
+2123 
+2124     /**
+2125      * get X.500 Name ASN.1 structure parameter array<br/>
+2126      * @name getX500NameArray
+2127      * @memberOf X509#
+2128      * @function
+2129      * @param {String} h hexadecimal string of Name
+2130      * @return {Array} array of RDN parameter array
+2131      * @since jsrsasign 10.0.6 x509 2.0.9
+2132      * @see X509#getX500Name
+2133      * @see X509#getRDN
+2134      * @see X509#getAttrTypeAndValue
+2135      * @description
+2136      * This method will get Name parameter defined in
+2137      * <a href="https://tools.ietf.org/html/rfc5280#section-4.1.2.4">
+2138      * RFC 5280 4.1.2.4</a>.
+2139      * <pre>
+2140      * Name ::= CHOICE { -- only one possibility for now --
+2141      *   rdnSequence  RDNSequence }
+2142      * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
+2143      * </pre>
+2144      * @example
+2145      * x = new X509();
+2146      * x.getX500NameArray("30...") →
+2147      * [[{type:"C",value:"US",ds:"prn"}],
+2148      *  [{type:"O",value:"Sample Corp.",ds:"utf8"}],
+2149      *  [{type:"CN",value:"john.smith@example.com",ds:"ia5"}]]
+2150      */
+2151     this.getX500NameArray = function(h) {
+2152 	var result = [];
+2153 	var a = _getChildIdx(h, 0);
+2154 	for (var i = 0; i < a.length; i++) {
+2155 	    result.push(this.getRDN(_getTLV(h, a[i])));
+2156 	}
+2157 	return result;
+2158     };
+2159     
+2160     /**
+2161      * get RelativeDistinguishedName ASN.1 structure parameter array<br/>
+2162      * @name getRDN
+2163      * @memberOf X509#
+2164      * @function
+2165      * @param {String} h hexadecimal string of RDN
+2166      * @return {Array} array of AttrTypeAndValue parameters
+2167      * @since jsrsasign 9.0.0 x509 2.0.0
+2168      * @see X509#getX500Name
+2169      * @see X509#getRDN
+2170      * @see X509#getAttrTypeAndValue
+2171      * @description
+2172      * This method will get RelativeDistinguishedName parameters defined in
+2173      * <a href="https://tools.ietf.org/html/rfc5280#section-4.1.2.4">
+2174      * RFC 5280 4.1.2.4</a>.
+2175      * <pre>
+2176      * RelativeDistinguishedName ::=
+2177      *   SET SIZE (1..MAX) OF AttributeTypeAndValue
+2178      * </pre>
+2179      * @example
+2180      * x = new X509();
+2181      * x.getRDN("31...") →
+2182      * [{type:"C",value:"US",ds:"prn"}] or
+2183      * [{type:"O",value:"Sample Corp.",ds:"prn"}] or
+2184      * [{type:"CN",value:"john.smith@example.com",ds:"ia5"}]
+2185      */
+2186     this.getRDN = function(h) {
+2187 	var result = [];
+2188 	var a = _getChildIdx(h, 0);
+2189 	for (var i = 0; i < a.length; i++) {
+2190 	    result.push(this.getAttrTypeAndValue(_getTLV(h, a[i])));
+2191 	}
+2192 	return result;
+2193     };
+2194 
+2195     /**
+2196      * get AttributeTypeAndValue ASN.1 structure parameter as JSON object<br/>
+2197      * @name getAttrTypeAndValue
+2198      * @memberOf X509#
+2199      * @function
+2200      * @param {String} h hexadecimal string of AttributeTypeAndValue
+2201      * @return {Object} JSON object of AttributeTypeAndValue parameters
+2202      * @since jsrsasign 9.0.0 x509 2.0.0
+2203      * @see X509#getX500Name
+2204      * @see X509#getRDN
+2205      * @description
+2206      * This method will get AttributeTypeAndValue parameters defined in
+2207      * <a href="https://tools.ietf.org/html/rfc5280#section-4.1.2.4">
+2208      * RFC 5280 4.1.2.4</a>.
+2209      * <pre>
+2210      * AttributeTypeAndValue ::= SEQUENCE {
+2211      *   type     AttributeType,
+2212      *   value    AttributeValue }
+2213      * AttributeType ::= OBJECT IDENTIFIER
+2214      * AttributeValue ::= ANY -- DEFINED BY AttributeType
+2215      * </pre>
+2216      * <ul>
+2217      * <li>{String}type - AttributeType name or OID(ex. C,O,CN)</li>
+2218      * <li>{String}value - raw string of ASN.1 value of AttributeValue</li>
+2219      * <li>{String}ds - DirectoryString type of AttributeValue</li>
+2220      * </ul>
+2221      * "ds" has one of following value:
+2222      * <ul>
+2223      * <li>utf8 - (0x0c) UTF8String</li>
+2224      * <li>prn  - (0x13) PrintableString</li>
+2225      * <li>ia5  - (0x16) IA5String</li>
+2226      * <li>vis  - (0x1a) VisibleString</li>
+2227      * <li>bmp  - (0x1e) BMPString</li>
+2228      * </ul>
+2229      * @example
+2230      * x = new X509();
+2231      * x.getAttrTypeAndValue("30...") →
+2232      * {type:"CN",value:"john.smith@example.com",ds:"ia5"} or
+2233      * {type:"O",value:"Sample Corp.",ds:"prn"}
+2234      */
+2235     // tel  - (0x14) TeletexString ... for future
+2236     // num  - (0x12) NumericString ... for future
+2237     // unv  - (0x1c??) UniversalString ... for future
+2238     this.getAttrTypeAndValue = function(h) {
+2239 	var result = {type: null, value: null, ds: null};
+2240 	var a = _getChildIdx(h, 0);
+2241 	var hOID = _getVbyList(h, a[0], [], "06");
+2242 	var hValue = _getVbyList(h, a[1], []);
+2243 	var oid = KJUR.asn1.ASN1Util.oidHexToInt(hOID);
+2244 	result.type = KJUR.asn1.x509.OID.oid2atype(oid);
+2245 	result.value = hextoutf8(hValue);
+2246 	result.ds = this.HEX2STAG[h.substr(a[1], 2)];
+2247 	return result;
+2248     };
+2249 
+2250     // ===== END X500Name related =====================================
+2251 
+2252     // ===== BEGIN read certificate =====================================
+2253     /**
+2254      * read PEM formatted X.509 certificate from string.<br/>
+2255      * @name readCertPEM
+2256      * @memberOf X509#
+2257      * @function
+2258      * @param {String} sCertPEM string for PEM formatted X.509 certificate
+2259      * @example
+2260      * x = new X509();
+2261      * x.readCertPEM(sCertPEM); // read certificate
+2262      */
+2263     this.readCertPEM = function(sCertPEM) {
+2264         this.readCertHex(_pemtohex(sCertPEM));
+2265     };
+2266 
+2267     /**
+2268      * read a hexadecimal string of X.509 certificate<br/>
+2269      * @name readCertHex
+2270      * @memberOf X509#
+2271      * @function
+2272      * @param {String} sCertHex hexadecimal string of X.509 certificate
+2273      * @since jsrsasign 7.1.4 x509 1.1.13
+2274      * @description
+2275      * NOTE: {@link X509#parseExt} will called internally since jsrsasign 7.2.0.
+2276      * @example
+2277      * x = new X509();
+2278      * x.readCertHex("3082..."); // read certificate
+2279      */
+2280     this.readCertHex = function(sCertHex) {
+2281         this.hex = sCertHex;
+2282 	this.getVersion(); // set version parameter
+2283 
+2284 	try {
+2285 	    _getIdxbyList(this.hex, 0, [0, 7], "a3"); // has [3] v3ext
+2286 	    this.parseExt();
+2287 	} catch(ex) {};
+2288     };
+2289 
+2290     // ===== END read certificate =====================================
+2291 
+2292     /**
+2293      * get JSON object of certificate parameters<br/>
+2294      * @name getParam
+2295      * @memberOf X509#
+2296      * @function
+2297      * @return {Array} JSON object of certificate parameters
+2298      * @since jsrsasign 9.0.0 x509 2.0.0
+2299      * @see KJUR.asn1.x509.X509Util.newCertPEM
+2300      * @description
+2301      * This method returns a JSON object of the certificate
+2302      * parameters. Return value can be passed to
+2303      * {@link KJUR.asn1.x509.X509Util.newCertPEM}.
+2304      * @example
+2305      * x = new X509();
+2306      * x.readCertPEM("-----BEGIN CERTIFICATE...");
+2307      * x.getParam() →
+2308      * {version:3,
+2309      *  serial:{hex:"12ab"},
+2310      *  sigalg:"SHA256withRSA",
+2311      *  issuer: {array:[[{type:'CN',value:'CA1',ds:'prn'}]],str:"/O=CA1"},
+2312      *  notbefore:"160403023700Z",
+2313      *  notafter:"160702023700Z",
+2314      *  subject: {array:[[{type:'CN',value:'Test1',ds:'prn'}]],str:"/CN=Test1"},
+2315      *  sbjpubkey:"-----BEGIN PUBLIC KEY...",
+2316      *  ext:[
+2317      *   {extname:"keyUsage",critical:true,names:["digitalSignature"]},
+2318      *   {extname:"basicConstraints",critical:true},
+2319      *   {extname:"subjectKeyIdentifier",kid:{hex:"f2eb..."}},
+2320      *   {extname:"authorityKeyIdentifier",kid:{hex:"12ab..."}},
+2321      *   {extname:"authorityInfoAccess",array:[{ocsp:"http://ocsp.example.com/"}]},
+2322      *   {extname:"certificatePolicies",array:[{policyoid:"2.23.140.1.2.1"}]}
+2323      *  ],
+2324      *  sighex:"0b76...8"
+2325      * };
+2326      */
+2327     this.getParam = function() {
+2328 	var result = {};
+2329 	result.version = this.getVersion();
+2330 	result.serial = {hex: this.getSerialNumberHex()};
+2331 	result.sigalg = this.getSignatureAlgorithmField();
+2332 	result.issuer = this.getIssuer();
+2333 	result.notbefore = this.getNotBefore();
+2334 	result.notafter = this.getNotAfter();
+2335 	result.subject = this.getSubject();
+2336 	result.sbjpubkey = hextopem(this.getPublicKeyHex(), "PUBLIC KEY");
+2337 	if (this.aExtInfo.length > 0) {
+2338 	    result.ext = this.getExtParamArray();
+2339 	}
+2340 	result.sighex = this.getSignatureValueHex();
+2341 	return result;
+2342     };
+2343 
+2344     /** 
+2345      * get array of certificate extension parameter JSON object<br/>
+2346      * @name getExtParamArray
+2347      * @memberOf X509#
+2348      * @function
+2349      * @param {String} hExtSeq hexadecimal string of SEQUENCE of Extension
+2350      * @return {Array} array of certificate extension parameter JSON object
+2351      * @since jsrsasign 9.0.0 x509 2.0.0
+2352      * @see KJUR.asn1.x509.X509Util.newCertPEM
+2353      * @see X509#getParam
+2354      * @see X509#getExtParam
+2355      * @see X509CRL#getParam
+2356      * @see KJUR.asn1.csr.CSRUtil.getParam
+2357      *
+2358      * @description
+2359      * This method returns an array of certificate extension
+2360      * parameters. 
+2361      * <br/>
+2362      * NOTE: Argument "hExtSeq" have been supported since jsrsasign 9.1.1.
+2363      *
+2364      * @example
+2365      * x = new X509();
+2366      * x.readCertPEM("-----BEGIN CERTIFICATE...");
+2367      * x.getExtParamArray() →
+2368      * [ {extname:"keyUsage",critical:true,names:["digitalSignature"]},
+2369      *   {extname:"basicConstraints",critical:true},
+2370      *   {extname:"subjectKeyIdentifier",kid:{hex:"f2eb..."}},
+2371      *   {extname:"authorityKeyIdentifier",kid:{hex:"12ab..."}},
+2372      *   {extname:"authorityInfoAccess",array:[{ocsp:"http://ocsp.example.com/"}]},
+2373      *   {extname:"certificatePolicies",array:[{policyoid:"2.23.140.1.2.1"}]}]
+2374      */
+2375     this.getExtParamArray = function(hExtSeq) {
+2376 	if (hExtSeq == undefined) {
+2377 	    // for X.509v3 certificate
+2378 	    var idx1 = _getIdxbyListEx(this.hex, 0, [0, "[3]"]);
+2379 	    if (idx1 != -1) {
+2380 		hExtSeq = _getTLVbyListEx(this.hex, 0, [0, "[3]", 0], "30");
+2381 	    }
+2382 	}
+2383 	var result = [];
+2384 	var aIdx = _getChildIdx(hExtSeq, 0);
+2385 
+2386 	for (var i = 0; i < aIdx.length; i++) {
+2387 	    var hExt = _getTLV(hExtSeq, aIdx[i]);
+2388 	    var extParam = this.getExtParam(hExt);
+2389 	    if (extParam != null) result.push(extParam);
+2390 	}
+2391 
+2392 	return result;
+2393     };
+2394 
+2395     /** 
+2396      * get a extension parameter JSON object<br/>
+2397      * @name getExtParam
+2398      * @memberOf X509#
+2399      * @function
+2400      * @param {String} hExt hexadecimal string of Extension
+2401      * @return {Array} Extension parameter JSON object
+2402      * @since jsrsasign 9.1.1 x509 2.0.1
+2403      * @see KJUR.asn1.x509.X509Util.newCertPEM
+2404      * @see X509#getParam
+2405      * @see X509#getExtParamArray
+2406      * @see X509CRL#getParam
+2407      * @see KJUR.asn1.csr.CSRUtil.getParam
+2408      *
+2409      * @description
+2410      * This method returns a extension parameters as JSON object. 
+2411      *
+2412      * @example
+2413      * x = new X509();
+2414      * ...
+2415      * x.getExtParam("30...") →
+2416      * {extname:"keyUsage",critical:true,names:["digitalSignature"]}
+2417      */
+2418     this.getExtParam = function(hExt) {
+2419 	var result = {};
+2420 	var aIdx = _getChildIdx(hExt, 0);
+2421 	var aIdxLen = aIdx.length;
+2422 	if (aIdxLen != 2 && aIdxLen != 3)
+2423 	    throw new Error("wrong number elements in Extension: " + 
+2424 			    aIdxLen + " " + hExt);
+2425 
+2426 	var oid = _hextooidstr(_getVbyList(hExt, 0, [0], "06"));
 2427 
-2428 	var hExtV = _getTLVbyList(hExt, 0, [aIdxLen - 1, 0]);
-2429 
-2430 	var extParam = undefined;
-2431 	if (oid == "2.5.29.14") {
-2432 	    extParam = this.getExtSubjectKeyIdentifier(hExtV, critical);
-2433 	} else if (oid == "2.5.29.15") {
-2434 	    extParam = this.getExtKeyUsage(hExtV, critical);
-2435 	} else if (oid == "2.5.29.17") {
-2436 	    extParam = this.getExtSubjectAltName(hExtV, critical);
-2437 	} else if (oid == "2.5.29.18") {
-2438 	    extParam = this.getExtIssuerAltName(hExtV, critical);
-2439 	} else if (oid == "2.5.29.19") {
-2440 	    extParam = this.getExtBasicConstraints(hExtV, critical);
-2441 	} else if (oid == "2.5.29.31") {
-2442 	    extParam = this.getExtCRLDistributionPoints(hExtV, critical);
-2443 	} else if (oid == "2.5.29.32") {
-2444 	    extParam = this.getExtCertificatePolicies(hExtV, critical);
-2445 	} else if (oid == "2.5.29.35") {
-2446 	    extParam = this.getExtAuthorityKeyIdentifier(hExtV, critical);
-2447 	} else if (oid == "2.5.29.37") {
-2448 	    extParam = this.getExtExtKeyUsage(hExtV, critical);
-2449 	} else if (oid == "1.3.6.1.5.5.7.1.1") {
-2450 	    extParam = this.getExtAuthorityInfoAccess(hExtV, critical);
-2451 	} else if (oid == "2.5.29.20") {
-2452 	    extParam = this.getExtCRLNumber(hExtV, critical);
-2453 	} else if (oid == "2.5.29.21") {
-2454 	    extParam = this.getExtCRLReason(hExtV, critical);
-2455 	} else if (oid == "1.3.6.1.5.5.7.48.1.2") {
-2456 	    extParam = this.getExtOcspNonce(hExtV, critical);
-2457 	} else if (oid == "1.3.6.1.5.5.7.48.1.5") {
-2458 	    extParam = this.getExtOcspNoCheck(hExtV, critical);
-2459 	} else if (oid == "1.2.840.113583.1.1.9.1") {
-2460 	    extParam = this.getExtAdobeTimeStamp(hExtV, critical);
-2461 	}
-2462 	if (extParam != undefined) return extParam;
-2463 
-2464 	var privateParam = { extname: oid, extn: hExtV };
-2465 	if (critical) privateParam.critical = true;
-2466 	return privateParam;
-2467     };
-2468 
-2469     /**
-2470      * find extension parameter in array<br/>
-2471      * @name findExt
-2472      * @memberOf X509#
-2473      * @function
-2474      * @param {Array} aExt array of extension parameters
-2475      * @param {String} extname extension name
-2476      * @return {Array} extension parameter in the array or null
-2477      * @since jsrsasign 10.0.3 x509 2.0.7
-2478      * @see X509#getParam
-2479      *
-2480      * @description
-2481      * This method returns an extension parameter for
-2482      * specified extension name in the array.
-2483      * This method is useful to update extension parameter value.
-2484      * When there is no such extension with the extname,
-2485      * this returns "null".
-2486      *
-2487      * @example
-2488      * // (1) 
-2489      * x = new X509(CERTPEM);
-2490      * params = x.getParam();
-2491      * pSKID = x.findExt(params.ext, "subjectKeyIdentifier");
-2492      * pSKID.kid = "1234abced..."; // skid in the params is updated.
-2493      *   // then params was updated
-2494      *
-2495      * // (2) another example
-2496      * aExt = [
-2497      *   {extname:"keyUsage",critical:true,names:["digitalSignature"]},
-2498      *   {extname:"basicConstraints",critical:true},
-2499      *   {extname:"subjectKeyIdentifier",kid:{hex:"f2eb..."}},
-2500      *   {extname:"authorityKeyIdentifier",kid:{hex:"12ab..."}},
-2501      *   {extname:"authorityInfoAccess",array:[{ocsp:"http://ocsp.example.com/"}]},
-2502      *   {extname:"certificatePolicies",array:[{policyoid:"2.23.140.1.2.1"}]}
-2503      * ];
-2504      * var x = new X509();
-2505      * x.findExt(aExt, "authorityKeyInfoAccess").array[0].ocsp = "http://aaa.com";
-2506      * pKU = x.findExt(aExt, "keyUsage");
-2507      * delete pKU["critical"]; // clear criticla flag
-2508      * pKU.names = ["keyCertSign", "cRLSign"];
-2509      *   // then aExt was updated
-2510      */
-2511     this.findExt = function(aExt, extname) {
-2512 	for (var i = 0; i < aExt.length; i++) {
-2513 	    if (aExt[i].extname == extname) return aExt[i];
-2514 	}
-2515 	return null;
-2516 
-2517     };
-2518 
-2519     /**
-2520      * update CRLDistributionPoints Full URI in parameter<br/>
-2521      * @name updateCDPFullURI
-2522      * @memberOf X509#
-2523      * @function
-2524      * @param {Array} aExt array of extension parameters
-2525      * @param {String} newURI string of new uri
-2526      * @since jsrsasign 10.0.4 x509 2.0.8
-2527      * @see X509#findExt
-2528      * @see KJUR.asn1.x509.CRLDistributionPoints
-2529      *
-2530      * @description
-2531      * This method updates Full URI of CRLDistributionPoints extension
-2532      * in the extension parameter array if it exists.
+2428 	var critical = false;
+2429 	if (aIdxLen == 3 && _getTLVbyList(hExt, 0, [1]) == "0101ff")
+2430 	    critical = true;
+2431 
+2432 	var hExtV = _getTLVbyList(hExt, 0, [aIdxLen - 1, 0]);
+2433 
+2434 	var extParam = undefined;
+2435 	if (oid == "2.5.29.14") {
+2436 	    extParam = this.getExtSubjectKeyIdentifier(hExtV, critical);
+2437 	} else if (oid == "2.5.29.15") {
+2438 	    extParam = this.getExtKeyUsage(hExtV, critical);
+2439 	} else if (oid == "2.5.29.17") {
+2440 	    extParam = this.getExtSubjectAltName(hExtV, critical);
+2441 	} else if (oid == "2.5.29.18") {
+2442 	    extParam = this.getExtIssuerAltName(hExtV, critical);
+2443 	} else if (oid == "2.5.29.19") {
+2444 	    extParam = this.getExtBasicConstraints(hExtV, critical);
+2445 	} else if (oid == "2.5.29.31") {
+2446 	    extParam = this.getExtCRLDistributionPoints(hExtV, critical);
+2447 	} else if (oid == "2.5.29.32") {
+2448 	    extParam = this.getExtCertificatePolicies(hExtV, critical);
+2449 	} else if (oid == "2.5.29.35") {
+2450 	    extParam = this.getExtAuthorityKeyIdentifier(hExtV, critical);
+2451 	} else if (oid == "2.5.29.37") {
+2452 	    extParam = this.getExtExtKeyUsage(hExtV, critical);
+2453 	} else if (oid == "1.3.6.1.5.5.7.1.1") {
+2454 	    extParam = this.getExtAuthorityInfoAccess(hExtV, critical);
+2455 	} else if (oid == "2.5.29.20") {
+2456 	    extParam = this.getExtCRLNumber(hExtV, critical);
+2457 	} else if (oid == "2.5.29.21") {
+2458 	    extParam = this.getExtCRLReason(hExtV, critical);
+2459 	} else if (oid == "1.3.6.1.5.5.7.48.1.2") {
+2460 	    extParam = this.getExtOcspNonce(hExtV, critical);
+2461 	} else if (oid == "1.3.6.1.5.5.7.48.1.5") {
+2462 	    extParam = this.getExtOcspNoCheck(hExtV, critical);
+2463 	} else if (oid == "1.2.840.113583.1.1.9.1") {
+2464 	    extParam = this.getExtAdobeTimeStamp(hExtV, critical);
+2465 	}
+2466 	if (extParam != undefined) return extParam;
+2467 
+2468 	var privateParam = { extname: oid, extn: hExtV };
+2469 	if (critical) privateParam.critical = true;
+2470 	return privateParam;
+2471     };
+2472 
+2473     /**
+2474      * find extension parameter in array<br/>
+2475      * @name findExt
+2476      * @memberOf X509#
+2477      * @function
+2478      * @param {Array} aExt array of extension parameters
+2479      * @param {String} extname extension name
+2480      * @return {Array} extension parameter in the array or null
+2481      * @since jsrsasign 10.0.3 x509 2.0.7
+2482      * @see X509#getParam
+2483      *
+2484      * @description
+2485      * This method returns an extension parameter for
+2486      * specified extension name in the array.
+2487      * This method is useful to update extension parameter value.
+2488      * When there is no such extension with the extname,
+2489      * this returns "null".
+2490      *
+2491      * @example
+2492      * // (1) 
+2493      * x = new X509(CERTPEM);
+2494      * params = x.getParam();
+2495      * pSKID = x.findExt(params.ext, "subjectKeyIdentifier");
+2496      * pSKID.kid = "1234abced..."; // skid in the params is updated.
+2497      *   // then params was updated
+2498      *
+2499      * // (2) another example
+2500      * aExt = [
+2501      *   {extname:"keyUsage",critical:true,names:["digitalSignature"]},
+2502      *   {extname:"basicConstraints",critical:true},
+2503      *   {extname:"subjectKeyIdentifier",kid:{hex:"f2eb..."}},
+2504      *   {extname:"authorityKeyIdentifier",kid:{hex:"12ab..."}},
+2505      *   {extname:"authorityInfoAccess",array:[{ocsp:"http://ocsp.example.com/"}]},
+2506      *   {extname:"certificatePolicies",array:[{policyoid:"2.23.140.1.2.1"}]}
+2507      * ];
+2508      * var x = new X509();
+2509      * x.findExt(aExt, "authorityKeyInfoAccess").array[0].ocsp = "http://aaa.com";
+2510      * pKU = x.findExt(aExt, "keyUsage");
+2511      * delete pKU["critical"]; // clear criticla flag
+2512      * pKU.names = ["keyCertSign", "cRLSign"];
+2513      *   // then aExt was updated
+2514      */
+2515     this.findExt = function(aExt, extname) {
+2516 	for (var i = 0; i < aExt.length; i++) {
+2517 	    if (aExt[i].extname == extname) return aExt[i];
+2518 	}
+2519 	return null;
+2520 
+2521     };
+2522 
+2523     /**
+2524      * update CRLDistributionPoints Full URI in parameter<br/>
+2525      * @name updateCDPFullURI
+2526      * @memberOf X509#
+2527      * @function
+2528      * @param {Array} aExt array of extension parameters
+2529      * @param {String} newURI string of new uri
+2530      * @since jsrsasign 10.0.4 x509 2.0.8
+2531      * @see X509#findExt
+2532      * @see KJUR.asn1.x509.CRLDistributionPoints
 2533      *
-2534      * @example
-2535      * aExt = [
-2536      *   {extname:"authorityKeyIdentifier",kid:{hex:"12ab..."}},
-2537      *   {extname:"cRLDistributionPoints",
-2538      *    array:[{dpname:{full:[{uri:"http://example.com/a.crl"}]}}]},
-2539      * ];
-2540      * x = new X509();
-2541      * x.updateCDPFullURI(aExt, "http://crl2.example.new/b.crl");
-2542      */
-2543     this.updateExtCDPFullURI = function(aExt, newURI) {
-2544 	var pExt = this.findExt(aExt, "cRLDistributionPoints");
-2545 	if (pExt == null) return;
-2546 	if (pExt.array == undefined) return;
-2547 	var aDP = pExt.array;
-2548 	for (var i = 0; i < aDP.length; i++) {
-2549 	    if (aDP[i].dpname == undefined) continue;
-2550 	    if (aDP[i].dpname.full == undefined) continue;
-2551 	    var aURI = aDP[i].dpname.full;
-2552 	    for (var j = 0; j < aURI.length; j++) {
-2553 		var pURI = aURI[i];
-2554 		if (pURI.uri == undefined) continue;
-2555 		pURI.uri = newURI;
-2556 	    }
-2557 	}
-2558     };
-2559 
-2560     /**
-2561      * update authorityInfoAccess ocsp in parameter<br/>
-2562      * @name updateAIAOCSP
-2563      * @memberOf X509#
-2564      * @function
-2565      * @param {Array} aExt array of extension parameters
-2566      * @param {String} newURI string of new uri
-2567      * @since jsrsasign 10.0.4 x509 2.0.8
-2568      * @see X509#findExt
-2569      * @see KJUR.asn1.x509.AuthorityInfoAccess
-2570      *
-2571      * @description
-2572      * This method updates "ocsp" accessMethod URI of 
-2573      * AuthorityInfoAccess extension
-2574      * in the extension parameter array if it exists.
-2575      *
-2576      * @example
-2577      * aExt = [
-2578      *   {extname:"authorityKeyIdentifier",kid:{hex:"12ab..."}},
-2579      *   {extname:"authoriyInfoAccess",
-2580      *    array:[
-2581      *      {ocsp: "http://ocsp1.example.com"},
-2582      *      {caissuer: "http://example.com/a.crt"}
-2583      *    ]}
-2584      * ];
-2585      * x = new X509();
-2586      * x.updateAIAOCSP(aExt, "http://ocsp2.example.net");
-2587      */
-2588     this.updateExtAIAOCSP = function(aExt, newURI) {
-2589 	var pExt = this.findExt(aExt, "authorityInfoAccess");
-2590 	if (pExt == null) return;
-2591 	if (pExt.array == undefined) return;
-2592 	var a = pExt.array;
-2593 	for (var i = 0; i < a.length; i++) {
-2594 	    if (a[i].ocsp != undefined) a[i].ocsp = newURI;
-2595 	}
-2596     };
-2597 
-2598     /**
-2599      * update authorityInfoAccess caIssuer in parameter<br/>
-2600      * @name updateAIACAIssuer
-2601      * @memberOf X509#
-2602      * @function
-2603      * @param {Array} aExt array of extension parameters
-2604      * @param {String} newURI string of new uri
-2605      * @since jsrsasign 10.0.4 x509 2.0.8
-2606      * @see X509#findExt
-2607      * @see KJUR.asn1.x509.AuthorityInfoAccess
-2608      *
-2609      * @description
-2610      * This method updates "caIssuer" accessMethod URI of 
-2611      * AuthorityInfoAccess extension
-2612      * in the extension parameter array if it exists.
-2613      *
-2614      * @example
-2615      * aExt = [
-2616      *   {extname:"authorityKeyIdentifier",kid:{hex:"12ab..."}},
-2617      *   {extname:"authoriyInfoAccess",
-2618      *    array:[
-2619      *      {ocsp: "http://ocsp1.example.com"},
-2620      *      {caissuer: "http://example.com/a.crt"}
-2621      *    ]}
-2622      * ];
-2623      * x = new X509();
-2624      * x.updateAIACAIssuer(aExt, "http://example.net/b.crt");
-2625      */
-2626     this.updateExtAIACAIssuer = function(aExt, newURI) {
-2627 	var pExt = this.findExt(aExt, "authorityInfoAccess");
-2628 	if (pExt == null) return;
-2629 	if (pExt.array == undefined) return;
-2630 	var a = pExt.array;
-2631 	for (var i = 0; i < a.length; i++) {
-2632 	    if (a[i].caissuer != undefined) a[i].caissuer = newURI;
-2633 	}
-2634     };
-2635 
-2636     /**
-2637      * convert array for X500 distinguish name to distinguish name string<br/>
-2638      * @name dnarraytostr
-2639      * @memberOf X509#
-2640      * @function
-2641      * @param {Array} aDN array for X500 distinguish name
-2642      * @return {String} distinguish name
-2643      * @since jsrsasign 10.0.6 x509 2.0.8
-2644      * @see X509#getX500Name
-2645      * @see X509#getX500NameArray
-2646      * @see KJUR.asn1.x509.X500Name
-2647      *
-2648      * @description
-2649      * This method converts from an array representation of 
-2650      * X.500 distinguished name to X.500 name string.
-2651      * This supports multi-valued RDN.
-2652      * 
-2653      * @example
-2654      * var x = new X509();
-2655      * x.dnarraytostr(
-2656      *   [[{type:"C",value:"JP",ds:"prn"}],
-2657      *   [{type:"O",value:"T1",ds:"prn"}]]) → "/C=JP/O=T1"
-2658      * x.dnarraytostr(
-2659      *   [[{type:"C",value:"JP",ds:"prn"}],
-2660      *   [{type:"O",value:"T1",ds:"prn"}
-2661      *    {type:"CN",value:"Bob",ds:"prn"}]]) → "/C=JP/O=T1+CN=Bob"
-2662      */
-2663     this.dnarraytostr = function(aDN) {
-2664 	function rdnarraytostr(aRDN) {
-2665 	    return aRDN.map(function(x){return atvtostr(x);}).join("+");
-2666 	};
-2667 
-2668 	function atvtostr(pATV) {
-2669 	    return pATV.type + "=" + pATV.value;
+2534      * @description
+2535      * This method updates Full URI of CRLDistributionPoints extension
+2536      * in the extension parameter array if it exists.
+2537      *
+2538      * @example
+2539      * aExt = [
+2540      *   {extname:"authorityKeyIdentifier",kid:{hex:"12ab..."}},
+2541      *   {extname:"cRLDistributionPoints",
+2542      *    array:[{dpname:{full:[{uri:"http://example.com/a.crl"}]}}]},
+2543      * ];
+2544      * x = new X509();
+2545      * x.updateCDPFullURI(aExt, "http://crl2.example.new/b.crl");
+2546      */
+2547     this.updateExtCDPFullURI = function(aExt, newURI) {
+2548 	var pExt = this.findExt(aExt, "cRLDistributionPoints");
+2549 	if (pExt == null) return;
+2550 	if (pExt.array == undefined) return;
+2551 	var aDP = pExt.array;
+2552 	for (var i = 0; i < aDP.length; i++) {
+2553 	    if (aDP[i].dpname == undefined) continue;
+2554 	    if (aDP[i].dpname.full == undefined) continue;
+2555 	    var aURI = aDP[i].dpname.full;
+2556 	    for (var j = 0; j < aURI.length; j++) {
+2557 		var pURI = aURI[i];
+2558 		if (pURI.uri == undefined) continue;
+2559 		pURI.uri = newURI;
+2560 	    }
+2561 	}
+2562     };
+2563 
+2564     /**
+2565      * update authorityInfoAccess ocsp in parameter<br/>
+2566      * @name updateAIAOCSP
+2567      * @memberOf X509#
+2568      * @function
+2569      * @param {Array} aExt array of extension parameters
+2570      * @param {String} newURI string of new uri
+2571      * @since jsrsasign 10.0.4 x509 2.0.8
+2572      * @see X509#findExt
+2573      * @see KJUR.asn1.x509.AuthorityInfoAccess
+2574      *
+2575      * @description
+2576      * This method updates "ocsp" accessMethod URI of 
+2577      * AuthorityInfoAccess extension
+2578      * in the extension parameter array if it exists.
+2579      *
+2580      * @example
+2581      * aExt = [
+2582      *   {extname:"authorityKeyIdentifier",kid:{hex:"12ab..."}},
+2583      *   {extname:"authoriyInfoAccess",
+2584      *    array:[
+2585      *      {ocsp: "http://ocsp1.example.com"},
+2586      *      {caissuer: "http://example.com/a.crt"}
+2587      *    ]}
+2588      * ];
+2589      * x = new X509();
+2590      * x.updateAIAOCSP(aExt, "http://ocsp2.example.net");
+2591      */
+2592     this.updateExtAIAOCSP = function(aExt, newURI) {
+2593 	var pExt = this.findExt(aExt, "authorityInfoAccess");
+2594 	if (pExt == null) return;
+2595 	if (pExt.array == undefined) return;
+2596 	var a = pExt.array;
+2597 	for (var i = 0; i < a.length; i++) {
+2598 	    if (a[i].ocsp != undefined) a[i].ocsp = newURI;
+2599 	}
+2600     };
+2601 
+2602     /**
+2603      * update authorityInfoAccess caIssuer in parameter<br/>
+2604      * @name updateAIACAIssuer
+2605      * @memberOf X509#
+2606      * @function
+2607      * @param {Array} aExt array of extension parameters
+2608      * @param {String} newURI string of new uri
+2609      * @since jsrsasign 10.0.4 x509 2.0.8
+2610      * @see X509#findExt
+2611      * @see KJUR.asn1.x509.AuthorityInfoAccess
+2612      *
+2613      * @description
+2614      * This method updates "caIssuer" accessMethod URI of 
+2615      * AuthorityInfoAccess extension
+2616      * in the extension parameter array if it exists.
+2617      *
+2618      * @example
+2619      * aExt = [
+2620      *   {extname:"authorityKeyIdentifier",kid:{hex:"12ab..."}},
+2621      *   {extname:"authoriyInfoAccess",
+2622      *    array:[
+2623      *      {ocsp: "http://ocsp1.example.com"},
+2624      *      {caissuer: "http://example.com/a.crt"}
+2625      *    ]}
+2626      * ];
+2627      * x = new X509();
+2628      * x.updateAIACAIssuer(aExt, "http://example.net/b.crt");
+2629      */
+2630     this.updateExtAIACAIssuer = function(aExt, newURI) {
+2631 	var pExt = this.findExt(aExt, "authorityInfoAccess");
+2632 	if (pExt == null) return;
+2633 	if (pExt.array == undefined) return;
+2634 	var a = pExt.array;
+2635 	for (var i = 0; i < a.length; i++) {
+2636 	    if (a[i].caissuer != undefined) a[i].caissuer = newURI;
+2637 	}
+2638     };
+2639 
+2640     /**
+2641      * convert array for X500 distinguish name to distinguish name string<br/>
+2642      * @name dnarraytostr
+2643      * @memberOf X509#
+2644      * @function
+2645      * @param {Array} aDN array for X500 distinguish name
+2646      * @return {String} distinguish name
+2647      * @since jsrsasign 10.0.6 x509 2.0.8
+2648      * @see X509#getX500Name
+2649      * @see X509#getX500NameArray
+2650      * @see KJUR.asn1.x509.X500Name
+2651      *
+2652      * @description
+2653      * This method converts from an array representation of 
+2654      * X.500 distinguished name to X.500 name string.
+2655      * This supports multi-valued RDN.
+2656      * 
+2657      * @example
+2658      * var x = new X509();
+2659      * x.dnarraytostr(
+2660      *   [[{type:"C",value:"JP",ds:"prn"}],
+2661      *   [{type:"O",value:"T1",ds:"prn"}]]) → "/C=JP/O=T1"
+2662      * x.dnarraytostr(
+2663      *   [[{type:"C",value:"JP",ds:"prn"}],
+2664      *   [{type:"O",value:"T1",ds:"prn"}
+2665      *    {type:"CN",value:"Bob",ds:"prn"}]]) → "/C=JP/O=T1+CN=Bob"
+2666      */
+2667     this.dnarraytostr = function(aDN) {
+2668 	function rdnarraytostr(aRDN) {
+2669 	    return aRDN.map(function(x){return atvtostr(x).replace(/\+/,"\\+");}).join("+");
 2670 	};
 2671 
-2672 	return "/" + aDN.map(function(x){return rdnarraytostr(x);}).join("/");
-2673     };
-2674 
-2675     /**
-2676      * get certificate information as string.<br/>
-2677      * @name getInfo
-2678      * @memberOf X509#
-2679      * @function
-2680      * @return {String} certificate information string
-2681      * @since jsrsasign 5.0.10 x509 1.1.8
-2682      * @example
-2683      * x = new X509();
-2684      * x.readCertPEM(certPEM);
-2685      * console.log(x.getInfo());
-2686      * // this shows as following
-2687      * Basic Fields
-2688      *   serial number: 02ac5c266a0b409b8f0b79f2ae462577
-2689      *   signature algorithm: SHA1withRSA
-2690      *   issuer: /C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA
-2691      *   notBefore: 061110000000Z
-2692      *   notAfter: 311110000000Z
-2693      *   subject: /C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA
-2694      *   subject public key info:
-2695      *     key algorithm: RSA
-2696      *     n=c6cce573e6fbd4bb...
-2697      *     e=10001
-2698      * X509v3 Extensions:
-2699      *   keyUsage CRITICAL:
-2700      *     digitalSignature,keyCertSign,cRLSign
-2701      *   basicConstraints CRITICAL:
-2702      *     cA=true
-2703      *   subjectKeyIdentifier :
-2704      *     b13ec36903f8bf4701d498261a0802ef63642bc3
-2705      *   authorityKeyIdentifier :
-2706      *     kid=b13ec36903f8bf4701d498261a0802ef63642bc3
-2707      * signature algorithm: SHA1withRSA
-2708      * signature: 1c1a0697dcd79c9f...
-2709      */
-2710     this.getInfo = function() {
-2711 	var _getSubjectAltNameStr = function(params) {
-2712 	    var s = JSON.stringify(params.array).replace(/[\[\]\{\}\"]/g, '');
-2713 	    return s;
-2714 	};
-2715 	var _getCertificatePoliciesStr = function(params) {
-2716 	    var s = "";
-2717 	    var a = params.array;
-2718 	    for (var i = 0; i < a.length; i++) {
-2719 		var pi = a[i];
-2720 		s += "    policy oid: " + pi.policyoid + "\n";
-2721 		if (pi.array === undefined) continue;
-2722 		for (var j = 0; j < pi.array.length; j++) {
-2723 		    var pqi = pi.array[j];
-2724 		    if (pqi.cps !== undefined) {
-2725 			s += "    cps: " + pqi.cps + "\n";
-2726 		    }
-2727 		}
-2728 	    }
-2729 	    return s;
-2730 	};
-2731 	var _getCRLDistributionPointsStr = function(params) {
-2732 	    var s = "";
-2733 	    var a = params.array;
-2734 	    for (var i = 0; i < a.length; i++) {
-2735 		var dp = a[i];
-2736 		try {
-2737 		    if (dp.dpname.full[0].uri !== undefined)
-2738 			s += "    " + dp.dpname.full[0].uri + "\n";
-2739 		} catch(ex) {};
+2672 	function atvtostr(pATV) {
+2673 	    return pATV.type + "=" + pATV.value;
+2674 	};
+2675 
+2676 	return "/" + aDN.map(function(x){return rdnarraytostr(x).replace(/\//, "\\/");}).join("/");
+2677     };
+2678 
+2679     /**
+2680      * get certificate information as string.<br/>
+2681      * @name getInfo
+2682      * @memberOf X509#
+2683      * @function
+2684      * @return {String} certificate information string
+2685      * @since jsrsasign 5.0.10 x509 1.1.8
+2686      * @example
+2687      * x = new X509();
+2688      * x.readCertPEM(certPEM);
+2689      * console.log(x.getInfo());
+2690      * // this shows as following
+2691      * Basic Fields
+2692      *   serial number: 02ac5c266a0b409b8f0b79f2ae462577
+2693      *   signature algorithm: SHA1withRSA
+2694      *   issuer: /C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA
+2695      *   notBefore: 061110000000Z
+2696      *   notAfter: 311110000000Z
+2697      *   subject: /C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA
+2698      *   subject public key info:
+2699      *     key algorithm: RSA
+2700      *     n=c6cce573e6fbd4bb...
+2701      *     e=10001
+2702      * X509v3 Extensions:
+2703      *   keyUsage CRITICAL:
+2704      *     digitalSignature,keyCertSign,cRLSign
+2705      *   basicConstraints CRITICAL:
+2706      *     cA=true
+2707      *   subjectKeyIdentifier :
+2708      *     b13ec36903f8bf4701d498261a0802ef63642bc3
+2709      *   authorityKeyIdentifier :
+2710      *     kid=b13ec36903f8bf4701d498261a0802ef63642bc3
+2711      * signature algorithm: SHA1withRSA
+2712      * signature: 1c1a0697dcd79c9f...
+2713      */
+2714     this.getInfo = function() {
+2715 	var _getSubjectAltNameStr = function(params) {
+2716 	    var s = JSON.stringify(params.array).replace(/[\[\]\{\}\"]/g, '');
+2717 	    return s;
+2718 	};
+2719 	var _getCertificatePoliciesStr = function(params) {
+2720 	    var s = "";
+2721 	    var a = params.array;
+2722 	    for (var i = 0; i < a.length; i++) {
+2723 		var pi = a[i];
+2724 		s += "    policy oid: " + pi.policyoid + "\n";
+2725 		if (pi.array === undefined) continue;
+2726 		for (var j = 0; j < pi.array.length; j++) {
+2727 		    var pqi = pi.array[j];
+2728 		    if (pqi.cps !== undefined) {
+2729 			s += "    cps: " + pqi.cps + "\n";
+2730 		    }
+2731 		}
+2732 	    }
+2733 	    return s;
+2734 	};
+2735 	var _getCRLDistributionPointsStr = function(params) {
+2736 	    var s = "";
+2737 	    var a = params.array;
+2738 	    for (var i = 0; i < a.length; i++) {
+2739 		var dp = a[i];
 2740 		try {
-2741 		    if (dp.dname.full[0].dn.hex !== undefined)
-2742 			s += "    " + X509.hex2dn(dp.dpname.full[0].dn.hex) + "\n";
+2741 		    if (dp.dpname.full[0].uri !== undefined)
+2742 			s += "    " + dp.dpname.full[0].uri + "\n";
 2743 		} catch(ex) {};
-2744 	    }
-2745 	    return s;
-2746 	}
-2747 	var _getAuthorityInfoAccessStr = function(params) {
-2748 	    var s = "";
-2749 	    var a = params.array;
-2750 	    for (var i = 0; i < a.length; i++) {
-2751 		var ad = a[i];
-2752 
-2753 		if (ad.caissuer !== undefined)
-2754 		    s += "    caissuer: " + ad.caissuer + "\n";
-2755 		if (ad.ocsp !== undefined)
-2756 		    s += "    ocsp: " + ad.ocsp + "\n";
-2757 	    }
-2758 	    return s;
-2759 	};
-2760 	var _X509 = X509;
-2761 	var s, pubkey, aExt;
-2762 	s  = "Basic Fields\n";
-2763         s += "  serial number: " + this.getSerialNumberHex() + "\n";
-2764 	s += "  signature algorithm: " + this.getSignatureAlgorithmField() + "\n";
-2765 	s += "  issuer: " + this.getIssuerString() + "\n";
-2766 	s += "  notBefore: " + this.getNotBefore() + "\n";
-2767 	s += "  notAfter: " + this.getNotAfter() + "\n";
-2768 	s += "  subject: " + this.getSubjectString() + "\n";
-2769 	s += "  subject public key info: " + "\n";
-2770 
-2771 	// subject public key info
-2772 	pubkey = this.getPublicKey();
-2773 	s += "    key algorithm: " + pubkey.type + "\n";
+2744 		try {
+2745 		    if (dp.dname.full[0].dn.hex !== undefined)
+2746 			s += "    " + X509.hex2dn(dp.dpname.full[0].dn.hex) + "\n";
+2747 		} catch(ex) {};
+2748 	    }
+2749 	    return s;
+2750 	}
+2751 	var _getAuthorityInfoAccessStr = function(params) {
+2752 	    var s = "";
+2753 	    var a = params.array;
+2754 	    for (var i = 0; i < a.length; i++) {
+2755 		var ad = a[i];
+2756 
+2757 		if (ad.caissuer !== undefined)
+2758 		    s += "    caissuer: " + ad.caissuer + "\n";
+2759 		if (ad.ocsp !== undefined)
+2760 		    s += "    ocsp: " + ad.ocsp + "\n";
+2761 	    }
+2762 	    return s;
+2763 	};
+2764 	var _X509 = X509;
+2765 	var s, pubkey, aExt;
+2766 	s  = "Basic Fields\n";
+2767         s += "  serial number: " + this.getSerialNumberHex() + "\n";
+2768 	s += "  signature algorithm: " + this.getSignatureAlgorithmField() + "\n";
+2769 	s += "  issuer: " + this.getIssuerString() + "\n";
+2770 	s += "  notBefore: " + this.getNotBefore() + "\n";
+2771 	s += "  notAfter: " + this.getNotAfter() + "\n";
+2772 	s += "  subject: " + this.getSubjectString() + "\n";
+2773 	s += "  subject public key info: " + "\n";
 2774 
-2775 	if (pubkey.type === "RSA") {
-2776 	    s += "    n=" + hextoposhex(pubkey.n.toString(16)).substr(0, 16) + "...\n";
-2777 	    s += "    e=" + hextoposhex(pubkey.e.toString(16)) + "\n";
-2778 	}
-2779 
-2780 	// X.509v3 Extensions
-2781         aExt = this.aExtInfo;
-2782 
-2783 	if (aExt !== undefined && aExt !== null) {
-2784             s += "X509v3 Extensions:\n";
-2785 	    
-2786             for (var i = 0; i < aExt.length; i++) {
-2787 		var info = aExt[i];
-2788 
-2789 		// show extension name and critical flag
-2790 		var extName = KJUR.asn1.x509.OID.oid2name(info["oid"]);
-2791 		if (extName === '') extName = info["oid"];
+2775 	// subject public key info
+2776 	pubkey = this.getPublicKey();
+2777 	s += "    key algorithm: " + pubkey.type + "\n";
+2778 
+2779 	if (pubkey.type === "RSA") {
+2780 	    s += "    n=" + hextoposhex(pubkey.n.toString(16)).substr(0, 16) + "...\n";
+2781 	    s += "    e=" + hextoposhex(pubkey.e.toString(16)) + "\n";
+2782 	}
+2783 
+2784 	// X.509v3 Extensions
+2785         aExt = this.aExtInfo;
+2786 
+2787 	if (aExt !== undefined && aExt !== null) {
+2788             s += "X509v3 Extensions:\n";
+2789 	    
+2790             for (var i = 0; i < aExt.length; i++) {
+2791 		var info = aExt[i];
 2792 
-2793 		var critical = '';
-2794 		if (info["critical"] === true) critical = "CRITICAL";
-2795 
-2796 		s += "  " + extName + " " + critical + ":\n";
-2797 
-2798 		// show extension value if supported
-2799 		if (extName === "basicConstraints") {
-2800 		    var bc = this.getExtBasicConstraints();
-2801 		    if (bc.cA === undefined) {
-2802 			s += "    {}\n";
-2803 		    } else {
-2804 			s += "    cA=true";
-2805 			if (bc.pathLen !== undefined)
-2806 			    s += ", pathLen=" + bc.pathLen;
-2807 			s += "\n";
-2808 		    }
-2809 		} else if (extName === "keyUsage") {
-2810 		    s += "    " + this.getExtKeyUsageString() + "\n";
-2811 		} else if (extName === "subjectKeyIdentifier") {
-2812 		    s += "    " + this.getExtSubjectKeyIdentifier().kid.hex + "\n";
-2813 		} else if (extName === "authorityKeyIdentifier") {
-2814 		    var akid = this.getExtAuthorityKeyIdentifier();
-2815 		    if (akid.kid !== undefined)
-2816 			s += "    kid=" + akid.kid.hex + "\n";
-2817 		} else if (extName === "extKeyUsage") {
-2818 		    var eku = this.getExtExtKeyUsage().array;
-2819 		    s += "    " + eku.join(", ") + "\n";
-2820 		} else if (extName === "subjectAltName") {
-2821 		    var san = _getSubjectAltNameStr(this.getExtSubjectAltName());
-2822 		    s += "    " + san + "\n";
-2823 		} else if (extName === "cRLDistributionPoints") {
-2824 		    var cdp = this.getExtCRLDistributionPoints();
-2825 		    s += _getCRLDistributionPointsStr(cdp);
-2826 		} else if (extName === "authorityInfoAccess") {
-2827 		    var aia = this.getExtAuthorityInfoAccess();
-2828 		    s += _getAuthorityInfoAccessStr(aia);
-2829 		} else if (extName === "certificatePolicies") {
-2830 		    s += _getCertificatePoliciesStr(this.getExtCertificatePolicies());
-2831 		}
-2832 	    }
-2833         }
-2834 
-2835 	s += "signature algorithm: " + this.getSignatureAlgorithmName() + "\n";
-2836 	s += "signature: " + this.getSignatureValueHex().substr(0, 16) + "...\n";
-2837 	return s;
-2838     };
-2839 
-2840     if (typeof params == "string") {
-2841 	if (params.indexOf("-----BEGIN") != -1) {
-2842 	    this.readCertPEM(params);
-2843 	} else if (KJUR.lang.String.isHex(params)) {
-2844 	    this.readCertHex(params);
-2845 	}
-2846     }
-2847 };
-2848 // ----- END of X509 class -----
-2849 
-2850 /**
-2851  * get distinguished name string in OpenSSL online format from hexadecimal string of ASN.1 DER X.500 name<br/>
-2852  * @name hex2dn
-2853  * @memberOf X509
-2854  * @function
-2855  * @param {String} hex hexadecimal string of ASN.1 DER distinguished name
-2856  * @param {Integer} idx index of hexadecimal string (DEFAULT=0)
-2857  * @return {String} OpenSSL online format distinguished name
-2858  * @description
-2859  * This static method converts from a hexadecimal string of 
-2860  * distinguished name (DN)
-2861  * specified by 'hex' and 'idx' to OpenSSL oneline string representation (ex. /C=US/O=a).
-2862  * @example
-2863  * X509.hex2dn("3031310b3...") → /C=US/O=a/CN=b2+OU=b1
-2864  */
-2865 X509.hex2dn = function(hex, idx) {
-2866     if (idx === undefined) idx = 0;
-2867     if (hex.substr(idx, 2) !== "30") throw new Error("malformed DN");
-2868 
-2869     var a = new Array();
-2870 
-2871     var aIdx = ASN1HEX.getChildIdx(hex, idx);
-2872     for (var i = 0; i < aIdx.length; i++) {
-2873 	a.push(X509.hex2rdn(hex, aIdx[i]));
-2874     }
-2875 
-2876     a = a.map(function(s) { return s.replace("/", "\\/"); });
-2877     return "/" + a.join("/");
-2878 };
-2879 
-2880 /**
-2881  * get relative distinguished name string in OpenSSL online format from hexadecimal string of ASN.1 DER RDN<br/>
-2882  * @name hex2rdn
-2883  * @memberOf X509
-2884  * @function
-2885  * @param {String} hex hexadecimal string of ASN.1 DER concludes relative distinguished name
-2886  * @param {Integer} idx index of hexadecimal string (DEFAULT=0)
-2887  * @return {String} OpenSSL online format relative distinguished name
-2888  * @description
-2889  * This static method converts from a hexadecimal string of 
-2890  * relative distinguished name (RDN)
-2891  * specified by 'hex' and 'idx' to LDAP string representation (ex. O=test+CN=test).<br/>
-2892  * NOTE: Multi-valued RDN is supported since jsnrsasign 6.2.2 x509 1.1.10.
-2893  * @example
-2894  * X509.hex2rdn("310a3008060355040a0c0161") → O=a
-2895  * X509.hex2rdn("31143008060355040a0c01613008060355040a0c0162") → O=a+O=b
-2896  */
-2897 X509.hex2rdn = function(hex, idx) {
-2898     if (idx === undefined) idx = 0;
-2899     if (hex.substr(idx, 2) !== "31") throw new Error("malformed RDN");
-2900 
-2901     var a = new Array();
-2902 
-2903     var aIdx = ASN1HEX.getChildIdx(hex, idx);
-2904     for (var i = 0; i < aIdx.length; i++) {
-2905 	a.push(X509.hex2attrTypeValue(hex, aIdx[i]));
-2906     }
-2907 
-2908     a = a.map(function(s) { return s.replace("+", "\\+"); });
-2909     return a.join("+");
-2910 };
-2911 
-2912 /**
-2913  * get string from hexadecimal string of ASN.1 DER AttributeTypeAndValue<br/>
-2914  * @name hex2attrTypeValue
-2915  * @memberOf X509
-2916  * @function
-2917  * @param {String} hex hexadecimal string of ASN.1 DER concludes AttributeTypeAndValue
-2918  * @param {Integer} idx index of hexadecimal string (DEFAULT=0)
-2919  * @return {String} string representation of AttributeTypeAndValue (ex. C=US)
-2920  * @description
-2921  * This static method converts from a hexadecimal string of AttributeTypeAndValue
-2922  * specified by 'hex' and 'idx' to LDAP string representation (ex. C=US).
-2923  * @example
-2924  * X509.hex2attrTypeValue("3008060355040a0c0161") → O=a
-2925  * X509.hex2attrTypeValue("300806035504060c0161") → C=a
-2926  * X509.hex2attrTypeValue("...3008060355040a0c0161...", 128) → O=a
-2927  */
-2928 X509.hex2attrTypeValue = function(hex, idx) {
-2929     var _ASN1HEX = ASN1HEX;
-2930     var _getV = _ASN1HEX.getV;
-2931 
-2932     if (idx === undefined) idx = 0;
-2933     if (hex.substr(idx, 2) !== "30") 
-2934 	throw new Error("malformed attribute type and value");
-2935 
-2936     var aIdx = _ASN1HEX.getChildIdx(hex, idx);
-2937     if (aIdx.length !== 2 || hex.substr(aIdx[0], 2) !== "06")
-2938 	"malformed attribute type and value";
-2939 
-2940     var oidHex = _getV(hex, aIdx[0]);
-2941     var oidInt = KJUR.asn1.ASN1Util.oidHexToInt(oidHex);
-2942     var atype = KJUR.asn1.x509.OID.oid2atype(oidInt);
+2793 		// show extension name and critical flag
+2794 		var extName = KJUR.asn1.x509.OID.oid2name(info["oid"]);
+2795 		if (extName === '') extName = info["oid"];
+2796 
+2797 		var critical = '';
+2798 		if (info["critical"] === true) critical = "CRITICAL";
+2799 
+2800 		s += "  " + extName + " " + critical + ":\n";
+2801 
+2802 		// show extension value if supported
+2803 		if (extName === "basicConstraints") {
+2804 		    var bc = this.getExtBasicConstraints();
+2805 		    if (bc.cA === undefined) {
+2806 			s += "    {}\n";
+2807 		    } else {
+2808 			s += "    cA=true";
+2809 			if (bc.pathLen !== undefined)
+2810 			    s += ", pathLen=" + bc.pathLen;
+2811 			s += "\n";
+2812 		    }
+2813 		} else if (extName === "keyUsage") {
+2814 		    s += "    " + this.getExtKeyUsageString() + "\n";
+2815 		} else if (extName === "subjectKeyIdentifier") {
+2816 		    s += "    " + this.getExtSubjectKeyIdentifier().kid.hex + "\n";
+2817 		} else if (extName === "authorityKeyIdentifier") {
+2818 		    var akid = this.getExtAuthorityKeyIdentifier();
+2819 		    if (akid.kid !== undefined)
+2820 			s += "    kid=" + akid.kid.hex + "\n";
+2821 		} else if (extName === "extKeyUsage") {
+2822 		    var eku = this.getExtExtKeyUsage().array;
+2823 		    s += "    " + eku.join(", ") + "\n";
+2824 		} else if (extName === "subjectAltName") {
+2825 		    var san = _getSubjectAltNameStr(this.getExtSubjectAltName());
+2826 		    s += "    " + san + "\n";
+2827 		} else if (extName === "cRLDistributionPoints") {
+2828 		    var cdp = this.getExtCRLDistributionPoints();
+2829 		    s += _getCRLDistributionPointsStr(cdp);
+2830 		} else if (extName === "authorityInfoAccess") {
+2831 		    var aia = this.getExtAuthorityInfoAccess();
+2832 		    s += _getAuthorityInfoAccessStr(aia);
+2833 		} else if (extName === "certificatePolicies") {
+2834 		    s += _getCertificatePoliciesStr(this.getExtCertificatePolicies());
+2835 		}
+2836 	    }
+2837         }
+2838 
+2839 	s += "signature algorithm: " + this.getSignatureAlgorithmName() + "\n";
+2840 	s += "signature: " + this.getSignatureValueHex().substr(0, 16) + "...\n";
+2841 	return s;
+2842     };
+2843 
+2844     if (typeof params == "string") {
+2845 	if (params.indexOf("-----BEGIN") != -1) {
+2846 	    this.readCertPEM(params);
+2847 	} else if (KJUR.lang.String.isHex(params)) {
+2848 	    this.readCertHex(params);
+2849 	}
+2850     }
+2851 };
+2852 // ----- END of X509 class -----
+2853 
+2854 /**
+2855  * get distinguished name string in OpenSSL online format from hexadecimal string of ASN.1 DER X.500 name<br/>
+2856  * @name hex2dn
+2857  * @memberOf X509
+2858  * @function
+2859  * @param {String} hex hexadecimal string of ASN.1 DER distinguished name
+2860  * @param {Integer} idx index of hexadecimal string (DEFAULT=0)
+2861  * @return {String} OpenSSL online format distinguished name
+2862  * @description
+2863  * This static method converts from a hexadecimal string of 
+2864  * distinguished name (DN)
+2865  * specified by 'hex' and 'idx' to OpenSSL oneline string representation (ex. /C=US/O=a).
+2866  * @example
+2867  * X509.hex2dn("3031310b3...") → /C=US/O=a/CN=b2+OU=b1
+2868  */
+2869 X509.hex2dn = function(hex, idx) {
+2870     if (idx === undefined) idx = 0;
+2871     var x = new X509();
+2872     var hDN = ASN1HEX.getTLV(hex, idx);
+2873     var pDN = x.getX500Name(hex);
+2874     return pDN.str;
+2875 };
+2876 
+2877 /**
+2878  * get relative distinguished name string in OpenSSL online format from hexadecimal string of ASN.1 DER RDN<br/>
+2879  * @name hex2rdn
+2880  * @memberOf X509
+2881  * @function
+2882  * @param {String} hex hexadecimal string of ASN.1 DER concludes relative distinguished name
+2883  * @param {Integer} idx index of hexadecimal string (DEFAULT=0)
+2884  * @return {String} OpenSSL online format relative distinguished name
+2885  * @description
+2886  * This static method converts from a hexadecimal string of 
+2887  * relative distinguished name (RDN)
+2888  * specified by 'hex' and 'idx' to LDAP string representation (ex. O=test+CN=test).<br/>
+2889  * NOTE: Multi-valued RDN is supported since jsnrsasign 6.2.2 x509 1.1.10.
+2890  * @example
+2891  * X509.hex2rdn("310a3008060355040a0c0161") → O=a
+2892  * X509.hex2rdn("31143008060355040a0c01613008060355040a0c0162") → O=a+O=b
+2893  */
+2894 X509.hex2rdn = function(hex, idx) {
+2895     if (idx === undefined) idx = 0;
+2896     if (hex.substr(idx, 2) !== "31") throw new Error("malformed RDN");
+2897 
+2898     var a = new Array();
+2899 
+2900     var aIdx = ASN1HEX.getChildIdx(hex, idx);
+2901     for (var i = 0; i < aIdx.length; i++) {
+2902 	a.push(X509.hex2attrTypeValue(hex, aIdx[i]));
+2903     }
+2904 
+2905     a = a.map(function(s) { return s.replace("+", "\\+"); });
+2906     return a.join("+");
+2907 };
+2908 
+2909 /**
+2910  * get string from hexadecimal string of ASN.1 DER AttributeTypeAndValue<br/>
+2911  * @name hex2attrTypeValue
+2912  * @memberOf X509
+2913  * @function
+2914  * @param {String} hex hexadecimal string of ASN.1 DER concludes AttributeTypeAndValue
+2915  * @param {Integer} idx index of hexadecimal string (DEFAULT=0)
+2916  * @return {String} string representation of AttributeTypeAndValue (ex. C=US)
+2917  * @description
+2918  * This static method converts from a hexadecimal string of AttributeTypeAndValue
+2919  * specified by 'hex' and 'idx' to LDAP string representation (ex. C=US).
+2920  * @example
+2921  * X509.hex2attrTypeValue("3008060355040a0c0161") → O=a
+2922  * X509.hex2attrTypeValue("300806035504060c0161") → C=a
+2923  * X509.hex2attrTypeValue("...3008060355040a0c0161...", 128) → O=a
+2924  */
+2925 X509.hex2attrTypeValue = function(hex, idx) {
+2926     var _ASN1HEX = ASN1HEX;
+2927     var _getV = _ASN1HEX.getV;
+2928 
+2929     if (idx === undefined) idx = 0;
+2930     if (hex.substr(idx, 2) !== "30") 
+2931 	throw new Error("malformed attribute type and value");
+2932 
+2933     var aIdx = _ASN1HEX.getChildIdx(hex, idx);
+2934     if (aIdx.length !== 2 || hex.substr(aIdx[0], 2) !== "06")
+2935 	"malformed attribute type and value";
+2936 
+2937     var oidHex = _getV(hex, aIdx[0]);
+2938     var oidInt = KJUR.asn1.ASN1Util.oidHexToInt(oidHex);
+2939     var atype = KJUR.asn1.x509.OID.oid2atype(oidInt);
+2940 
+2941     var hV = _getV(hex, aIdx[1]);
+2942     var rawV = hextorstr(hV);
 2943 
-2944     var hV = _getV(hex, aIdx[1]);
-2945     var rawV = hextorstr(hV);
+2944     return atype + "=" + rawV;
+2945 };
 2946 
-2947     return atype + "=" + rawV;
-2948 };
-2949 
-2950 /**
-2951  * get RSA/DSA/ECDSA public key object from X.509 certificate hexadecimal string<br/>
-2952  * @name getPublicKeyFromCertHex
-2953  * @memberOf X509
-2954  * @function
-2955  * @param {String} h hexadecimal string of X.509 certificate for RSA/ECDSA/DSA public key
-2956  * @return returns RSAKey/KJUR.crypto.{ECDSA,DSA} object of public key
-2957  * @since jsrasign 7.1.0 x509 1.1.11
-2958  */
-2959 X509.getPublicKeyFromCertHex = function(h) {
-2960     var x = new X509();
-2961     x.readCertHex(h);
-2962     return x.getPublicKey();
-2963 };
-2964 
-2965 /**
-2966  * get RSA/DSA/ECDSA public key object from PEM certificate string
-2967  * @name getPublicKeyFromCertPEM
-2968  * @memberOf X509
-2969  * @function
-2970  * @param {String} sCertPEM PEM formatted RSA/ECDSA/DSA X.509 certificate
-2971  * @return returns RSAKey/KJUR.crypto.{ECDSA,DSA} object of public key
-2972  * @since x509 1.1.1
-2973  * @description
-2974  * NOTE: DSA is also supported since x509 1.1.2.
-2975  */
-2976 X509.getPublicKeyFromCertPEM = function(sCertPEM) {
-2977     var x = new X509();
-2978     x.readCertPEM(sCertPEM);
-2979     return x.getPublicKey();
-2980 };
-2981 
-2982 /**
-2983  * get public key information from PEM certificate
-2984  * @name getPublicKeyInfoPropOfCertPEM
-2985  * @memberOf X509
-2986  * @function
-2987  * @param {String} sCertPEM string of PEM formatted certificate
-2988  * @return {Hash} hash of information for public key
-2989  * @since x509 1.1.1
-2990  * @description
-2991  * Resulted associative array has following properties:<br/>
-2992  * <ul>
-2993  * <li>algoid - hexadecimal string of OID of asymmetric key algorithm</li>
-2994  * <li>algparam - hexadecimal string of OID of ECC curve name or null</li>
-2995  * <li>keyhex - hexadecimal string of key in the certificate</li>
-2996  * </ul>
-2997  * NOTE: X509v1 certificate is also supported since x509.js 1.1.9.
-2998  */
-2999 X509.getPublicKeyInfoPropOfCertPEM = function(sCertPEM) {
-3000     var _ASN1HEX = ASN1HEX;
-3001     var _getVbyList = _ASN1HEX.getVbyList;
-3002 
-3003     var result = {};
-3004     var x, hSPKI, pubkey;
-3005     result.algparam = null;
+2947 /**
+2948  * get RSA/DSA/ECDSA public key object from X.509 certificate hexadecimal string<br/>
+2949  * @name getPublicKeyFromCertHex
+2950  * @memberOf X509
+2951  * @function
+2952  * @param {String} h hexadecimal string of X.509 certificate for RSA/ECDSA/DSA public key
+2953  * @return returns RSAKey/KJUR.crypto.{ECDSA,DSA} object of public key
+2954  * @since jsrasign 7.1.0 x509 1.1.11
+2955  */
+2956 X509.getPublicKeyFromCertHex = function(h) {
+2957     var x = new X509();
+2958     x.readCertHex(h);
+2959     return x.getPublicKey();
+2960 };
+2961 
+2962 /**
+2963  * get RSA/DSA/ECDSA public key object from PEM certificate string
+2964  * @name getPublicKeyFromCertPEM
+2965  * @memberOf X509
+2966  * @function
+2967  * @param {String} sCertPEM PEM formatted RSA/ECDSA/DSA X.509 certificate
+2968  * @return returns RSAKey/KJUR.crypto.{ECDSA,DSA} object of public key
+2969  * @since x509 1.1.1
+2970  * @description
+2971  * NOTE: DSA is also supported since x509 1.1.2.
+2972  */
+2973 X509.getPublicKeyFromCertPEM = function(sCertPEM) {
+2974     var x = new X509();
+2975     x.readCertPEM(sCertPEM);
+2976     return x.getPublicKey();
+2977 };
+2978 
+2979 /**
+2980  * get public key information from PEM certificate
+2981  * @name getPublicKeyInfoPropOfCertPEM
+2982  * @memberOf X509
+2983  * @function
+2984  * @param {String} sCertPEM string of PEM formatted certificate
+2985  * @return {Hash} hash of information for public key
+2986  * @since x509 1.1.1
+2987  * @description
+2988  * Resulted associative array has following properties:<br/>
+2989  * <ul>
+2990  * <li>algoid - hexadecimal string of OID of asymmetric key algorithm</li>
+2991  * <li>algparam - hexadecimal string of OID of ECC curve name or null</li>
+2992  * <li>keyhex - hexadecimal string of key in the certificate</li>
+2993  * </ul>
+2994  * NOTE: X509v1 certificate is also supported since x509.js 1.1.9.
+2995  */
+2996 X509.getPublicKeyInfoPropOfCertPEM = function(sCertPEM) {
+2997     var _ASN1HEX = ASN1HEX;
+2998     var _getVbyList = _ASN1HEX.getVbyList;
+2999 
+3000     var result = {};
+3001     var x, hSPKI, pubkey;
+3002     result.algparam = null;
+3003 
+3004     x = new X509();
+3005     x.readCertPEM(sCertPEM);
 3006 
-3007     x = new X509();
-3008     x.readCertPEM(sCertPEM);
-3009 
-3010     hSPKI = x.getPublicKeyHex();
-3011     result.keyhex = _getVbyList(hSPKI, 0, [1], "03").substr(2);
-3012     result.algoid = _getVbyList(hSPKI, 0, [0, 0], "06");
-3013 
-3014     if (result.algoid === "2a8648ce3d0201") { // ecPublicKey
-3015 	result.algparam = _getVbyList(hSPKI, 0, [0, 1], "06");
-3016     };
+3007     hSPKI = x.getPublicKeyHex();
+3008     result.keyhex = _getVbyList(hSPKI, 0, [1], "03").substr(2);
+3009     result.algoid = _getVbyList(hSPKI, 0, [0, 0], "06");
+3010 
+3011     if (result.algoid === "2a8648ce3d0201") { // ecPublicKey
+3012 	result.algparam = _getVbyList(hSPKI, 0, [0, 1], "06");
+3013     };
+3014 
+3015     return result;
+3016 };
 3017 
-3018     return result;
-3019 };
-3020 
-3021 /* ======================================================================
-3022  *   Specific V3 Extensions
-3023  * ====================================================================== */
-3024 
-3025 X509.KEYUSAGE_NAME = [
-3026     "digitalSignature",
-3027     "nonRepudiation",
-3028     "keyEncipherment",
-3029     "dataEncipherment",
-3030     "keyAgreement",
-3031     "keyCertSign",
-3032     "cRLSign",
-3033     "encipherOnly",
-3034     "decipherOnly"
-3035 ];
-3036 
\ No newline at end of file +3018
/* ====================================================================== +3019 * Specific V3 Extensions +3020 * ====================================================================== */ +3021 +3022 X509.KEYUSAGE_NAME = [ +3023 "digitalSignature", +3024 "nonRepudiation", +3025 "keyEncipherment", +3026 "dataEncipherment", +3027 "keyAgreement", +3028 "keyCertSign", +3029 "cRLSign", +3030 "encipherOnly", +3031 "decipherOnly" +3032 ]; +3033
\ No newline at end of file diff --git a/bower.json b/bower.json index 38ba3bb2..367946ca 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "kjur-jsrsasign", - "version": "10.1.11", + "version": "10.1.12", "main": "jsrsasign-all-min.js", "description": "The 'jsrsasign' (RSA-Sign JavaScript Library) is an opensource free cryptography library supporting RSA/RSAPSS/ECDSA/DSA signing/validation, ASN.1, PKCS#1/5/8 private/public key, X.509 certificate, CRL, OCSP, CMS SignedData, TimeStamp, CAdES, JWS and JWT in pure JavaScript.", "license": "MIT", diff --git a/jsrsasign-all-min.js b/jsrsasign-all-min.js index e7801440..921f27bd 100644 --- a/jsrsasign-all-min.js +++ b/jsrsasign-all-min.js @@ -1,5 +1,5 @@ /* - * jsrsasign(all) 10.1.11 (2021-02-19) (c) 2010-2021 Kenji Urushima | kjur.github.com/jsrsasign/license + * jsrsasign(all) 10.1.12 (2021-02-25) (c) 2010-2021 Kenji Urushima | kjur.github.com/jsrsasign/license */ /*! @@ -241,7 +241,7 @@ if(typeof KJUR=="undefined"||!KJUR){KJUR={}}if(typeof KJUR.crypto=="undefined"|| var KEYUTIL=function(){var d=function(p,r,q){return k(CryptoJS.AES,p,r,q)};var e=function(p,r,q){return k(CryptoJS.TripleDES,p,r,q)};var a=function(p,r,q){return k(CryptoJS.DES,p,r,q)};var k=function(s,x,u,q){var r=CryptoJS.enc.Hex.parse(x);var w=CryptoJS.enc.Hex.parse(u);var p=CryptoJS.enc.Hex.parse(q);var t={};t.key=w;t.iv=p;t.ciphertext=r;var v=s.decrypt(t,w,{iv:p});return CryptoJS.enc.Hex.stringify(v)};var l=function(p,r,q){return g(CryptoJS.AES,p,r,q)};var o=function(p,r,q){return g(CryptoJS.TripleDES,p,r,q)};var f=function(p,r,q){return g(CryptoJS.DES,p,r,q)};var g=function(t,y,v,q){var s=CryptoJS.enc.Hex.parse(y);var x=CryptoJS.enc.Hex.parse(v);var p=CryptoJS.enc.Hex.parse(q);var w=t.encrypt(s,x,{iv:p});var r=CryptoJS.enc.Hex.parse(w.toString());var u=CryptoJS.enc.Base64.stringify(r);return u};var i={"AES-256-CBC":{proc:d,eproc:l,keylen:32,ivlen:16},"AES-192-CBC":{proc:d,eproc:l,keylen:24,ivlen:16},"AES-128-CBC":{proc:d,eproc:l,keylen:16,ivlen:16},"DES-EDE3-CBC":{proc:e,eproc:o,keylen:24,ivlen:8},"DES-CBC":{proc:a,eproc:f,keylen:8,ivlen:8}};var c=function(p){return i[p]["proc"]};var m=function(p){var r=CryptoJS.lib.WordArray.random(p);var q=CryptoJS.enc.Hex.stringify(r);return q};var n=function(v){var w={};var q=v.match(new RegExp("DEK-Info: ([^,]+),([0-9A-Fa-f]+)","m"));if(q){w.cipher=q[1];w.ivsalt=q[2]}var p=v.match(new RegExp("-----BEGIN ([A-Z]+) PRIVATE KEY-----"));if(p){w.type=p[1]}var u=-1;var x=0;if(v.indexOf("\r\n\r\n")!=-1){u=v.indexOf("\r\n\r\n");x=2}if(v.indexOf("\n\n")!=-1){u=v.indexOf("\n\n");x=1}var t=v.indexOf("-----END");if(u!=-1&&t!=-1){var r=v.substring(u+x*2,t-x);r=r.replace(/\s+/g,"");w.data=r}return w};var j=function(q,y,p){var v=p.substring(0,16);var t=CryptoJS.enc.Hex.parse(v);var r=CryptoJS.enc.Utf8.parse(y);var u=i[q]["keylen"]+i[q]["ivlen"];var x="";var w=null;for(;;){var s=CryptoJS.algo.MD5.create();if(w!=null){s.update(w)}s.update(r);s.update(t);w=s.finalize();x=x+CryptoJS.enc.Hex.stringify(w);if(x.length>=u*2){break}}var z={};z.keyhex=x.substr(0,i[q]["keylen"]*2);z.ivhex=x.substr(i[q]["keylen"]*2,i[q]["ivlen"]*2);return z};var b=function(p,v,r,w){var s=CryptoJS.enc.Base64.parse(p);var q=CryptoJS.enc.Hex.stringify(s);var u=i[v]["proc"];var t=u(q,r,w);return t};var h=function(p,s,q,u){var r=i[s]["eproc"];var t=r(p,q,u);return t};return{version:"1.0.0",parsePKCS5PEM:function(p){return n(p)},getKeyAndUnusedIvByPasscodeAndIvsalt:function(q,p,r){return j(q,p,r)},decryptKeyB64:function(p,r,q,s){return b(p,r,q,s)},getDecryptedKeyHex:function(y,x){var q=n(y);var t=q.type;var r=q.cipher;var p=q.ivsalt;var s=q.data;var w=j(r,x,p);var v=w.keyhex;var u=b(s,r,v,p);return u},getEncryptedPKCS5PEMFromPrvKeyHex:function(x,s,A,t,r){var p="";if(typeof t=="undefined"||t==null){t="AES-256-CBC"}if(typeof i[t]=="undefined"){throw"KEYUTIL unsupported algorithm: "+t}if(typeof r=="undefined"||r==null){var v=i[t]["ivlen"];var u=m(v);r=u.toUpperCase()}var z=j(t,A,r);var y=z.keyhex;var w=h(s,t,y,r);var q=w.replace(/(.{64})/g,"$1\r\n");var p="-----BEGIN "+x+" PRIVATE KEY-----\r\n";p+="Proc-Type: 4,ENCRYPTED\r\n";p+="DEK-Info: "+t+","+r+"\r\n";p+="\r\n";p+=q;p+="\r\n-----END "+x+" PRIVATE KEY-----\r\n";return p},parseHexOfEncryptedPKCS8:function(y){var B=ASN1HEX;var z=B.getChildIdx;var w=B.getV;var t={};var r=z(y,0);if(r.length!=2){throw"malformed format: SEQUENCE(0).items != 2: "+r.length}t.ciphertext=w(y,r[1]);var A=z(y,r[0]);if(A.length!=2){throw"malformed format: SEQUENCE(0.0).items != 2: "+A.length}if(w(y,A[0])!="2a864886f70d01050d"){throw"this only supports pkcs5PBES2"}var p=z(y,A[1]);if(A.length!=2){throw"malformed format: SEQUENCE(0.0.1).items != 2: "+p.length}var q=z(y,p[1]);if(q.length!=2){throw"malformed format: SEQUENCE(0.0.1.1).items != 2: "+q.length}if(w(y,q[0])!="2a864886f70d0307"){throw"this only supports TripleDES"}t.encryptionSchemeAlg="TripleDES";t.encryptionSchemeIV=w(y,q[1]);var s=z(y,p[0]);if(s.length!=2){throw"malformed format: SEQUENCE(0.0.1.0).items != 2: "+s.length}if(w(y,s[0])!="2a864886f70d01050c"){throw"this only supports pkcs5PBKDF2"}var x=z(y,s[1]);if(x.length<2){throw"malformed format: SEQUENCE(0.0.1.0.1).items < 2: "+x.length}t.pbkdf2Salt=w(y,x[0]);var u=w(y,x[1]);try{t.pbkdf2Iter=parseInt(u,16)}catch(v){throw"malformed format pbkdf2Iter: "+u}return t},getPBKDF2KeyHexFromParam:function(u,p){var t=CryptoJS.enc.Hex.parse(u.pbkdf2Salt);var q=u.pbkdf2Iter;var s=CryptoJS.PBKDF2(p,t,{keySize:192/32,iterations:q});var r=CryptoJS.enc.Hex.stringify(s);return r},_getPlainPKCS8HexFromEncryptedPKCS8PEM:function(x,y){var r=pemtohex(x,"ENCRYPTED PRIVATE KEY");var p=this.parseHexOfEncryptedPKCS8(r);var u=KEYUTIL.getPBKDF2KeyHexFromParam(p,y);var v={};v.ciphertext=CryptoJS.enc.Hex.parse(p.ciphertext);var t=CryptoJS.enc.Hex.parse(u);var s=CryptoJS.enc.Hex.parse(p.encryptionSchemeIV);var w=CryptoJS.TripleDES.decrypt(v,t,{iv:s});var q=CryptoJS.enc.Hex.stringify(w);return q},getKeyFromEncryptedPKCS8PEM:function(s,q){var p=this._getPlainPKCS8HexFromEncryptedPKCS8PEM(s,q);var r=this.getKeyFromPlainPrivatePKCS8Hex(p);return r},parsePlainPrivatePKCS8Hex:function(s){var v=ASN1HEX;var u=v.getChildIdx;var t=v.getV;var q={};q.algparam=null;if(s.substr(0,2)!="30"){throw new Error("malformed plain PKCS8 private key(code:001)")}var r=u(s,0);if(r.length<3){throw new Error("malformed plain PKCS8 private key(code:002)")}if(s.substr(r[1],2)!="30"){throw new Error("malformed PKCS8 private key(code:003)")}var p=u(s,r[1]);if(p.length!=2){throw new Error("malformed PKCS8 private key(code:004)")}if(s.substr(p[0],2)!="06"){throw new Error("malformed PKCS8 private key(code:005)")}q.algoid=t(s,p[0]);if(s.substr(p[1],2)=="06"){q.algparam=t(s,p[1])}if(s.substr(r[2],2)!="04"){throw new Error("malformed PKCS8 private key(code:006)")}q.keyidx=v.getVidx(s,r[2]);return q},getKeyFromPlainPrivatePKCS8PEM:function(q){var p=pemtohex(q,"PRIVATE KEY");var r=this.getKeyFromPlainPrivatePKCS8Hex(p);return r},getKeyFromPlainPrivatePKCS8Hex:function(p){var q=this.parsePlainPrivatePKCS8Hex(p);var r;if(q.algoid=="2a864886f70d010101"){r=new RSAKey()}else{if(q.algoid=="2a8648ce380401"){r=new KJUR.crypto.DSA()}else{if(q.algoid=="2a8648ce3d0201"){r=new KJUR.crypto.ECDSA()}else{throw"unsupported private key algorithm"}}}r.readPKCS8PrvKeyHex(p);return r},_getKeyFromPublicPKCS8Hex:function(q){var p;var r=ASN1HEX.getVbyList(q,0,[0,0],"06");if(r==="2a864886f70d010101"){p=new RSAKey()}else{if(r==="2a8648ce380401"){p=new KJUR.crypto.DSA()}else{if(r==="2a8648ce3d0201"){p=new KJUR.crypto.ECDSA()}else{throw"unsupported PKCS#8 public key hex"}}}p.readPKCS8PubKeyHex(q);return p},parsePublicRawRSAKeyHex:function(r){var u=ASN1HEX;var t=u.getChildIdx;var s=u.getV;var p={};if(r.substr(0,2)!="30"){throw"malformed RSA key(code:001)"}var q=t(r,0);if(q.length!=2){throw"malformed RSA key(code:002)"}if(r.substr(q[0],2)!="02"){throw"malformed RSA key(code:003)"}p.n=s(r,q[0]);if(r.substr(q[1],2)!="02"){throw"malformed RSA key(code:004)"}p.e=s(r,q[1]);return p},parsePublicPKCS8Hex:function(t){var v=ASN1HEX;var u=v.getChildIdx;var s=v.getV;var q={};q.algparam=null;var r=u(t,0);if(r.length!=2){throw"outer DERSequence shall have 2 elements: "+r.length}var w=r[0];if(t.substr(w,2)!="30"){throw"malformed PKCS8 public key(code:001)"}var p=u(t,w);if(p.length!=2){throw"malformed PKCS8 public key(code:002)"}if(t.substr(p[0],2)!="06"){throw"malformed PKCS8 public key(code:003)"}q.algoid=s(t,p[0]);if(t.substr(p[1],2)=="06"){q.algparam=s(t,p[1])}else{if(t.substr(p[1],2)=="30"){q.algparam={};q.algparam.p=v.getVbyList(t,p[1],[0],"02");q.algparam.q=v.getVbyList(t,p[1],[1],"02");q.algparam.g=v.getVbyList(t,p[1],[2],"02")}}if(t.substr(r[1],2)!="03"){throw"malformed PKCS8 public key(code:004)"}q.key=s(t,r[1]).substr(2);return q},}}();KEYUTIL.getKey=function(l,k,n){var G=ASN1HEX,L=G.getChildIdx,v=G.getV,d=G.getVbyList,c=KJUR.crypto,i=c.ECDSA,C=c.DSA,w=RSAKey,M=pemtohex,F=KEYUTIL;if(typeof w!="undefined"&&l instanceof w){return l}if(typeof i!="undefined"&&l instanceof i){return l}if(typeof C!="undefined"&&l instanceof C){return l}if(l.curve!==undefined&&l.xy!==undefined&&l.d===undefined){return new i({pub:l.xy,curve:l.curve})}if(l.curve!==undefined&&l.d!==undefined){return new i({prv:l.d,curve:l.curve})}if(l.kty===undefined&&l.n!==undefined&&l.e!==undefined&&l.d===undefined){var P=new w();P.setPublic(l.n,l.e);return P}if(l.kty===undefined&&l.n!==undefined&&l.e!==undefined&&l.d!==undefined&&l.p!==undefined&&l.q!==undefined&&l.dp!==undefined&&l.dq!==undefined&&l.co!==undefined&&l.qi===undefined){var P=new w();P.setPrivateEx(l.n,l.e,l.d,l.p,l.q,l.dp,l.dq,l.co);return P}if(l.kty===undefined&&l.n!==undefined&&l.e!==undefined&&l.d!==undefined&&l.p===undefined){var P=new w();P.setPrivate(l.n,l.e,l.d);return P}if(l.p!==undefined&&l.q!==undefined&&l.g!==undefined&&l.y!==undefined&&l.x===undefined){var P=new C();P.setPublic(l.p,l.q,l.g,l.y);return P}if(l.p!==undefined&&l.q!==undefined&&l.g!==undefined&&l.y!==undefined&&l.x!==undefined){var P=new C();P.setPrivate(l.p,l.q,l.g,l.y,l.x);return P}if(l.kty==="RSA"&&l.n!==undefined&&l.e!==undefined&&l.d===undefined){var P=new w();P.setPublic(b64utohex(l.n),b64utohex(l.e));return P}if(l.kty==="RSA"&&l.n!==undefined&&l.e!==undefined&&l.d!==undefined&&l.p!==undefined&&l.q!==undefined&&l.dp!==undefined&&l.dq!==undefined&&l.qi!==undefined){var P=new w();P.setPrivateEx(b64utohex(l.n),b64utohex(l.e),b64utohex(l.d),b64utohex(l.p),b64utohex(l.q),b64utohex(l.dp),b64utohex(l.dq),b64utohex(l.qi));return P}if(l.kty==="RSA"&&l.n!==undefined&&l.e!==undefined&&l.d!==undefined){var P=new w();P.setPrivate(b64utohex(l.n),b64utohex(l.e),b64utohex(l.d));return P}if(l.kty==="EC"&&l.crv!==undefined&&l.x!==undefined&&l.y!==undefined&&l.d===undefined){var j=new i({curve:l.crv});var t=j.ecparams.keylen/4;var B=("0000000000"+b64utohex(l.x)).slice(-t);var z=("0000000000"+b64utohex(l.y)).slice(-t);var u="04"+B+z;j.setPublicKeyHex(u);return j}if(l.kty==="EC"&&l.crv!==undefined&&l.x!==undefined&&l.y!==undefined&&l.d!==undefined){var j=new i({curve:l.crv});var t=j.ecparams.keylen/4;var B=("0000000000"+b64utohex(l.x)).slice(-t);var z=("0000000000"+b64utohex(l.y)).slice(-t);var u="04"+B+z;var b=("0000000000"+b64utohex(l.d)).slice(-t);j.setPublicKeyHex(u);j.setPrivateKeyHex(b);return j}if(n==="pkcs5prv"){var J=l,G=ASN1HEX,N,P;N=L(J,0);if(N.length===9){P=new w();P.readPKCS5PrvKeyHex(J)}else{if(N.length===6){P=new C();P.readPKCS5PrvKeyHex(J)}else{if(N.length>2&&J.substr(N[1],2)==="04"){P=new i();P.readPKCS5PrvKeyHex(J)}else{throw"unsupported PKCS#1/5 hexadecimal key"}}}return P}if(n==="pkcs8prv"){var P=F.getKeyFromPlainPrivatePKCS8Hex(l);return P}if(n==="pkcs8pub"){return F._getKeyFromPublicPKCS8Hex(l)}if(n==="x509pub"){return X509.getPublicKeyFromCertHex(l)}if(l.indexOf("-END CERTIFICATE-",0)!=-1||l.indexOf("-END X509 CERTIFICATE-",0)!=-1||l.indexOf("-END TRUSTED CERTIFICATE-",0)!=-1){return X509.getPublicKeyFromCertPEM(l)}if(l.indexOf("-END PUBLIC KEY-")!=-1){var O=pemtohex(l,"PUBLIC KEY");return F._getKeyFromPublicPKCS8Hex(O)}if(l.indexOf("-END RSA PRIVATE KEY-")!=-1&&l.indexOf("4,ENCRYPTED")==-1){var m=M(l,"RSA PRIVATE KEY");return F.getKey(m,null,"pkcs5prv")}if(l.indexOf("-END DSA PRIVATE KEY-")!=-1&&l.indexOf("4,ENCRYPTED")==-1){var I=M(l,"DSA PRIVATE KEY");var E=d(I,0,[1],"02");var D=d(I,0,[2],"02");var K=d(I,0,[3],"02");var r=d(I,0,[4],"02");var s=d(I,0,[5],"02");var P=new C();P.setPrivate(new BigInteger(E,16),new BigInteger(D,16),new BigInteger(K,16),new BigInteger(r,16),new BigInteger(s,16));return P}if(l.indexOf("-END EC PRIVATE KEY-")!=-1&&l.indexOf("4,ENCRYPTED")==-1){var m=M(l,"EC PRIVATE KEY");return F.getKey(m,null,"pkcs5prv")}if(l.indexOf("-END PRIVATE KEY-")!=-1){return F.getKeyFromPlainPrivatePKCS8PEM(l)}if(l.indexOf("-END RSA PRIVATE KEY-")!=-1&&l.indexOf("4,ENCRYPTED")!=-1){var o=F.getDecryptedKeyHex(l,k);var H=new RSAKey();H.readPKCS5PrvKeyHex(o);return H}if(l.indexOf("-END EC PRIVATE KEY-")!=-1&&l.indexOf("4,ENCRYPTED")!=-1){var I=F.getDecryptedKeyHex(l,k);var P=d(I,0,[1],"04");var f=d(I,0,[2,0],"06");var A=d(I,0,[3,0],"03").substr(2);var e="";if(KJUR.crypto.OID.oidhex2name[f]!==undefined){e=KJUR.crypto.OID.oidhex2name[f]}else{throw"undefined OID(hex) in KJUR.crypto.OID: "+f}var j=new i({curve:e});j.setPublicKeyHex(A);j.setPrivateKeyHex(P);j.isPublic=false;return j}if(l.indexOf("-END DSA PRIVATE KEY-")!=-1&&l.indexOf("4,ENCRYPTED")!=-1){var I=F.getDecryptedKeyHex(l,k);var E=d(I,0,[1],"02");var D=d(I,0,[2],"02");var K=d(I,0,[3],"02");var r=d(I,0,[4],"02");var s=d(I,0,[5],"02");var P=new C();P.setPrivate(new BigInteger(E,16),new BigInteger(D,16),new BigInteger(K,16),new BigInteger(r,16),new BigInteger(s,16));return P}if(l.indexOf("-END ENCRYPTED PRIVATE KEY-")!=-1){return F.getKeyFromEncryptedPKCS8PEM(l,k)}throw new Error("not supported argument")};KEYUTIL.generateKeypair=function(a,c){if(a=="RSA"){var b=c;var h=new RSAKey();h.generate(b,"10001");h.isPrivate=true;h.isPublic=true;var f=new RSAKey();var e=h.n.toString(16);var i=h.e.toString(16);f.setPublic(e,i);f.isPrivate=false;f.isPublic=true;var k={};k.prvKeyObj=h;k.pubKeyObj=f;return k}else{if(a=="EC"){var d=c;var g=new KJUR.crypto.ECDSA({curve:d});var j=g.generateKeyPairHex();var h=new KJUR.crypto.ECDSA({curve:d});h.setPublicKeyHex(j.ecpubhex);h.setPrivateKeyHex(j.ecprvhex);h.isPrivate=true;h.isPublic=false;var f=new KJUR.crypto.ECDSA({curve:d});f.setPublicKeyHex(j.ecpubhex);f.isPrivate=false;f.isPublic=true;var k={};k.prvKeyObj=h;k.pubKeyObj=f;return k}else{throw"unknown algorithm: "+a}}};KEYUTIL.getPEM=function(b,D,y,m,q,j){var F=KJUR,k=F.asn1,z=k.DERObjectIdentifier,f=k.DERInteger,l=k.ASN1Util.newObject,a=k.x509,C=a.SubjectPublicKeyInfo,e=F.crypto,u=e.DSA,r=e.ECDSA,n=RSAKey;function A(s){var G=l({seq:[{"int":0},{"int":{bigint:s.n}},{"int":s.e},{"int":{bigint:s.d}},{"int":{bigint:s.p}},{"int":{bigint:s.q}},{"int":{bigint:s.dmp1}},{"int":{bigint:s.dmq1}},{"int":{bigint:s.coeff}}]});return G}function B(G){var s=l({seq:[{"int":1},{octstr:{hex:G.prvKeyHex}},{tag:["a0",true,{oid:{name:G.curveName}}]},{tag:["a1",true,{bitstr:{hex:"00"+G.pubKeyHex}}]}]});return s}function x(s){var G=l({seq:[{"int":0},{"int":{bigint:s.p}},{"int":{bigint:s.q}},{"int":{bigint:s.g}},{"int":{bigint:s.y}},{"int":{bigint:s.x}}]});return G}if(((n!==undefined&&b instanceof n)||(u!==undefined&&b instanceof u)||(r!==undefined&&b instanceof r))&&b.isPublic==true&&(D===undefined||D=="PKCS8PUB")){var E=new C(b);var w=E.getEncodedHex();return hextopem(w,"PUBLIC KEY")}if(D=="PKCS1PRV"&&n!==undefined&&b instanceof n&&(y===undefined||y==null)&&b.isPrivate==true){var E=A(b);var w=E.getEncodedHex();return hextopem(w,"RSA PRIVATE KEY")}if(D=="PKCS1PRV"&&r!==undefined&&b instanceof r&&(y===undefined||y==null)&&b.isPrivate==true){var i=new z({name:b.curveName});var v=i.getEncodedHex();var h=B(b);var t=h.getEncodedHex();var p="";p+=hextopem(v,"EC PARAMETERS");p+=hextopem(t,"EC PRIVATE KEY");return p}if(D=="PKCS1PRV"&&u!==undefined&&b instanceof u&&(y===undefined||y==null)&&b.isPrivate==true){var E=x(b);var w=E.getEncodedHex();return hextopem(w,"DSA PRIVATE KEY")}if(D=="PKCS5PRV"&&n!==undefined&&b instanceof n&&(y!==undefined&&y!=null)&&b.isPrivate==true){var E=A(b);var w=E.getEncodedHex();if(m===undefined){m="DES-EDE3-CBC"}return this.getEncryptedPKCS5PEMFromPrvKeyHex("RSA",w,y,m,j)}if(D=="PKCS5PRV"&&r!==undefined&&b instanceof r&&(y!==undefined&&y!=null)&&b.isPrivate==true){var E=B(b);var w=E.getEncodedHex();if(m===undefined){m="DES-EDE3-CBC"}return this.getEncryptedPKCS5PEMFromPrvKeyHex("EC",w,y,m,j)}if(D=="PKCS5PRV"&&u!==undefined&&b instanceof u&&(y!==undefined&&y!=null)&&b.isPrivate==true){var E=x(b);var w=E.getEncodedHex();if(m===undefined){m="DES-EDE3-CBC"}return this.getEncryptedPKCS5PEMFromPrvKeyHex("DSA",w,y,m,j)}var o=function(G,s){var I=c(G,s);var H=new l({seq:[{seq:[{oid:{name:"pkcs5PBES2"}},{seq:[{seq:[{oid:{name:"pkcs5PBKDF2"}},{seq:[{octstr:{hex:I.pbkdf2Salt}},{"int":I.pbkdf2Iter}]}]},{seq:[{oid:{name:"des-EDE3-CBC"}},{octstr:{hex:I.encryptionSchemeIV}}]}]}]},{octstr:{hex:I.ciphertext}}]});return H.getEncodedHex()};var c=function(N,O){var H=100;var M=CryptoJS.lib.WordArray.random(8);var L="DES-EDE3-CBC";var s=CryptoJS.lib.WordArray.random(8);var I=CryptoJS.PBKDF2(O,M,{keySize:192/32,iterations:H});var J=CryptoJS.enc.Hex.parse(N);var K=CryptoJS.TripleDES.encrypt(J,I,{iv:s})+"";var G={};G.ciphertext=K;G.pbkdf2Salt=CryptoJS.enc.Hex.stringify(M);G.pbkdf2Iter=H;G.encryptionSchemeAlg=L;G.encryptionSchemeIV=CryptoJS.enc.Hex.stringify(s);return G};if(D=="PKCS8PRV"&&n!=undefined&&b instanceof n&&b.isPrivate==true){var g=A(b);var d=g.getEncodedHex();var E=l({seq:[{"int":0},{seq:[{oid:{name:"rsaEncryption"}},{"null":true}]},{octstr:{hex:d}}]});var w=E.getEncodedHex();if(y===undefined||y==null){return hextopem(w,"PRIVATE KEY")}else{var t=o(w,y);return hextopem(t,"ENCRYPTED PRIVATE KEY")}}if(D=="PKCS8PRV"&&r!==undefined&&b instanceof r&&b.isPrivate==true){var g=new l({seq:[{"int":1},{octstr:{hex:b.prvKeyHex}},{tag:["a1",true,{bitstr:{hex:"00"+b.pubKeyHex}}]}]});var d=g.getEncodedHex();var E=l({seq:[{"int":0},{seq:[{oid:{name:"ecPublicKey"}},{oid:{name:b.curveName}}]},{octstr:{hex:d}}]});var w=E.getEncodedHex();if(y===undefined||y==null){return hextopem(w,"PRIVATE KEY")}else{var t=o(w,y);return hextopem(t,"ENCRYPTED PRIVATE KEY")}}if(D=="PKCS8PRV"&&u!==undefined&&b instanceof u&&b.isPrivate==true){var g=new f({bigint:b.x});var d=g.getEncodedHex();var E=l({seq:[{"int":0},{seq:[{oid:{name:"dsa"}},{seq:[{"int":{bigint:b.p}},{"int":{bigint:b.q}},{"int":{bigint:b.g}}]}]},{octstr:{hex:d}}]});var w=E.getEncodedHex();if(y===undefined||y==null){return hextopem(w,"PRIVATE KEY")}else{var t=o(w,y);return hextopem(t,"ENCRYPTED PRIVATE KEY")}}throw new Error("unsupported object nor format")};KEYUTIL.getKeyFromCSRPEM=function(b){var a=pemtohex(b,"CERTIFICATE REQUEST");var c=KEYUTIL.getKeyFromCSRHex(a);return c};KEYUTIL.getKeyFromCSRHex=function(a){var c=KEYUTIL.parseCSRHex(a);var b=KEYUTIL.getKey(c.p8pubkeyhex,null,"pkcs8pub");return b};KEYUTIL.parseCSRHex=function(d){var i=ASN1HEX;var f=i.getChildIdx;var c=i.getTLV;var b={};var g=d;if(g.substr(0,2)!="30"){throw"malformed CSR(code:001)"}var e=f(g,0);if(e.length<1){throw"malformed CSR(code:002)"}if(g.substr(e[0],2)!="30"){throw"malformed CSR(code:003)"}var a=f(g,e[0]);if(a.length<3){throw"malformed CSR(code:004)"}b.p8pubkeyhex=c(g,a[2]);return b};KEYUTIL.getKeyID=function(f){var c=KEYUTIL;var e=ASN1HEX;if(typeof f==="string"&&f.indexOf("BEGIN ")!=-1){f=c.getKey(f)}var d=pemtohex(c.getPEM(f));var b=e.getIdxbyList(d,0,[1]);var a=e.getV(d,b).substring(2);return KJUR.crypto.Util.hashHex(a,"sha1")};KEYUTIL.getJWKFromKey=function(d){var b={};if(d instanceof RSAKey&&d.isPrivate){b.kty="RSA";b.n=hextob64u(d.n.toString(16));b.e=hextob64u(d.e.toString(16));b.d=hextob64u(d.d.toString(16));b.p=hextob64u(d.p.toString(16));b.q=hextob64u(d.q.toString(16));b.dp=hextob64u(d.dmp1.toString(16));b.dq=hextob64u(d.dmq1.toString(16));b.qi=hextob64u(d.coeff.toString(16));return b}else{if(d instanceof RSAKey&&d.isPublic){b.kty="RSA";b.n=hextob64u(d.n.toString(16));b.e=hextob64u(d.e.toString(16));return b}else{if(d instanceof KJUR.crypto.ECDSA&&d.isPrivate){var a=d.getShortNISTPCurveName();if(a!=="P-256"&&a!=="P-384"){throw"unsupported curve name for JWT: "+a}var c=d.getPublicKeyXYHex();b.kty="EC";b.crv=a;b.x=hextob64u(c.x);b.y=hextob64u(c.y);b.d=hextob64u(d.prvKeyHex);return b}else{if(d instanceof KJUR.crypto.ECDSA&&d.isPublic){var a=d.getShortNISTPCurveName();if(a!=="P-256"&&a!=="P-384"){throw"unsupported curve name for JWT: "+a}var c=d.getPublicKeyXYHex();b.kty="EC";b.crv=a;b.x=hextob64u(c.x);b.y=hextob64u(c.y);return b}}}}throw"not supported key object"}; RSAKey.getPosArrayOfChildrenFromHex=function(a){return ASN1HEX.getChildIdx(a,0)};RSAKey.getHexValueArrayOfChildrenFromHex=function(f){var n=ASN1HEX;var i=n.getV;var k=RSAKey.getPosArrayOfChildrenFromHex(f);var e=i(f,k[0]);var j=i(f,k[1]);var b=i(f,k[2]);var c=i(f,k[3]);var h=i(f,k[4]);var g=i(f,k[5]);var m=i(f,k[6]);var l=i(f,k[7]);var d=i(f,k[8]);var k=new Array();k.push(e,j,b,c,h,g,m,l,d);return k};RSAKey.prototype.readPrivateKeyFromPEMString=function(d){var c=pemtohex(d);var b=RSAKey.getHexValueArrayOfChildrenFromHex(c);this.setPrivateEx(b[1],b[2],b[3],b[4],b[5],b[6],b[7],b[8])};RSAKey.prototype.readPKCS5PrvKeyHex=function(c){var b=RSAKey.getHexValueArrayOfChildrenFromHex(c);this.setPrivateEx(b[1],b[2],b[3],b[4],b[5],b[6],b[7],b[8])};RSAKey.prototype.readPKCS8PrvKeyHex=function(e){var c,i,k,b,a,f,d,j;var m=ASN1HEX;var l=m.getVbyListEx;if(m.isASN1HEX(e)===false){throw new Error("not ASN.1 hex string")}try{c=l(e,0,[2,0,1],"02");i=l(e,0,[2,0,2],"02");k=l(e,0,[2,0,3],"02");b=l(e,0,[2,0,4],"02");a=l(e,0,[2,0,5],"02");f=l(e,0,[2,0,6],"02");d=l(e,0,[2,0,7],"02");j=l(e,0,[2,0,8],"02")}catch(g){throw new Error("malformed PKCS#8 plain RSA private key")}this.setPrivateEx(c,i,k,b,a,f,d,j)};RSAKey.prototype.readPKCS5PubKeyHex=function(c){var e=ASN1HEX;var b=e.getV;if(e.isASN1HEX(c)===false){throw new Error("keyHex is not ASN.1 hex string")}var a=e.getChildIdx(c,0);if(a.length!==2||c.substr(a[0],2)!=="02"||c.substr(a[1],2)!=="02"){throw new Error("wrong hex for PKCS#5 public key")}var f=b(c,a[0]);var d=b(c,a[1]);this.setPublic(f,d)};RSAKey.prototype.readPKCS8PubKeyHex=function(b){var c=ASN1HEX;if(c.isASN1HEX(b)===false){throw new Error("not ASN.1 hex string")}if(c.getTLVbyListEx(b,0,[0,0])!=="06092a864886f70d010101"){throw new Error("not PKCS8 RSA public key")}var a=c.getTLVbyListEx(b,0,[1,0]);this.readPKCS5PubKeyHex(a)};RSAKey.prototype.readCertPubKeyHex=function(b,d){var a,c;a=new X509();a.readCertHex(b);c=a.getPublicKeyHex();this.readPKCS8PubKeyHex(c)}; var _RE_HEXDECONLY=new RegExp("[^0-9a-f]","gi");function _rsasign_getHexPaddedDigestInfoForString(d,e,a){var b=function(f){return KJUR.crypto.Util.hashString(f,a)};var c=b(d);return KJUR.crypto.Util.getPaddedDigestInfoHex(c,a,e)}function _zeroPaddingOfSignature(e,d){var c="";var a=d/4-e.length;for(var b=0;b>24,(d&16711680)>>16,(d&65280)>>8,d&255]))));d+=1}return b}RSAKey.prototype.signPSS=function(e,a,d){var c=function(f){return KJUR.crypto.Util.hashHex(f,a)};var b=c(rstrtohex(e));if(d===undefined){d=-1}return this.signWithMessageHashPSS(b,a,d)};RSAKey.prototype.signWithMessageHashPSS=function(l,a,k){var b=hextorstr(l);var g=b.length;var m=this.n.bitLength()-1;var c=Math.ceil(m/8);var d;var o=function(i){return KJUR.crypto.Util.hashHex(i,a)};if(k===-1||k===undefined){k=g}else{if(k===-2){k=c-g-2}else{if(k<-2){throw new Error("invalid salt length")}}}if(c<(g+k+2)){throw new Error("data too long")}var f="";if(k>0){f=new Array(k);new SecureRandom().nextBytes(f);f=String.fromCharCode.apply(String,f)}var n=hextorstr(o(rstrtohex("\x00\x00\x00\x00\x00\x00\x00\x00"+b+f)));var j=[];for(d=0;d>(8*c-m))&255;q[0]&=~p;for(d=0;dthis.n.bitLength()){return 0}var i=this.doPublic(b);var e=i.toString(16).replace(/^1f+00/,"");var g=_rsasign_getAlgNameAndHashFromHexDisgestInfo(e);if(g.length==0){return false}var d=g[0];var h=g[1];var a=function(k){return KJUR.crypto.Util.hashString(k,d)};var c=a(f);return(h==c)};RSAKey.prototype.verifyWithMessageHash=function(e,a){if(a.length!=Math.ceil(this.n.bitLength()/4)){return false}var b=parseBigInt(a,16);if(b.bitLength()>this.n.bitLength()){return 0}var h=this.doPublic(b);var g=h.toString(16).replace(/^1f+00/,"");var c=_rsasign_getAlgNameAndHashFromHexDisgestInfo(g);if(c.length==0){return false}var d=c[0];var f=c[1];return(f==e)};RSAKey.prototype.verifyPSS=function(c,b,a,f){var e=function(g){return KJUR.crypto.Util.hashHex(g,a)};var d=e(rstrtohex(c));if(f===undefined){f=-1}return this.verifyWithMessageHashPSS(d,b,a,f)};RSAKey.prototype.verifyWithMessageHashPSS=function(f,s,l,c){if(s.length!=Math.ceil(this.n.bitLength()/4)){return false}var k=new BigInteger(s,16);var r=function(i){return KJUR.crypto.Util.hashHex(i,l)};var j=hextorstr(f);var h=j.length;var g=this.n.bitLength()-1;var m=Math.ceil(g/8);var q;if(c===-1||c===undefined){c=h}else{if(c===-2){c=m-h-2}else{if(c<-2){throw new Error("invalid salt length")}}}if(m<(h+c+2)){throw new Error("data too long")}var a=this.doPublic(k).toByteArray();for(q=0;q>(8*m-g))&255;if((d.charCodeAt(0)&p)!==0){throw new Error("bits beyond keysize not zero")}var n=pss_mgf1_str(e,d.length,r);var o=[];for(q=0;q1){var A=b(w,v[1]);var u=this.getGeneralName(A);if(u.uri!=undefined){t.uri=u.uri}}if(v.length>2){var x=b(w,v[2]);if(x=="0101ff"){t.reqauth=true}if(x=="010100"){t.reqauth=false}}return t};this.getX500NameRule=function(t){var A=true;var E=true;var D=false;var u="";var x="";var G=null;var B=[];for(var w=0;w0){t.ext=this.getExtParamArray()}t.sighex=this.getSignatureValueHex();return t};this.getExtParamArray=function(u){if(u==undefined){var w=e(this.hex,0,[0,"[3]"]);if(w!=-1){u=l(this.hex,0,[0,"[3]",0],"30")}}var t=[];var v=n(u,0);for(var x=0;x1){var A=b(w,v[1]);var u=this.getGeneralName(A);if(u.uri!=undefined){t.uri=u.uri}}if(v.length>2){var x=b(w,v[2]);if(x=="0101ff"){t.reqauth=true}if(x=="010100"){t.reqauth=false}}return t};this.getX500NameRule=function(t){var A=true;var E=true;var D=false;var u="";var x="";var G=null;var B=[];for(var w=0;w0){t.ext=this.getExtParamArray()}t.sighex=this.getSignatureValueHex();return t};this.getExtParamArray=function(u){if(u==undefined){var w=e(this.hex,0,[0,"[3]"]);if(w!=-1){u=l(this.hex,0,[0,"[3]",0],"30")}}var t=[];var v=n(u,0);for(var x=0;x0){var b=":"+n.join(":")+":";if(b.indexOf(":"+k+":")==-1){throw"algorithm '"+k+"' not accepted in the list"}}if(k!="none"&&B===null){throw"key shall be specified to verify."}if(typeof B=="string"&&B.indexOf("-----BEGIN ")!=-1){B=KEYUTIL.getKey(B)}if(z=="RS"||z=="PS"){if(!(B instanceof m)){throw"key shall be a RSAKey obj for RS* and PS* algs"}}if(z=="ES"){if(!(B instanceof p)){throw"key shall be a ECDSA obj for ES* algs"}}if(k=="none"){}var u=null;if(t.jwsalg2sigalg[l.alg]===undefined){throw"unsupported alg name: "+k}else{u=t.jwsalg2sigalg[k]}if(u=="none"){throw"not supported"}else{if(u.substr(0,4)=="Hmac"){var o=null;if(B===undefined){throw"hexadecimal key shall be specified for HMAC"}var j=new s({alg:u,pass:B});j.updateString(c);o=j.doFinal();return A==o}else{if(u.indexOf("withECDSA")!=-1){var h=null;try{h=p.concatSigToASN1Sig(A)}catch(v){return false}var g=new d({alg:u});g.init(B);g.updateString(c);return g.verify(h)}else{var g=new d({alg:u});g.init(B);g.updateString(c);return g.verify(A)}}}};KJUR.jws.JWS.parse=function(g){var c=g.split(".");var b={};var f,e,d;if(c.length!=2&&c.length!=3){throw"malformed sJWS: wrong number of '.' splitted elements"}f=c[0];e=c[1];if(c.length==3){d=c[2]}b.headerObj=KJUR.jws.JWS.readSafeJSONString(b64utoutf8(f));b.payloadObj=KJUR.jws.JWS.readSafeJSONString(b64utoutf8(e));b.headerPP=JSON.stringify(b.headerObj,null," ");if(b.payloadObj==null){b.payloadPP=b64utoutf8(e)}else{b.payloadPP=JSON.stringify(b.payloadObj,null," ")}if(d!==undefined){b.sigHex=b64utohex(d)}return b};KJUR.jws.JWS.verifyJWT=function(e,l,r){var d=KJUR,j=d.jws,o=j.JWS,n=o.readSafeJSONString,p=o.inArray,f=o.includedArray;var k=e.split(".");var c=k[0];var i=k[1];var q=c+"."+i;var m=b64utohex(k[2]);var h=n(b64utoutf8(c));var g=n(b64utoutf8(i));if(h.alg===undefined){return false}if(r.alg===undefined){throw"acceptField.alg shall be specified"}if(!p(h.alg,r.alg)){return false}if(g.iss!==undefined&&typeof r.iss==="object"){if(!p(g.iss,r.iss)){return false}}if(g.sub!==undefined&&typeof r.sub==="object"){if(!p(g.sub,r.sub)){return false}}if(g.aud!==undefined&&typeof r.aud==="object"){if(typeof g.aud=="string"){if(!p(g.aud,r.aud)){return false}}else{if(typeof g.aud=="object"){if(!f(g.aud,r.aud)){return false}}}}var b=j.IntDate.getNow();if(r.verifyAt!==undefined&&typeof r.verifyAt==="number"){b=r.verifyAt}if(r.gracePeriod===undefined||typeof r.gracePeriod!=="number"){r.gracePeriod=0}if(g.exp!==undefined&&typeof g.exp=="number"){if(g.exp+r.gracePeriodl){this.aHeader.pop()}if(this.aSignature.length>l){this.aSignature.pop()}throw"addSignature failed: "+i}};this.verifyAll=function(h){if(this.aHeader.length!==h.length||this.aSignature.length!==h.length){return false}for(var g=0;g0){this.aHeader=g.headers}else{throw"malformed header"}if(typeof g.payload==="string"){this.sPayload=g.payload}else{throw"malformed signatures"}if(g.signatures.length>0){this.aSignature=g.signatures}else{throw"malformed signatures"}}catch(e){throw"malformed JWS-JS JSON object: "+e}}};this.getJSON=function(){return{headers:this.aHeader,payload:this.sPayload,signatures:this.aSignature}};this.isEmpty=function(){if(this.aHeader.length==0){return 1}return 0}}; diff --git a/jsrsasign-jwths-min.js b/jsrsasign-jwths-min.js index 123b54a1..a3cf3a0b 100644 --- a/jsrsasign-jwths-min.js +++ b/jsrsasign-jwths-min.js @@ -1,5 +1,5 @@ /* - * jsrsasign(jwths) 10.1.11 (2021-02-19) (c) 2010-2021 Kenji Urushima | kjur.github.com/jsrsasign/license + * jsrsasign(jwths) 10.1.12 (2021-02-25) (c) 2010-2021 Kenji Urushima | kjur.github.com/jsrsasign/license */ /*! diff --git a/jsrsasign-rsa-min.js b/jsrsasign-rsa-min.js index adddbdfa..d04f0316 100644 --- a/jsrsasign-rsa-min.js +++ b/jsrsasign-rsa-min.js @@ -1,5 +1,5 @@ /* - * jsrsasign(rsa) 10.1.11 (2021-02-19) (c) 2010-2021 Kenji Urushima | kjur.github.com/jsrsasign/license + * jsrsasign(rsa) 10.1.12 (2021-02-25) (c) 2010-2021 Kenji Urushima | kjur.github.com/jsrsasign/license */ /*! diff --git a/min/x509-1.1.min.js b/min/x509-1.1.min.js index 18fc3f23..382281ea 100644 --- a/min/x509-1.1.min.js +++ b/min/x509-1.1.min.js @@ -1 +1 @@ -function X509(q){var j=ASN1HEX,n=j.getChildIdx,g=j.getV,b=j.getTLV,c=j.getVbyList,k=j.getVbyListEx,a=j.getTLVbyList,l=j.getTLVbyListEx,h=j.getIdxbyList,e=j.getIdxbyListEx,i=j.getVidx,s=j.getInt,p=j.oidname,m=j.hextooidstr,d=X509,r=pemtohex,f;try{f=KJUR.asn1.x509.AlgorithmIdentifier.PSSNAME2ASN1TLV}catch(o){}this.HEX2STAG={"0c":"utf8","13":"prn","16":"ia5","1a":"vis","1e":"bmp"};this.hex=null;this.version=0;this.foffset=0;this.aExtInfo=null;this.getVersion=function(){if(this.hex===null||this.version!==0){return this.version}var u=a(this.hex,0,[0,0]);if(u.substr(0,2)=="a0"){var v=a(u,0,[0]);var t=s(v,0);if(t<0||21){var A=b(w,v[1]);var u=this.getGeneralName(A);if(u.uri!=undefined){t.uri=u.uri}}if(v.length>2){var x=b(w,v[2]);if(x=="0101ff"){t.reqauth=true}if(x=="010100"){t.reqauth=false}}return t};this.getX500NameRule=function(t){var A=true;var E=true;var D=false;var u="";var x="";var G=null;var B=[];for(var w=0;w0){t.ext=this.getExtParamArray()}t.sighex=this.getSignatureValueHex();return t};this.getExtParamArray=function(u){if(u==undefined){var w=e(this.hex,0,[0,"[3]"]);if(w!=-1){u=l(this.hex,0,[0,"[3]",0],"30")}}var t=[];var v=n(u,0);for(var x=0;x1){var A=b(w,v[1]);var u=this.getGeneralName(A);if(u.uri!=undefined){t.uri=u.uri}}if(v.length>2){var x=b(w,v[2]);if(x=="0101ff"){t.reqauth=true}if(x=="010100"){t.reqauth=false}}return t};this.getX500NameRule=function(t){var A=true;var E=true;var D=false;var u="";var x="";var G=null;var B=[];for(var w=0;w0){t.ext=this.getExtParamArray()}t.sighex=this.getSignatureValueHex();return t};this.getExtParamArray=function(u){if(u==undefined){var w=e(this.hex,0,[0,"[3]"]);if(w!=-1){u=l(this.hex,0,[0,"[3]",0],"30")}}var t=[];var v=n(u,0);for(var x=0;x=u*2){break}}var z={};z.keyhex=x.substr(0,i[q]["keylen"]*2);z.ivhex=x.substr(i[q]["keylen"]*2,i[q]["ivlen"]*2);return z};var b=function(p,v,r,w){var s=CryptoJS.enc.Base64.parse(p);var q=CryptoJS.enc.Hex.stringify(s);var u=i[v]["proc"];var t=u(q,r,w);return t};var h=function(p,s,q,u){var r=i[s]["eproc"];var t=r(p,q,u);return t};return{version:"1.0.0",parsePKCS5PEM:function(p){return n(p)},getKeyAndUnusedIvByPasscodeAndIvsalt:function(q,p,r){return j(q,p,r)},decryptKeyB64:function(p,r,q,s){return b(p,r,q,s)},getDecryptedKeyHex:function(y,x){var q=n(y);var t=q.type;var r=q.cipher;var p=q.ivsalt;var s=q.data;var w=j(r,x,p);var v=w.keyhex;var u=b(s,r,v,p);return u},getEncryptedPKCS5PEMFromPrvKeyHex:function(x,s,A,t,r){var p="";if(typeof t=="undefined"||t==null){t="AES-256-CBC"}if(typeof i[t]=="undefined"){throw"KEYUTIL unsupported algorithm: "+t}if(typeof r=="undefined"||r==null){var v=i[t]["ivlen"];var u=m(v);r=u.toUpperCase()}var z=j(t,A,r);var y=z.keyhex;var w=h(s,t,y,r);var q=w.replace(/(.{64})/g,"$1\r\n");var p="-----BEGIN "+x+" PRIVATE KEY-----\r\n";p+="Proc-Type: 4,ENCRYPTED\r\n";p+="DEK-Info: "+t+","+r+"\r\n";p+="\r\n";p+=q;p+="\r\n-----END "+x+" PRIVATE KEY-----\r\n";return p},parseHexOfEncryptedPKCS8:function(y){var B=ASN1HEX;var z=B.getChildIdx;var w=B.getV;var t={};var r=z(y,0);if(r.length!=2){throw"malformed format: SEQUENCE(0).items != 2: "+r.length}t.ciphertext=w(y,r[1]);var A=z(y,r[0]);if(A.length!=2){throw"malformed format: SEQUENCE(0.0).items != 2: "+A.length}if(w(y,A[0])!="2a864886f70d01050d"){throw"this only supports pkcs5PBES2"}var p=z(y,A[1]);if(A.length!=2){throw"malformed format: SEQUENCE(0.0.1).items != 2: "+p.length}var q=z(y,p[1]);if(q.length!=2){throw"malformed format: SEQUENCE(0.0.1.1).items != 2: "+q.length}if(w(y,q[0])!="2a864886f70d0307"){throw"this only supports TripleDES"}t.encryptionSchemeAlg="TripleDES";t.encryptionSchemeIV=w(y,q[1]);var s=z(y,p[0]);if(s.length!=2){throw"malformed format: SEQUENCE(0.0.1.0).items != 2: "+s.length}if(w(y,s[0])!="2a864886f70d01050c"){throw"this only supports pkcs5PBKDF2"}var x=z(y,s[1]);if(x.length<2){throw"malformed format: SEQUENCE(0.0.1.0.1).items < 2: "+x.length}t.pbkdf2Salt=w(y,x[0]);var u=w(y,x[1]);try{t.pbkdf2Iter=parseInt(u,16)}catch(v){throw"malformed format pbkdf2Iter: "+u}return t},getPBKDF2KeyHexFromParam:function(u,p){var t=CryptoJS.enc.Hex.parse(u.pbkdf2Salt);var q=u.pbkdf2Iter;var s=CryptoJS.PBKDF2(p,t,{keySize:192/32,iterations:q});var r=CryptoJS.enc.Hex.stringify(s);return r},_getPlainPKCS8HexFromEncryptedPKCS8PEM:function(x,y){var r=pemtohex(x,"ENCRYPTED PRIVATE KEY");var p=this.parseHexOfEncryptedPKCS8(r);var u=KEYUTIL.getPBKDF2KeyHexFromParam(p,y);var v={};v.ciphertext=CryptoJS.enc.Hex.parse(p.ciphertext);var t=CryptoJS.enc.Hex.parse(u);var s=CryptoJS.enc.Hex.parse(p.encryptionSchemeIV);var w=CryptoJS.TripleDES.decrypt(v,t,{iv:s});var q=CryptoJS.enc.Hex.stringify(w);return q},getKeyFromEncryptedPKCS8PEM:function(s,q){var p=this._getPlainPKCS8HexFromEncryptedPKCS8PEM(s,q);var r=this.getKeyFromPlainPrivatePKCS8Hex(p);return r},parsePlainPrivatePKCS8Hex:function(s){var v=ASN1HEX;var u=v.getChildIdx;var t=v.getV;var q={};q.algparam=null;if(s.substr(0,2)!="30"){throw new Error("malformed plain PKCS8 private key(code:001)")}var r=u(s,0);if(r.length<3){throw new Error("malformed plain PKCS8 private key(code:002)")}if(s.substr(r[1],2)!="30"){throw new Error("malformed PKCS8 private key(code:003)")}var p=u(s,r[1]);if(p.length!=2){throw new Error("malformed PKCS8 private key(code:004)")}if(s.substr(p[0],2)!="06"){throw new Error("malformed PKCS8 private key(code:005)")}q.algoid=t(s,p[0]);if(s.substr(p[1],2)=="06"){q.algparam=t(s,p[1])}if(s.substr(r[2],2)!="04"){throw new Error("malformed PKCS8 private key(code:006)")}q.keyidx=v.getVidx(s,r[2]);return q},getKeyFromPlainPrivatePKCS8PEM:function(q){var p=pemtohex(q,"PRIVATE KEY");var r=this.getKeyFromPlainPrivatePKCS8Hex(p);return r},getKeyFromPlainPrivatePKCS8Hex:function(p){var q=this.parsePlainPrivatePKCS8Hex(p);var r;if(q.algoid=="2a864886f70d010101"){r=new RSAKey()}else{if(q.algoid=="2a8648ce380401"){r=new KJUR.crypto.DSA()}else{if(q.algoid=="2a8648ce3d0201"){r=new KJUR.crypto.ECDSA()}else{throw"unsupported private key algorithm"}}}r.readPKCS8PrvKeyHex(p);return r},_getKeyFromPublicPKCS8Hex:function(q){var p;var r=ASN1HEX.getVbyList(q,0,[0,0],"06");if(r==="2a864886f70d010101"){p=new RSAKey()}else{if(r==="2a8648ce380401"){p=new KJUR.crypto.DSA()}else{if(r==="2a8648ce3d0201"){p=new KJUR.crypto.ECDSA()}else{throw"unsupported PKCS#8 public key hex"}}}p.readPKCS8PubKeyHex(q);return p},parsePublicRawRSAKeyHex:function(r){var u=ASN1HEX;var t=u.getChildIdx;var s=u.getV;var p={};if(r.substr(0,2)!="30"){throw"malformed RSA key(code:001)"}var q=t(r,0);if(q.length!=2){throw"malformed RSA key(code:002)"}if(r.substr(q[0],2)!="02"){throw"malformed RSA key(code:003)"}p.n=s(r,q[0]);if(r.substr(q[1],2)!="02"){throw"malformed RSA key(code:004)"}p.e=s(r,q[1]);return p},parsePublicPKCS8Hex:function(t){var v=ASN1HEX;var u=v.getChildIdx;var s=v.getV;var q={};q.algparam=null;var r=u(t,0);if(r.length!=2){throw"outer DERSequence shall have 2 elements: "+r.length}var w=r[0];if(t.substr(w,2)!="30"){throw"malformed PKCS8 public key(code:001)"}var p=u(t,w);if(p.length!=2){throw"malformed PKCS8 public key(code:002)"}if(t.substr(p[0],2)!="06"){throw"malformed PKCS8 public key(code:003)"}q.algoid=s(t,p[0]);if(t.substr(p[1],2)=="06"){q.algparam=s(t,p[1])}else{if(t.substr(p[1],2)=="30"){q.algparam={};q.algparam.p=v.getVbyList(t,p[1],[0],"02");q.algparam.q=v.getVbyList(t,p[1],[1],"02");q.algparam.g=v.getVbyList(t,p[1],[2],"02")}}if(t.substr(r[1],2)!="03"){throw"malformed PKCS8 public key(code:004)"}q.key=s(t,r[1]).substr(2);return q},}}();KEYUTIL.getKey=function(l,k,n){var G=ASN1HEX,L=G.getChildIdx,v=G.getV,d=G.getVbyList,c=KJUR.crypto,i=c.ECDSA,C=c.DSA,w=RSAKey,M=pemtohex,F=KEYUTIL;if(typeof w!="undefined"&&l instanceof w){return l}if(typeof i!="undefined"&&l instanceof i){return l}if(typeof C!="undefined"&&l instanceof C){return l}if(l.curve!==undefined&&l.xy!==undefined&&l.d===undefined){return new i({pub:l.xy,curve:l.curve})}if(l.curve!==undefined&&l.d!==undefined){return new i({prv:l.d,curve:l.curve})}if(l.kty===undefined&&l.n!==undefined&&l.e!==undefined&&l.d===undefined){var P=new w();P.setPublic(l.n,l.e);return P}if(l.kty===undefined&&l.n!==undefined&&l.e!==undefined&&l.d!==undefined&&l.p!==undefined&&l.q!==undefined&&l.dp!==undefined&&l.dq!==undefined&&l.co!==undefined&&l.qi===undefined){var P=new w();P.setPrivateEx(l.n,l.e,l.d,l.p,l.q,l.dp,l.dq,l.co);return P}if(l.kty===undefined&&l.n!==undefined&&l.e!==undefined&&l.d!==undefined&&l.p===undefined){var P=new w();P.setPrivate(l.n,l.e,l.d);return P}if(l.p!==undefined&&l.q!==undefined&&l.g!==undefined&&l.y!==undefined&&l.x===undefined){var P=new C();P.setPublic(l.p,l.q,l.g,l.y);return P}if(l.p!==undefined&&l.q!==undefined&&l.g!==undefined&&l.y!==undefined&&l.x!==undefined){var P=new C();P.setPrivate(l.p,l.q,l.g,l.y,l.x);return P}if(l.kty==="RSA"&&l.n!==undefined&&l.e!==undefined&&l.d===undefined){var P=new w();P.setPublic(b64utohex(l.n),b64utohex(l.e));return P}if(l.kty==="RSA"&&l.n!==undefined&&l.e!==undefined&&l.d!==undefined&&l.p!==undefined&&l.q!==undefined&&l.dp!==undefined&&l.dq!==undefined&&l.qi!==undefined){var P=new w();P.setPrivateEx(b64utohex(l.n),b64utohex(l.e),b64utohex(l.d),b64utohex(l.p),b64utohex(l.q),b64utohex(l.dp),b64utohex(l.dq),b64utohex(l.qi));return P}if(l.kty==="RSA"&&l.n!==undefined&&l.e!==undefined&&l.d!==undefined){var P=new w();P.setPrivate(b64utohex(l.n),b64utohex(l.e),b64utohex(l.d));return P}if(l.kty==="EC"&&l.crv!==undefined&&l.x!==undefined&&l.y!==undefined&&l.d===undefined){var j=new i({curve:l.crv});var t=j.ecparams.keylen/4;var B=("0000000000"+b64utohex(l.x)).slice(-t);var z=("0000000000"+b64utohex(l.y)).slice(-t);var u="04"+B+z;j.setPublicKeyHex(u);return j}if(l.kty==="EC"&&l.crv!==undefined&&l.x!==undefined&&l.y!==undefined&&l.d!==undefined){var j=new i({curve:l.crv});var t=j.ecparams.keylen/4;var B=("0000000000"+b64utohex(l.x)).slice(-t);var z=("0000000000"+b64utohex(l.y)).slice(-t);var u="04"+B+z;var b=("0000000000"+b64utohex(l.d)).slice(-t);j.setPublicKeyHex(u);j.setPrivateKeyHex(b);return j}if(n==="pkcs5prv"){var J=l,G=ASN1HEX,N,P;N=L(J,0);if(N.length===9){P=new w();P.readPKCS5PrvKeyHex(J)}else{if(N.length===6){P=new C();P.readPKCS5PrvKeyHex(J)}else{if(N.length>2&&J.substr(N[1],2)==="04"){P=new i();P.readPKCS5PrvKeyHex(J)}else{throw"unsupported PKCS#1/5 hexadecimal key"}}}return P}if(n==="pkcs8prv"){var P=F.getKeyFromPlainPrivatePKCS8Hex(l);return P}if(n==="pkcs8pub"){return F._getKeyFromPublicPKCS8Hex(l)}if(n==="x509pub"){return X509.getPublicKeyFromCertHex(l)}if(l.indexOf("-END CERTIFICATE-",0)!=-1||l.indexOf("-END X509 CERTIFICATE-",0)!=-1||l.indexOf("-END TRUSTED CERTIFICATE-",0)!=-1){return X509.getPublicKeyFromCertPEM(l)}if(l.indexOf("-END PUBLIC KEY-")!=-1){var O=pemtohex(l,"PUBLIC KEY");return F._getKeyFromPublicPKCS8Hex(O)}if(l.indexOf("-END RSA PRIVATE KEY-")!=-1&&l.indexOf("4,ENCRYPTED")==-1){var m=M(l,"RSA PRIVATE KEY");return F.getKey(m,null,"pkcs5prv")}if(l.indexOf("-END DSA PRIVATE KEY-")!=-1&&l.indexOf("4,ENCRYPTED")==-1){var I=M(l,"DSA PRIVATE KEY");var E=d(I,0,[1],"02");var D=d(I,0,[2],"02");var K=d(I,0,[3],"02");var r=d(I,0,[4],"02");var s=d(I,0,[5],"02");var P=new C();P.setPrivate(new BigInteger(E,16),new BigInteger(D,16),new BigInteger(K,16),new BigInteger(r,16),new BigInteger(s,16));return P}if(l.indexOf("-END EC PRIVATE KEY-")!=-1&&l.indexOf("4,ENCRYPTED")==-1){var m=M(l,"EC PRIVATE KEY");return F.getKey(m,null,"pkcs5prv")}if(l.indexOf("-END PRIVATE KEY-")!=-1){return F.getKeyFromPlainPrivatePKCS8PEM(l)}if(l.indexOf("-END RSA PRIVATE KEY-")!=-1&&l.indexOf("4,ENCRYPTED")!=-1){var o=F.getDecryptedKeyHex(l,k);var H=new RSAKey();H.readPKCS5PrvKeyHex(o);return H}if(l.indexOf("-END EC PRIVATE KEY-")!=-1&&l.indexOf("4,ENCRYPTED")!=-1){var I=F.getDecryptedKeyHex(l,k);var P=d(I,0,[1],"04");var f=d(I,0,[2,0],"06");var A=d(I,0,[3,0],"03").substr(2);var e="";if(KJUR.crypto.OID.oidhex2name[f]!==undefined){e=KJUR.crypto.OID.oidhex2name[f]}else{throw"undefined OID(hex) in KJUR.crypto.OID: "+f}var j=new i({curve:e});j.setPublicKeyHex(A);j.setPrivateKeyHex(P);j.isPublic=false;return j}if(l.indexOf("-END DSA PRIVATE KEY-")!=-1&&l.indexOf("4,ENCRYPTED")!=-1){var I=F.getDecryptedKeyHex(l,k);var E=d(I,0,[1],"02");var D=d(I,0,[2],"02");var K=d(I,0,[3],"02");var r=d(I,0,[4],"02");var s=d(I,0,[5],"02");var P=new C();P.setPrivate(new BigInteger(E,16),new BigInteger(D,16),new BigInteger(K,16),new BigInteger(r,16),new BigInteger(s,16));return P}if(l.indexOf("-END ENCRYPTED PRIVATE KEY-")!=-1){return F.getKeyFromEncryptedPKCS8PEM(l,k)}throw new Error("not supported argument")};KEYUTIL.generateKeypair=function(a,c){if(a=="RSA"){var b=c;var h=new RSAKey();h.generate(b,"10001");h.isPrivate=true;h.isPublic=true;var f=new RSAKey();var e=h.n.toString(16);var i=h.e.toString(16);f.setPublic(e,i);f.isPrivate=false;f.isPublic=true;var k={};k.prvKeyObj=h;k.pubKeyObj=f;return k}else{if(a=="EC"){var d=c;var g=new KJUR.crypto.ECDSA({curve:d});var j=g.generateKeyPairHex();var h=new KJUR.crypto.ECDSA({curve:d});h.setPublicKeyHex(j.ecpubhex);h.setPrivateKeyHex(j.ecprvhex);h.isPrivate=true;h.isPublic=false;var f=new KJUR.crypto.ECDSA({curve:d});f.setPublicKeyHex(j.ecpubhex);f.isPrivate=false;f.isPublic=true;var k={};k.prvKeyObj=h;k.pubKeyObj=f;return k}else{throw"unknown algorithm: "+a}}};KEYUTIL.getPEM=function(b,D,y,m,q,j){var F=KJUR,k=F.asn1,z=k.DERObjectIdentifier,f=k.DERInteger,l=k.ASN1Util.newObject,a=k.x509,C=a.SubjectPublicKeyInfo,e=F.crypto,u=e.DSA,r=e.ECDSA,n=RSAKey;function A(s){var G=l({seq:[{"int":0},{"int":{bigint:s.n}},{"int":s.e},{"int":{bigint:s.d}},{"int":{bigint:s.p}},{"int":{bigint:s.q}},{"int":{bigint:s.dmp1}},{"int":{bigint:s.dmq1}},{"int":{bigint:s.coeff}}]});return G}function B(G){var s=l({seq:[{"int":1},{octstr:{hex:G.prvKeyHex}},{tag:["a0",true,{oid:{name:G.curveName}}]},{tag:["a1",true,{bitstr:{hex:"00"+G.pubKeyHex}}]}]});return s}function x(s){var G=l({seq:[{"int":0},{"int":{bigint:s.p}},{"int":{bigint:s.q}},{"int":{bigint:s.g}},{"int":{bigint:s.y}},{"int":{bigint:s.x}}]});return G}if(((n!==undefined&&b instanceof n)||(u!==undefined&&b instanceof u)||(r!==undefined&&b instanceof r))&&b.isPublic==true&&(D===undefined||D=="PKCS8PUB")){var E=new C(b);var w=E.getEncodedHex();return hextopem(w,"PUBLIC KEY")}if(D=="PKCS1PRV"&&n!==undefined&&b instanceof n&&(y===undefined||y==null)&&b.isPrivate==true){var E=A(b);var w=E.getEncodedHex();return hextopem(w,"RSA PRIVATE KEY")}if(D=="PKCS1PRV"&&r!==undefined&&b instanceof r&&(y===undefined||y==null)&&b.isPrivate==true){var i=new z({name:b.curveName});var v=i.getEncodedHex();var h=B(b);var t=h.getEncodedHex();var p="";p+=hextopem(v,"EC PARAMETERS");p+=hextopem(t,"EC PRIVATE KEY");return p}if(D=="PKCS1PRV"&&u!==undefined&&b instanceof u&&(y===undefined||y==null)&&b.isPrivate==true){var E=x(b);var w=E.getEncodedHex();return hextopem(w,"DSA PRIVATE KEY")}if(D=="PKCS5PRV"&&n!==undefined&&b instanceof n&&(y!==undefined&&y!=null)&&b.isPrivate==true){var E=A(b);var w=E.getEncodedHex();if(m===undefined){m="DES-EDE3-CBC"}return this.getEncryptedPKCS5PEMFromPrvKeyHex("RSA",w,y,m,j)}if(D=="PKCS5PRV"&&r!==undefined&&b instanceof r&&(y!==undefined&&y!=null)&&b.isPrivate==true){var E=B(b);var w=E.getEncodedHex();if(m===undefined){m="DES-EDE3-CBC"}return this.getEncryptedPKCS5PEMFromPrvKeyHex("EC",w,y,m,j)}if(D=="PKCS5PRV"&&u!==undefined&&b instanceof u&&(y!==undefined&&y!=null)&&b.isPrivate==true){var E=x(b);var w=E.getEncodedHex();if(m===undefined){m="DES-EDE3-CBC"}return this.getEncryptedPKCS5PEMFromPrvKeyHex("DSA",w,y,m,j)}var o=function(G,s){var I=c(G,s);var H=new l({seq:[{seq:[{oid:{name:"pkcs5PBES2"}},{seq:[{seq:[{oid:{name:"pkcs5PBKDF2"}},{seq:[{octstr:{hex:I.pbkdf2Salt}},{"int":I.pbkdf2Iter}]}]},{seq:[{oid:{name:"des-EDE3-CBC"}},{octstr:{hex:I.encryptionSchemeIV}}]}]}]},{octstr:{hex:I.ciphertext}}]});return H.getEncodedHex()};var c=function(N,O){var H=100;var M=CryptoJS.lib.WordArray.random(8);var L="DES-EDE3-CBC";var s=CryptoJS.lib.WordArray.random(8);var I=CryptoJS.PBKDF2(O,M,{keySize:192/32,iterations:H});var J=CryptoJS.enc.Hex.parse(N);var K=CryptoJS.TripleDES.encrypt(J,I,{iv:s})+"";var G={};G.ciphertext=K;G.pbkdf2Salt=CryptoJS.enc.Hex.stringify(M);G.pbkdf2Iter=H;G.encryptionSchemeAlg=L;G.encryptionSchemeIV=CryptoJS.enc.Hex.stringify(s);return G};if(D=="PKCS8PRV"&&n!=undefined&&b instanceof n&&b.isPrivate==true){var g=A(b);var d=g.getEncodedHex();var E=l({seq:[{"int":0},{seq:[{oid:{name:"rsaEncryption"}},{"null":true}]},{octstr:{hex:d}}]});var w=E.getEncodedHex();if(y===undefined||y==null){return hextopem(w,"PRIVATE KEY")}else{var t=o(w,y);return hextopem(t,"ENCRYPTED PRIVATE KEY")}}if(D=="PKCS8PRV"&&r!==undefined&&b instanceof r&&b.isPrivate==true){var g=new l({seq:[{"int":1},{octstr:{hex:b.prvKeyHex}},{tag:["a1",true,{bitstr:{hex:"00"+b.pubKeyHex}}]}]});var d=g.getEncodedHex();var E=l({seq:[{"int":0},{seq:[{oid:{name:"ecPublicKey"}},{oid:{name:b.curveName}}]},{octstr:{hex:d}}]});var w=E.getEncodedHex();if(y===undefined||y==null){return hextopem(w,"PRIVATE KEY")}else{var t=o(w,y);return hextopem(t,"ENCRYPTED PRIVATE KEY")}}if(D=="PKCS8PRV"&&u!==undefined&&b instanceof u&&b.isPrivate==true){var g=new f({bigint:b.x});var d=g.getEncodedHex();var E=l({seq:[{"int":0},{seq:[{oid:{name:"dsa"}},{seq:[{"int":{bigint:b.p}},{"int":{bigint:b.q}},{"int":{bigint:b.g}}]}]},{octstr:{hex:d}}]});var w=E.getEncodedHex();if(y===undefined||y==null){return hextopem(w,"PRIVATE KEY")}else{var t=o(w,y);return hextopem(t,"ENCRYPTED PRIVATE KEY")}}throw new Error("unsupported object nor format")};KEYUTIL.getKeyFromCSRPEM=function(b){var a=pemtohex(b,"CERTIFICATE REQUEST");var c=KEYUTIL.getKeyFromCSRHex(a);return c};KEYUTIL.getKeyFromCSRHex=function(a){var c=KEYUTIL.parseCSRHex(a);var b=KEYUTIL.getKey(c.p8pubkeyhex,null,"pkcs8pub");return b};KEYUTIL.parseCSRHex=function(d){var i=ASN1HEX;var f=i.getChildIdx;var c=i.getTLV;var b={};var g=d;if(g.substr(0,2)!="30"){throw"malformed CSR(code:001)"}var e=f(g,0);if(e.length<1){throw"malformed CSR(code:002)"}if(g.substr(e[0],2)!="30"){throw"malformed CSR(code:003)"}var a=f(g,e[0]);if(a.length<3){throw"malformed CSR(code:004)"}b.p8pubkeyhex=c(g,a[2]);return b};KEYUTIL.getKeyID=function(f){var c=KEYUTIL;var e=ASN1HEX;if(typeof f==="string"&&f.indexOf("BEGIN ")!=-1){f=c.getKey(f)}var d=pemtohex(c.getPEM(f));var b=e.getIdxbyList(d,0,[1]);var a=e.getV(d,b).substring(2);return KJUR.crypto.Util.hashHex(a,"sha1")};KEYUTIL.getJWKFromKey=function(d){var b={};if(d instanceof RSAKey&&d.isPrivate){b.kty="RSA";b.n=hextob64u(d.n.toString(16));b.e=hextob64u(d.e.toString(16));b.d=hextob64u(d.d.toString(16));b.p=hextob64u(d.p.toString(16));b.q=hextob64u(d.q.toString(16));b.dp=hextob64u(d.dmp1.toString(16));b.dq=hextob64u(d.dmq1.toString(16));b.qi=hextob64u(d.coeff.toString(16));return b}else{if(d instanceof RSAKey&&d.isPublic){b.kty="RSA";b.n=hextob64u(d.n.toString(16));b.e=hextob64u(d.e.toString(16));return b}else{if(d instanceof KJUR.crypto.ECDSA&&d.isPrivate){var a=d.getShortNISTPCurveName();if(a!=="P-256"&&a!=="P-384"){throw"unsupported curve name for JWT: "+a}var c=d.getPublicKeyXYHex();b.kty="EC";b.crv=a;b.x=hextob64u(c.x);b.y=hextob64u(c.y);b.d=hextob64u(d.prvKeyHex);return b}else{if(d instanceof KJUR.crypto.ECDSA&&d.isPublic){var a=d.getShortNISTPCurveName();if(a!=="P-256"&&a!=="P-384"){throw"unsupported curve name for JWT: "+a}var c=d.getPublicKeyXYHex();b.kty="EC";b.crv=a;b.x=hextob64u(c.x);b.y=hextob64u(c.y);return b}}}}throw"not supported key object"}; RSAKey.getPosArrayOfChildrenFromHex=function(a){return ASN1HEX.getChildIdx(a,0)};RSAKey.getHexValueArrayOfChildrenFromHex=function(f){var n=ASN1HEX;var i=n.getV;var k=RSAKey.getPosArrayOfChildrenFromHex(f);var e=i(f,k[0]);var j=i(f,k[1]);var b=i(f,k[2]);var c=i(f,k[3]);var h=i(f,k[4]);var g=i(f,k[5]);var m=i(f,k[6]);var l=i(f,k[7]);var d=i(f,k[8]);var k=new Array();k.push(e,j,b,c,h,g,m,l,d);return k};RSAKey.prototype.readPrivateKeyFromPEMString=function(d){var c=pemtohex(d);var b=RSAKey.getHexValueArrayOfChildrenFromHex(c);this.setPrivateEx(b[1],b[2],b[3],b[4],b[5],b[6],b[7],b[8])};RSAKey.prototype.readPKCS5PrvKeyHex=function(c){var b=RSAKey.getHexValueArrayOfChildrenFromHex(c);this.setPrivateEx(b[1],b[2],b[3],b[4],b[5],b[6],b[7],b[8])};RSAKey.prototype.readPKCS8PrvKeyHex=function(e){var c,i,k,b,a,f,d,j;var m=ASN1HEX;var l=m.getVbyListEx;if(m.isASN1HEX(e)===false){throw new Error("not ASN.1 hex string")}try{c=l(e,0,[2,0,1],"02");i=l(e,0,[2,0,2],"02");k=l(e,0,[2,0,3],"02");b=l(e,0,[2,0,4],"02");a=l(e,0,[2,0,5],"02");f=l(e,0,[2,0,6],"02");d=l(e,0,[2,0,7],"02");j=l(e,0,[2,0,8],"02")}catch(g){throw new Error("malformed PKCS#8 plain RSA private key")}this.setPrivateEx(c,i,k,b,a,f,d,j)};RSAKey.prototype.readPKCS5PubKeyHex=function(c){var e=ASN1HEX;var b=e.getV;if(e.isASN1HEX(c)===false){throw new Error("keyHex is not ASN.1 hex string")}var a=e.getChildIdx(c,0);if(a.length!==2||c.substr(a[0],2)!=="02"||c.substr(a[1],2)!=="02"){throw new Error("wrong hex for PKCS#5 public key")}var f=b(c,a[0]);var d=b(c,a[1]);this.setPublic(f,d)};RSAKey.prototype.readPKCS8PubKeyHex=function(b){var c=ASN1HEX;if(c.isASN1HEX(b)===false){throw new Error("not ASN.1 hex string")}if(c.getTLVbyListEx(b,0,[0,0])!=="06092a864886f70d010101"){throw new Error("not PKCS8 RSA public key")}var a=c.getTLVbyListEx(b,0,[1,0]);this.readPKCS5PubKeyHex(a)};RSAKey.prototype.readCertPubKeyHex=function(b,d){var a,c;a=new X509();a.readCertHex(b);c=a.getPublicKeyHex();this.readPKCS8PubKeyHex(c)}; var _RE_HEXDECONLY=new RegExp("[^0-9a-f]","gi");function _rsasign_getHexPaddedDigestInfoForString(d,e,a){var b=function(f){return KJUR.crypto.Util.hashString(f,a)};var c=b(d);return KJUR.crypto.Util.getPaddedDigestInfoHex(c,a,e)}function _zeroPaddingOfSignature(e,d){var c="";var a=d/4-e.length;for(var b=0;b>24,(d&16711680)>>16,(d&65280)>>8,d&255]))));d+=1}return b}RSAKey.prototype.signPSS=function(e,a,d){var c=function(f){return KJUR.crypto.Util.hashHex(f,a)};var b=c(rstrtohex(e));if(d===undefined){d=-1}return this.signWithMessageHashPSS(b,a,d)};RSAKey.prototype.signWithMessageHashPSS=function(l,a,k){var b=hextorstr(l);var g=b.length;var m=this.n.bitLength()-1;var c=Math.ceil(m/8);var d;var o=function(i){return KJUR.crypto.Util.hashHex(i,a)};if(k===-1||k===undefined){k=g}else{if(k===-2){k=c-g-2}else{if(k<-2){throw new Error("invalid salt length")}}}if(c<(g+k+2)){throw new Error("data too long")}var f="";if(k>0){f=new Array(k);new SecureRandom().nextBytes(f);f=String.fromCharCode.apply(String,f)}var n=hextorstr(o(rstrtohex("\x00\x00\x00\x00\x00\x00\x00\x00"+b+f)));var j=[];for(d=0;d>(8*c-m))&255;q[0]&=~p;for(d=0;dthis.n.bitLength()){return 0}var i=this.doPublic(b);var e=i.toString(16).replace(/^1f+00/,"");var g=_rsasign_getAlgNameAndHashFromHexDisgestInfo(e);if(g.length==0){return false}var d=g[0];var h=g[1];var a=function(k){return KJUR.crypto.Util.hashString(k,d)};var c=a(f);return(h==c)};RSAKey.prototype.verifyWithMessageHash=function(e,a){if(a.length!=Math.ceil(this.n.bitLength()/4)){return false}var b=parseBigInt(a,16);if(b.bitLength()>this.n.bitLength()){return 0}var h=this.doPublic(b);var g=h.toString(16).replace(/^1f+00/,"");var c=_rsasign_getAlgNameAndHashFromHexDisgestInfo(g);if(c.length==0){return false}var d=c[0];var f=c[1];return(f==e)};RSAKey.prototype.verifyPSS=function(c,b,a,f){var e=function(g){return KJUR.crypto.Util.hashHex(g,a)};var d=e(rstrtohex(c));if(f===undefined){f=-1}return this.verifyWithMessageHashPSS(d,b,a,f)};RSAKey.prototype.verifyWithMessageHashPSS=function(f,s,l,c){if(s.length!=Math.ceil(this.n.bitLength()/4)){return false}var k=new BigInteger(s,16);var r=function(i){return KJUR.crypto.Util.hashHex(i,l)};var j=hextorstr(f);var h=j.length;var g=this.n.bitLength()-1;var m=Math.ceil(g/8);var q;if(c===-1||c===undefined){c=h}else{if(c===-2){c=m-h-2}else{if(c<-2){throw new Error("invalid salt length")}}}if(m<(h+c+2)){throw new Error("data too long")}var a=this.doPublic(k).toByteArray();for(q=0;q>(8*m-g))&255;if((d.charCodeAt(0)&p)!==0){throw new Error("bits beyond keysize not zero")}var n=pss_mgf1_str(e,d.length,r);var o=[];for(q=0;q1){var A=b(w,v[1]);var u=this.getGeneralName(A);if(u.uri!=undefined){t.uri=u.uri}}if(v.length>2){var x=b(w,v[2]);if(x=="0101ff"){t.reqauth=true}if(x=="010100"){t.reqauth=false}}return t};this.getX500NameRule=function(t){var A=true;var E=true;var D=false;var u="";var x="";var G=null;var B=[];for(var w=0;w0){t.ext=this.getExtParamArray()}t.sighex=this.getSignatureValueHex();return t};this.getExtParamArray=function(u){if(u==undefined){var w=e(this.hex,0,[0,"[3]"]);if(w!=-1){u=l(this.hex,0,[0,"[3]",0],"30")}}var t=[];var v=n(u,0);for(var x=0;x1){var A=b(w,v[1]);var u=this.getGeneralName(A);if(u.uri!=undefined){t.uri=u.uri}}if(v.length>2){var x=b(w,v[2]);if(x=="0101ff"){t.reqauth=true}if(x=="010100"){t.reqauth=false}}return t};this.getX500NameRule=function(t){var A=true;var E=true;var D=false;var u="";var x="";var G=null;var B=[];for(var w=0;w0){t.ext=this.getExtParamArray()}t.sighex=this.getSignatureValueHex();return t};this.getExtParamArray=function(u){if(u==undefined){var w=e(this.hex,0,[0,"[3]"]);if(w!=-1){u=l(this.hex,0,[0,"[3]",0],"30")}}var t=[];var v=n(u,0);for(var x=0;x0){var b=":"+n.join(":")+":";if(b.indexOf(":"+k+":")==-1){throw"algorithm '"+k+"' not accepted in the list"}}if(k!="none"&&B===null){throw"key shall be specified to verify."}if(typeof B=="string"&&B.indexOf("-----BEGIN ")!=-1){B=KEYUTIL.getKey(B)}if(z=="RS"||z=="PS"){if(!(B instanceof m)){throw"key shall be a RSAKey obj for RS* and PS* algs"}}if(z=="ES"){if(!(B instanceof p)){throw"key shall be a ECDSA obj for ES* algs"}}if(k=="none"){}var u=null;if(t.jwsalg2sigalg[l.alg]===undefined){throw"unsupported alg name: "+k}else{u=t.jwsalg2sigalg[k]}if(u=="none"){throw"not supported"}else{if(u.substr(0,4)=="Hmac"){var o=null;if(B===undefined){throw"hexadecimal key shall be specified for HMAC"}var j=new s({alg:u,pass:B});j.updateString(c);o=j.doFinal();return A==o}else{if(u.indexOf("withECDSA")!=-1){var h=null;try{h=p.concatSigToASN1Sig(A)}catch(v){return false}var g=new d({alg:u});g.init(B);g.updateString(c);return g.verify(h)}else{var g=new d({alg:u});g.init(B);g.updateString(c);return g.verify(A)}}}};KJUR.jws.JWS.parse=function(g){var c=g.split(".");var b={};var f,e,d;if(c.length!=2&&c.length!=3){throw"malformed sJWS: wrong number of '.' splitted elements"}f=c[0];e=c[1];if(c.length==3){d=c[2]}b.headerObj=KJUR.jws.JWS.readSafeJSONString(b64utoutf8(f));b.payloadObj=KJUR.jws.JWS.readSafeJSONString(b64utoutf8(e));b.headerPP=JSON.stringify(b.headerObj,null," ");if(b.payloadObj==null){b.payloadPP=b64utoutf8(e)}else{b.payloadPP=JSON.stringify(b.payloadObj,null," ")}if(d!==undefined){b.sigHex=b64utohex(d)}return b};KJUR.jws.JWS.verifyJWT=function(e,l,r){var d=KJUR,j=d.jws,o=j.JWS,n=o.readSafeJSONString,p=o.inArray,f=o.includedArray;var k=e.split(".");var c=k[0];var i=k[1];var q=c+"."+i;var m=b64utohex(k[2]);var h=n(b64utoutf8(c));var g=n(b64utoutf8(i));if(h.alg===undefined){return false}if(r.alg===undefined){throw"acceptField.alg shall be specified"}if(!p(h.alg,r.alg)){return false}if(g.iss!==undefined&&typeof r.iss==="object"){if(!p(g.iss,r.iss)){return false}}if(g.sub!==undefined&&typeof r.sub==="object"){if(!p(g.sub,r.sub)){return false}}if(g.aud!==undefined&&typeof r.aud==="object"){if(typeof g.aud=="string"){if(!p(g.aud,r.aud)){return false}}else{if(typeof g.aud=="object"){if(!f(g.aud,r.aud)){return false}}}}var b=j.IntDate.getNow();if(r.verifyAt!==undefined&&typeof r.verifyAt==="number"){b=r.verifyAt}if(r.gracePeriod===undefined||typeof r.gracePeriod!=="number"){r.gracePeriod=0}if(g.exp!==undefined&&typeof g.exp=="number"){if(g.exp+r.gracePeriodl){this.aHeader.pop()}if(this.aSignature.length>l){this.aSignature.pop()}throw"addSignature failed: "+i}};this.verifyAll=function(h){if(this.aHeader.length!==h.length||this.aSignature.length!==h.length){return false}for(var g=0;g0){this.aHeader=g.headers}else{throw"malformed header"}if(typeof g.payload==="string"){this.sPayload=g.payload}else{throw"malformed signatures"}if(g.signatures.length>0){this.aSignature=g.signatures}else{throw"malformed signatures"}}catch(e){throw"malformed JWS-JS JSON object: "+e}}};this.getJSON=function(){return{headers:this.aHeader,payload:this.sPayload,signatures:this.aSignature}};this.isEmpty=function(){if(this.aHeader.length==0){return 1}return 0}}; diff --git a/npm/lib/jsrsasign-jwths-min.js b/npm/lib/jsrsasign-jwths-min.js index 123b54a1..a3cf3a0b 100644 --- a/npm/lib/jsrsasign-jwths-min.js +++ b/npm/lib/jsrsasign-jwths-min.js @@ -1,5 +1,5 @@ /* - * jsrsasign(jwths) 10.1.11 (2021-02-19) (c) 2010-2021 Kenji Urushima | kjur.github.com/jsrsasign/license + * jsrsasign(jwths) 10.1.12 (2021-02-25) (c) 2010-2021 Kenji Urushima | kjur.github.com/jsrsasign/license */ /*! diff --git a/npm/lib/jsrsasign-rsa-min.js b/npm/lib/jsrsasign-rsa-min.js index adddbdfa..d04f0316 100644 --- a/npm/lib/jsrsasign-rsa-min.js +++ b/npm/lib/jsrsasign-rsa-min.js @@ -1,5 +1,5 @@ /* - * jsrsasign(rsa) 10.1.11 (2021-02-19) (c) 2010-2021 Kenji Urushima | kjur.github.com/jsrsasign/license + * jsrsasign(rsa) 10.1.12 (2021-02-25) (c) 2010-2021 Kenji Urushima | kjur.github.com/jsrsasign/license */ /*! diff --git a/npm/lib/jsrsasign.js b/npm/lib/jsrsasign.js index 8e2fe6a5..4a91773f 100755 --- a/npm/lib/jsrsasign.js +++ b/npm/lib/jsrsasign.js @@ -4,7 +4,7 @@ navigator.userAgent = false; var window = {}; /* - * jsrsasign(all) 10.1.11 (2021-02-19) (c) 2010-2021 Kenji Urushima | kjur.github.com/jsrsasign/license + * jsrsasign(all) 10.1.12 (2021-02-25) (c) 2010-2021 Kenji Urushima | kjur.github.com/jsrsasign/license */ /*! @@ -246,7 +246,7 @@ if(typeof KJUR=="undefined"||!KJUR){KJUR={}}if(typeof KJUR.crypto=="undefined"|| var KEYUTIL=function(){var d=function(p,r,q){return k(CryptoJS.AES,p,r,q)};var e=function(p,r,q){return k(CryptoJS.TripleDES,p,r,q)};var a=function(p,r,q){return k(CryptoJS.DES,p,r,q)};var k=function(s,x,u,q){var r=CryptoJS.enc.Hex.parse(x);var w=CryptoJS.enc.Hex.parse(u);var p=CryptoJS.enc.Hex.parse(q);var t={};t.key=w;t.iv=p;t.ciphertext=r;var v=s.decrypt(t,w,{iv:p});return CryptoJS.enc.Hex.stringify(v)};var l=function(p,r,q){return g(CryptoJS.AES,p,r,q)};var o=function(p,r,q){return g(CryptoJS.TripleDES,p,r,q)};var f=function(p,r,q){return g(CryptoJS.DES,p,r,q)};var g=function(t,y,v,q){var s=CryptoJS.enc.Hex.parse(y);var x=CryptoJS.enc.Hex.parse(v);var p=CryptoJS.enc.Hex.parse(q);var w=t.encrypt(s,x,{iv:p});var r=CryptoJS.enc.Hex.parse(w.toString());var u=CryptoJS.enc.Base64.stringify(r);return u};var i={"AES-256-CBC":{proc:d,eproc:l,keylen:32,ivlen:16},"AES-192-CBC":{proc:d,eproc:l,keylen:24,ivlen:16},"AES-128-CBC":{proc:d,eproc:l,keylen:16,ivlen:16},"DES-EDE3-CBC":{proc:e,eproc:o,keylen:24,ivlen:8},"DES-CBC":{proc:a,eproc:f,keylen:8,ivlen:8}};var c=function(p){return i[p]["proc"]};var m=function(p){var r=CryptoJS.lib.WordArray.random(p);var q=CryptoJS.enc.Hex.stringify(r);return q};var n=function(v){var w={};var q=v.match(new RegExp("DEK-Info: ([^,]+),([0-9A-Fa-f]+)","m"));if(q){w.cipher=q[1];w.ivsalt=q[2]}var p=v.match(new RegExp("-----BEGIN ([A-Z]+) PRIVATE KEY-----"));if(p){w.type=p[1]}var u=-1;var x=0;if(v.indexOf("\r\n\r\n")!=-1){u=v.indexOf("\r\n\r\n");x=2}if(v.indexOf("\n\n")!=-1){u=v.indexOf("\n\n");x=1}var t=v.indexOf("-----END");if(u!=-1&&t!=-1){var r=v.substring(u+x*2,t-x);r=r.replace(/\s+/g,"");w.data=r}return w};var j=function(q,y,p){var v=p.substring(0,16);var t=CryptoJS.enc.Hex.parse(v);var r=CryptoJS.enc.Utf8.parse(y);var u=i[q]["keylen"]+i[q]["ivlen"];var x="";var w=null;for(;;){var s=CryptoJS.algo.MD5.create();if(w!=null){s.update(w)}s.update(r);s.update(t);w=s.finalize();x=x+CryptoJS.enc.Hex.stringify(w);if(x.length>=u*2){break}}var z={};z.keyhex=x.substr(0,i[q]["keylen"]*2);z.ivhex=x.substr(i[q]["keylen"]*2,i[q]["ivlen"]*2);return z};var b=function(p,v,r,w){var s=CryptoJS.enc.Base64.parse(p);var q=CryptoJS.enc.Hex.stringify(s);var u=i[v]["proc"];var t=u(q,r,w);return t};var h=function(p,s,q,u){var r=i[s]["eproc"];var t=r(p,q,u);return t};return{version:"1.0.0",parsePKCS5PEM:function(p){return n(p)},getKeyAndUnusedIvByPasscodeAndIvsalt:function(q,p,r){return j(q,p,r)},decryptKeyB64:function(p,r,q,s){return b(p,r,q,s)},getDecryptedKeyHex:function(y,x){var q=n(y);var t=q.type;var r=q.cipher;var p=q.ivsalt;var s=q.data;var w=j(r,x,p);var v=w.keyhex;var u=b(s,r,v,p);return u},getEncryptedPKCS5PEMFromPrvKeyHex:function(x,s,A,t,r){var p="";if(typeof t=="undefined"||t==null){t="AES-256-CBC"}if(typeof i[t]=="undefined"){throw"KEYUTIL unsupported algorithm: "+t}if(typeof r=="undefined"||r==null){var v=i[t]["ivlen"];var u=m(v);r=u.toUpperCase()}var z=j(t,A,r);var y=z.keyhex;var w=h(s,t,y,r);var q=w.replace(/(.{64})/g,"$1\r\n");var p="-----BEGIN "+x+" PRIVATE KEY-----\r\n";p+="Proc-Type: 4,ENCRYPTED\r\n";p+="DEK-Info: "+t+","+r+"\r\n";p+="\r\n";p+=q;p+="\r\n-----END "+x+" PRIVATE KEY-----\r\n";return p},parseHexOfEncryptedPKCS8:function(y){var B=ASN1HEX;var z=B.getChildIdx;var w=B.getV;var t={};var r=z(y,0);if(r.length!=2){throw"malformed format: SEQUENCE(0).items != 2: "+r.length}t.ciphertext=w(y,r[1]);var A=z(y,r[0]);if(A.length!=2){throw"malformed format: SEQUENCE(0.0).items != 2: "+A.length}if(w(y,A[0])!="2a864886f70d01050d"){throw"this only supports pkcs5PBES2"}var p=z(y,A[1]);if(A.length!=2){throw"malformed format: SEQUENCE(0.0.1).items != 2: "+p.length}var q=z(y,p[1]);if(q.length!=2){throw"malformed format: SEQUENCE(0.0.1.1).items != 2: "+q.length}if(w(y,q[0])!="2a864886f70d0307"){throw"this only supports TripleDES"}t.encryptionSchemeAlg="TripleDES";t.encryptionSchemeIV=w(y,q[1]);var s=z(y,p[0]);if(s.length!=2){throw"malformed format: SEQUENCE(0.0.1.0).items != 2: "+s.length}if(w(y,s[0])!="2a864886f70d01050c"){throw"this only supports pkcs5PBKDF2"}var x=z(y,s[1]);if(x.length<2){throw"malformed format: SEQUENCE(0.0.1.0.1).items < 2: "+x.length}t.pbkdf2Salt=w(y,x[0]);var u=w(y,x[1]);try{t.pbkdf2Iter=parseInt(u,16)}catch(v){throw"malformed format pbkdf2Iter: "+u}return t},getPBKDF2KeyHexFromParam:function(u,p){var t=CryptoJS.enc.Hex.parse(u.pbkdf2Salt);var q=u.pbkdf2Iter;var s=CryptoJS.PBKDF2(p,t,{keySize:192/32,iterations:q});var r=CryptoJS.enc.Hex.stringify(s);return r},_getPlainPKCS8HexFromEncryptedPKCS8PEM:function(x,y){var r=pemtohex(x,"ENCRYPTED PRIVATE KEY");var p=this.parseHexOfEncryptedPKCS8(r);var u=KEYUTIL.getPBKDF2KeyHexFromParam(p,y);var v={};v.ciphertext=CryptoJS.enc.Hex.parse(p.ciphertext);var t=CryptoJS.enc.Hex.parse(u);var s=CryptoJS.enc.Hex.parse(p.encryptionSchemeIV);var w=CryptoJS.TripleDES.decrypt(v,t,{iv:s});var q=CryptoJS.enc.Hex.stringify(w);return q},getKeyFromEncryptedPKCS8PEM:function(s,q){var p=this._getPlainPKCS8HexFromEncryptedPKCS8PEM(s,q);var r=this.getKeyFromPlainPrivatePKCS8Hex(p);return r},parsePlainPrivatePKCS8Hex:function(s){var v=ASN1HEX;var u=v.getChildIdx;var t=v.getV;var q={};q.algparam=null;if(s.substr(0,2)!="30"){throw new Error("malformed plain PKCS8 private key(code:001)")}var r=u(s,0);if(r.length<3){throw new Error("malformed plain PKCS8 private key(code:002)")}if(s.substr(r[1],2)!="30"){throw new Error("malformed PKCS8 private key(code:003)")}var p=u(s,r[1]);if(p.length!=2){throw new Error("malformed PKCS8 private key(code:004)")}if(s.substr(p[0],2)!="06"){throw new Error("malformed PKCS8 private key(code:005)")}q.algoid=t(s,p[0]);if(s.substr(p[1],2)=="06"){q.algparam=t(s,p[1])}if(s.substr(r[2],2)!="04"){throw new Error("malformed PKCS8 private key(code:006)")}q.keyidx=v.getVidx(s,r[2]);return q},getKeyFromPlainPrivatePKCS8PEM:function(q){var p=pemtohex(q,"PRIVATE KEY");var r=this.getKeyFromPlainPrivatePKCS8Hex(p);return r},getKeyFromPlainPrivatePKCS8Hex:function(p){var q=this.parsePlainPrivatePKCS8Hex(p);var r;if(q.algoid=="2a864886f70d010101"){r=new RSAKey()}else{if(q.algoid=="2a8648ce380401"){r=new KJUR.crypto.DSA()}else{if(q.algoid=="2a8648ce3d0201"){r=new KJUR.crypto.ECDSA()}else{throw"unsupported private key algorithm"}}}r.readPKCS8PrvKeyHex(p);return r},_getKeyFromPublicPKCS8Hex:function(q){var p;var r=ASN1HEX.getVbyList(q,0,[0,0],"06");if(r==="2a864886f70d010101"){p=new RSAKey()}else{if(r==="2a8648ce380401"){p=new KJUR.crypto.DSA()}else{if(r==="2a8648ce3d0201"){p=new KJUR.crypto.ECDSA()}else{throw"unsupported PKCS#8 public key hex"}}}p.readPKCS8PubKeyHex(q);return p},parsePublicRawRSAKeyHex:function(r){var u=ASN1HEX;var t=u.getChildIdx;var s=u.getV;var p={};if(r.substr(0,2)!="30"){throw"malformed RSA key(code:001)"}var q=t(r,0);if(q.length!=2){throw"malformed RSA key(code:002)"}if(r.substr(q[0],2)!="02"){throw"malformed RSA key(code:003)"}p.n=s(r,q[0]);if(r.substr(q[1],2)!="02"){throw"malformed RSA key(code:004)"}p.e=s(r,q[1]);return p},parsePublicPKCS8Hex:function(t){var v=ASN1HEX;var u=v.getChildIdx;var s=v.getV;var q={};q.algparam=null;var r=u(t,0);if(r.length!=2){throw"outer DERSequence shall have 2 elements: "+r.length}var w=r[0];if(t.substr(w,2)!="30"){throw"malformed PKCS8 public key(code:001)"}var p=u(t,w);if(p.length!=2){throw"malformed PKCS8 public key(code:002)"}if(t.substr(p[0],2)!="06"){throw"malformed PKCS8 public key(code:003)"}q.algoid=s(t,p[0]);if(t.substr(p[1],2)=="06"){q.algparam=s(t,p[1])}else{if(t.substr(p[1],2)=="30"){q.algparam={};q.algparam.p=v.getVbyList(t,p[1],[0],"02");q.algparam.q=v.getVbyList(t,p[1],[1],"02");q.algparam.g=v.getVbyList(t,p[1],[2],"02")}}if(t.substr(r[1],2)!="03"){throw"malformed PKCS8 public key(code:004)"}q.key=s(t,r[1]).substr(2);return q},}}();KEYUTIL.getKey=function(l,k,n){var G=ASN1HEX,L=G.getChildIdx,v=G.getV,d=G.getVbyList,c=KJUR.crypto,i=c.ECDSA,C=c.DSA,w=RSAKey,M=pemtohex,F=KEYUTIL;if(typeof w!="undefined"&&l instanceof w){return l}if(typeof i!="undefined"&&l instanceof i){return l}if(typeof C!="undefined"&&l instanceof C){return l}if(l.curve!==undefined&&l.xy!==undefined&&l.d===undefined){return new i({pub:l.xy,curve:l.curve})}if(l.curve!==undefined&&l.d!==undefined){return new i({prv:l.d,curve:l.curve})}if(l.kty===undefined&&l.n!==undefined&&l.e!==undefined&&l.d===undefined){var P=new w();P.setPublic(l.n,l.e);return P}if(l.kty===undefined&&l.n!==undefined&&l.e!==undefined&&l.d!==undefined&&l.p!==undefined&&l.q!==undefined&&l.dp!==undefined&&l.dq!==undefined&&l.co!==undefined&&l.qi===undefined){var P=new w();P.setPrivateEx(l.n,l.e,l.d,l.p,l.q,l.dp,l.dq,l.co);return P}if(l.kty===undefined&&l.n!==undefined&&l.e!==undefined&&l.d!==undefined&&l.p===undefined){var P=new w();P.setPrivate(l.n,l.e,l.d);return P}if(l.p!==undefined&&l.q!==undefined&&l.g!==undefined&&l.y!==undefined&&l.x===undefined){var P=new C();P.setPublic(l.p,l.q,l.g,l.y);return P}if(l.p!==undefined&&l.q!==undefined&&l.g!==undefined&&l.y!==undefined&&l.x!==undefined){var P=new C();P.setPrivate(l.p,l.q,l.g,l.y,l.x);return P}if(l.kty==="RSA"&&l.n!==undefined&&l.e!==undefined&&l.d===undefined){var P=new w();P.setPublic(b64utohex(l.n),b64utohex(l.e));return P}if(l.kty==="RSA"&&l.n!==undefined&&l.e!==undefined&&l.d!==undefined&&l.p!==undefined&&l.q!==undefined&&l.dp!==undefined&&l.dq!==undefined&&l.qi!==undefined){var P=new w();P.setPrivateEx(b64utohex(l.n),b64utohex(l.e),b64utohex(l.d),b64utohex(l.p),b64utohex(l.q),b64utohex(l.dp),b64utohex(l.dq),b64utohex(l.qi));return P}if(l.kty==="RSA"&&l.n!==undefined&&l.e!==undefined&&l.d!==undefined){var P=new w();P.setPrivate(b64utohex(l.n),b64utohex(l.e),b64utohex(l.d));return P}if(l.kty==="EC"&&l.crv!==undefined&&l.x!==undefined&&l.y!==undefined&&l.d===undefined){var j=new i({curve:l.crv});var t=j.ecparams.keylen/4;var B=("0000000000"+b64utohex(l.x)).slice(-t);var z=("0000000000"+b64utohex(l.y)).slice(-t);var u="04"+B+z;j.setPublicKeyHex(u);return j}if(l.kty==="EC"&&l.crv!==undefined&&l.x!==undefined&&l.y!==undefined&&l.d!==undefined){var j=new i({curve:l.crv});var t=j.ecparams.keylen/4;var B=("0000000000"+b64utohex(l.x)).slice(-t);var z=("0000000000"+b64utohex(l.y)).slice(-t);var u="04"+B+z;var b=("0000000000"+b64utohex(l.d)).slice(-t);j.setPublicKeyHex(u);j.setPrivateKeyHex(b);return j}if(n==="pkcs5prv"){var J=l,G=ASN1HEX,N,P;N=L(J,0);if(N.length===9){P=new w();P.readPKCS5PrvKeyHex(J)}else{if(N.length===6){P=new C();P.readPKCS5PrvKeyHex(J)}else{if(N.length>2&&J.substr(N[1],2)==="04"){P=new i();P.readPKCS5PrvKeyHex(J)}else{throw"unsupported PKCS#1/5 hexadecimal key"}}}return P}if(n==="pkcs8prv"){var P=F.getKeyFromPlainPrivatePKCS8Hex(l);return P}if(n==="pkcs8pub"){return F._getKeyFromPublicPKCS8Hex(l)}if(n==="x509pub"){return X509.getPublicKeyFromCertHex(l)}if(l.indexOf("-END CERTIFICATE-",0)!=-1||l.indexOf("-END X509 CERTIFICATE-",0)!=-1||l.indexOf("-END TRUSTED CERTIFICATE-",0)!=-1){return X509.getPublicKeyFromCertPEM(l)}if(l.indexOf("-END PUBLIC KEY-")!=-1){var O=pemtohex(l,"PUBLIC KEY");return F._getKeyFromPublicPKCS8Hex(O)}if(l.indexOf("-END RSA PRIVATE KEY-")!=-1&&l.indexOf("4,ENCRYPTED")==-1){var m=M(l,"RSA PRIVATE KEY");return F.getKey(m,null,"pkcs5prv")}if(l.indexOf("-END DSA PRIVATE KEY-")!=-1&&l.indexOf("4,ENCRYPTED")==-1){var I=M(l,"DSA PRIVATE KEY");var E=d(I,0,[1],"02");var D=d(I,0,[2],"02");var K=d(I,0,[3],"02");var r=d(I,0,[4],"02");var s=d(I,0,[5],"02");var P=new C();P.setPrivate(new BigInteger(E,16),new BigInteger(D,16),new BigInteger(K,16),new BigInteger(r,16),new BigInteger(s,16));return P}if(l.indexOf("-END EC PRIVATE KEY-")!=-1&&l.indexOf("4,ENCRYPTED")==-1){var m=M(l,"EC PRIVATE KEY");return F.getKey(m,null,"pkcs5prv")}if(l.indexOf("-END PRIVATE KEY-")!=-1){return F.getKeyFromPlainPrivatePKCS8PEM(l)}if(l.indexOf("-END RSA PRIVATE KEY-")!=-1&&l.indexOf("4,ENCRYPTED")!=-1){var o=F.getDecryptedKeyHex(l,k);var H=new RSAKey();H.readPKCS5PrvKeyHex(o);return H}if(l.indexOf("-END EC PRIVATE KEY-")!=-1&&l.indexOf("4,ENCRYPTED")!=-1){var I=F.getDecryptedKeyHex(l,k);var P=d(I,0,[1],"04");var f=d(I,0,[2,0],"06");var A=d(I,0,[3,0],"03").substr(2);var e="";if(KJUR.crypto.OID.oidhex2name[f]!==undefined){e=KJUR.crypto.OID.oidhex2name[f]}else{throw"undefined OID(hex) in KJUR.crypto.OID: "+f}var j=new i({curve:e});j.setPublicKeyHex(A);j.setPrivateKeyHex(P);j.isPublic=false;return j}if(l.indexOf("-END DSA PRIVATE KEY-")!=-1&&l.indexOf("4,ENCRYPTED")!=-1){var I=F.getDecryptedKeyHex(l,k);var E=d(I,0,[1],"02");var D=d(I,0,[2],"02");var K=d(I,0,[3],"02");var r=d(I,0,[4],"02");var s=d(I,0,[5],"02");var P=new C();P.setPrivate(new BigInteger(E,16),new BigInteger(D,16),new BigInteger(K,16),new BigInteger(r,16),new BigInteger(s,16));return P}if(l.indexOf("-END ENCRYPTED PRIVATE KEY-")!=-1){return F.getKeyFromEncryptedPKCS8PEM(l,k)}throw new Error("not supported argument")};KEYUTIL.generateKeypair=function(a,c){if(a=="RSA"){var b=c;var h=new RSAKey();h.generate(b,"10001");h.isPrivate=true;h.isPublic=true;var f=new RSAKey();var e=h.n.toString(16);var i=h.e.toString(16);f.setPublic(e,i);f.isPrivate=false;f.isPublic=true;var k={};k.prvKeyObj=h;k.pubKeyObj=f;return k}else{if(a=="EC"){var d=c;var g=new KJUR.crypto.ECDSA({curve:d});var j=g.generateKeyPairHex();var h=new KJUR.crypto.ECDSA({curve:d});h.setPublicKeyHex(j.ecpubhex);h.setPrivateKeyHex(j.ecprvhex);h.isPrivate=true;h.isPublic=false;var f=new KJUR.crypto.ECDSA({curve:d});f.setPublicKeyHex(j.ecpubhex);f.isPrivate=false;f.isPublic=true;var k={};k.prvKeyObj=h;k.pubKeyObj=f;return k}else{throw"unknown algorithm: "+a}}};KEYUTIL.getPEM=function(b,D,y,m,q,j){var F=KJUR,k=F.asn1,z=k.DERObjectIdentifier,f=k.DERInteger,l=k.ASN1Util.newObject,a=k.x509,C=a.SubjectPublicKeyInfo,e=F.crypto,u=e.DSA,r=e.ECDSA,n=RSAKey;function A(s){var G=l({seq:[{"int":0},{"int":{bigint:s.n}},{"int":s.e},{"int":{bigint:s.d}},{"int":{bigint:s.p}},{"int":{bigint:s.q}},{"int":{bigint:s.dmp1}},{"int":{bigint:s.dmq1}},{"int":{bigint:s.coeff}}]});return G}function B(G){var s=l({seq:[{"int":1},{octstr:{hex:G.prvKeyHex}},{tag:["a0",true,{oid:{name:G.curveName}}]},{tag:["a1",true,{bitstr:{hex:"00"+G.pubKeyHex}}]}]});return s}function x(s){var G=l({seq:[{"int":0},{"int":{bigint:s.p}},{"int":{bigint:s.q}},{"int":{bigint:s.g}},{"int":{bigint:s.y}},{"int":{bigint:s.x}}]});return G}if(((n!==undefined&&b instanceof n)||(u!==undefined&&b instanceof u)||(r!==undefined&&b instanceof r))&&b.isPublic==true&&(D===undefined||D=="PKCS8PUB")){var E=new C(b);var w=E.getEncodedHex();return hextopem(w,"PUBLIC KEY")}if(D=="PKCS1PRV"&&n!==undefined&&b instanceof n&&(y===undefined||y==null)&&b.isPrivate==true){var E=A(b);var w=E.getEncodedHex();return hextopem(w,"RSA PRIVATE KEY")}if(D=="PKCS1PRV"&&r!==undefined&&b instanceof r&&(y===undefined||y==null)&&b.isPrivate==true){var i=new z({name:b.curveName});var v=i.getEncodedHex();var h=B(b);var t=h.getEncodedHex();var p="";p+=hextopem(v,"EC PARAMETERS");p+=hextopem(t,"EC PRIVATE KEY");return p}if(D=="PKCS1PRV"&&u!==undefined&&b instanceof u&&(y===undefined||y==null)&&b.isPrivate==true){var E=x(b);var w=E.getEncodedHex();return hextopem(w,"DSA PRIVATE KEY")}if(D=="PKCS5PRV"&&n!==undefined&&b instanceof n&&(y!==undefined&&y!=null)&&b.isPrivate==true){var E=A(b);var w=E.getEncodedHex();if(m===undefined){m="DES-EDE3-CBC"}return this.getEncryptedPKCS5PEMFromPrvKeyHex("RSA",w,y,m,j)}if(D=="PKCS5PRV"&&r!==undefined&&b instanceof r&&(y!==undefined&&y!=null)&&b.isPrivate==true){var E=B(b);var w=E.getEncodedHex();if(m===undefined){m="DES-EDE3-CBC"}return this.getEncryptedPKCS5PEMFromPrvKeyHex("EC",w,y,m,j)}if(D=="PKCS5PRV"&&u!==undefined&&b instanceof u&&(y!==undefined&&y!=null)&&b.isPrivate==true){var E=x(b);var w=E.getEncodedHex();if(m===undefined){m="DES-EDE3-CBC"}return this.getEncryptedPKCS5PEMFromPrvKeyHex("DSA",w,y,m,j)}var o=function(G,s){var I=c(G,s);var H=new l({seq:[{seq:[{oid:{name:"pkcs5PBES2"}},{seq:[{seq:[{oid:{name:"pkcs5PBKDF2"}},{seq:[{octstr:{hex:I.pbkdf2Salt}},{"int":I.pbkdf2Iter}]}]},{seq:[{oid:{name:"des-EDE3-CBC"}},{octstr:{hex:I.encryptionSchemeIV}}]}]}]},{octstr:{hex:I.ciphertext}}]});return H.getEncodedHex()};var c=function(N,O){var H=100;var M=CryptoJS.lib.WordArray.random(8);var L="DES-EDE3-CBC";var s=CryptoJS.lib.WordArray.random(8);var I=CryptoJS.PBKDF2(O,M,{keySize:192/32,iterations:H});var J=CryptoJS.enc.Hex.parse(N);var K=CryptoJS.TripleDES.encrypt(J,I,{iv:s})+"";var G={};G.ciphertext=K;G.pbkdf2Salt=CryptoJS.enc.Hex.stringify(M);G.pbkdf2Iter=H;G.encryptionSchemeAlg=L;G.encryptionSchemeIV=CryptoJS.enc.Hex.stringify(s);return G};if(D=="PKCS8PRV"&&n!=undefined&&b instanceof n&&b.isPrivate==true){var g=A(b);var d=g.getEncodedHex();var E=l({seq:[{"int":0},{seq:[{oid:{name:"rsaEncryption"}},{"null":true}]},{octstr:{hex:d}}]});var w=E.getEncodedHex();if(y===undefined||y==null){return hextopem(w,"PRIVATE KEY")}else{var t=o(w,y);return hextopem(t,"ENCRYPTED PRIVATE KEY")}}if(D=="PKCS8PRV"&&r!==undefined&&b instanceof r&&b.isPrivate==true){var g=new l({seq:[{"int":1},{octstr:{hex:b.prvKeyHex}},{tag:["a1",true,{bitstr:{hex:"00"+b.pubKeyHex}}]}]});var d=g.getEncodedHex();var E=l({seq:[{"int":0},{seq:[{oid:{name:"ecPublicKey"}},{oid:{name:b.curveName}}]},{octstr:{hex:d}}]});var w=E.getEncodedHex();if(y===undefined||y==null){return hextopem(w,"PRIVATE KEY")}else{var t=o(w,y);return hextopem(t,"ENCRYPTED PRIVATE KEY")}}if(D=="PKCS8PRV"&&u!==undefined&&b instanceof u&&b.isPrivate==true){var g=new f({bigint:b.x});var d=g.getEncodedHex();var E=l({seq:[{"int":0},{seq:[{oid:{name:"dsa"}},{seq:[{"int":{bigint:b.p}},{"int":{bigint:b.q}},{"int":{bigint:b.g}}]}]},{octstr:{hex:d}}]});var w=E.getEncodedHex();if(y===undefined||y==null){return hextopem(w,"PRIVATE KEY")}else{var t=o(w,y);return hextopem(t,"ENCRYPTED PRIVATE KEY")}}throw new Error("unsupported object nor format")};KEYUTIL.getKeyFromCSRPEM=function(b){var a=pemtohex(b,"CERTIFICATE REQUEST");var c=KEYUTIL.getKeyFromCSRHex(a);return c};KEYUTIL.getKeyFromCSRHex=function(a){var c=KEYUTIL.parseCSRHex(a);var b=KEYUTIL.getKey(c.p8pubkeyhex,null,"pkcs8pub");return b};KEYUTIL.parseCSRHex=function(d){var i=ASN1HEX;var f=i.getChildIdx;var c=i.getTLV;var b={};var g=d;if(g.substr(0,2)!="30"){throw"malformed CSR(code:001)"}var e=f(g,0);if(e.length<1){throw"malformed CSR(code:002)"}if(g.substr(e[0],2)!="30"){throw"malformed CSR(code:003)"}var a=f(g,e[0]);if(a.length<3){throw"malformed CSR(code:004)"}b.p8pubkeyhex=c(g,a[2]);return b};KEYUTIL.getKeyID=function(f){var c=KEYUTIL;var e=ASN1HEX;if(typeof f==="string"&&f.indexOf("BEGIN ")!=-1){f=c.getKey(f)}var d=pemtohex(c.getPEM(f));var b=e.getIdxbyList(d,0,[1]);var a=e.getV(d,b).substring(2);return KJUR.crypto.Util.hashHex(a,"sha1")};KEYUTIL.getJWKFromKey=function(d){var b={};if(d instanceof RSAKey&&d.isPrivate){b.kty="RSA";b.n=hextob64u(d.n.toString(16));b.e=hextob64u(d.e.toString(16));b.d=hextob64u(d.d.toString(16));b.p=hextob64u(d.p.toString(16));b.q=hextob64u(d.q.toString(16));b.dp=hextob64u(d.dmp1.toString(16));b.dq=hextob64u(d.dmq1.toString(16));b.qi=hextob64u(d.coeff.toString(16));return b}else{if(d instanceof RSAKey&&d.isPublic){b.kty="RSA";b.n=hextob64u(d.n.toString(16));b.e=hextob64u(d.e.toString(16));return b}else{if(d instanceof KJUR.crypto.ECDSA&&d.isPrivate){var a=d.getShortNISTPCurveName();if(a!=="P-256"&&a!=="P-384"){throw"unsupported curve name for JWT: "+a}var c=d.getPublicKeyXYHex();b.kty="EC";b.crv=a;b.x=hextob64u(c.x);b.y=hextob64u(c.y);b.d=hextob64u(d.prvKeyHex);return b}else{if(d instanceof KJUR.crypto.ECDSA&&d.isPublic){var a=d.getShortNISTPCurveName();if(a!=="P-256"&&a!=="P-384"){throw"unsupported curve name for JWT: "+a}var c=d.getPublicKeyXYHex();b.kty="EC";b.crv=a;b.x=hextob64u(c.x);b.y=hextob64u(c.y);return b}}}}throw"not supported key object"}; RSAKey.getPosArrayOfChildrenFromHex=function(a){return ASN1HEX.getChildIdx(a,0)};RSAKey.getHexValueArrayOfChildrenFromHex=function(f){var n=ASN1HEX;var i=n.getV;var k=RSAKey.getPosArrayOfChildrenFromHex(f);var e=i(f,k[0]);var j=i(f,k[1]);var b=i(f,k[2]);var c=i(f,k[3]);var h=i(f,k[4]);var g=i(f,k[5]);var m=i(f,k[6]);var l=i(f,k[7]);var d=i(f,k[8]);var k=new Array();k.push(e,j,b,c,h,g,m,l,d);return k};RSAKey.prototype.readPrivateKeyFromPEMString=function(d){var c=pemtohex(d);var b=RSAKey.getHexValueArrayOfChildrenFromHex(c);this.setPrivateEx(b[1],b[2],b[3],b[4],b[5],b[6],b[7],b[8])};RSAKey.prototype.readPKCS5PrvKeyHex=function(c){var b=RSAKey.getHexValueArrayOfChildrenFromHex(c);this.setPrivateEx(b[1],b[2],b[3],b[4],b[5],b[6],b[7],b[8])};RSAKey.prototype.readPKCS8PrvKeyHex=function(e){var c,i,k,b,a,f,d,j;var m=ASN1HEX;var l=m.getVbyListEx;if(m.isASN1HEX(e)===false){throw new Error("not ASN.1 hex string")}try{c=l(e,0,[2,0,1],"02");i=l(e,0,[2,0,2],"02");k=l(e,0,[2,0,3],"02");b=l(e,0,[2,0,4],"02");a=l(e,0,[2,0,5],"02");f=l(e,0,[2,0,6],"02");d=l(e,0,[2,0,7],"02");j=l(e,0,[2,0,8],"02")}catch(g){throw new Error("malformed PKCS#8 plain RSA private key")}this.setPrivateEx(c,i,k,b,a,f,d,j)};RSAKey.prototype.readPKCS5PubKeyHex=function(c){var e=ASN1HEX;var b=e.getV;if(e.isASN1HEX(c)===false){throw new Error("keyHex is not ASN.1 hex string")}var a=e.getChildIdx(c,0);if(a.length!==2||c.substr(a[0],2)!=="02"||c.substr(a[1],2)!=="02"){throw new Error("wrong hex for PKCS#5 public key")}var f=b(c,a[0]);var d=b(c,a[1]);this.setPublic(f,d)};RSAKey.prototype.readPKCS8PubKeyHex=function(b){var c=ASN1HEX;if(c.isASN1HEX(b)===false){throw new Error("not ASN.1 hex string")}if(c.getTLVbyListEx(b,0,[0,0])!=="06092a864886f70d010101"){throw new Error("not PKCS8 RSA public key")}var a=c.getTLVbyListEx(b,0,[1,0]);this.readPKCS5PubKeyHex(a)};RSAKey.prototype.readCertPubKeyHex=function(b,d){var a,c;a=new X509();a.readCertHex(b);c=a.getPublicKeyHex();this.readPKCS8PubKeyHex(c)}; var _RE_HEXDECONLY=new RegExp("[^0-9a-f]","gi");function _rsasign_getHexPaddedDigestInfoForString(d,e,a){var b=function(f){return KJUR.crypto.Util.hashString(f,a)};var c=b(d);return KJUR.crypto.Util.getPaddedDigestInfoHex(c,a,e)}function _zeroPaddingOfSignature(e,d){var c="";var a=d/4-e.length;for(var b=0;b>24,(d&16711680)>>16,(d&65280)>>8,d&255]))));d+=1}return b}RSAKey.prototype.signPSS=function(e,a,d){var c=function(f){return KJUR.crypto.Util.hashHex(f,a)};var b=c(rstrtohex(e));if(d===undefined){d=-1}return this.signWithMessageHashPSS(b,a,d)};RSAKey.prototype.signWithMessageHashPSS=function(l,a,k){var b=hextorstr(l);var g=b.length;var m=this.n.bitLength()-1;var c=Math.ceil(m/8);var d;var o=function(i){return KJUR.crypto.Util.hashHex(i,a)};if(k===-1||k===undefined){k=g}else{if(k===-2){k=c-g-2}else{if(k<-2){throw new Error("invalid salt length")}}}if(c<(g+k+2)){throw new Error("data too long")}var f="";if(k>0){f=new Array(k);new SecureRandom().nextBytes(f);f=String.fromCharCode.apply(String,f)}var n=hextorstr(o(rstrtohex("\x00\x00\x00\x00\x00\x00\x00\x00"+b+f)));var j=[];for(d=0;d>(8*c-m))&255;q[0]&=~p;for(d=0;dthis.n.bitLength()){return 0}var i=this.doPublic(b);var e=i.toString(16).replace(/^1f+00/,"");var g=_rsasign_getAlgNameAndHashFromHexDisgestInfo(e);if(g.length==0){return false}var d=g[0];var h=g[1];var a=function(k){return KJUR.crypto.Util.hashString(k,d)};var c=a(f);return(h==c)};RSAKey.prototype.verifyWithMessageHash=function(e,a){if(a.length!=Math.ceil(this.n.bitLength()/4)){return false}var b=parseBigInt(a,16);if(b.bitLength()>this.n.bitLength()){return 0}var h=this.doPublic(b);var g=h.toString(16).replace(/^1f+00/,"");var c=_rsasign_getAlgNameAndHashFromHexDisgestInfo(g);if(c.length==0){return false}var d=c[0];var f=c[1];return(f==e)};RSAKey.prototype.verifyPSS=function(c,b,a,f){var e=function(g){return KJUR.crypto.Util.hashHex(g,a)};var d=e(rstrtohex(c));if(f===undefined){f=-1}return this.verifyWithMessageHashPSS(d,b,a,f)};RSAKey.prototype.verifyWithMessageHashPSS=function(f,s,l,c){if(s.length!=Math.ceil(this.n.bitLength()/4)){return false}var k=new BigInteger(s,16);var r=function(i){return KJUR.crypto.Util.hashHex(i,l)};var j=hextorstr(f);var h=j.length;var g=this.n.bitLength()-1;var m=Math.ceil(g/8);var q;if(c===-1||c===undefined){c=h}else{if(c===-2){c=m-h-2}else{if(c<-2){throw new Error("invalid salt length")}}}if(m<(h+c+2)){throw new Error("data too long")}var a=this.doPublic(k).toByteArray();for(q=0;q>(8*m-g))&255;if((d.charCodeAt(0)&p)!==0){throw new Error("bits beyond keysize not zero")}var n=pss_mgf1_str(e,d.length,r);var o=[];for(q=0;q1){var A=b(w,v[1]);var u=this.getGeneralName(A);if(u.uri!=undefined){t.uri=u.uri}}if(v.length>2){var x=b(w,v[2]);if(x=="0101ff"){t.reqauth=true}if(x=="010100"){t.reqauth=false}}return t};this.getX500NameRule=function(t){var A=true;var E=true;var D=false;var u="";var x="";var G=null;var B=[];for(var w=0;w0){t.ext=this.getExtParamArray()}t.sighex=this.getSignatureValueHex();return t};this.getExtParamArray=function(u){if(u==undefined){var w=e(this.hex,0,[0,"[3]"]);if(w!=-1){u=l(this.hex,0,[0,"[3]",0],"30")}}var t=[];var v=n(u,0);for(var x=0;x1){var A=b(w,v[1]);var u=this.getGeneralName(A);if(u.uri!=undefined){t.uri=u.uri}}if(v.length>2){var x=b(w,v[2]);if(x=="0101ff"){t.reqauth=true}if(x=="010100"){t.reqauth=false}}return t};this.getX500NameRule=function(t){var A=true;var E=true;var D=false;var u="";var x="";var G=null;var B=[];for(var w=0;w0){t.ext=this.getExtParamArray()}t.sighex=this.getSignatureValueHex();return t};this.getExtParamArray=function(u){if(u==undefined){var w=e(this.hex,0,[0,"[3]"]);if(w!=-1){u=l(this.hex,0,[0,"[3]",0],"30")}}var t=[];var v=n(u,0);for(var x=0;x0){var b=":"+n.join(":")+":";if(b.indexOf(":"+k+":")==-1){throw"algorithm '"+k+"' not accepted in the list"}}if(k!="none"&&B===null){throw"key shall be specified to verify."}if(typeof B=="string"&&B.indexOf("-----BEGIN ")!=-1){B=KEYUTIL.getKey(B)}if(z=="RS"||z=="PS"){if(!(B instanceof m)){throw"key shall be a RSAKey obj for RS* and PS* algs"}}if(z=="ES"){if(!(B instanceof p)){throw"key shall be a ECDSA obj for ES* algs"}}if(k=="none"){}var u=null;if(t.jwsalg2sigalg[l.alg]===undefined){throw"unsupported alg name: "+k}else{u=t.jwsalg2sigalg[k]}if(u=="none"){throw"not supported"}else{if(u.substr(0,4)=="Hmac"){var o=null;if(B===undefined){throw"hexadecimal key shall be specified for HMAC"}var j=new s({alg:u,pass:B});j.updateString(c);o=j.doFinal();return A==o}else{if(u.indexOf("withECDSA")!=-1){var h=null;try{h=p.concatSigToASN1Sig(A)}catch(v){return false}var g=new d({alg:u});g.init(B);g.updateString(c);return g.verify(h)}else{var g=new d({alg:u});g.init(B);g.updateString(c);return g.verify(A)}}}};KJUR.jws.JWS.parse=function(g){var c=g.split(".");var b={};var f,e,d;if(c.length!=2&&c.length!=3){throw"malformed sJWS: wrong number of '.' splitted elements"}f=c[0];e=c[1];if(c.length==3){d=c[2]}b.headerObj=KJUR.jws.JWS.readSafeJSONString(b64utoutf8(f));b.payloadObj=KJUR.jws.JWS.readSafeJSONString(b64utoutf8(e));b.headerPP=JSON.stringify(b.headerObj,null," ");if(b.payloadObj==null){b.payloadPP=b64utoutf8(e)}else{b.payloadPP=JSON.stringify(b.payloadObj,null," ")}if(d!==undefined){b.sigHex=b64utohex(d)}return b};KJUR.jws.JWS.verifyJWT=function(e,l,r){var d=KJUR,j=d.jws,o=j.JWS,n=o.readSafeJSONString,p=o.inArray,f=o.includedArray;var k=e.split(".");var c=k[0];var i=k[1];var q=c+"."+i;var m=b64utohex(k[2]);var h=n(b64utoutf8(c));var g=n(b64utoutf8(i));if(h.alg===undefined){return false}if(r.alg===undefined){throw"acceptField.alg shall be specified"}if(!p(h.alg,r.alg)){return false}if(g.iss!==undefined&&typeof r.iss==="object"){if(!p(g.iss,r.iss)){return false}}if(g.sub!==undefined&&typeof r.sub==="object"){if(!p(g.sub,r.sub)){return false}}if(g.aud!==undefined&&typeof r.aud==="object"){if(typeof g.aud=="string"){if(!p(g.aud,r.aud)){return false}}else{if(typeof g.aud=="object"){if(!f(g.aud,r.aud)){return false}}}}var b=j.IntDate.getNow();if(r.verifyAt!==undefined&&typeof r.verifyAt==="number"){b=r.verifyAt}if(r.gracePeriod===undefined||typeof r.gracePeriod!=="number"){r.gracePeriod=0}if(g.exp!==undefined&&typeof g.exp=="number"){if(g.exp+r.gracePeriodl){this.aHeader.pop()}if(this.aSignature.length>l){this.aSignature.pop()}throw"addSignature failed: "+i}};this.verifyAll=function(h){if(this.aHeader.length!==h.length||this.aSignature.length!==h.length){return false}for(var g=0;g0){this.aHeader=g.headers}else{throw"malformed header"}if(typeof g.payload==="string"){this.sPayload=g.payload}else{throw"malformed signatures"}if(g.signatures.length>0){this.aSignature=g.signatures}else{throw"malformed signatures"}}catch(e){throw"malformed JWS-JS JSON object: "+e}}};this.getJSON=function(){return{headers:this.aHeader,payload:this.sPayload,signatures:this.aSignature}};this.isEmpty=function(){if(this.aHeader.length==0){return 1}return 0}}; diff --git a/npm/package.json b/npm/package.json index 3a080363..11ce13a3 100755 --- a/npm/package.json +++ b/npm/package.json @@ -1,6 +1,6 @@ { "name": "jsrsasign", - "version": "10.1.11", + "version": "10.1.12", "description": "opensource free pure JavaScript cryptographic library supports RSA/RSAPSS/ECDSA/DSA signing/validation, ASN.1, PKCS#1/5/8 private/public key, X.509 certificate, CRL, OCSP, CMS SignedData, TimeStamp and CAdES and JSON Web Signature(JWS)/Token(JWT)/Key(JWK).", "main": "lib/jsrsasign.js", "scripts": { diff --git a/src/x509-1.1.js b/src/x509-1.1.js index f369a299..9c9820c7 100644 --- a/src/x509-1.1.js +++ b/src/x509-1.1.js @@ -1,9 +1,9 @@ -/* x509-2.0.9.js (c) 2012-2020 Kenji Urushima | kjur.github.io/jsrsasign/license +/* x509-2.0.10.js (c) 2012-2021 Kenji Urushima | kjur.github.io/jsrsasign/license */ /* * x509.js - X509 class to read subject public key from certificate. * - * Copyright (c) 2010-2020 Kenji Urushima (kenji.urushima@gmail.com) + * Copyright (c) 2010-2021 Kenji Urushima (kenji.urushima@gmail.com) * * This software is licensed under the terms of the MIT License. * https://kjur.github.io/jsrsasign/license @@ -16,7 +16,7 @@ * @fileOverview * @name x509-1.1.js * @author Kenji Urushima kenji.urushima@gmail.com - * @version jsrsasign 10.1.0 x509 2.0.9 (2020-Nov-18) + * @version jsrsasign 10.1.12 x509 2.0.10 (2021-Feb-25) * @since jsrsasign 1.x.x * @license MIT License */ @@ -271,6 +271,7 @@ function X509(params) { * @memberOf X509# * @function * @return {String} issuer DN string + * @see X509#getIssuer * @example * var x = new X509(); * x.readCertPEM(sCertPEM); @@ -278,7 +279,8 @@ function X509(params) { * var dn2 = KJUR.asn1.x509.X500Name.compatToLDAP(dn1); // returns "O=TEST, C=US" */ this.getIssuerString = function() { - return _X509.hex2dn(this.getIssuerHex()); + var pIssuer = this.getIssuer(); + return pIssuer.str; }; /** @@ -321,6 +323,7 @@ function X509(params) { * @memberOf X509# * @function * @return {String} subject DN string + * @see X509#getSubject * @example * var x = new X509(); * x.readCertPEM(sCertPEM); @@ -328,7 +331,8 @@ function X509(params) { * var dn2 = KJUR.asn1.x509.X500Name.compatToLDAP(dn1); // returns "O=TEST, C=US" */ this.getSubjectString = function() { - return _X509.hex2dn(this.getSubjectHex()); + var pSubject = this.getSubject(); + return pSubject.str; }; /** @@ -2238,7 +2242,7 @@ function X509(params) { var hValue = _getVbyList(h, a[1], []); var oid = KJUR.asn1.ASN1Util.oidHexToInt(hOID); result.type = KJUR.asn1.x509.OID.oid2atype(oid); - result.value = hextorstr(hValue); + result.value = hextoutf8(hValue); result.ds = this.HEX2STAG[h.substr(a[1], 2)]; return result; }; @@ -2662,14 +2666,14 @@ function X509(params) { */ this.dnarraytostr = function(aDN) { function rdnarraytostr(aRDN) { - return aRDN.map(function(x){return atvtostr(x);}).join("+"); + return aRDN.map(function(x){return atvtostr(x).replace(/\+/,"\\+");}).join("+"); }; function atvtostr(pATV) { return pATV.type + "=" + pATV.value; }; - return "/" + aDN.map(function(x){return rdnarraytostr(x);}).join("/"); + return "/" + aDN.map(function(x){return rdnarraytostr(x).replace(/\//, "\\/");}).join("/"); }; /** @@ -2864,17 +2868,10 @@ function X509(params) { */ X509.hex2dn = function(hex, idx) { if (idx === undefined) idx = 0; - if (hex.substr(idx, 2) !== "30") throw new Error("malformed DN"); - - var a = new Array(); - - var aIdx = ASN1HEX.getChildIdx(hex, idx); - for (var i = 0; i < aIdx.length; i++) { - a.push(X509.hex2rdn(hex, aIdx[i])); - } - - a = a.map(function(s) { return s.replace("/", "\\/"); }); - return "/" + a.join("/"); + var x = new X509(); + var hDN = ASN1HEX.getTLV(hex, idx); + var pDN = x.getX500Name(hex); + return pDN.str; }; /** diff --git a/test/qunit-do-x509-ext.html b/test/qunit-do-x509-ext.html index 88fcfdef..f5eadfd3 100755 --- a/test/qunit-do-x509-ext.html +++ b/test/qunit-do-x509-ext.html @@ -912,8 +912,16 @@ ], str: "/C=JP/O=b/CN=a@a.jp" }; - deepEqual(x.getX500Name(hIn1), pExpect, "/C=JP/O=b/CN=a@a.jp") + +var hIn2 = "30123110300e06035504030c0743c3a06e617279"; +var pExpect2 = { + array: [ + [{type:"CN",value:"Cànary",ds:"utf8"}] + ], + str: "/CN=Cànary" +}; +deepEqual(x.getX500Name(hIn2), pExpect2, "/CN=Cànary") }); test("getRDN test", function() {