diff --git a/ChangeLog.txt b/ChangeLog.txt index 5c4d5b65..cc2c8b4b 100755 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,6 +1,14 @@ ChangeLog for jsrsasign +CRL parser update +* Changes from 10.5.4 to 10.5.5 (2022-Feb-17) + - src/x509crl.js X509CRL class + - add getIssuerHex method + - add findRevCert method + - add findRevCertBySN method + - test/x509crl.html update + ASN.1 parser update and fix * Changes from 10.5.3 to 10.5.4 (2022-Feb-15) - src/asn1.js diff --git a/api/files.html b/api/files.html index da45c0e0..ca4edb20 100644 --- a/api/files.html +++ b/api/files.html @@ -905,7 +905,7 @@
// constructor +crl = new X509CRL("-----BEGIN X509 CRL..."); +crl = new X509CRL("3082...");+ + +
crl = new X509CRL(PEMCRL); + +crl.findRevCert(PEMCERT-REVOKED) → +{sn:"123a", date:"208025235959Z", ext: [{extname:"cRLReason",code:3}]} + +crl.findRevCert(PEMCERT-NOTREVOKED) → null + +crl.findRevCert(CERT-HEX) → null or {sn:...}+ + + + +
crl = new X509CRL(PEMCRL); +crl.findRevCertBySN("123a") → // revoked +{sn:"123a", date:"208025235959Z", ext: [{extname:"cRLReason",code:3}]} + +crl.findRevCertBySN("0000") → null // not revoked+ + + + +
crl = new X509CRL("-----BEGIN X509 CRL..."); +x.getIssuerHex() → "30..."+ + + + + + +
1 /* x509crl.js (c) 2012-2021 Kenji Urushima | kjur.github.io/jsrsasign/license +1 /* x509crl.js (c) 2012-2022 Kenji Urushima | kjur.github.io/jsrsasign/license 2 */ 3 /* 4 * x509crl.js - X509CRL class to parse X.509 CRL 5 * - 6 * Copyright (c) 2010-2020 Kenji Urushima (kenji.urushima@gmail.com) + 6 * Copyright (c) 2010-2022 Kenji Urushima (kenji.urushima@gmail.com) 7 * 8 * This software is licensed under the terms of the MIT License. 9 * https://kjur.github.io/jsrsasign/license @@ -23,7 +23,7 @@ 16 * @fileOverview 17 * @name x509crl.js 18 * @author Kenji Urushima kenji.urushima@gmail.com - 19 * @version jsrsasign 10.1.0 x509crl 1.0.2 (2020-Nov-18) + 19 * @version jsrsasign 10.5.5 x509crl 1.0.3 (2021-Feb-17) 20 * @since jsrsasign 10.1.0 21 * @license <a href="https://kjur.github.io/jsrsasign/license/">MIT License</a> 22 */ @@ -48,364 +48,469 @@ 41 * <li>version - {@link X509CRL#getVersion}</li> 42 * <li>signatureAlgorithm - {@link X509CRL#getSignatureAlgorithmField}</li> 43 * <li>issuer - {@link X509CRL#getIssuer}</li> - 44 * <li>thisUpdate - {@link X509CRL#getThisUpdate}</li> - 45 * <li>nextUpdate - {@link X509CRL#getNextUpdate}</li> - 46 * <li>revokedCertificates - {@link X509CRL#getRevCertArray}</li> - 47 * <li>revokedCertificate - {@link X509CRL#getRevCert}</li> - 48 * <li>signature - {@link X509CRL#getSignatureValueHex}</li> - 49 * </ul> - 50 * <b>UTILITIES</b><br/> - 51 * <ul> - 52 * <li>{@link X509CRL#getParam} - get all parameters</li> - 53 * </ul> - 54 */ - 55 var X509CRL = function(params) { - 56 var _KJUR = KJUR, - 57 _isHex = _KJUR.lang.String.isHex, - 58 _ASN1HEX = ASN1HEX, - 59 _getV = _ASN1HEX.getV, - 60 _getTLV = _ASN1HEX.getTLV, - 61 _getVbyList = _ASN1HEX.getVbyList, - 62 _getTLVbyList = _ASN1HEX.getTLVbyList, - 63 _getTLVbyListEx = _ASN1HEX.getTLVbyListEx, - 64 _getIdxbyList = _ASN1HEX.getIdxbyList, - 65 _getIdxbyListEx = _ASN1HEX.getIdxbyListEx, - 66 _getChildIdx = _ASN1HEX.getChildIdx, - 67 _x509obj = new X509(); - 68 - 69 this.hex = null; - 70 this.posSigAlg = null; - 71 this.posRevCert = null; - 72 - 73 /* - 74 * set field position of SignatureAlgorithm and revokedCertificates<br/> - 75 * @description - 76 * This method will set "posSigAlg" and "posRevCert" properties. - 77 */ - 78 this._setPos = function() { - 79 // for sigAlg - 80 var idx = _getIdxbyList(this.hex, 0, [0, 0]); - 81 var tag = this.hex.substr(idx, 2); - 82 if (tag == "02") { - 83 this.posSigAlg = 1; - 84 } else if (tag == "30") { - 85 this.posSigAlg = 0; - 86 } else { - 87 throw new Error("malformed 1st item of TBSCertList: " + tag); - 88 } - 89 - 90 // for revCerts - 91 var idx2 = _getIdxbyList(this.hex, 0, [0, this.posSigAlg + 3]); - 92 var tag2 = this.hex.substr(idx2, 2); - 93 if (tag2 == "17" || tag2 == "18") { - 94 var idx3, tag3; - 95 idx3 = _getIdxbyList(this.hex, 0, [0, this.posSigAlg + 4]); - 96 this.posRevCert = null; - 97 if (idx3 != -1) { - 98 tag3 = this.hex.substr(idx3, 2); - 99 if (tag3 == "30") { -100 this.posRevCert = this.posSigAlg + 4; -101 } -102 } -103 } else if (tag2 == "30") { // found revCert -104 this.posRevCert = this.posSigAlg + 3; -105 } else if (tag2 == "a0") { // no nextUpdate and revCert -106 this.posRevCert = null; -107 } else { -108 throw new Error("malformed nextUpdate or revCert tag: " + tag2); -109 } -110 }; -111 -112 /** -113 * get X.509 CRL format version<br/> -114 * @name getVersion -115 * @memberOf X509CRL# -116 * @function -117 * @return {Number} version field value (generally 2) or null -118 * @description -119 * This method returns a version field value TBSCertList. -120 * This returns null if there is no such field. -121 * @example -122 * crl = new X509CRL("-----BEGIN X509 CRL..."); -123 * crl.getVersion() → 2 -124 */ -125 this.getVersion = function() { -126 if (this.posSigAlg == 0) return null; -127 return parseInt(_getVbyList(this.hex, 0, [0, 0], "02"), 16) + 1; -128 } -129 -130 /** -131 * get signature algorithm name in basic field -132 * @name getSignatureAlgorithmField -133 * @memberOf X509CRL# -134 * @function -135 * @return {String} signature algorithm name (ex. SHA1withRSA, SHA256withECDSA, SHA512withRSAandMGF1) -136 * @see X509#getSignatureAlgorithmField -137 * @see KJUR.asn1.x509.AlgirithmIdentifier -138 * -139 * @description -140 * This method will get a name of signature algorithm in CRL. -141 * -142 * @example -143 * crl = new X509CRL("-----BEGIN X509 CRL..."); -144 * crl.getSignatureAlgorithmField() → "SHA256withRSAandMGF1" -145 */ -146 this.getSignatureAlgorithmField = function() { -147 var hTLV = _getTLVbyList(this.hex, 0, [0, this.posSigAlg], "30"); -148 return _x509obj.getAlgorithmIdentifierName(hTLV); -149 }; -150 -151 /** -152 * get JSON object of issuer field<br/> -153 * @name getIssuer -154 * @memberOf X509CRL# -155 * @function -156 * @return {Array} JSON object of issuer field -157 * @see X509#getIssuer -158 * @see X509#getX500Name -159 * @see KJUR.asn1.x509.X500Name -160 * -161 * @description -162 * This method returns parsed issuer field value as -163 * JSON object. -164 * -165 * @example -166 * crl = new X509CRL("-----BEGIN X509 CRL..."); -167 * x.getIssuer() → -168 * { array: [[{type:'C',value:'JP',ds:'prn'}],...], -169 * str: "/C=JP/..." } -170 */ -171 this.getIssuer = function() { -172 var hIssuer = _getTLVbyList(this.hex, 0, [0, this.posSigAlg + 1], "30"); -173 return _x509obj.getX500Name(hIssuer); -174 }; -175 -176 /** -177 * get JSON object of thisUpdate field<br/> -178 * @name getThisUpdate -179 * @memberOf X509CRL# -180 * @function -181 * @return {String} string of thisUpdate field (ex. "YYMMDDHHmmSSZ") -182 * @see X509#getNotBefore -183 * @see X509CRL#getNextUpdate -184 * @see KJUR.asn1.x509.Time -185 * -186 * @description -187 * This method returns parsed thisUpdate field value as -188 * string. -189 * -190 * @example -191 * crl = new X509CRL("-----BEGIN X509 CRL..."); -192 * x.getThisUpdate() → "200825235959Z" -193 */ -194 this.getThisUpdate = function() { -195 var hThisUpdate = _getVbyList(this.hex, 0, [0, this.posSigAlg + 2]); -196 return result = hextorstr(hThisUpdate); -197 }; -198 -199 /** -200 * get JSON object of nextUpdate field<br/> -201 * @name getNextUpdate -202 * @memberOf X509CRL# -203 * @function -204 * @return {String} string of nextUpdate field or null -205 * @see X509#getNotBefore -206 * @see X509CRL#getThisUpdate -207 * @see KJUR.asn1.x509.Time -208 * -209 * @description -210 * This method returns parsed nextUpdate field value as -211 * string. "nextUpdate" is OPTIONAL field so -212 * when nextUpdate field doesn't exists, this returns null. -213 * -214 * @example -215 * crl = new X509CRL("-----BEGIN X509 CRL..."); -216 * crl.getNextUpdate() → "200825235959Z" -217 */ -218 this.getNextUpdate = function() { -219 var idx = _getIdxbyList(this.hex, 0, [0, this.posSigAlg + 3]); -220 var tag = this.hex.substr(idx, 2); -221 if (tag != "17" && tag != "18") return null; -222 return hextorstr(_getV(this.hex, idx)); -223 }; -224 -225 /** -226 * get array for revokedCertificates field<br/> -227 * @name getRevCertArray -228 * @memberOf X509CRL# -229 * @function -230 * @return {Array} array of revokedCertificate parameter or null -231 * @see X509CRL#getRevCert -232 * -233 * @description -234 * This method returns parsed revokedCertificates field value as -235 * array of revokedCertificate parameter. -236 * If the field doesn't exists, it returns null. -237 * -238 * @example -239 * crl = new X509CRL("-----BEGIN X509 CRL..."); -240 * crl.getRevCertArray() → -241 * [{sn:"123a", date:"208025235959Z", ext: [{extname:"cRLReason",code:3}]}, -242 * {sn:"123b", date:"208026235959Z", ext: [{extname:"cRLReason",code:0}]}] -243 */ -244 this.getRevCertArray = function() { -245 if (this.posRevCert == null) return null; -246 var a = []; -247 var idx = _getIdxbyList(this.hex, 0, [0, this.posRevCert]); -248 var aIdx = _getChildIdx(this.hex, idx); -249 for (var i = 0; i < aIdx.length; i++) { -250 var hRevCert = _getTLV(this.hex, aIdx[i]); -251 a.push(this.getRevCert(hRevCert)); -252 } -253 return a; -254 }; -255 -256 /** -257 * get revokedCertificate JSON parameter<br/> -258 * @name getRevCert -259 * @memberOf X509CRL# -260 * @function -261 * @return {Array} JSON object for revokedCertificate parameter -262 * @see X509CRL#getRevCertArray -263 * -264 * @description -265 * This method returns parsed revokedCertificate parameter -266 * as JSON object. -267 * -268 * @example -269 * crl = new X509CRL(); -270 * crl.getRevCertArray("30...") → -271 * {sn:"123a", date:"208025235959Z", ext: [{extname:"cRLReason",code:3}]} -272 */ -273 this.getRevCert = function(hRevCert) { -274 var param = {}; -275 var aIdx = _getChildIdx(hRevCert, 0); -276 -277 param.sn = {hex: _getVbyList(hRevCert, 0, [0], "02")}; -278 param.date = hextorstr(_getVbyList(hRevCert, 0, [1])); -279 if (aIdx.length == 3) { -280 param.ext = -281 _x509obj.getExtParamArray(_getTLVbyList(hRevCert, 0, [2])); -282 } -283 -284 return param; -285 }; -286 -287 /** -288 * get signature value as hexadecimal string<br/> -289 * @name getSignatureValueHex -290 * @memberOf X509CRL# -291 * @function -292 * @return {String} signature value hexadecimal string without BitString unused bits -293 * -294 * @description -295 * This method will get signature value of CRL. -296 * -297 * @example -298 * crl = new X509CRL("-----BEGIN X509 CRL..."); -299 * crl.getSignatureValueHex() &rarr "8a4c47913..." -300 */ -301 this.getSignatureValueHex = function() { -302 return _getVbyList(this.hex, 0, [2], "03", true); -303 }; -304 -305 /** -306 * verifies signature value by public key<br/> -307 * @name verifySignature -308 * @memberOf X509CRL# -309 * @function -310 * @param {Object} pubKey public key object, pubkey PEM or PEM issuer cert -311 * @return {Boolean} true if signature value is valid otherwise false -312 * @see X509#verifySignature -313 * @see KJUR.crypto.Signature -314 * -315 * @description -316 * This method verifies signature value of hexadecimal string of -317 * X.509 CRL by specified public key. -318 * The signature algorithm used to verify will refer -319 * signatureAlgorithm field. -320 * (See {@link X509CRL#getSignatureAlgorithmField}) -321 * -322 * @example -323 * crl = new X509CRL("-----BEGIN X509 CRL..."); -324 * x.verifySignature(pubKey) → true, false or raising exception -325 */ -326 this.verifySignature = function(pubKey) { -327 var algName = this.getSignatureAlgorithmField(); -328 var hSigVal = this.getSignatureValueHex(); -329 var hTbsCertList = _getTLVbyList(this.hex, 0, [0], "30"); -330 -331 var sig = new KJUR.crypto.Signature({alg: algName}); -332 sig.init(pubKey); -333 sig.updateHex(hTbsCertList); -334 return sig.verify(hSigVal); -335 }; -336 -337 /** -338 * get JSON object for CRL parameters<br/> -339 * @name getParam -340 * @memberOf X509CRL# -341 * @function -342 * @return {Array} JSON object for CRL parameters -343 * @see KJUR.asn1.x509.CRL -344 * -345 * @description -346 * This method returns a JSON object of the CRL -347 * parameters. -348 * Return value can be passed to -349 * {@link KJUR.asn1.x509.CRL} constructor. -350 * -351 * @example -352 * crl = new X509CRL("-----BEGIN X509 CRL..."); -353 * crl.getParam() → -354 * {version: 2, -355 * sigalg: "SHA256withRSA", -356 * issuer: {array: -357 * [[{type:"C",value:"JP",ds:"prn"}],[{type:"O",value:"T1",ds:"prn"}]]}, -358 * thisupdate: "200820212434Z", -359 * nextupdate: "200910212434Z", -360 * revcert: [ -361 * {sn:{hex:"123d..."}, -362 * date:"061110000000Z", -363 * ext:[{extname:"cRLReason",code:4}]}], -364 * ext: [ -365 * {extname:"authorityKeyIdentifier",kid:{hex: "03de..."}}, -366 * {extname:"cRLNumber",num:{hex:"0211"}}], -367 * sighex: "3c5e..."} -368 */ -369 this.getParam = function() { -370 var result = {}; -371 -372 var version = this.getVersion(); -373 if (version != null) result.version = version; -374 -375 result.sigalg = this.getSignatureAlgorithmField(); -376 result.issuer = this.getIssuer(); -377 result.thisupdate = this.getThisUpdate(); -378 -379 var nextUpdate = this.getNextUpdate(); -380 if (nextUpdate != null) result.nextupdate = nextUpdate; -381 -382 var revCerts = this.getRevCertArray(); -383 if (revCerts != null) result.revcert = revCerts; -384 -385 var idxExt = _getIdxbyListEx(this.hex, 0, [0, "[0]"]); -386 if (idxExt != -1) { -387 var hExtSeq = _getTLVbyListEx(this.hex, 0, [0, "[0]", 0]); -388 result.ext = _x509obj.getExtParamArray(hExtSeq); -389 } -390 -391 result.sighex = this.getSignatureValueHex(); -392 return result; -393 }; -394 -395 if (typeof params == "string") { -396 if (_isHex(params)) { -397 this.hex = params; -398 } else if (params.match(/-----BEGIN X509 CRL/)) { -399 this.hex = pemtohex(params); -400 } -401 this._setPos(); -402 } -403 }; -404