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 @@
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