diff --git a/java/ql/src/experimental/Security/CWE/CWE-347/MissingJWTSignatureCheck.java b/java/ql/src/experimental/Security/CWE/CWE-347/MissingJWTSignatureCheck.java new file mode 100644 index 000000000000..1760b4d60973 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-347/MissingJWTSignatureCheck.java @@ -0,0 +1,34 @@ +public void badJwt(String token) { + Jwts.parserBuilder() + .setSigningKey("someBase64EncodedKey").build() + .parse(token); // BAD: Does not verify the signature +} + +public void badJwtHandler(String token) { + Jwts.parserBuilder() + .setSigningKey("someBase64EncodedKey").build() + .parse(plaintextJwt, new JwtHandlerAdapter>() { + @Override + public Jwt onPlaintextJwt(Jwt jwt) { + return jwt; + } + }); // BAD: The handler is called on an unverified JWT +} + +public void goodJwt(String token) { + Jwts.parserBuilder() + .setSigningKey("someBase64EncodedKey").build() + .parseClaimsJws(token) // GOOD: Verify the signature + .getBody(); +} + +public void goodJwtHandler(String token) { + Jwts.parserBuilder() + .setSigningKey("someBase64EncodedKey").build() + .parse(plaintextJwt, new JwtHandlerAdapter>() { + @Override + public Jws onPlaintextJws(Jws jws) { + return jws; + } + }); // GOOD: The handler is called on a verified JWS +} \ No newline at end of file diff --git a/java/ql/src/experimental/Security/CWE/CWE-347/MissingJWTSignatureCheck.qhelp b/java/ql/src/experimental/Security/CWE/CWE-347/MissingJWTSignatureCheck.qhelp new file mode 100644 index 000000000000..3b93936c21b8 --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-347/MissingJWTSignatureCheck.qhelp @@ -0,0 +1,39 @@ + + + + +

A JSON Web Token (JWT) consists of three parts: header, payload, and signature. +The io.jsonwebtoken.jjwt library is one of many libraries used for working with JWTs. +It offers different methods for parsing tokens like parse, parseClaimsJws, and parsePlaintextJws. +The last two correctly verify that the JWT is properly signed. +This is done by computing the signature of the combination of header and payload and +comparing the locally computed signature with the signature part of the JWT. +

+

+Therefore it is necessary to provide the JwtParser with a key that is used for signature validation. +Unfortunately the parse method accepts a JWT whose signature is empty although a signing key has been set for the parser. +This means that an attacker can create arbitrary JWTs that will be accepted if this method is used. +

+
+ + +

Always verify the signature by using either the parseClaimsJws and parsePlaintextJws methods or +by overriding the onPlaintextJws or onClaimsJws of JwtHandlerAdapter. +

+ +
+ + +

The following example shows four cases where a signing key is set for a parser. +In the first bad case the parse method is used which will not validate the signature. +The second bad case uses a JwtHandlerAdapter where the onPlaintextJwt method is overriden so it will not validate the signature. +The third and fourth good cases use parseClaimsJws method or override the onPlaintextJws method. +

+ + + +
+ +
  • zofrex: How I Found An alg=none JWT Vulnerability in the NHS Contact Tracing App.
  • +
    +
    diff --git a/java/ql/src/experimental/Security/CWE/CWE-347/MissingJWTSignatureCheck.ql b/java/ql/src/experimental/Security/CWE/CWE-347/MissingJWTSignatureCheck.ql new file mode 100644 index 000000000000..6d7462f1338e --- /dev/null +++ b/java/ql/src/experimental/Security/CWE/CWE-347/MissingJWTSignatureCheck.ql @@ -0,0 +1,200 @@ +/** + * @name Missing JWT signature check + * @description Not checking the JWT signature allows an attacker to forge their own tokens. + * @kind problem + * @problem.severity error + * @precision high + * @id java/missing-jwt-signature-check + * @tags security + * external/cwe/cwe-347 + */ + +import java +import semmle.code.java.dataflow.DataFlow + +/** The interface `io.jsonwebtoken.JwtParser`. */ +class TypeJwtParser extends Interface { + TypeJwtParser() { this.hasQualifiedName("io.jsonwebtoken", "JwtParser") } +} + +/** The interface `io.jsonwebtoken.JwtParser` or a type derived from it. */ +class TypeDerivedJwtParser extends RefType { + TypeDerivedJwtParser() { this.getASourceSupertype*() instanceof TypeJwtParser } +} + +/** The interface `io.jsonwebtoken.JwtParserBuilder`. */ +class TypeJwtParserBuilder extends Interface { + TypeJwtParserBuilder() { this.hasQualifiedName("io.jsonwebtoken", "JwtParserBuilder") } +} + +/** The interface `io.jsonwebtoken.JwtHandler`. */ +class TypeJwtHandler extends Interface { + TypeJwtHandler() { this.hasQualifiedName("io.jsonwebtoken", "JwtHandler") } +} + +/** The class `io.jsonwebtoken.JwtHandlerAdapter`. */ +class TypeJwtHandlerAdapter extends Class { + TypeJwtHandlerAdapter() { this.hasQualifiedName("io.jsonwebtoken", "JwtHandlerAdapter") } +} + +/** The `parse(token, handler)` method defined in `JwtParser`. */ +private class JwtParserParseHandlerMethod extends Method { + JwtParserParseHandlerMethod() { + this.hasName("parse") and + this.getDeclaringType() instanceof TypeJwtParser and + this.getNumberOfParameters() = 2 + } +} + +/** The `parse(token)`, `parseClaimsJwt(token)` and `parsePlaintextJwt(token)` methods defined in `JwtParser`. */ +private class JwtParserInsecureParseMethod extends Method { + JwtParserInsecureParseMethod() { + this.hasName(["parse", "parseClaimsJwt", "parsePlaintextJwt"]) and + this.getNumberOfParameters() = 1 and + this.getDeclaringType() instanceof TypeJwtParser + } +} + +/** The `on(Claims|Plaintext)Jwt` methods defined in `JwtHandler`. */ +private class JwtHandlerOnJwtMethod extends Method { + JwtHandlerOnJwtMethod() { + this.hasName(["onClaimsJwt", "onPlaintextJwt"]) and + this.getNumberOfParameters() = 1 and + this.getDeclaringType() instanceof TypeJwtHandler + } +} + +/** The `on(Claims|Plaintext)Jwt` methods defined in `JwtHandlerAdapter`. */ +private class JwtHandlerAdapterOnJwtMethod extends Method { + JwtHandlerAdapterOnJwtMethod() { + this.hasName(["onClaimsJwt", "onPlaintextJwt"]) and + this.getNumberOfParameters() = 1 and + this.getDeclaringType() instanceof TypeJwtHandlerAdapter + } +} + +/** + * Holds if `parseHandlerExpr` is an insecure `JwtHandler`. + * That is, it overrides a method from `JwtHandlerOnJwtMethod` and the override is not defined on `JwtHandlerAdapter`. + * `JwtHandlerAdapter`'s overrides are safe since they always throw an exception. + */ +private predicate isInsecureJwtHandler(Expr parseHandlerExpr) { + exists(RefType t | + parseHandlerExpr.getType() = t and + t.getASourceSupertype*() instanceof TypeJwtHandler and + exists(Method m | + m = t.getAMethod() and + m.getASourceOverriddenMethod+() instanceof JwtHandlerOnJwtMethod and + not m.getSourceDeclaration() instanceof JwtHandlerAdapterOnJwtMethod + ) + ) +} + +/** + * An access to an insecure parsing method. + * That is, either a call to a `parse(token)`, `parseClaimsJwt(token)` or `parsePlaintextJwt(token)` method or + * a call to a `parse(token, handler)` method where the `handler` is considered insecure. + */ +private class JwtParserInsecureParseMethodAccess extends MethodAccess { + JwtParserInsecureParseMethodAccess() { + this.getMethod().getASourceOverriddenMethod*() instanceof JwtParserInsecureParseMethod + or + this.getMethod().getASourceOverriddenMethod*() instanceof JwtParserParseHandlerMethod and + isInsecureJwtHandler(this.getArgument(1)) + } +} + +/** + * Holds if `signingMa` directly or indirectly sets a signing key for `expr`, which is a `JwtParser`. + * The `setSigningKey` and `setSigningKeyResolver` methods set a signing key for a `JwtParser`. + * Directly means code like this: + * ```java + * Jwts.parser().setSigningKey(key).parse(token); + * ``` + * Here the signing key is set directly on a `JwtParser`. + * Indirectly means code like this: + * ```java + * Jwts.parserBuilder().setSigningKey(key).build().parse(token); + * ``` + * In this case, the signing key is set on a `JwtParserBuilder` indirectly setting the key of `JwtParser` that is created by the call to `build`. + */ +private predicate isSigningKeySetter(Expr expr, MethodAccess signingMa) { + any(SigningToInsecureMethodAccessDataFlow s) + .hasFlow(DataFlow::exprNode(signingMa), DataFlow::exprNode(expr)) +} + +/** + * An expr that is a (sub-type of) `JwtParser` for which a signing key has been set and which is used as + * the qualifier to a `JwtParserInsecureParseMethodAccess`. + */ +private class JwtParserWithSigningKeyExpr extends Expr { + MethodAccess signingMa; + + JwtParserWithSigningKeyExpr() { + this.getType() instanceof TypeDerivedJwtParser and + isSigningKeySetter(this, signingMa) + } + + /** Gets the method access that sets the signing key for this parser. */ + MethodAccess getSigningMethodAccess() { result = signingMa } +} + +/** + * Models flow from `SigningKeyMethodAccess`es to qualifiers of `JwtParserInsecureParseMethodAccess`es. + * This is used to determine whether a `JwtParser` has a signing key set. + */ +private class SigningToInsecureMethodAccessDataFlow extends DataFlow::Configuration { + SigningToInsecureMethodAccessDataFlow() { this = "SigningToExprDataFlow" } + + override predicate isSource(DataFlow::Node source) { + source.asExpr() instanceof SigningKeyMethodAccess + } + + override predicate isSink(DataFlow::Node sink) { + any(JwtParserInsecureParseMethodAccess ma).getQualifier() = sink.asExpr() + } + + /** Models the builder style of `JwtParser` and `JwtParserBuilder`. */ + override predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) { + ( + pred.asExpr().getType() instanceof TypeDerivedJwtParser or + pred.asExpr().getType().(RefType).getASourceSupertype*() instanceof TypeJwtParserBuilder + ) and + succ.asExpr().(MethodAccess).getQualifier() = pred.asExpr() + } +} + +/** An access to the `setSigningKey` or `setSigningKeyResolver` method (or an overridden method) defined in `JwtParser` and `JwtParserBuilder`. */ +private class SigningKeyMethodAccess extends MethodAccess { + SigningKeyMethodAccess() { + exists(Method m | + m.hasName(["setSigningKey", "setSigningKeyResolver"]) and + m.getNumberOfParameters() = 1 and + ( + m.getDeclaringType() instanceof TypeJwtParser or + m.getDeclaringType() instanceof TypeJwtParserBuilder + ) + | + m = this.getMethod().getASourceOverriddenMethod*() + ) + } +} + +/** + * Holds if the `MethodAccess` `ma` occurs in a test file. A test file is any file that + * is a direct or indirect child of a directory named `test`, ignoring case. + */ +private predicate isInTestFile(MethodAccess ma) { + exists(string lowerCasedAbsolutePath | + lowerCasedAbsolutePath = ma.getLocation().getFile().getAbsolutePath().toLowerCase() + | + lowerCasedAbsolutePath.matches("%/test/%") and + not lowerCasedAbsolutePath + .matches("%/ql/test/experimental/query-tests/security/CWE-347/%".toLowerCase()) + ) +} + +from JwtParserInsecureParseMethodAccess ma, JwtParserWithSigningKeyExpr parserExpr +where ma.getQualifier() = parserExpr and not isInTestFile(ma) +select ma, "A signing key is set $@, but the signature is not verified.", + parserExpr.getSigningMethodAccess(), "here" diff --git a/java/ql/test/experimental/query-tests/security/CWE-347/MissingJWTSignatureCheck.expected b/java/ql/test/experimental/query-tests/security/CWE-347/MissingJWTSignatureCheck.expected new file mode 100644 index 000000000000..e93720fcea83 --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/CWE-347/MissingJWTSignatureCheck.expected @@ -0,0 +1,8 @@ +| MissingJWTSignatureCheck.java:96:9:96:27 | parse(...) | A signing key is set $@, but the signature is not verified. | MissingJWTSignatureCheck.java:18:16:18:66 | setSigningKey(...) | here | +| MissingJWTSignatureCheck.java:96:9:96:27 | parse(...) | A signing key is set $@, but the signature is not verified. | MissingJWTSignatureCheck.java:22:16:22:73 | setSigningKey(...) | here | +| MissingJWTSignatureCheck.java:96:9:96:27 | parse(...) | A signing key is set $@, but the signature is not verified. | MissingJWTSignatureCheck.java:26:16:26:75 | setSigningKey(...) | here | +| MissingJWTSignatureCheck.java:100:9:105:22 | parse(...) | A signing key is set $@, but the signature is not verified. | MissingJWTSignatureCheck.java:18:16:18:66 | setSigningKey(...) | here | +| MissingJWTSignatureCheck.java:100:9:105:22 | parse(...) | A signing key is set $@, but the signature is not verified. | MissingJWTSignatureCheck.java:22:16:22:73 | setSigningKey(...) | here | +| MissingJWTSignatureCheck.java:100:9:105:22 | parse(...) | A signing key is set $@, but the signature is not verified. | MissingJWTSignatureCheck.java:26:16:26:75 | setSigningKey(...) | here | +| MissingJWTSignatureCheck.java:127:9:129:33 | parse(...) | A signing key is set $@, but the signature is not verified. | MissingJWTSignatureCheck.java:127:9:128:58 | setSigningKey(...) | here | +| MissingJWTSignatureCheck.java:133:9:140:22 | parse(...) | A signing key is set $@, but the signature is not verified. | MissingJWTSignatureCheck.java:133:9:134:58 | setSigningKey(...) | here | diff --git a/java/ql/test/experimental/query-tests/security/CWE-347/MissingJWTSignatureCheck.java b/java/ql/test/experimental/query-tests/security/CWE-347/MissingJWTSignatureCheck.java new file mode 100644 index 000000000000..624dbb1d48da --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/CWE-347/MissingJWTSignatureCheck.java @@ -0,0 +1,164 @@ +//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/jwtk-jjwt-0.11.2 + +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.JwtParser; +import io.jsonwebtoken.Jwt; +import io.jsonwebtoken.Jws; +import io.jsonwebtoken.Header; +import io.jsonwebtoken.JwtParserBuilder; +import io.jsonwebtoken.JwtHandlerAdapter; +import io.jsonwebtoken.impl.DefaultJwtParser; + +public class MissingJWTSignatureCheck { + + + // SIGNED + + private JwtParser getASignedParser() { + return Jwts.parser().setSigningKey("someBase64EncodedKey"); + } + + private JwtParser getASignedParserFromParserBuilder() { + return Jwts.parserBuilder().setSigningKey("someBase64EncodedKey").build(); + } + + private JwtParser getASignedNewParser() { + return new DefaultJwtParser().setSigningKey("someBase64EncodedKey"); + } + + private void callSignedParsers() { + JwtParser parser1 = getASignedParser(); + badJwtOnParserBuilder(parser1, ""); + badJwtHandlerOnParserBuilder(parser1, ""); + goodJwtOnParserBuilder(parser1, ""); + goodJwtHandler(parser1, ""); + + JwtParser parser2 = getASignedParserFromParserBuilder(); + badJwtOnParserBuilder(parser2, ""); + badJwtHandlerOnParserBuilder(parser2, ""); + goodJwtOnParserBuilder(parser2, ""); + goodJwtHandler(parser2, ""); + + JwtParser parser3 = getASignedNewParser(); + badJwtOnParserBuilder(parser3, ""); + badJwtHandlerOnParserBuilder(parser3, ""); + goodJwtOnParserBuilder(parser3, ""); + goodJwtHandler(parser3, ""); + } + + // SIGNED END + + // UNSIGNED + + private JwtParser getAnUnsignedParser() { + return Jwts.parser(); + } + + private JwtParser getAnUnsignedParserFromParserBuilder() { + return Jwts.parserBuilder().build(); + } + + private JwtParser getAnUnsignedNewParser() { + return new DefaultJwtParser(); + } + + private void callUnsignedParsers() { + JwtParser parser1 = getAnUnsignedParser(); + badJwtOnParserBuilder(parser1, ""); + badJwtHandlerOnParserBuilder(parser1, ""); + goodJwtOnParserBuilder(parser1, ""); + goodJwtHandler(parser1, ""); + + JwtParser parser2 = getAnUnsignedParserFromParserBuilder(); + badJwtOnParserBuilder(parser2, ""); + badJwtHandlerOnParserBuilder(parser2, ""); + goodJwtOnParserBuilder(parser2, ""); + goodJwtHandler(parser2, ""); + + JwtParser parser3 = getAnUnsignedNewParser(); + badJwtOnParserBuilder(parser3, ""); + badJwtHandlerOnParserBuilder(parser3, ""); + goodJwtOnParserBuilder(parser3, ""); + goodJwtHandler(parser3, ""); + } + + private void signParserAfterParseCall() { + JwtParser parser = getAnUnsignedParser(); + parser.parse(""); // Should not be detected + parser.setSigningKey("someBase64EncodedKey"); + } + + // UNSIGNED END + + // INDIRECT + + private void badJwtOnParserBuilder(JwtParser parser, String token) { + parser.parse(token); // BAD: Does not verify the signature + } + + private void badJwtHandlerOnParserBuilder(JwtParser parser, String token) { + parser.parse(token, new JwtHandlerAdapter>() { // BAD: The handler is called on an unverified JWT + @Override + public Jwt onPlaintextJwt(Jwt jwt) { + return jwt; + } + }); + } + + private void goodJwtOnParserBuilder(JwtParser parser, String token) { + parser.parseClaimsJws(token) // GOOD: Verify the signature + .getBody(); + } + + private void goodJwtHandler(JwtParser parser, String token) { + parser.parse(token, new JwtHandlerAdapter>() { // GOOD: The handler is called on a verified JWS + @Override + public Jws onPlaintextJws(Jws jws) { + return jws; + } + }); + } + + // INDIRECT END + + // DIRECT + + private void badJwtOnParserBuilder(String token) { + Jwts.parserBuilder() + .setSigningKey("someBase64EncodedKey").build() + .parse(token); // BAD: Does not verify the signature + } + + private void badJwtHandlerOnParser(String token) { + Jwts.parser() + .setSigningKey("someBase64EncodedKey") + .parse(token, new JwtHandlerAdapter>() { // BAD: The handler is called on an unverified JWT + @Override + public Jwt onPlaintextJwt(Jwt jwt) { + return jwt; + } + }); + } + + private void goodJwtOnParser(String token) { + Jwts.parser() + .setSigningKey("someBase64EncodedKey") + .parseClaimsJws(token) // GOOD: Verify the signature + .getBody(); + } + + private void goodJwtHandlerOnParserBuilder(String token) { + Jwts.parserBuilder() + .setSigningKey("someBase64EncodedKey").build() + .parse(token, new JwtHandlerAdapter>() { // GOOD: The handler is called on a verified JWS + @Override + public Jws onPlaintextJws(Jws jws) { + return jws; + } + }); + } + + // DIRECT END + + +} diff --git a/java/ql/test/experimental/query-tests/security/CWE-347/MissingJWTSignatureCheck.qlref b/java/ql/test/experimental/query-tests/security/CWE-347/MissingJWTSignatureCheck.qlref new file mode 100644 index 000000000000..67e7bf3e158c --- /dev/null +++ b/java/ql/test/experimental/query-tests/security/CWE-347/MissingJWTSignatureCheck.qlref @@ -0,0 +1 @@ +experimental/Security/CWE/CWE-347/MissingJWTSignatureCheck.ql \ No newline at end of file diff --git a/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/LICENSE b/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/LICENSE new file mode 100644 index 000000000000..5c304d1a4a7b --- /dev/null +++ b/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/LICENSE @@ -0,0 +1,201 @@ +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/ClaimJwtException.java b/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/ClaimJwtException.java new file mode 100644 index 000000000000..af003d48a659 --- /dev/null +++ b/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/ClaimJwtException.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2014 jsonwebtoken.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.jsonwebtoken; + +/** + * ClaimJwtException is a subclass of the {@link JwtException} that is thrown after a validation of an JTW claim failed. + * + * @since 0.5 + */ +public abstract class ClaimJwtException extends JwtException { + + protected ClaimJwtException(Header header, Claims claims, String message) { + super(message); + } + + protected ClaimJwtException(Header header, Claims claims, String message, Throwable cause) { + super(message, cause); + } + + public Claims getClaims() { + return null; + } + + public Header getHeader() { + return null; + } +} diff --git a/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/Claims.java b/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/Claims.java new file mode 100644 index 000000000000..e1fab7582bff --- /dev/null +++ b/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/Claims.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2014 jsonwebtoken.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.jsonwebtoken; + +import java.util.Date; +import java.util.Map; + +/** + * A JWT Claims set. + * + *

    This is ultimately a JSON map and any values can be added to it, but JWT standard names are provided as + * type-safe getters and setters for convenience.

    + * + *

    Because this interface extends {@code Map<String, Object>}, if you would like to add your own properties, + * you simply use map methods, for example:

    + * + *
    + * claims.{@link Map#put(Object, Object) put}("someKey", "someValue");
    + * 
    + * + *

    Creation

    + * + *

    It is easiest to create a {@code Claims} instance by calling one of the + * {@link Jwts#claims() JWTs.claims()} factory methods.

    + * + * @since 0.1 + */ +public interface Claims extends Map, ClaimsMutator { + +} diff --git a/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/ClaimsMutator.java b/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/ClaimsMutator.java new file mode 100644 index 000000000000..1fda02c2b4de --- /dev/null +++ b/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/ClaimsMutator.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2014 jsonwebtoken.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.jsonwebtoken; + +import java.util.Date; + +/** + * Mutation (modifications) to a {@link io.jsonwebtoken.Claims Claims} instance. + * + * @param the type of mutator + * @see io.jsonwebtoken.JwtBuilder + * @see io.jsonwebtoken.Claims + * @since 0.2 + */ +public interface ClaimsMutator { + +} diff --git a/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/ExpiredJwtException.java b/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/ExpiredJwtException.java new file mode 100644 index 000000000000..0748ca367c60 --- /dev/null +++ b/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/ExpiredJwtException.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2014 jsonwebtoken.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.jsonwebtoken; + +/** + * Exception indicating that a JWT was accepted after it expired and must be rejected. + * + * @since 0.3 + */ +public class ExpiredJwtException extends ClaimJwtException { + + public ExpiredJwtException(Header header, Claims claims, String message) { + super(header, claims, message); + } + + /** + * @param header jwt header + * @param claims jwt claims (body) + * @param message exception message + * @param cause cause + * @since 0.5 + */ + public ExpiredJwtException(Header header, Claims claims, String message, Throwable cause) { + super(header, claims, message, cause); + } +} diff --git a/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/Header.java b/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/Header.java new file mode 100644 index 000000000000..f25935ebe173 --- /dev/null +++ b/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/Header.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2014 jsonwebtoken.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.jsonwebtoken; + +import java.util.Map; + +/** + * A JWT JOSE header. + * + *

    This is ultimately a JSON map and any values can be added to it, but JWT JOSE standard names are provided as + * type-safe getters and setters for convenience.

    + * + *

    Because this interface extends {@code Map<String, Object>}, if you would like to add your own properties, + * you simply use map methods, for example:

    + * + *
    + * header.{@link Map#put(Object, Object) put}("headerParamName", "headerParamValue");
    + * 
    + * + *

    Creation

    + * + *

    It is easiest to create a {@code Header} instance by calling one of the + * {@link Jwts#header() JWTs.header()} factory methods.

    + * + * @since 0.1 + */ +public interface Header> extends Map { +} diff --git a/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/Jws.java b/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/Jws.java new file mode 100644 index 000000000000..2fbdd2d61834 --- /dev/null +++ b/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/Jws.java @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2014 jsonwebtoken.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.jsonwebtoken; + +/** + * An expanded (not compact/serialized) Signed JSON Web Token. + * + * @param the type of the JWS body contents, either a String or a {@link Claims} instance. + * + * @since 0.1 */ +public interface Jws extends Jwt { +} diff --git a/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/JwsHeader.java b/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/JwsHeader.java new file mode 100644 index 000000000000..3a07b66720d5 --- /dev/null +++ b/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/JwsHeader.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2014 jsonwebtoken.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.jsonwebtoken; + +/** + * A JWS header. + * + * @param header type + * @since 0.1 + */ +public interface JwsHeader> extends Header { + +} diff --git a/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/Jwt.java b/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/Jwt.java new file mode 100644 index 000000000000..0d27328b3291 --- /dev/null +++ b/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/Jwt.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2014 jsonwebtoken.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.jsonwebtoken; + +/** + * An expanded (not compact/serialized) JSON Web Token. + * + * @param the type of the JWT body contents, either a String or a {@link Claims} instance. + * + * @since 0.1 + */ +public interface Jwt { + /** + * Returns the JWT body, either a {@code String} or a {@code Claims} instance. + * + * @return the JWT body, either a {@code String} or a {@code Claims} instance. + */ + B getBody(); +} diff --git a/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/JwtException.java b/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/JwtException.java new file mode 100644 index 000000000000..c25aa22392cf --- /dev/null +++ b/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/JwtException.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2014 jsonwebtoken.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.jsonwebtoken; + +/** + * Base class for JWT-related runtime exceptions. + * + * @since 0.1 + */ +public class JwtException extends RuntimeException { + + public JwtException(String message) { + super(message); + } + + public JwtException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/JwtHandler.java b/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/JwtHandler.java new file mode 100644 index 000000000000..0e23f8339862 --- /dev/null +++ b/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/JwtHandler.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2014 jsonwebtoken.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.jsonwebtoken; + +/** + * A JwtHandler is invoked by a {@link io.jsonwebtoken.JwtParser JwtParser} after parsing a JWT to indicate the exact + * type of JWT or JWS parsed. + * + * @param the type of object to return to the parser caller after handling the parsed JWT. + * @since 0.2 + */ +public interface JwtHandler { + + /** + * This method is invoked when a {@link io.jsonwebtoken.JwtParser JwtParser} determines that the parsed JWT is + * a plaintext JWT. A plaintext JWT has a String (non-JSON) body payload and it is not cryptographically signed. + * + * @param jwt the parsed plaintext JWT + * @return any object to be used after inspecting the JWT, or {@code null} if no return value is necessary. + */ + T onPlaintextJwt(Jwt jwt); + + /** + * This method is invoked when a {@link io.jsonwebtoken.JwtParser JwtParser} determines that the parsed JWT is + * a Claims JWT. A Claims JWT has a {@link Claims} body and it is not cryptographically signed. + * + * @param jwt the parsed claims JWT + * @return any object to be used after inspecting the JWT, or {@code null} if no return value is necessary. + */ + T onClaimsJwt(Jwt jwt); + + /** + * This method is invoked when a {@link io.jsonwebtoken.JwtParser JwtParser} determines that the parsed JWT is + * a plaintext JWS. A plaintext JWS is a JWT with a String (non-JSON) body (payload) that has been + * cryptographically signed. + * + *

    This method will only be invoked if the cryptographic signature can be successfully verified.

    + * + * @param jws the parsed plaintext JWS + * @return any object to be used after inspecting the JWS, or {@code null} if no return value is necessary. + */ + T onPlaintextJws(Jws jws); + + /** + * This method is invoked when a {@link io.jsonwebtoken.JwtParser JwtParser} determines that the parsed JWT is + * a valid Claims JWS. A Claims JWS is a JWT with a {@link Claims} body that has been cryptographically signed. + * + *

    This method will only be invoked if the cryptographic signature can be successfully verified.

    + * + * @param jws the parsed claims JWS + * @return any object to be used after inspecting the JWS, or {@code null} if no return value is necessary. + */ + T onClaimsJws(Jws jws); + +} diff --git a/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/JwtHandlerAdapter.java b/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/JwtHandlerAdapter.java new file mode 100644 index 000000000000..749488372e7e --- /dev/null +++ b/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/JwtHandlerAdapter.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2014 jsonwebtoken.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.jsonwebtoken; + +/** + * An Adapter implementation of the + * {@link JwtHandler} interface that allows for anonymous subclasses to process only the JWT results that are + * known/expected for a particular use case. + * + *

    All of the methods in this implementation throw exceptions: overridden methods represent + * scenarios expected by calling code in known situations. It would be unexpected to receive a JWS or JWT that did + * not match parsing expectations, so all non-overridden methods throw exceptions to indicate that the JWT + * input was unexpected.

    + * + * @param the type of object to return to the parser caller after handling the parsed JWT. + * @since 0.2 + */ +public class JwtHandlerAdapter implements JwtHandler { + + @Override + public T onPlaintextJwt(Jwt jwt) { + throw new UnsupportedJwtException("Unsigned plaintext JWTs are not supported."); + } + + @Override + public T onClaimsJwt(Jwt jwt) { + throw new UnsupportedJwtException("Unsigned Claims JWTs are not supported."); + } + + @Override + public T onPlaintextJws(Jws jws) { + throw new UnsupportedJwtException("Signed plaintext JWSs are not supported."); + } + + @Override + public T onClaimsJws(Jws jws) { + throw new UnsupportedJwtException("Signed Claims JWSs are not supported."); + } +} diff --git a/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/JwtParser.java b/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/JwtParser.java new file mode 100644 index 000000000000..3e43079f1c22 --- /dev/null +++ b/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/JwtParser.java @@ -0,0 +1,343 @@ +/* + * Copyright (C) 2014 jsonwebtoken.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.jsonwebtoken; + +import java.security.Key; +import java.util.Date; +import java.util.Map; + +/** + * A parser for reading JWT strings, used to convert them into a {@link Jwt} object representing the expanded JWT. + * + * @since 0.1 + */ +public interface JwtParser { + + /** + * Sets the signing key used to verify any discovered JWS digital signature. If the specified JWT string is not + * a JWS (no signature), this key is not used. + *

    + *

    Note that this key MUST be a valid key for the signature algorithm found in the JWT header + * (as the {@code alg} header parameter).

    + *

    + *

    This method overwrites any previously set key.

    + * + * @param key the algorithm-specific signature verification key used to validate any discovered JWS digital + * signature. + * @return the parser for method chaining. + * @deprecated see {@link JwtParserBuilder#setSigningKey(byte[])}. + * To construct a JwtParser use the corresponding builder via {@link Jwts#parserBuilder()}. This will construct an + * immutable JwtParser. + *

    NOTE: this method will be removed before version 1.0 + */ + @Deprecated + JwtParser setSigningKey(byte[] key); + + /** + * Sets the signing key used to verify any discovered JWS digital signature. If the specified JWT string is not + * a JWS (no signature), this key is not used. + * + *

    Note that this key MUST be a valid key for the signature algorithm found in the JWT header + * (as the {@code alg} header parameter).

    + * + *

    This method overwrites any previously set key.

    + * + *

    This is a convenience method: the string argument is first BASE64-decoded to a byte array and this resulting + * byte array is used to invoke {@link #setSigningKey(byte[])}.

    + * + *

    Deprecation Notice: Deprecated as of 0.10.0, will be removed in 1.0.0

    + * + *

    This method has been deprecated because the {@code key} argument for this method can be confusing: keys for + * cryptographic operations are always binary (byte arrays), and many people were confused as to how bytes were + * obtained from the String argument.

    + * + *

    This method always expected a String argument that was effectively the same as the result of the following + * (pseudocode):

    + * + *

    {@code String base64EncodedSecretKey = base64Encode(secretKeyBytes);}

    + * + *

    However, a non-trivial number of JJWT users were confused by the method signature and attempted to + * use raw password strings as the key argument - for example {@code setSigningKey(myPassword)} - which is + * almost always incorrect for cryptographic hashes and can produce erroneous or insecure results.

    + * + *

    See this + * + * StackOverflow answer explaining why raw (non-base64-encoded) strings are almost always incorrect for + * signature operations.

    + * + *

    Finally, please use the {@link #setSigningKey(Key) setSigningKey(Key)} instead, as this method and the + * {@code byte[]} variant will be removed before the 1.0.0 release.

    + * + * @param base64EncodedSecretKey the BASE64-encoded algorithm-specific signature verification key to use to validate + * any discovered JWS digital signature. + * @return the parser for method chaining. + * @deprecated see {@link JwtParserBuilder#setSigningKey(String)}. + * To construct a JwtParser use the corresponding builder via {@link Jwts#parserBuilder()}. This will construct an + * immutable JwtParser. + *

    NOTE: this method will be removed before version 1.0 + */ + @Deprecated + JwtParser setSigningKey(String base64EncodedSecretKey); + + /** + * Sets the signing key used to verify any discovered JWS digital signature. If the specified JWT string is not + * a JWS (no signature), this key is not used. + *

    + *

    Note that this key MUST be a valid key for the signature algorithm found in the JWT header + * (as the {@code alg} header parameter).

    + *

    + *

    This method overwrites any previously set key.

    + * + * @param key the algorithm-specific signature verification key to use to validate any discovered JWS digital + * signature. + * @return the parser for method chaining. + * @deprecated see {@link JwtParserBuilder#setSigningKey(Key)}. + * To construct a JwtParser use the corresponding builder via {@link Jwts#parserBuilder()}. This will construct an + * immutable JwtParser. + *

    NOTE: this method will be removed before version 1.0 + */ + @Deprecated + JwtParser setSigningKey(Key key); + + /** + * Sets the {@link SigningKeyResolver} used to acquire the signing key that should be used to verify + * a JWS's signature. If the parsed String is not a JWS (no signature), this resolver is not used. + *

    + *

    Specifying a {@code SigningKeyResolver} is necessary when the signing key is not already known before parsing + * the JWT and the JWT header or payload (plaintext body or Claims) must be inspected first to determine how to + * look up the signing key. Once returned by the resolver, the JwtParser will then verify the JWS signature with the + * returned key. For example:

    + *

    + *

    +     * Jws<Claims> jws = Jwts.parser().setSigningKeyResolver(new SigningKeyResolverAdapter() {
    +     *         @Override
    +     *         public byte[] resolveSigningKeyBytes(JwsHeader header, Claims claims) {
    +     *             //inspect the header or claims, lookup and return the signing key
    +     *             return getSigningKey(header, claims); //implement me
    +     *         }})
    +     *     .parseClaimsJws(compact);
    +     * 
    + *

    + *

    A {@code SigningKeyResolver} is invoked once during parsing before the signature is verified.

    + *

    + *

    This method should only be used if a signing key is not provided by the other {@code setSigningKey*} builder + * methods.

    + * + * @param signingKeyResolver the signing key resolver used to retrieve the signing key. + * @return the parser for method chaining. + * @since 0.4 + * @deprecated see {@link JwtParserBuilder#setSigningKeyResolver(SigningKeyResolver)}. + * To construct a JwtParser use the corresponding builder via {@link Jwts#parserBuilder()}. This will construct an + * immutable JwtParser. + *

    NOTE: this method will be removed before version 1.0 + */ + @Deprecated + JwtParser setSigningKeyResolver(SigningKeyResolver signingKeyResolver); + + /** + * Parses the specified compact serialized JWT string based on the builder's current configuration state and + * returns the resulting JWT or JWS instance. + *

    + *

    This method returns a JWT or JWS based on the parsed string. Because it may be cumbersome to determine if it + * is a JWT or JWS, or if the body/payload is a Claims or String with {@code instanceof} checks, the + * {@link #parse(String, JwtHandler) parse(String,JwtHandler)} method allows for a type-safe callback approach that + * may help reduce code or instanceof checks.

    + * + * @param jwt the compact serialized JWT to parse + * @return the specified compact serialized JWT string based on the builder's current configuration state. + * @throws MalformedJwtException if the specified JWT was incorrectly constructed (and therefore invalid). + * Invalid + * JWTs should not be trusted and should be discarded. + * @throws SignatureException if a JWS signature was discovered, but could not be verified. JWTs that fail + * signature validation should not be trusted and should be discarded. + * @throws ExpiredJwtException if the specified JWT is a Claims JWT and the Claims has an expiration time + * before the time this method is invoked. + * @throws IllegalArgumentException if the specified string is {@code null} or empty or only whitespace. + * @see #parse(String, JwtHandler) + * @see #parsePlaintextJwt(String) + * @see #parseClaimsJwt(String) + * @see #parsePlaintextJws(String) + * @see #parseClaimsJws(String) + */ + Jwt parse(String jwt) throws ExpiredJwtException, MalformedJwtException, SignatureException, IllegalArgumentException; + + /** + * Parses the specified compact serialized JWT string based on the builder's current configuration state and + * invokes the specified {@code handler} with the resulting JWT or JWS instance. + *

    + *

    If you are confident of the format of the JWT before parsing, you can create an anonymous subclass using the + * {@link io.jsonwebtoken.JwtHandlerAdapter JwtHandlerAdapter} and override only the methods you know are relevant + * for your use case(s), for example:

    + *

    + *

    +     * String compactJwt = request.getParameter("jwt"); //we are confident this is a signed JWS
    +     *
    +     * String subject = Jwts.parser().setSigningKey(key).parse(compactJwt, new JwtHandlerAdapter<String>() {
    +     *     @Override
    +     *     public String onClaimsJws(Jws<Claims> jws) {
    +     *         return jws.getBody().getSubject();
    +     *     }
    +     * });
    +     * 
    + *

    + *

    If you know the JWT string can be only one type of JWT, then it is even easier to invoke one of the + * following convenience methods instead of this one:

    + *

    + *

      + *
    • {@link #parsePlaintextJwt(String)}
    • + *
    • {@link #parseClaimsJwt(String)}
    • + *
    • {@link #parsePlaintextJws(String)}
    • + *
    • {@link #parseClaimsJws(String)}
    • + *
    + * + * @param jwt the compact serialized JWT to parse + * @return the result returned by the {@code JwtHandler} + * @throws MalformedJwtException if the specified JWT was incorrectly constructed (and therefore invalid). + * Invalid JWTs should not be trusted and should be discarded. + * @throws SignatureException if a JWS signature was discovered, but could not be verified. JWTs that fail + * signature validation should not be trusted and should be discarded. + * @throws ExpiredJwtException if the specified JWT is a Claims JWT and the Claims has an expiration time + * before the time this method is invoked. + * @throws IllegalArgumentException if the specified string is {@code null} or empty or only whitespace, or if the + * {@code handler} is {@code null}. + * @see #parsePlaintextJwt(String) + * @see #parseClaimsJwt(String) + * @see #parsePlaintextJws(String) + * @see #parseClaimsJws(String) + * @see #parse(String) + * @since 0.2 + */ + T parse(String jwt, JwtHandler handler) + throws ExpiredJwtException, UnsupportedJwtException, MalformedJwtException, SignatureException, IllegalArgumentException; + + /** + * Parses the specified compact serialized JWT string based on the builder's current configuration state and + * returns + * the resulting unsigned plaintext JWT instance. + *

    + *

    This is a convenience method that is usable if you are confident that the compact string argument reflects an + * unsigned plaintext JWT. An unsigned plaintext JWT has a String (non-JSON) body payload and it is not + * cryptographically signed.

    + *

    + *

    If the compact string presented does not reflect an unsigned plaintext JWT with non-JSON string body, + * an {@link UnsupportedJwtException} will be thrown.

    + * + * @param plaintextJwt a compact serialized unsigned plaintext JWT string. + * @return the {@link Jwt Jwt} instance that reflects the specified compact JWT string. + * @throws UnsupportedJwtException if the {@code plaintextJwt} argument does not represent an unsigned plaintext + * JWT + * @throws MalformedJwtException if the {@code plaintextJwt} string is not a valid JWT + * @throws SignatureException if the {@code plaintextJwt} string is actually a JWS and signature validation + * fails + * @throws IllegalArgumentException if the {@code plaintextJwt} string is {@code null} or empty or only whitespace + * @see #parseClaimsJwt(String) + * @see #parsePlaintextJws(String) + * @see #parseClaimsJws(String) + * @see #parse(String, JwtHandler) + * @see #parse(String) + * @since 0.2 + */ + Jwt parsePlaintextJwt(String plaintextJwt) + throws UnsupportedJwtException, MalformedJwtException, SignatureException, IllegalArgumentException; + + /** + * Parses the specified compact serialized JWT string based on the builder's current configuration state and + * returns + * the resulting unsigned plaintext JWT instance. + *

    + *

    This is a convenience method that is usable if you are confident that the compact string argument reflects an + * unsigned Claims JWT. An unsigned Claims JWT has a {@link Claims} body and it is not cryptographically + * signed.

    + *

    + *

    If the compact string presented does not reflect an unsigned Claims JWT, an + * {@link UnsupportedJwtException} will be thrown.

    + * + * @param claimsJwt a compact serialized unsigned Claims JWT string. + * @return the {@link Jwt Jwt} instance that reflects the specified compact JWT string. + * @throws UnsupportedJwtException if the {@code claimsJwt} argument does not represent an unsigned Claims JWT + * @throws MalformedJwtException if the {@code claimsJwt} string is not a valid JWT + * @throws SignatureException if the {@code claimsJwt} string is actually a JWS and signature validation + * fails + * @throws ExpiredJwtException if the specified JWT is a Claims JWT and the Claims has an expiration time + * before the time this method is invoked. + * @throws IllegalArgumentException if the {@code claimsJwt} string is {@code null} or empty or only whitespace + * @see #parsePlaintextJwt(String) + * @see #parsePlaintextJws(String) + * @see #parseClaimsJws(String) + * @see #parse(String, JwtHandler) + * @see #parse(String) + * @since 0.2 + */ + Jwt parseClaimsJwt(String claimsJwt) + throws ExpiredJwtException, UnsupportedJwtException, MalformedJwtException, SignatureException, IllegalArgumentException; + + /** + * Parses the specified compact serialized JWS string based on the builder's current configuration state and + * returns + * the resulting plaintext JWS instance. + *

    + *

    This is a convenience method that is usable if you are confident that the compact string argument reflects a + * plaintext JWS. A plaintext JWS is a JWT with a String (non-JSON) body (payload) that has been + * cryptographically signed.

    + *

    + *

    If the compact string presented does not reflect a plaintext JWS, an {@link UnsupportedJwtException} + * will be thrown.

    + * + * @param plaintextJws a compact serialized JWS string. + * @return the {@link Jws Jws} instance that reflects the specified compact JWS string. + * @throws UnsupportedJwtException if the {@code plaintextJws} argument does not represent an plaintext JWS + * @throws MalformedJwtException if the {@code plaintextJws} string is not a valid JWS + * @throws SignatureException if the {@code plaintextJws} JWS signature validation fails + * @throws IllegalArgumentException if the {@code plaintextJws} string is {@code null} or empty or only whitespace + * @see #parsePlaintextJwt(String) + * @see #parseClaimsJwt(String) + * @see #parseClaimsJws(String) + * @see #parse(String, JwtHandler) + * @see #parse(String) + * @since 0.2 + */ + Jws parsePlaintextJws(String plaintextJws) + throws UnsupportedJwtException, MalformedJwtException, SignatureException, IllegalArgumentException; + + /** + * Parses the specified compact serialized JWS string based on the builder's current configuration state and + * returns + * the resulting Claims JWS instance. + *

    + *

    This is a convenience method that is usable if you are confident that the compact string argument reflects a + * Claims JWS. A Claims JWS is a JWT with a {@link Claims} body that has been cryptographically signed.

    + *

    + *

    If the compact string presented does not reflect a Claims JWS, an {@link UnsupportedJwtException} will be + * thrown.

    + * + * @param claimsJws a compact serialized Claims JWS string. + * @return the {@link Jws Jws} instance that reflects the specified compact Claims JWS string. + * @throws UnsupportedJwtException if the {@code claimsJws} argument does not represent an Claims JWS + * @throws MalformedJwtException if the {@code claimsJws} string is not a valid JWS + * @throws SignatureException if the {@code claimsJws} JWS signature validation fails + * @throws ExpiredJwtException if the specified JWT is a Claims JWT and the Claims has an expiration time + * before the time this method is invoked. + * @throws IllegalArgumentException if the {@code claimsJws} string is {@code null} or empty or only whitespace + * @see #parsePlaintextJwt(String) + * @see #parseClaimsJwt(String) + * @see #parsePlaintextJws(String) + * @see #parse(String, JwtHandler) + * @see #parse(String) + * @since 0.2 + */ + Jws parseClaimsJws(String claimsJws) + throws ExpiredJwtException, UnsupportedJwtException, MalformedJwtException, SignatureException, IllegalArgumentException; +} diff --git a/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/JwtParserBuilder.java b/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/JwtParserBuilder.java new file mode 100644 index 000000000000..cc0060b0c269 --- /dev/null +++ b/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/JwtParserBuilder.java @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2019 jsonwebtoken.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.jsonwebtoken; + +import java.security.Key; +import java.util.Date; +import java.util.Map; + +/** + * A builder to construct a {@link JwtParser}. Example usage: + *
    {@code
    + *     Jwts.parserBuilder()
    + *         .setSigningKey(...)
    + *         .requireIssuer("https://issuer.example.com")
    + *         .build()
    + *         .parse(jwtString)
    + * }
    + * @since 0.11.0 + */ +public interface JwtParserBuilder { + + + /** + * Sets the signing key used to verify any discovered JWS digital signature. If the specified JWT string is not + * a JWS (no signature), this key is not used. + *

    + *

    Note that this key MUST be a valid key for the signature algorithm found in the JWT header + * (as the {@code alg} header parameter).

    + *

    + *

    This method overwrites any previously set key.

    + * + * @param key the algorithm-specific signature verification key used to validate any discovered JWS digital + * signature. + * @return the parser builder for method chaining. + */ + JwtParserBuilder setSigningKey(byte[] key); + + /** + * Sets the signing key used to verify any discovered JWS digital signature. If the specified JWT string is not + * a JWS (no signature), this key is not used. + * + *

    Note that this key MUST be a valid key for the signature algorithm found in the JWT header + * (as the {@code alg} header parameter).

    + * + *

    This method overwrites any previously set key.

    + * + *

    This is a convenience method: the string argument is first BASE64-decoded to a byte array and this resulting + * byte array is used to invoke {@link #setSigningKey(byte[])}.

    + * + *

    Deprecation Notice: Deprecated as of 0.10.0, will be removed in 1.0.0

    + * + *

    This method has been deprecated because the {@code key} argument for this method can be confusing: keys for + * cryptographic operations are always binary (byte arrays), and many people were confused as to how bytes were + * obtained from the String argument.

    + * + *

    This method always expected a String argument that was effectively the same as the result of the following + * (pseudocode):

    + * + *

    {@code String base64EncodedSecretKey = base64Encode(secretKeyBytes);}

    + * + *

    However, a non-trivial number of JJWT users were confused by the method signature and attempted to + * use raw password strings as the key argument - for example {@code setSigningKey(myPassword)} - which is + * almost always incorrect for cryptographic hashes and can produce erroneous or insecure results.

    + * + *

    See this + * + * StackOverflow answer explaining why raw (non-base64-encoded) strings are almost always incorrect for + * signature operations.

    + * + *

    Finally, please use the {@link #setSigningKey(Key) setSigningKey(Key)} instead, as this method and the + * {@code byte[]} variant will be removed before the 1.0.0 release.

    + * + * @param base64EncodedSecretKey the BASE64-encoded algorithm-specific signature verification key to use to validate + * any discovered JWS digital signature. + * @return the parser builder for method chaining. + */ + JwtParserBuilder setSigningKey(String base64EncodedSecretKey); + + /** + * Sets the signing key used to verify any discovered JWS digital signature. If the specified JWT string is not + * a JWS (no signature), this key is not used. + *

    + *

    Note that this key MUST be a valid key for the signature algorithm found in the JWT header + * (as the {@code alg} header parameter).

    + *

    + *

    This method overwrites any previously set key.

    + * + * @param key the algorithm-specific signature verification key to use to validate any discovered JWS digital + * signature. + * @return the parser builder for method chaining. + */ + JwtParserBuilder setSigningKey(Key key); + + /** + * Sets the {@link SigningKeyResolver} used to acquire the signing key that should be used to verify + * a JWS's signature. If the parsed String is not a JWS (no signature), this resolver is not used. + *

    + *

    Specifying a {@code SigningKeyResolver} is necessary when the signing key is not already known before parsing + * the JWT and the JWT header or payload (plaintext body or Claims) must be inspected first to determine how to + * look up the signing key. Once returned by the resolver, the JwtParser will then verify the JWS signature with the + * returned key. For example:

    + *

    + *

    +     * Jws<Claims> jws = Jwts.parser().setSigningKeyResolver(new SigningKeyResolverAdapter() {
    +     *         @Override
    +     *         public byte[] resolveSigningKeyBytes(JwsHeader header, Claims claims) {
    +     *             //inspect the header or claims, lookup and return the signing key
    +     *             return getSigningKey(header, claims); //implement me
    +     *         }})
    +     *     .parseClaimsJws(compact);
    +     * 
    + *

    + *

    A {@code SigningKeyResolver} is invoked once during parsing before the signature is verified.

    + *

    + *

    This method should only be used if a signing key is not provided by the other {@code setSigningKey*} builder + * methods.

    + * + * @param signingKeyResolver the signing key resolver used to retrieve the signing key. + * @return the parser builder for method chaining. + */ + JwtParserBuilder setSigningKeyResolver(SigningKeyResolver signingKeyResolver); + + /** + * Returns an immutable/thread-safe {@link JwtParser} created from the configuration from this JwtParserBuilder. + * @return an immutable/thread-safe JwtParser created from the configuration from this JwtParserBuilder. + */ + JwtParser build(); +} diff --git a/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/Jwts.java b/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/Jwts.java new file mode 100644 index 000000000000..11caab3b7d33 --- /dev/null +++ b/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/Jwts.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2014 jsonwebtoken.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.jsonwebtoken; + +import java.util.Map; + +/** + * Factory class useful for creating instances of JWT interfaces. Using this factory class can be a good + * alternative to tightly coupling your code to implementation classes. + * + * @since 0.1 + */ +public final class Jwts { + + private Jwts() { + } + + + /** + * Returns a new {@link JwtParser} instance that can be configured and then used to parse JWT strings. + * + * @return a new {@link JwtParser} instance that can be configured and then used to parse JWT strings. + * @deprecated use {@link Jwts#parserBuilder()} instead. See {@link JwtParserBuilder} for usage details. + *

    Migration to new method structure is minimal, for example: + *

    Old code: + *

    {@code
    +     *     Jwts.parser()
    +     *         .requireAudience("string")
    +     *         .parse(jwtString)
    +     * }
    + *

    New code: + *

    {@code
    +     *     Jwts.parserBuilder()
    +     *         .requireAudience("string")
    +     *         .build()
    +     *         .parse(jwtString)
    +     * }
    + *

    NOTE: this method will be removed before version 1.0 + */ + @Deprecated + public static JwtParser parser() { + return null; + } + + /** + * Returns a new {@link JwtParserBuilder} instance that can be configured to create an immutable/thread-safe {@link JwtParser). + * + * @return a new {@link JwtParser} instance that can be configured create an immutable/thread-safe {@link JwtParser). + */ + public static JwtParserBuilder parserBuilder() { + return null; + } +} diff --git a/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/MalformedJwtException.java b/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/MalformedJwtException.java new file mode 100644 index 000000000000..6490550aaf7e --- /dev/null +++ b/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/MalformedJwtException.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2014 jsonwebtoken.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.jsonwebtoken; + +/** + * Exception indicating that a JWT was not correctly constructed and should be rejected. + * + * @since 0.2 + */ +public class MalformedJwtException extends JwtException { + + public MalformedJwtException(String message) { + super(message); + } + + public MalformedJwtException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/SignatureException.java b/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/SignatureException.java new file mode 100644 index 000000000000..e98b4c72298a --- /dev/null +++ b/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/SignatureException.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2014 jsonwebtoken.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.jsonwebtoken; + +import io.jsonwebtoken.security.SecurityException; + +/** + * Exception indicating that either calculating a signature or verifying an existing signature of a JWT failed. + * + * @since 0.1 + * @deprecated in favor of {@link io.jsonwebtoken.security.SecurityException}; this class will be removed before 1.0 + */ +@Deprecated +public class SignatureException extends SecurityException { + + public SignatureException(String message) { + super(message); + } + + public SignatureException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/SigningKeyResolver.java b/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/SigningKeyResolver.java new file mode 100644 index 000000000000..1d584612cc9a --- /dev/null +++ b/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/SigningKeyResolver.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2014 jsonwebtoken.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.jsonwebtoken; + +import java.security.Key; + +/** + * A {@code SigningKeyResolver} can be used by a {@link io.jsonwebtoken.JwtParser JwtParser} to find a signing key that + * should be used to verify a JWS signature. + * + *

    A {@code SigningKeyResolver} is necessary when the signing key is not already known before parsing the JWT and the + * JWT header or payload (plaintext body or Claims) must be inspected first to determine how to look up the signing key. + * Once returned by the resolver, the JwtParser will then verify the JWS signature with the returned key. For + * example:

    + * + *
    + * Jws<Claims> jws = Jwts.parser().setSigningKeyResolver(new SigningKeyResolverAdapter() {
    + *         @Override
    + *         public byte[] resolveSigningKeyBytes(JwsHeader header, Claims claims) {
    + *             //inspect the header or claims, lookup and return the signing key
    + *             return getSigningKeyBytes(header, claims); //implement me
    + *         }})
    + *     .parseClaimsJws(compact);
    + * 
    + * + *

    A {@code SigningKeyResolver} is invoked once during parsing before the signature is verified.

    + * + *

    SigningKeyResolverAdapter

    + * + *

    If you only need to resolve a signing key for a particular JWS (either a plaintext or Claims JWS), consider using + * the {@link io.jsonwebtoken.SigningKeyResolverAdapter} and overriding only the method you need to support instead of + * implementing this interface directly.

    + * + * @see io.jsonwebtoken.SigningKeyResolverAdapter + * @since 0.4 + */ +public interface SigningKeyResolver { + +} diff --git a/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/UnsupportedJwtException.java b/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/UnsupportedJwtException.java new file mode 100644 index 000000000000..3735f7d4257d --- /dev/null +++ b/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/UnsupportedJwtException.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2014 jsonwebtoken.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.jsonwebtoken; + +/** + * Exception thrown when receiving a JWT in a particular format/configuration that does not match the format expected + * by the application. + * + *

    For example, this exception would be thrown if parsing an unsigned plaintext JWT when the application + * requires a cryptographically signed Claims JWS instead.

    + * + * @since 0.2 + */ +public class UnsupportedJwtException extends JwtException { + + public UnsupportedJwtException(String message) { + super(message); + } + + public UnsupportedJwtException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/impl/DefaultJwtParser.java b/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/impl/DefaultJwtParser.java new file mode 100644 index 000000000000..ddd137027deb --- /dev/null +++ b/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/impl/DefaultJwtParser.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2014 jsonwebtoken.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.jsonwebtoken.impl; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.ExpiredJwtException; +import io.jsonwebtoken.Header; +import io.jsonwebtoken.Jws; +import io.jsonwebtoken.JwsHeader; +import io.jsonwebtoken.Jwt; +import io.jsonwebtoken.JwtHandler; +import io.jsonwebtoken.JwtParser; +import io.jsonwebtoken.MalformedJwtException; +import io.jsonwebtoken.SignatureException; +import io.jsonwebtoken.SigningKeyResolver; + +import java.security.Key; + +@SuppressWarnings("unchecked") +public class DefaultJwtParser implements JwtParser { + @Deprecated + public DefaultJwtParser() { + } + + @Override + public JwtParser setSigningKey(byte[] key) { + return null; + } + + @Override + public JwtParser setSigningKey(String base64EncodedSecretKey) { + return null; + } + + @Override + public JwtParser setSigningKey(Key key) { + return null; + } + + @Override + public JwtParser setSigningKeyResolver(SigningKeyResolver signingKeyResolver) { + return null; + } + + @Override + public Jwt parse(String jwt) throws ExpiredJwtException, MalformedJwtException, SignatureException { + return null; + } + + @Override + public T parse(String compact, JwtHandler handler) + throws ExpiredJwtException, MalformedJwtException, SignatureException { + return null; + } + + @Override + public Jwt parsePlaintextJwt(String plaintextJwt) { + return null; + } + + @Override + public Jwt parseClaimsJwt(String claimsJwt) { + return null; + } + + @Override + public Jws parsePlaintextJws(String plaintextJws) { + return null; + } + + @Override + public Jws parseClaimsJws(String claimsJws) { + return null; + } +} diff --git a/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/security/SecurityException.java b/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/security/SecurityException.java new file mode 100644 index 000000000000..8b5f8abd87e3 --- /dev/null +++ b/java/ql/test/experimental/stubs/jwtk-jjwt-0.11.2/io/jsonwebtoken/security/SecurityException.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2014 jsonwebtoken.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.jsonwebtoken.security; + +import io.jsonwebtoken.JwtException; + +/** + * @since 0.10.0 + */ +public class SecurityException extends JwtException { + + public SecurityException(String message) { + super(message); + } + + public SecurityException(String message, Throwable cause) { + super(message, cause); + } +}