mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-05-14 16:51:28 +00:00
Compare commits
1 Commits
develop
...
feature/x5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8dae4c55ea |
@@ -34,6 +34,8 @@ public class Environment {
|
||||
private static final String PLUGIN_DIR_PROP_NAME = "cryptomator.pluginDir";
|
||||
private static final String TRAY_ICON_PROP_NAME = "cryptomator.showTrayIcon";
|
||||
private static final String DISABLE_UPDATE_CHECK_PROP_NAME = "cryptomator.disableUpdateCheck";
|
||||
private static final String LICENSE_CHAIN_REQUIRED_CN_PROP_NAME = "cryptomator.licenseChainRequiredCn";
|
||||
private static final String DEFAULT_LICENSE_CHAIN_REQUIRED_CN = "License Intermediate CA (Prod)";
|
||||
|
||||
private Environment() {}
|
||||
|
||||
@@ -57,6 +59,7 @@ public class Environment {
|
||||
logCryptomatorSystemProperty(PLUGIN_DIR_PROP_NAME);
|
||||
logCryptomatorSystemProperty(TRAY_ICON_PROP_NAME);
|
||||
logCryptomatorSystemProperty(DISABLE_UPDATE_CHECK_PROP_NAME);
|
||||
logCryptomatorSystemProperty(LICENSE_CHAIN_REQUIRED_CN_PROP_NAME);
|
||||
}
|
||||
|
||||
public static Environment getInstance() {
|
||||
@@ -145,6 +148,10 @@ public class Environment {
|
||||
return Boolean.getBoolean(DISABLE_UPDATE_CHECK_PROP_NAME);
|
||||
}
|
||||
|
||||
public String getLicenseChainRequiredCn() {
|
||||
return System.getProperty(LICENSE_CHAIN_REQUIRED_CN_PROP_NAME, DEFAULT_LICENSE_CHAIN_REQUIRED_CN);
|
||||
}
|
||||
|
||||
private Optional<Path> getPath(String propertyName) {
|
||||
String value = System.getProperty(propertyName);
|
||||
return Optional.ofNullable(value).map(Paths::get);
|
||||
|
||||
@@ -2,31 +2,60 @@ package org.cryptomator.common;
|
||||
|
||||
import com.auth0.jwt.JWT;
|
||||
import com.auth0.jwt.algorithms.Algorithm;
|
||||
import com.auth0.jwt.exceptions.JWTDecodeException;
|
||||
import com.auth0.jwt.exceptions.JWTVerificationException;
|
||||
import com.auth0.jwt.interfaces.Claim;
|
||||
import com.auth0.jwt.interfaces.DecodedJWT;
|
||||
import com.auth0.jwt.interfaces.JWTVerifier;
|
||||
import com.google.common.io.BaseEncoding;
|
||||
import org.jetbrains.annotations.VisibleForTesting;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PublicKey;
|
||||
import java.security.cert.CertPathValidatorException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.security.interfaces.ECPublicKey;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Singleton
|
||||
class LicenseChecker {
|
||||
|
||||
private final JWTVerifier verifier;
|
||||
private static final String LICENSE_ROOT_CERTIFICATE = """
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBqDCCAVqgAwIBAgIUKNImuR2JD+NyAWaYzb8V8w8SdFwwBQYDK2VwMD8xCzAJ
|
||||
BgNVBAYTAkRFMRYwFAYDVQQKDA1Ta3ltYXRpYyBHbWJIMRgwFgYDVQQDDA9MaWNl
|
||||
bnNlIFJvb3QgQ0EwIBcNMjYwMjI2MTMzMTQxWhgPMjA3NjAyMTQxMzMxNDFaMD8x
|
||||
CzAJBgNVBAYTAkRFMRYwFAYDVQQKDA1Ta3ltYXRpYyBHbWJIMRgwFgYDVQQDDA9M
|
||||
aWNlbnNlIFJvb3QgQ0EwKjAFBgMrZXADIQCOyUIv+3Ust66VWJ8yH5ruJGxyZC1u
|
||||
LK2Yxb+ZtPGAQKNmMGQwEgYDVR0TAQH/BAgwBgEB/wIBATAOBgNVHQ8BAf8EBAMC
|
||||
AQYwHQYDVR0OBBYEFGhKUh0jCta2wXzxrUldIBqB4Bz3MB8GA1UdIwQYMBaAFGhK
|
||||
Uh0jCta2wXzxrUldIBqB4Bz3MAUGAytlcANBAOERjFKpGnjxH1nh2u5lsCjX65zz
|
||||
XisC7XFaZQikVLKzHK+YTIusi3x7dGCFBjO/m3ieQpt7BsaPo0lLL719pQ8=
|
||||
-----END CERTIFICATE-----
|
||||
""";
|
||||
|
||||
private final ECPublicKey legacyPublicKey;
|
||||
private final X509Certificate rootCertificate;
|
||||
private final String requiredChainCn;
|
||||
|
||||
@Inject
|
||||
public LicenseChecker(@Named("licensePublicKey") String pemEncodedPublicKey) {
|
||||
Algorithm algorithm = Algorithm.ECDSA512(decodePublicKey(pemEncodedPublicKey), null);
|
||||
this.verifier = JWT.require(algorithm).build();
|
||||
public LicenseChecker(@Named("licensePublicKey") String legacyLicensePublicKey, Environment environment) {
|
||||
this(legacyLicensePublicKey, LICENSE_ROOT_CERTIFICATE, environment.getLicenseChainRequiredCn());
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
LicenseChecker(String legacyLicensePublicKey, String trustedRootCert, String requiredChainCn) {
|
||||
this.legacyPublicKey = decodePublicKey(legacyLicensePublicKey);
|
||||
this.rootCertificate = X509Helper.parsePemCertificate(trustedRootCert);
|
||||
this.requiredChainCn = requiredChainCn;
|
||||
}
|
||||
|
||||
private static ECPublicKey decodePublicKey(String pemEncodedPublicKey) {
|
||||
@@ -47,10 +76,44 @@ class LicenseChecker {
|
||||
|
||||
public Optional<DecodedJWT> check(String licenseKey) {
|
||||
try {
|
||||
DecodedJWT decodedJwt = JWT.decode(licenseKey);
|
||||
Claim x5cClaim = decodedJwt.getHeaderClaim("x5c");
|
||||
ECPublicKey signingKey;
|
||||
if (x5cClaim == null || x5cClaim.isMissing()) {
|
||||
signingKey = this.legacyPublicKey;
|
||||
} else {
|
||||
var certChain = verifyChain(x5cClaim);
|
||||
signingKey = asEcPublicKey(certChain.getFirst().getPublicKey());
|
||||
}
|
||||
JWTVerifier verifier = JWT.require(Algorithm.ECDSA512(signingKey, null)).build();
|
||||
return Optional.of(verifier.verify(licenseKey));
|
||||
} catch (JWTVerificationException exception) {
|
||||
} catch (JWTVerificationException | GeneralSecurityException e) {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
private List<X509Certificate> verifyChain(Claim x5cClaim) throws GeneralSecurityException {
|
||||
List<String> x5cEntries = x5cClaim.asList(String.class);
|
||||
if (x5cEntries == null || x5cEntries.isEmpty()) {
|
||||
throw new CertPathValidatorException("x5c claim is empty.");
|
||||
}
|
||||
List<X509Certificate> certChain = X509Helper.parseX5cCertificateChain(x5cEntries);
|
||||
boolean containsRequiredCn = certChain.stream() //
|
||||
.flatMap(cert -> X509Helper.extractCommonName(cert).stream()) //
|
||||
.anyMatch(requiredChainCn::equals);
|
||||
if (!containsRequiredCn) {
|
||||
throw new CertPathValidatorException("x5c certificate chain does not contain required CN " + requiredChainCn);
|
||||
}
|
||||
X509Helper.validateChain(certChain, rootCertificate);
|
||||
return certChain;
|
||||
}
|
||||
|
||||
private static ECPublicKey asEcPublicKey(PublicKey publicKey) {
|
||||
if (publicKey instanceof ECPublicKey ecPublicKey) {
|
||||
return ecPublicKey;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Leaf certificate key is not an EC public key.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
121
src/main/java/org/cryptomator/common/X509Helper.java
Normal file
121
src/main/java/org/cryptomator/common/X509Helper.java
Normal file
@@ -0,0 +1,121 @@
|
||||
package org.cryptomator.common;
|
||||
|
||||
import com.google.common.io.BaseEncoding;
|
||||
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.cert.CertPath;
|
||||
import java.security.cert.CertPathValidator;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.TrustAnchor;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.security.cert.PKIXParameters;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
final class X509Helper {
|
||||
|
||||
private static final String CERT_BEGIN = "-----BEGIN CERTIFICATE-----";
|
||||
private static final String CERT_END = "-----END CERTIFICATE-----";
|
||||
|
||||
private X509Helper() {
|
||||
}
|
||||
|
||||
static X509Certificate parsePemCertificate(String pemCertificate) {
|
||||
String base64 = pemCertificate.replace(CERT_BEGIN, "").replace(CERT_END, "").replaceAll("\\s", "");
|
||||
byte[] der = BaseEncoding.base64().decode(base64);
|
||||
return parseDerCertificate(der);
|
||||
}
|
||||
|
||||
static List<X509Certificate> parseX5cCertificateChain(List<String> x5cEntries) {
|
||||
List<X509Certificate> certificates = new ArrayList<>(x5cEntries.size());
|
||||
for (String x5cEntry : x5cEntries) {
|
||||
byte[] der = BaseEncoding.base64().decode(x5cEntry);
|
||||
certificates.add(parseDerCertificate(der));
|
||||
}
|
||||
return certificates;
|
||||
}
|
||||
|
||||
static void validateChain(List<X509Certificate> certificateChain, X509Certificate rootCertificate) throws GeneralSecurityException {
|
||||
if (certificateChain.isEmpty()) {
|
||||
throw new IllegalArgumentException("Certificate chain must not be empty.");
|
||||
}
|
||||
|
||||
List<X509Certificate> certPathCertificates = new ArrayList<>(certificateChain);
|
||||
if (rootCertificate.equals(certPathCertificates.get(certPathCertificates.size() - 1))) {
|
||||
certPathCertificates.remove(certPathCertificates.size() - 1);
|
||||
}
|
||||
if (certPathCertificates.isEmpty()) {
|
||||
throw new IllegalArgumentException("Certificate path must contain at least one non-root certificate.");
|
||||
}
|
||||
|
||||
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
|
||||
CertPath certPath = certificateFactory.generateCertPath(certPathCertificates);
|
||||
PKIXParameters params = new PKIXParameters(Set.of(new TrustAnchor(rootCertificate, null)));
|
||||
params.setRevocationEnabled(false);
|
||||
CertPathValidator.getInstance("PKIX").validate(certPath, params);
|
||||
}
|
||||
|
||||
static Optional<String> extractCommonName(X509Certificate cert) {
|
||||
String rfc2253Name = cert.getSubjectX500Principal().getName(X500Principal.RFC2253);
|
||||
for (String rdn : splitRdns(rfc2253Name)) {
|
||||
int equalsPos = rdn.indexOf('=');
|
||||
if (equalsPos > 0 && "CN".equalsIgnoreCase(rdn.substring(0, equalsPos).trim())) {
|
||||
return Optional.of(unescapeRdnValue(rdn.substring(equalsPos + 1).trim()));
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private static List<String> splitRdns(String distinguishedName) {
|
||||
List<String> rdns = new ArrayList<>();
|
||||
StringBuilder current = new StringBuilder();
|
||||
boolean escaped = false;
|
||||
for (int i = 0; i < distinguishedName.length(); i++) {
|
||||
char c = distinguishedName.charAt(i);
|
||||
if (escaped) {
|
||||
current.append(c);
|
||||
escaped = false;
|
||||
} else if (c == '\\') {
|
||||
current.append(c);
|
||||
escaped = true;
|
||||
} else if (c == ',') {
|
||||
rdns.add(current.toString());
|
||||
current.setLength(0);
|
||||
} else {
|
||||
current.append(c);
|
||||
}
|
||||
}
|
||||
rdns.add(current.toString());
|
||||
return rdns;
|
||||
}
|
||||
|
||||
private static String unescapeRdnValue(String value) {
|
||||
StringBuilder unescaped = new StringBuilder(value.length());
|
||||
boolean escaped = false;
|
||||
for (int i = 0; i < value.length(); i++) {
|
||||
char c = value.charAt(i);
|
||||
if (escaped) {
|
||||
unescaped.append(c);
|
||||
escaped = false;
|
||||
} else if (c == '\\') {
|
||||
escaped = true;
|
||||
} else {
|
||||
unescaped.append(c);
|
||||
}
|
||||
}
|
||||
return unescaped.toString();
|
||||
}
|
||||
|
||||
private static X509Certificate parseDerCertificate(byte[] derEncodedCertificate) {
|
||||
try {
|
||||
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
|
||||
return (X509Certificate) certificateFactory.generateCertificate(new ByteArrayInputStream(derEncodedCertificate));
|
||||
} catch (GeneralSecurityException e) {
|
||||
throw new IllegalArgumentException("Invalid certificate.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,25 +9,49 @@ import java.util.Optional;
|
||||
|
||||
public class LicenseCheckerTest {
|
||||
|
||||
@SuppressWarnings("SpellCheckingInspection")
|
||||
private static final String PUBLIC_KEY = """
|
||||
MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBgc4HZz+/fBbC7lmEww0AO3NK9wVZ\
|
||||
PDZ0VEnsaUFLEYpTzb90nITtJUcPUbvOsdZIZ1Q8fnbquAYgxXL5UgHMoywAib47\
|
||||
6MkyyYgPk0BXZq3mq4zImTRNuaU9slj9TVJ3ScT3L1bXwVuPJDzpr5GOFpaj+WwM\
|
||||
Al8G7CqwoJOsW7Kddns=\
|
||||
private static final String LEGACY_PUBLIC_KEY = """
|
||||
MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBiUVQ0HhZMuAOqiO2lPIT+MMSH4bcl\
|
||||
6BOWnFn205bzTcRI9RuRdtrXVNwp/IPtjMVXTj/oW0r12HcrEdLmi9QI6QASTEByW\
|
||||
LNTS/d94IoXmRYQTnC+RtH+H/4I1TWYw90aiig2yV0G1s0qCgAiyKswj+ST6r71NM\
|
||||
/gepmlW3+qiv9/PU=\
|
||||
""";
|
||||
|
||||
private static final String TEST_ROOT_CERT = """
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBpjCCAVigAwIBAgIUJWMTr10U1lkxgPhxjed4kPqSu4EwBQYDK2VwMD8xCzAJ
|
||||
BgNVBAYTAkRFMRYwFAYDVQQKDA1Ta3ltYXRpYyBHbWJIMRgwFgYDVQQDDA9MaWNl
|
||||
bnNlIFRlc3QgQ0EwHhcNMjYwMjI2MTUzMzIwWhcNMzYwMjI0MTUzMzIwWjA/MQsw
|
||||
CQYDVQQGEwJERTEWMBQGA1UECgwNU2t5bWF0aWMgR21iSDEYMBYGA1UEAwwPTGlj
|
||||
ZW5zZSBUZXN0IENBMCowBQYDK2VwAyEAVi5WsfyHgHiL0vr4d2Lt1g7kPgC5m8u0
|
||||
DIKLalKJqHSjZjBkMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEG
|
||||
MB0GA1UdDgQWBBQBiO+yqMTag59eH8fgcF9gMsXeEzAfBgNVHSMEGDAWgBQBiO+y
|
||||
qMTag59eH8fgcF9gMsXeEzAFBgMrZXADQQD1I6bFKdHW+MaSpNVl/seCJny0Tp5L
|
||||
3+v6IyybvV0e66ks8BhsRWbqoSSBEaF4zlX7gAPzNuOIEFadM4s1fVMC
|
||||
-----END CERTIFICATE-----
|
||||
""";
|
||||
|
||||
private static final String TEST_CN = "License Issuer CA (Test)";
|
||||
|
||||
private LicenseChecker licenseChecker;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
licenseChecker = new LicenseChecker(PUBLIC_KEY);
|
||||
licenseChecker = new LicenseChecker(LEGACY_PUBLIC_KEY, TEST_ROOT_CERT, TEST_CN);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckValidLegacyLicense() {
|
||||
String license = "eyJhbGciOiJFUzUxMiJ9.eyJhdWQiOiJDcnlwdG9tYXRvciIsInN1YiI6ImNyeXB0b2JvdEBleGFtcGxlLmNvbSIsImtpZCI6IllFVjFFSXY5dllMR1lfR1RoQ0VPTGtleW1xUDBlZVhVVTdNbWxKaHFnR0EiLCJpc3MiOiJodHRwOlwvXC9sb2NhbGhvc3Q6ODA4MVwvIiwiZXhwIjozMjUwMzY4MDAwMCwiaWF0Ijo5NDY2ODQ4MDAsInNlYXRzIjozfQ.ATHMZ95Z3cx-ghYvbT9XBT-Z-c4BWJOK6WM3JbOjCzIO-3pddYpey0uAfMipIfLzHZypE4NPtNR4nB8z7JRGcqj8AMBpXBxZnDGXsftGHkOuHw6kTq2b-HPmcYBKFZ4hH7ptQRS9byaypFc7ftonLyYODWqar6DXtHSJtlf01jnuAdVi";
|
||||
|
||||
Optional<DecodedJWT> decoded = licenseChecker.check(license);
|
||||
|
||||
Assertions.assertTrue(decoded.isPresent());
|
||||
Assertions.assertEquals("cryptobot@example.com", decoded.get().getSubject());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckValidLicense() {
|
||||
@SuppressWarnings("SpellCheckingInspection")
|
||||
String license = "eyJhbGciOiJFUzUxMiIsInR5cCI6IkpXVCIsImtpZCI6InhaRGZacHJ5NFA5dlpQWnlHMmZOQlJqLTdMejVvbVZkbTd0SG9DZ1NOZlkifQ.eyJzdWIiOiJjcnlwdG9ib3RAZXhhbXBsZS5jb20iLCJpYXQiOjE1MTYyMzkwMjJ9.AQaBIKQdNCxmRJi2wLOcbagTgi39WhdWwgdpKTYSPicg-aPr_tst_RjmnqMemx3cBe0Blr4nEbj_lAtSKHz_i61fAUyI1xCIAZYbK9Q3ICHIHQl3AiuCpBwFl-k81OB4QDYiKpEc9gLN5dhW_VymJMsgOvyiC0UjC91f2AM7s46byDNj";
|
||||
String license = "eyJ4NWMiOlsiTUlJQ0REQ0NBYjZnQXdJQkFnSVVETU96eEpZMzgxSmpkTjgyY1c3cWQrQjN2aDB3QlFZREsyVndNRTR4Q3pBSkJnTlZCQVlUQWtSRk1SWXdGQVlEVlFRS0RBMVRhM2x0WVhScFl5QkhiV0pJTVNjd0pRWURWUVFEREI1TWFXTmxibk5sSUVsdWRHVnliV1ZrYVdGMFpTQkRRU0FvVkdWemRDa3dIaGNOTWpZd01qSTJNVFUwTURNMldoY05Nell3TWpJME1UVTBNRE0yV2pCSU1Rc3dDUVlEVlFRR0V3SkVSVEVXTUJRR0ExVUVDZ3dOVTJ0NWJXRjBhV01nUjIxaVNERWhNQjhHQTFVRUF3d1lUR2xqWlc1elpTQkpjM04xWlhJZ1EwRWdLRlJsYzNRcE1JR2JNQkFHQnlxR1NNNDlBZ0VHQlN1QkJBQWpBNEdHQUFRQmlVVlEwSGhaTXVBT3FpTzJsUElUK01NU0g0YmNsNkJPV25GbjIwNWJ6VGNSSTlSdVJkdHJYVk53cFwvSVB0ak1WWFRqXC9vVzByMTJIY3JFZExtaTlRSTZRQVNURUJ5V0xOVFNcL2Q5NElvWG1SWVFUbkMrUnRIK0hcLzRJMVRXWXc5MGFpaWcyeVYwRzFzMHFDZ0FpeUtzd2orU1Q2cjcxTk1cL2dlcG1sVzMrcWl2OVwvUFdqUWpCQU1CMEdBMVVkRGdRV0JCU05qQnd2K1wvaVlRdnBPT3F6MDJ1N3hhQVNTSVRBZkJnTlZIU01FR0RBV2dCUk1BU3NwMWtpYXdKbThZb0o2KzhcL3NxMjFYNHpBRkJnTXJaWEFEUVFBNE9rXC8reTBiZHptMlJVbWtIZDZRRlM2V2JCS2Y5TzR6ejNVYzdpQk1wS0lxMWtCbHErN1RiYmdNSEp1K2FZYk9EY1JXVCsrNXN4NGkyT3Nwa2dPc0oiLCJNSUlCdFRDQ0FXZWdBd0lCQWdJVUpteDhVcXRnbktjYXVRYnFiMDRUYVVCRytVSXdCUVlESzJWd01EOHhDekFKQmdOVkJBWVRBa1JGTVJZd0ZBWURWUVFLREExVGEzbHRZWFJwWXlCSGJXSklNUmd3RmdZRFZRUUREQTlNYVdObGJuTmxJRlJsYzNRZ1EwRXdIaGNOTWpZd01qSTJNVFV6TmpNMldoY05Nell3TWpJME1UVXpOak0yV2pCT01Rc3dDUVlEVlFRR0V3SkVSVEVXTUJRR0ExVUVDZ3dOVTJ0NWJXRjBhV01nUjIxaVNERW5NQ1VHQTFVRUF3d2VUR2xqWlc1elpTQkpiblJsY20xbFpHbGhkR1VnUTBFZ0tGUmxjM1FwTUNvd0JRWURLMlZ3QXlFQUczdnI4Tks3WVpzMXE2cFF0SmhIRGJUMnhNRDNDMnlzbXNuZW13MUZRbGFqWmpCa01CSUdBMVVkRXdFQlwvd1FJTUFZQkFmOENBUUF3RGdZRFZSMFBBUUhcL0JBUURBZ0VHTUIwR0ExVWREZ1FXQkJSTUFTc3Axa2lhd0ptOFlvSjYrOFwvc3EyMVg0ekFmQmdOVkhTTUVHREFXZ0JRQmlPK3lxTVRhZzU5ZUg4ZmdjRjlnTXNYZUV6QUZCZ01yWlhBRFFRQktkR0cybmpWa3JqMEwxbWVXVTROcGxaZHlHUTJxYUNxNFBSenk1OUg5WW1EUzc5M1JsTWE0TU9ad0FtVGtVUTV2YWt1dnR6MTM0SWl6NmpKa0RCZ0YiXSwiYWxnIjoiRVM1MTIifQ.eyJhdWQiOiJDcnlwdG9tYXRvciIsInN1YiI6ImNyeXB0b2JvdEBleGFtcGxlLmNvbSIsImtpZCI6IllFVjFFSXY5dllMR1lfR1RoQ0VPTGtleW1xUDBlZVhVVTdNbWxKaHFnR0EiLCJpc3MiOiJodHRwOlwvXC9sb2NhbGhvc3Q6ODA4MVwvIiwiZXhwIjozMjUwMzY4MDAwMCwiaWF0Ijo5NDY2ODQ4MDAsInNlYXRzIjozfQ.AMBwG0CnIu8FHLsmynfT-JHwE-pwjXGh8SoExaYWY6n88cL18gzI_tYl3cjZSvLVZImg-VRZi7SkhDVt5zrOXX12AdNst1jJc0HJIA0dJUiM22b3XmkIjionTXmK-Njgp9XIQV4qtYoFPXjsL4KKTa95yx5oTvDD7ZAHFxur5_nN3y4t";
|
||||
|
||||
Optional<DecodedJWT> decoded = licenseChecker.check(license);
|
||||
|
||||
@@ -37,8 +61,7 @@ public class LicenseCheckerTest {
|
||||
|
||||
@Test
|
||||
public void testCheckInvalidLicenseHeader() {
|
||||
@SuppressWarnings("SpellCheckingInspection")
|
||||
String license = "EyJhbGciOiJFUzUxMiIsInR5cCI6IkpXVCIsImtpZCI6InhaRGZacHJ5NFA5dlpQWnlHMmZOQlJqLTdMejVvbVZkbTd0SG9DZ1NOZlkifQ.eyJzdWIiOiJjcnlwdG9ib3RAZXhhbXBsZS5jb20iLCJpYXQiOjE1MTYyMzkwMjJ9.AQaBIKQdNCxmRJi2wLOcbagTgi39WhdWwgdpKTYSPicg-aPr_tst_RjmnqMemx3cBe0Blr4nEbj_lAtSKHz_i61fAUyI1xCIAZYbK9Q3ICHIHQl3AiuCpBwFl-k81OB4QDYiKpEc9gLN5dhW_VymJMsgOvyiC0UjC91f2AM7s46byDNj";
|
||||
String license = "EyJ4NWMiOlsiTUlJQ0REQ0NBYjZnQXdJQkFnSVVETU96eEpZMzgxSmpkTjgyY1c3cWQrQjN2aDB3QlFZREsyVndNRTR4Q3pBSkJnTlZCQVlUQWtSRk1SWXdGQVlEVlFRS0RBMVRhM2x0WVhScFl5QkhiV0pJTVNjd0pRWURWUVFEREI1TWFXTmxibk5sSUVsdWRHVnliV1ZrYVdGMFpTQkRRU0FvVkdWemRDa3dIaGNOTWpZd01qSTJNVFUwTURNMldoY05Nell3TWpJME1UVTBNRE0yV2pCSU1Rc3dDUVlEVlFRR0V3SkVSVEVXTUJRR0ExVUVDZ3dOVTJ0NWJXRjBhV01nUjIxaVNERWhNQjhHQTFVRUF3d1lUR2xqWlc1elpTQkpjM04xWlhJZ1EwRWdLRlJsYzNRcE1JR2JNQkFHQnlxR1NNNDlBZ0VHQlN1QkJBQWpBNEdHQUFRQmlVVlEwSGhaTXVBT3FpTzJsUElUK01NU0g0YmNsNkJPV25GbjIwNWJ6VGNSSTlSdVJkdHJYVk53cFwvSVB0ak1WWFRqXC9vVzByMTJIY3JFZExtaTlRSTZRQVNURUJ5V0xOVFNcL2Q5NElvWG1SWVFUbkMrUnRIK0hcLzRJMVRXWXc5MGFpaWcyeVYwRzFzMHFDZ0FpeUtzd2orU1Q2cjcxTk1cL2dlcG1sVzMrcWl2OVwvUFdqUWpCQU1CMEdBMVVkRGdRV0JCU05qQnd2K1wvaVlRdnBPT3F6MDJ1N3hhQVNTSVRBZkJnTlZIU01FR0RBV2dCUk1BU3NwMWtpYXdKbThZb0o2KzhcL3NxMjFYNHpBRkJnTXJaWEFEUVFBNE9rXC8reTBiZHptMlJVbWtIZDZRRlM2V2JCS2Y5TzR6ejNVYzdpQk1wS0lxMWtCbHErN1RiYmdNSEp1K2FZYk9EY1JXVCsrNXN4NGkyT3Nwa2dPc0oiLCJNSUlCdFRDQ0FXZWdBd0lCQWdJVUpteDhVcXRnbktjYXVRYnFiMDRUYVVCRytVSXdCUVlESzJWd01EOHhDekFKQmdOVkJBWVRBa1JGTVJZd0ZBWURWUVFLREExVGEzbHRZWFJwWXlCSGJXSklNUmd3RmdZRFZRUUREQTlNYVdObGJuTmxJRlJsYzNRZ1EwRXdIaGNOTWpZd01qSTJNVFV6TmpNMldoY05Nell3TWpJME1UVXpOak0yV2pCT01Rc3dDUVlEVlFRR0V3SkVSVEVXTUJRR0ExVUVDZ3dOVTJ0NWJXRjBhV01nUjIxaVNERW5NQ1VHQTFVRUF3d2VUR2xqWlc1elpTQkpiblJsY20xbFpHbGhkR1VnUTBFZ0tGUmxjM1FwTUNvd0JRWURLMlZ3QXlFQUczdnI4Tks3WVpzMXE2cFF0SmhIRGJUMnhNRDNDMnlzbXNuZW13MUZRbGFqWmpCa01CSUdBMVVkRXdFQlwvd1FJTUFZQkFmOENBUUF3RGdZRFZSMFBBUUhcL0JBUURBZ0VHTUIwR0ExVWREZ1FXQkJSTUFTc3Axa2lhd0ptOFlvSjYrOFwvc3EyMVg0ekFmQmdOVkhTTUVHREFXZ0JRQmlPK3lxTVRhZzU5ZUg4ZmdjRjlnTXNYZUV6QUZCZ01yWlhBRFFRQktkR0cybmpWa3JqMEwxbWVXVTROcGxaZHlHUTJxYUNxNFBSenk1OUg5WW1EUzc5M1JsTWE0TU9ad0FtVGtVUTV2YWt1dnR6MTM0SWl6NmpKa0RCZ0YiXSwiYWxnIjoiRVM1MTIifQ.eyJhdWQiOiJDcnlwdG9tYXRvciIsInN1YiI6ImNyeXB0b2JvdEBleGFtcGxlLmNvbSIsImtpZCI6IllFVjFFSXY5dllMR1lfR1RoQ0VPTGtleW1xUDBlZVhVVTdNbWxKaHFnR0EiLCJpc3MiOiJodHRwOlwvXC9sb2NhbGhvc3Q6ODA4MVwvIiwiZXhwIjozMjUwMzY4MDAwMCwiaWF0Ijo5NDY2ODQ4MDAsInNlYXRzIjozfQ.AMBwG0CnIu8FHLsmynfT-JHwE-pwjXGh8SoExaYWY6n88cL18gzI_tYl3cjZSvLVZImg-VRZi7SkhDVt5zrOXX12AdNst1jJc0HJIA0dJUiM22b3XmkIjionTXmK-Njgp9XIQV4qtYoFPXjsL4KKTa95yx5oTvDD7ZAHFxur5_nN3y4t";
|
||||
|
||||
Optional<DecodedJWT> decoded = licenseChecker.check(license);
|
||||
|
||||
@@ -47,8 +70,7 @@ public class LicenseCheckerTest {
|
||||
|
||||
@Test
|
||||
public void testCheckInvalidLicensePayload() {
|
||||
@SuppressWarnings("SpellCheckingInspection")
|
||||
String license = "eyJhbGciOiJFUzUxMiIsInR5cCI6IkpXVCIsImtpZCI6InhaRGZacHJ5NFA5dlpQWnlHMmZOQlJqLTdMejVvbVZkbTd0SG9DZ1NOZlkifQ.EyJzdWIiOiJjcnlwdG9ib3RAZXhhbXBsZS5jb20iLCJpYXQiOjE1MTYyMzkwMjJ9.AQaBIKQdNCxmRJi2wLOcbagTgi39WhdWwgdpKTYSPicg-aPr_tst_RjmnqMemx3cBe0Blr4nEbj_lAtSKHz_i61fAUyI1xCIAZYbK9Q3ICHIHQl3AiuCpBwFl-k81OB4QDYiKpEc9gLN5dhW_VymJMsgOvyiC0UjC91f2AM7s46byDNj";
|
||||
String license = "eyJ4NWMiOlsiTUlJQ0REQ0NBYjZnQXdJQkFnSVVETU96eEpZMzgxSmpkTjgyY1c3cWQrQjN2aDB3QlFZREsyVndNRTR4Q3pBSkJnTlZCQVlUQWtSRk1SWXdGQVlEVlFRS0RBMVRhM2x0WVhScFl5QkhiV0pJTVNjd0pRWURWUVFEREI1TWFXTmxibk5sSUVsdWRHVnliV1ZrYVdGMFpTQkRRU0FvVkdWemRDa3dIaGNOTWpZd01qSTJNVFUwTURNMldoY05Nell3TWpJME1UVTBNRE0yV2pCSU1Rc3dDUVlEVlFRR0V3SkVSVEVXTUJRR0ExVUVDZ3dOVTJ0NWJXRjBhV01nUjIxaVNERWhNQjhHQTFVRUF3d1lUR2xqWlc1elpTQkpjM04xWlhJZ1EwRWdLRlJsYzNRcE1JR2JNQkFHQnlxR1NNNDlBZ0VHQlN1QkJBQWpBNEdHQUFRQmlVVlEwSGhaTXVBT3FpTzJsUElUK01NU0g0YmNsNkJPV25GbjIwNWJ6VGNSSTlSdVJkdHJYVk53cFwvSVB0ak1WWFRqXC9vVzByMTJIY3JFZExtaTlRSTZRQVNURUJ5V0xOVFNcL2Q5NElvWG1SWVFUbkMrUnRIK0hcLzRJMVRXWXc5MGFpaWcyeVYwRzFzMHFDZ0FpeUtzd2orU1Q2cjcxTk1cL2dlcG1sVzMrcWl2OVwvUFdqUWpCQU1CMEdBMVVkRGdRV0JCU05qQnd2K1wvaVlRdnBPT3F6MDJ1N3hhQVNTSVRBZkJnTlZIU01FR0RBV2dCUk1BU3NwMWtpYXdKbThZb0o2KzhcL3NxMjFYNHpBRkJnTXJaWEFEUVFBNE9rXC8reTBiZHptMlJVbWtIZDZRRlM2V2JCS2Y5TzR6ejNVYzdpQk1wS0lxMWtCbHErN1RiYmdNSEp1K2FZYk9EY1JXVCsrNXN4NGkyT3Nwa2dPc0oiLCJNSUlCdFRDQ0FXZWdBd0lCQWdJVUpteDhVcXRnbktjYXVRYnFiMDRUYVVCRytVSXdCUVlESzJWd01EOHhDekFKQmdOVkJBWVRBa1JGTVJZd0ZBWURWUVFLREExVGEzbHRZWFJwWXlCSGJXSklNUmd3RmdZRFZRUUREQTlNYVdObGJuTmxJRlJsYzNRZ1EwRXdIaGNOTWpZd01qSTJNVFV6TmpNMldoY05Nell3TWpJME1UVXpOak0yV2pCT01Rc3dDUVlEVlFRR0V3SkVSVEVXTUJRR0ExVUVDZ3dOVTJ0NWJXRjBhV01nUjIxaVNERW5NQ1VHQTFVRUF3d2VUR2xqWlc1elpTQkpiblJsY20xbFpHbGhkR1VnUTBFZ0tGUmxjM1FwTUNvd0JRWURLMlZ3QXlFQUczdnI4Tks3WVpzMXE2cFF0SmhIRGJUMnhNRDNDMnlzbXNuZW13MUZRbGFqWmpCa01CSUdBMVVkRXdFQlwvd1FJTUFZQkFmOENBUUF3RGdZRFZSMFBBUUhcL0JBUURBZ0VHTUIwR0ExVWREZ1FXQkJSTUFTc3Axa2lhd0ptOFlvSjYrOFwvc3EyMVg0ekFmQmdOVkhTTUVHREFXZ0JRQmlPK3lxTVRhZzU5ZUg4ZmdjRjlnTXNYZUV6QUZCZ01yWlhBRFFRQktkR0cybmpWa3JqMEwxbWVXVTROcGxaZHlHUTJxYUNxNFBSenk1OUg5WW1EUzc5M1JsTWE0TU9ad0FtVGtVUTV2YWt1dnR6MTM0SWl6NmpKa0RCZ0YiXSwiYWxnIjoiRVM1MTIifQ.EyJhdWQiOiJDcnlwdG9tYXRvciIsInN1YiI6ImNyeXB0b2JvdEBleGFtcGxlLmNvbSIsImtpZCI6IllFVjFFSXY5dllMR1lfR1RoQ0VPTGtleW1xUDBlZVhVVTdNbWxKaHFnR0EiLCJpc3MiOiJodHRwOlwvXC9sb2NhbGhvc3Q6ODA4MVwvIiwiZXhwIjozMjUwMzY4MDAwMCwiaWF0Ijo5NDY2ODQ4MDAsInNlYXRzIjozfQ.AMBwG0CnIu8FHLsmynfT-JHwE-pwjXGh8SoExaYWY6n88cL18gzI_tYl3cjZSvLVZImg-VRZi7SkhDVt5zrOXX12AdNst1jJc0HJIA0dJUiM22b3XmkIjionTXmK-Njgp9XIQV4qtYoFPXjsL4KKTa95yx5oTvDD7ZAHFxur5_nN3y4t";
|
||||
|
||||
Optional<DecodedJWT> decoded = licenseChecker.check(license);
|
||||
|
||||
@@ -57,12 +79,11 @@ public class LicenseCheckerTest {
|
||||
|
||||
@Test
|
||||
public void testCheckInvalidLicenseSignature() {
|
||||
@SuppressWarnings("SpellCheckingInspection")
|
||||
String license = "eyJhbGciOiJFUzUxMiIsInR5cCI6IkpXVCIsImtpZCI6InhaRGZacHJ5NFA5dlpQWnlHMmZOQlJqLTdMejVvbVZkbTd0SG9DZ1NOZlkifQ.eyJzdWIiOiJjcnlwdG9ib3RAZXhhbXBsZS5jb20iLCJpYXQiOjE1MTYyMzkwMjJ9.aQaBIKQdNCxmRJi2wLOcbagTgi39WhdWwgdpKTYSPicg-aPr_tst_RjmnqMemx3cBe0Blr4nEbj_lAtSKHz_i61fAUyI1xCIAZYbK9Q3ICHIHQl3AiuCpBwFl-k81OB4QDYiKpEc9gLN5dhW_VymJMsgOvyiC0UjC91f2AM7s46byDNj";
|
||||
String license = "eyJ4NWMiOlsiTUlJQ0REQ0NBYjZnQXdJQkFnSVVETU96eEpZMzgxSmpkTjgyY1c3cWQrQjN2aDB3QlFZREsyVndNRTR4Q3pBSkJnTlZCQVlUQWtSRk1SWXdGQVlEVlFRS0RBMVRhM2x0WVhScFl5QkhiV0pJTVNjd0pRWURWUVFEREI1TWFXTmxibk5sSUVsdWRHVnliV1ZrYVdGMFpTQkRRU0FvVkdWemRDa3dIaGNOTWpZd01qSTJNVFUwTURNMldoY05Nell3TWpJME1UVTBNRE0yV2pCSU1Rc3dDUVlEVlFRR0V3SkVSVEVXTUJRR0ExVUVDZ3dOVTJ0NWJXRjBhV01nUjIxaVNERWhNQjhHQTFVRUF3d1lUR2xqWlc1elpTQkpjM04xWlhJZ1EwRWdLRlJsYzNRcE1JR2JNQkFHQnlxR1NNNDlBZ0VHQlN1QkJBQWpBNEdHQUFRQmlVVlEwSGhaTXVBT3FpTzJsUElUK01NU0g0YmNsNkJPV25GbjIwNWJ6VGNSSTlSdVJkdHJYVk53cFwvSVB0ak1WWFRqXC9vVzByMTJIY3JFZExtaTlRSTZRQVNURUJ5V0xOVFNcL2Q5NElvWG1SWVFUbkMrUnRIK0hcLzRJMVRXWXc5MGFpaWcyeVYwRzFzMHFDZ0FpeUtzd2orU1Q2cjcxTk1cL2dlcG1sVzMrcWl2OVwvUFdqUWpCQU1CMEdBMVVkRGdRV0JCU05qQnd2K1wvaVlRdnBPT3F6MDJ1N3hhQVNTSVRBZkJnTlZIU01FR0RBV2dCUk1BU3NwMWtpYXdKbThZb0o2KzhcL3NxMjFYNHpBRkJnTXJaWEFEUVFBNE9rXC8reTBiZHptMlJVbWtIZDZRRlM2V2JCS2Y5TzR6ejNVYzdpQk1wS0lxMWtCbHErN1RiYmdNSEp1K2FZYk9EY1JXVCsrNXN4NGkyT3Nwa2dPc0oiLCJNSUlCdFRDQ0FXZWdBd0lCQWdJVUpteDhVcXRnbktjYXVRYnFiMDRUYVVCRytVSXdCUVlESzJWd01EOHhDekFKQmdOVkJBWVRBa1JGTVJZd0ZBWURWUVFLREExVGEzbHRZWFJwWXlCSGJXSklNUmd3RmdZRFZRUUREQTlNYVdObGJuTmxJRlJsYzNRZ1EwRXdIaGNOTWpZd01qSTJNVFV6TmpNMldoY05Nell3TWpJME1UVXpOak0yV2pCT01Rc3dDUVlEVlFRR0V3SkVSVEVXTUJRR0ExVUVDZ3dOVTJ0NWJXRjBhV01nUjIxaVNERW5NQ1VHQTFVRUF3d2VUR2xqWlc1elpTQkpiblJsY20xbFpHbGhkR1VnUTBFZ0tGUmxjM1FwTUNvd0JRWURLMlZ3QXlFQUczdnI4Tks3WVpzMXE2cFF0SmhIRGJUMnhNRDNDMnlzbXNuZW13MUZRbGFqWmpCa01CSUdBMVVkRXdFQlwvd1FJTUFZQkFmOENBUUF3RGdZRFZSMFBBUUhcL0JBUURBZ0VHTUIwR0ExVWREZ1FXQkJSTUFTc3Axa2lhd0ptOFlvSjYrOFwvc3EyMVg0ekFmQmdOVkhTTUVHREFXZ0JRQmlPK3lxTVRhZzU5ZUg4ZmdjRjlnTXNYZUV6QUZCZ01yWlhBRFFRQktkR0cybmpWa3JqMEwxbWVXVTROcGxaZHlHUTJxYUNxNFBSenk1OUg5WW1EUzc5M1JsTWE0TU9ad0FtVGtVUTV2YWt1dnR6MTM0SWl6NmpKa0RCZ0YiXSwiYWxnIjoiRVM1MTIifQ.eyJhdWQiOiJDcnlwdG9tYXRvciIsInN1YiI6ImNyeXB0b2JvdEBleGFtcGxlLmNvbSIsImtpZCI6IllFVjFFSXY5dllMR1lfR1RoQ0VPTGtleW1xUDBlZVhVVTdNbWxKaHFnR0EiLCJpc3MiOiJodHRwOlwvXC9sb2NhbGhvc3Q6ODA4MVwvIiwiZXhwIjozMjUwMzY4MDAwMCwiaWF0Ijo5NDY2ODQ4MDAsInNlYXRzIjozfQ.AMBwG0CnIu8FHLsmynfT-JHwE-pwjXGh8SoExaYWY6n88cL18gzI_tYl3cjZSvLVZImg-VRZi7SkhDVt5zrOXX12AdNst1jJc0HJIA0dJUiM22b3XmkIjionTXmK-Njgp9XIQV4qtYoFPXjsL4KKTa95yx5oTvDD7ZAHFxur5_nN3y4T";
|
||||
|
||||
Optional<DecodedJWT> decoded = licenseChecker.check(license);
|
||||
|
||||
Assertions.assertFalse(decoded.isPresent());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user