From a739ac5070d87651dcd2a0a95209b9344b33f955 Mon Sep 17 00:00:00 2001 From: Mart Somermaa Date: Sat, 16 Jan 2021 01:22:58 +0200 Subject: [PATCH] feat: add SubjectCertificatePolicyValidator (#1) Signed-off-by: Mart Somermaa --- ...rCertificateDisallowedPolicyException.java | 10 ++++ ...UserCertificateInvalidPolicyException.java | 10 ++++ .../util/SubjectCertificatePolicies.java | 12 +++++ .../AuthTokenValidationConfiguration.java | 17 ++++-- .../validator/AuthTokenValidatorBuilder.java | 19 ++++++- .../validator/AuthTokenValidatorImpl.java | 3 +- .../SubjectCertificatePolicyValidator.java | 52 +++++++++++++++++++ .../testutil/AuthTokenValidators.java | 8 +++ .../org/webeid/security/testutil/Tokens.java | 6 ++- ...SubjectCertificatePolicyValidatorTest.java | 34 ++++++++++++ .../webeid/security/validator/X5cTest.java | 15 ++++-- 11 files changed, 176 insertions(+), 10 deletions(-) create mode 100644 src/main/java/org/webeid/security/exceptions/UserCertificateDisallowedPolicyException.java create mode 100644 src/main/java/org/webeid/security/exceptions/UserCertificateInvalidPolicyException.java create mode 100644 src/main/java/org/webeid/security/util/SubjectCertificatePolicies.java create mode 100644 src/main/java/org/webeid/security/validator/validators/SubjectCertificatePolicyValidator.java create mode 100644 src/test/java/org/webeid/security/validator/SubjectCertificatePolicyValidatorTest.java diff --git a/src/main/java/org/webeid/security/exceptions/UserCertificateDisallowedPolicyException.java b/src/main/java/org/webeid/security/exceptions/UserCertificateDisallowedPolicyException.java new file mode 100644 index 00000000..f7e3b045 --- /dev/null +++ b/src/main/java/org/webeid/security/exceptions/UserCertificateDisallowedPolicyException.java @@ -0,0 +1,10 @@ +package org.webeid.security.exceptions; + +/** + * Thrown when any of the configured disallowed policies is present in the user certificate. + */ +public class UserCertificateDisallowedPolicyException extends TokenValidationException { + public UserCertificateDisallowedPolicyException() { + super("Disallowed user certificate policy"); + } +} diff --git a/src/main/java/org/webeid/security/exceptions/UserCertificateInvalidPolicyException.java b/src/main/java/org/webeid/security/exceptions/UserCertificateInvalidPolicyException.java new file mode 100644 index 00000000..fb2143ff --- /dev/null +++ b/src/main/java/org/webeid/security/exceptions/UserCertificateInvalidPolicyException.java @@ -0,0 +1,10 @@ +package org.webeid.security.exceptions; + +/** + * Thrown when the user certificate policy is invalid. + */ +public class UserCertificateInvalidPolicyException extends TokenValidationException { + public UserCertificateInvalidPolicyException() { + super("User certificate policy is invalid"); + } +} diff --git a/src/main/java/org/webeid/security/util/SubjectCertificatePolicies.java b/src/main/java/org/webeid/security/util/SubjectCertificatePolicies.java new file mode 100644 index 00000000..5bbaf6b9 --- /dev/null +++ b/src/main/java/org/webeid/security/util/SubjectCertificatePolicies.java @@ -0,0 +1,12 @@ +package org.webeid.security.util; + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; + +public final class SubjectCertificatePolicies { + + public static final ASN1ObjectIdentifier EST_MOBILE_ID_POLICY = new ASN1ObjectIdentifier("1.3.6.1.4.1.10015.1.3"); + + private SubjectCertificatePolicies() { + throw new IllegalStateException("Constants class"); + } +} diff --git a/src/main/java/org/webeid/security/validator/AuthTokenValidationConfiguration.java b/src/main/java/org/webeid/security/validator/AuthTokenValidationConfiguration.java index 55fa4723..0fdc73fe 100644 --- a/src/main/java/org/webeid/security/validator/AuthTokenValidationConfiguration.java +++ b/src/main/java/org/webeid/security/validator/AuthTokenValidationConfiguration.java @@ -22,6 +22,8 @@ package org.webeid.security.validator; +import com.google.common.collect.Sets; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.webeid.security.validator.validators.OriginValidator; import javax.cache.Cache; @@ -29,11 +31,12 @@ import java.security.cert.X509Certificate; import java.time.Duration; import java.time.LocalDateTime; -import java.util.ArrayList; import java.util.Collection; +import java.util.HashSet; import java.util.Objects; import static org.webeid.security.nonce.NonceGeneratorBuilder.requirePositiveDuration; +import static org.webeid.security.util.SubjectCertificatePolicies.EST_MOBILE_ID_POLICY; /** * Stores configuration parameters for {@link AuthTokenValidatorImpl}. @@ -42,12 +45,14 @@ final class AuthTokenValidationConfiguration { private URI siteOrigin; private Cache nonceCache; - private Collection trustedCACertificates = new ArrayList<>(); + private Collection trustedCACertificates = new HashSet<>(); private boolean isUserCertificateRevocationCheckWithOcspEnabled = true; private Duration ocspRequestTimeout = Duration.ofSeconds(5); private Duration allowedClientClockSkew = Duration.ofMinutes(3); private boolean isSiteCertificateFingerprintValidationEnabled = false; private String siteCertificateSha256Fingerprint; + // Don't allow Estonian Mobile-ID policy by default. + private Collection disallowedSubjectCertificatePolicies = Sets.newHashSet(EST_MOBILE_ID_POLICY); AuthTokenValidationConfiguration() { } @@ -55,12 +60,13 @@ final class AuthTokenValidationConfiguration { private AuthTokenValidationConfiguration(AuthTokenValidationConfiguration other) { this.siteOrigin = other.siteOrigin; this.nonceCache = other.nonceCache; - this.trustedCACertificates = new ArrayList<>(other.trustedCACertificates); + this.trustedCACertificates = new HashSet<>(other.trustedCACertificates); this.isUserCertificateRevocationCheckWithOcspEnabled = other.isUserCertificateRevocationCheckWithOcspEnabled; this.ocspRequestTimeout = other.ocspRequestTimeout; this.allowedClientClockSkew = other.allowedClientClockSkew; this.isSiteCertificateFingerprintValidationEnabled = other.isSiteCertificateFingerprintValidationEnabled; this.siteCertificateSha256Fingerprint = other.siteCertificateSha256Fingerprint; + this.disallowedSubjectCertificatePolicies = new HashSet<>(other.disallowedSubjectCertificatePolicies); } void setSiteOrigin(URI siteOrigin) { @@ -144,4 +150,9 @@ void validate() { AuthTokenValidationConfiguration copy() { return new AuthTokenValidationConfiguration(this); } + + public Collection getDisallowedSubjectCertificatePolicies() { + return disallowedSubjectCertificatePolicies; + } + } diff --git a/src/main/java/org/webeid/security/validator/AuthTokenValidatorBuilder.java b/src/main/java/org/webeid/security/validator/AuthTokenValidatorBuilder.java index fbeeb2f1..3b4151ba 100644 --- a/src/main/java/org/webeid/security/validator/AuthTokenValidatorBuilder.java +++ b/src/main/java/org/webeid/security/validator/AuthTokenValidatorBuilder.java @@ -22,6 +22,7 @@ package org.webeid.security.validator; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,7 +31,7 @@ import java.security.cert.X509Certificate; import java.time.Duration; import java.time.LocalDateTime; -import java.util.Arrays; +import java.util.Collections; /** * Builder for constructing {@link AuthTokenValidator} instances. @@ -81,11 +82,25 @@ public AuthTokenValidatorBuilder withNonceCache(Cache cac * @return the builder instance for method chaining */ public AuthTokenValidatorBuilder withTrustedCertificateAuthorities(X509Certificate... certificates) { - configuration.getTrustedCACertificates().addAll(Arrays.asList(certificates)); + Collections.addAll(configuration.getTrustedCACertificates(), certificates); LOG.debug("Trusted certificate authorities set to {}", configuration.getTrustedCACertificates()); return this; } + /** + * Sets the list of disallowed user certificate policies. + * In order for the user certificate to be considered valid, it must not contain any policies + * present in this list. + * + * @param policies disallowed user certificate policies + * @return the builder instance for method chaining + */ + public AuthTokenValidatorBuilder withDisallowedCertificatePolicies(ASN1ObjectIdentifier... policies) { + Collections.addAll(configuration.getDisallowedSubjectCertificatePolicies(), policies); + LOG.debug("Disallowed subject certificate policies set to {}", configuration.getDisallowedSubjectCertificatePolicies()); + return this; + } + /** * Turns off user certificate revocation check with OCSP. *

diff --git a/src/main/java/org/webeid/security/validator/AuthTokenValidatorImpl.java b/src/main/java/org/webeid/security/validator/AuthTokenValidatorImpl.java index 291856da..17367d8b 100644 --- a/src/main/java/org/webeid/security/validator/AuthTokenValidatorImpl.java +++ b/src/main/java/org/webeid/security/validator/AuthTokenValidatorImpl.java @@ -72,7 +72,8 @@ final class AuthTokenValidatorImpl implements AuthTokenValidator { simpleSubjectCertificateValidators = ValidatorBatch.createFrom( FunctionalSubjectCertificateValidators::validateCertificateExpiry, - FunctionalSubjectCertificateValidators::validateCertificatePurpose + FunctionalSubjectCertificateValidators::validateCertificatePurpose, + new SubjectCertificatePolicyValidator(configuration.getDisallowedSubjectCertificatePolicies())::validateCertificatePolicies ); tokenBodyValidators = ValidatorBatch.createFrom( new NonceValidator(configuration.getNonceCache())::validateNonce, diff --git a/src/main/java/org/webeid/security/validator/validators/SubjectCertificatePolicyValidator.java b/src/main/java/org/webeid/security/validator/validators/SubjectCertificatePolicyValidator.java new file mode 100644 index 00000000..6f9c0334 --- /dev/null +++ b/src/main/java/org/webeid/security/validator/validators/SubjectCertificatePolicyValidator.java @@ -0,0 +1,52 @@ +package org.webeid.security.validator.validators; + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.x509.CertificatePolicies; +import org.bouncycastle.asn1.x509.Extension; +import org.bouncycastle.asn1.x509.PolicyInformation; +import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils; +import org.webeid.security.exceptions.TokenValidationException; +import org.webeid.security.exceptions.UserCertificateDisallowedPolicyException; +import org.webeid.security.exceptions.UserCertificateInvalidPolicyException; +import org.webeid.security.validator.AuthTokenValidatorData; + +import java.io.IOException; +import java.security.cert.X509Certificate; +import java.util.Arrays; +import java.util.Collection; +import java.util.Optional; + +public class SubjectCertificatePolicyValidator { + + private final Collection disallowedSubjectCertificatePolicies; + + public SubjectCertificatePolicyValidator(Collection disallowedSubjectCertificatePolicies) { + this.disallowedSubjectCertificatePolicies = disallowedSubjectCertificatePolicies; + } + + /** + * Validates that the user certificate policies match the configured policies. + * + * @param actualTokenData authentication token data that contains the user certificate. + * @throws UserCertificateDisallowedPolicyException when user certificate policy does not match the configured policies. + * @throws UserCertificateInvalidPolicyException when user certificate policy is invalid. + */ + public void validateCertificatePolicies(AuthTokenValidatorData actualTokenData) throws TokenValidationException { + final X509Certificate certificate = actualTokenData.getSubjectCertificate(); + final byte[] extensionValue = certificate.getExtensionValue(Extension.certificatePolicies.getId()); + try { + final CertificatePolicies policies = CertificatePolicies.getInstance( + JcaX509ExtensionUtils.parseExtensionValue(extensionValue) + ); + final Optional disallowedPolicy = Arrays.stream(policies.getPolicyInformation()) + .filter(policyInformation -> + disallowedSubjectCertificatePolicies.contains(policyInformation.getPolicyIdentifier())) + .findFirst(); + if (disallowedPolicy.isPresent()) { + throw new UserCertificateDisallowedPolicyException(); + } + } catch (IOException e) { + throw new UserCertificateInvalidPolicyException(); + } + } +} diff --git a/src/test/java/org/webeid/security/testutil/AuthTokenValidators.java b/src/test/java/org/webeid/security/testutil/AuthTokenValidators.java index 6a91fdd7..76faef68 100644 --- a/src/test/java/org/webeid/security/testutil/AuthTokenValidators.java +++ b/src/test/java/org/webeid/security/testutil/AuthTokenValidators.java @@ -22,6 +22,7 @@ package org.webeid.security.testutil; +import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.webeid.security.validator.AuthTokenValidator; import org.webeid.security.validator.AuthTokenValidatorBuilder; @@ -34,6 +35,7 @@ public final class AuthTokenValidators { private static final String TOKEN_ORIGIN_URL = "https://ria.ee"; + private static final ASN1ObjectIdentifier EST_IDEMIA_POLICY = new ASN1ObjectIdentifier("1.3.6.1.4.1.51361.1.2.1"); public static AuthTokenValidator getAuthTokenValidator(Cache cache) throws CertificateException { return getAuthTokenValidator(TOKEN_ORIGIN_URL, cache); @@ -65,6 +67,12 @@ public static AuthTokenValidator getAuthTokenValidatorWithWrongTrustedCA(Cache cache) throws CertificateException { + return getAuthTokenValidatorBuilder(TOKEN_ORIGIN_URL, cache, getCACertificates()) + .withDisallowedCertificatePolicies(EST_IDEMIA_POLICY) + .build(); + } + private static AuthTokenValidatorBuilder getAuthTokenValidatorBuilder(String uri, Cache cache, X509Certificate[] certificates) { return new AuthTokenValidatorBuilder() .withSiteOrigin(URI.create(uri)) diff --git a/src/test/java/org/webeid/security/testutil/Tokens.java b/src/test/java/org/webeid/security/testutil/Tokens.java index 2901e9bc..092bb07d 100644 --- a/src/test/java/org/webeid/security/testutil/Tokens.java +++ b/src/test/java/org/webeid/security/testutil/Tokens.java @@ -91,11 +91,15 @@ public final class Tokens { //----------------------------------------------------------------------------------------------------------------- public static final String TOKEN_TOO_SHORT = new String(new char[99]); - public static final String TOKEN_TOO_LONG = new String(new char[10001]); //----------------------------------------------------------------------------------------------------------------- + public static final String X5C_WRONG_POLICY_CERTIFICATE = "eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiIsIng1YyI6WyJNSUlFQVRDQ0EyT2dBd0lCQWdJUU9Xa0JXWE5ESm0xYnlGZDNYc1drdmpBS0JnZ3Foa2pPUFFRREJEQmdNUXN3Q1FZRFZRUUdFd0pGUlRFYk1Ca0dBMVVFQ2d3U1Uwc2dTVVFnVTI5c2RYUnBiMjV6SUVGVE1SY3dGUVlEVlFSaERBNU9WRkpGUlMweE1EYzBOekF4TXpFYk1Ca0dBMVVFQXd3U1ZFVlRWQ0J2WmlCRlUxUkZTVVF5TURFNE1CNFhEVEU0TVRBeE9EQTVOVEEwTjFvWERUSXpNVEF4TnpJeE5UazFPVm93ZnpFTE1Ba0dBMVVFQmhNQ1JVVXhLakFvQmdOVkJBTU1JVXJEbFVWUFVrY3NTa0ZCU3kxTFVrbFRWRXBCVGl3ek9EQXdNVEE0TlRjeE9ERVFNQTRHQTFVRUJBd0hTc09WUlU5U1J6RVdNQlFHQTFVRUtnd05Ta0ZCU3kxTFVrbFRWRXBCVGpFYU1CZ0dBMVVFQlJNUlVFNVBSVVV0TXpnd01ERXdPRFUzTVRnd2RqQVFCZ2NxaGtqT1BRSUJCZ1VyZ1FRQUlnTmlBQVI1azFsWHp2U2VJOU8vMXMxcFp2amhFVzhuSXRKb0cwRUJGeG1MRVk2UzdraTF2RjJRM1RFRHg2ZE56dEkxWHR4OTZjczhyNHpZVHdkaVFvRGc3azNkaVV1UjluVFdHeFFFTU8xRkRvNFk5ZkFtaVBHV1QrK0d1T1ZvWlFZM1h4aWpnZ0hCTUlJQnZUQUpCZ05WSFJNRUFqQUFNQTRHQTFVZER3RUIvd1FFQXdJRGlEQkZCZ05WSFNBRVBqQThNREFHQ1NzR0FRUUJ6aDhCQXpBak1DRUdDQ3NHQVFVRkJ3SUJGaFZvZEhSd2N6b3ZMM2QzZHk1emF5NWxaUzlEVUZNd0NBWUdCQUNQZWdFQ01COEdBMVVkRVFRWU1CYUJGRE00TURBeE1EZzFOekU0UUdWbGMzUnBMbVZsTUIwR0ExVWREZ1FXQkJUa0xMMDBDUkFWVERFcG9jbVYrVzRtMkNibXdEQmhCZ2dyQmdFRkJRY0JBd1JWTUZNd1VRWUdCQUNPUmdFRk1FY3dSUlkvYUhSMGNITTZMeTl6YXk1bFpTOWxiaTl5WlhCdmMybDBiM0o1TDJOdmJtUnBkR2x2Ym5NdFptOXlMWFZ6WlMxdlppMWpaWEowYVdacFkyRjBaWE12RXdKRlRqQWdCZ05WSFNVQkFmOEVGakFVQmdnckJnRUZCUWNEQWdZSUt3WUJCUVVIQXdRd0h3WURWUjBqQkJnd0ZvQVV3SVNaS2NST256c0NOUGFaNFFwV0FBZ3BQbnN3Y3dZSUt3WUJCUVVIQVFFRVp6QmxNQ3dHQ0NzR0FRVUZCekFCaGlCb2RIUndPaTh2WVdsaExtUmxiVzh1YzJzdVpXVXZaWE4wWldsa01qQXhPREExQmdnckJnRUZCUWN3QW9ZcGFIUjBjRG92TDJNdWMyc3VaV1V2VkdWemRGOXZabDlGVTFSRlNVUXlNREU0TG1SbGNpNWpjblF3Q2dZSUtvWkl6ajBFQXdRRGdZc0FNSUdIQWtJQjlWTEpqSGJTMmJZdWRSYXRrRWVNRkpBTUtiSjRiQVZkaDBLbEZ4V0FTZXhGNXl3cEdsNDNXU3BCNlFBWHpORUJNZTFGSVdpT0l1ZDQ0aWV4TldPMWpnQUNRUTErTSt0YVo0aHlXcVNOVzVEQ0lpVVA3WXU0V3ZIM1NVakVxUUhiT1FzaHlNaDVFTTFwVmN2T24vWmdPeEx0NkVUdjlhdm5oVk13MnpUZDFiOHU0RUZrIl19.eyJhdWQiOlsiaHR0cHM6Ly9yaWEuZWUiLCJ1cm46Y2VydDpzaGEtMjU2OjZmMGRmMjQ0ZTRhODU2Yjk0YjNiM2I0NzU4MmEwYTUxYTMyZDY3NGRiYzcxMDcyMTFlZDIzZDRiZWM2ZDljNzIiXSwiZXhwIjoiMTU4Njg3MTE2OSIsImlhdCI6IjE1ODY4NzA4NjkiLCJpc3MiOiJ3ZWItZWlkIGFwcCB2MC45LjAtMS1nZTZlODlmYSIsIm5vbmNlIjoiMTIzNDU2NzgxMjM0NTY3ODEyMzQ1Njc4MTIzNDU2NzgiLCJzdWIiOiJKXHUwMGQ1RU9SRyxKQUFLLUtSSVNUSkFOLDM4MDAxMDg1NzE4In0"; + public static final String X5C_MOBILE_ID_CERTIFICATE = "eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiIsIng1YyI6WyJNSUlGbURDQ0E0Q2dBd0lCQWdJUU13Y3k4WWdndjJsZlRUS0xRT2hOWVRBTkJna3Foa2lHOXcwQkFRc0ZBREJqTVFzd0NRWURWUVFHRXdKRlJURWlNQ0FHQTFVRUNnd1pRVk1nVTJWeWRHbG1hWFJ6WldWeWFXMXBjMnRsYzJ0MWN6RVhNQlVHQTFVRVlRd09UbFJTUlVVdE1UQTNORGN3TVRNeEZ6QVZCZ05WQkFNTURrVlRWRVZKUkMxVFN5QXlNREUxTUI0WERUSXdNRGd6TVRFM01qVXpNVm9YRFRJMU1EZ3pNVEl3TlRrMU9Wb3djVEVMTUFrR0ExVUVCaE1DUlVVeEl6QWhCZ05WQkFNTUdrdkRsVlpGVWxOQlVpeE5RVlJKTERNNE16QTVNVFF3TkRJd01SSXdFQVlEVlFRRURBbEx3NVZXUlZKVFFWSXhEVEFMQmdOVkJDb01CRTFCVkVreEdqQVlCZ05WQkFVVEVWQk9UMFZGTFRNNE16QTVNVFF3TkRJd01Ga3dFd1lIS29aSXpqMENBUVlJS29aSXpqMERBUWNEUWdBRUpjZ0lqWkVFSXlJTUdWbGkxeHA4OFlsUzhQbldCQ2NYZEJpQlRETmlWVC80T2xUVHRlQkJJZVBuMnZLV09nVU5ET1d5RnNCUVJQeTkzUGlnMnRoQXpxT0NBZ013Z2dIL01Ba0dBMVVkRXdRQ01BQXdEZ1lEVlIwUEFRSC9CQVFEQWdPSU1ISUdBMVVkSUFSck1Ha3dYUVlKS3dZQkJBSE9Id0VETUZBd0x3WUlLd1lCQlFVSEFnRVdJMmgwZEhCek9pOHZkM2QzTG5OckxtVmxMM0psY0c5emFYUnZiM0pwZFcwdlExQlRNQjBHQ0NzR0FRVUZCd0lDTUJFYUQwTnZiblJ5WVdOMElERXVNVEV0T1RBSUJnWUVBSTk2QVFJd0lRWURWUjBSQkJvd0dJRVdiV0YwYVM1cmIzWmxjbk5oY2tCbFpYTjBhUzVsWlRBZEJnTlZIUTRFRmdRVWFOVzZuMjlhTVJiVUxQdEl5dm1ScTUwZzhnOHdId1lEVlIwakJCZ3dGb0FVczZ1SXZKblZZcVNGS2dqTnRCMXlPNE55UjFFd2FnWUlLd1lCQlFVSEFRRUVYakJjTUNjR0NDc0dBUVVGQnpBQmhodG9kSFJ3T2k4dllXbGhMbk5yTG1WbEwyVnpkR1ZwWkRJd01UVXdNUVlJS3dZQkJRVUhNQUtHSldoMGRIQTZMeTlqTG5OckxtVmxMMFZUVkVWSlJDMVRTMTh5TURFMUxtUmxjaTVqY25Rd1lRWUlLd1lCQlFVSEFRTUVWVEJUTUZFR0JnUUFqa1lCQlRCSE1FVVdQMmgwZEhCek9pOHZjMnN1WldVdlpXNHZjbVZ3YjNOcGRHOXllUzlqYjI1a2FYUnBiMjV6TFdadmNpMTFjMlV0YjJZdFkyVnlkR2xtYVdOaGRHVnpMeE1DUlU0d1BBWURWUjBmQkRVd016QXhvQytnTFlZcmFIUjBjRG92TDNkM2R5NXpheTVsWlM5amNteHpMMlZ6ZEdWcFpDOWxjM1JsYVdReU1ERTFMbU55YkRBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQWdFQUZ2WW1tYWVOdmg2dmFraXprdjZIdlhZWFhEdlRJVkE3WjNXc1hOOVpmZnZxaXFNNndnOWlJQmlXalVFNXFLaDBzVmE2cWx4VEhKOTBrZWx0Z1dzTGtQYnlDZUp2c2w3bnBJKy8zTnZIandSODNkSHptaThWMjF6TEFWd2czbkdwYmtsZzJ1VFBBYWdRZlJ3YTkxRDMrU1B1LzJVbzZhL3Z3SlZUYU1aUCtQRUhFa0NtTnV3UEFFQ2dubmlOZ2N3bENLMG1oTks5dXJEV2V3c0RjWnFSSWk2MVF5UXpIZGU5bDBJVWxUY0k4blB6SW1hNWY4MzF4VlhHcWk5OFdRWnBxZkhzZFBMMTR3d0FQNVVqc3p2RGUzRE92eDBlQVJob1NybThNTGozWTlvTjgyb00wWEJJYzZ1UncwS05wOGx1bkhNSUFMMmIzMFVMSmtYTUxMZEEvRks0S1MyTXZsdCtkTzN4K3RxS1VHWDR3cnhQdE5tV3Z2TEZLZlBwempMS0RsL0pBNmZCY0QyTEhjS1NETUs4Smdjb2tsM3R6STh6RzBSS3kzeURDcEErYzNDUDdwSURMQmIwZnBOempVQXRUUzcybWdBelJiRk5YY3ROMDV1ZWtZbVRoVTJaNzFNdlVDdzBKaXhONkc3RG1pT2UzY3A5a0EwMWYwUkJsTTc2ZjJ4NlltWjdYQ2RJMEpOUW04U3B5Y3RWWC8yU2JlZDBrYmpwT1YwNUNGRXRXV1lsQk8zb0hmN1NmMGpxWXJzM1NOOTk5TUhIQ2c0d2RzV1VKaUd1SUx5TUppK2dRcGhJRC9QZ2pEVzlxeExkMGtxSzFjQkxLeWJ3Z0JTY2R0NUtaanJUS1lXT1NUd3ZoNUZoRktWVndzQ01lT2gvK29qS1doWDZ1S2h3TU9RPSJdfQ.eyJhdWQiOlsiaHR0cHM6Ly9yaWEuZWUiLCJ1cm46Y2VydDpzaGEtMjU2OjZmMGRmMjQ0ZTRhODU2Yjk0YjNiM2I0NzU4MmEwYTUxYTMyZDY3NGRiYzcxMDcyMTFlZDIzZDRiZWM2ZDljNzIiXSwiZXhwIjoiMTU4Njg3MTE2OSIsImlhdCI6IjE1ODY4NzA4NjkiLCJpc3MiOiJ3ZWItZWlkIGFwcCB2MC45LjAtMS1nZTZlODlmYSIsIm5vbmNlIjoiMTIzNDU2NzgxMjM0NTY3ODEyMzQ1Njc4MTIzNDU2NzgiLCJzdWIiOiJKXHUwMGQ1RU9SRyxKQUFLLUtSSVNUSkFOLDM4MDAxMDg1NzE4In0"; + + //----------------------------------------------------------------------------------------------------------------- + public static String getUnsignedTokenString() { int sigPos = Tokens.SIGNED.lastIndexOf("."); return Tokens.SIGNED.substring(0, sigPos + 1); diff --git a/src/test/java/org/webeid/security/validator/SubjectCertificatePolicyValidatorTest.java b/src/test/java/org/webeid/security/validator/SubjectCertificatePolicyValidatorTest.java new file mode 100644 index 00000000..b9b09bda --- /dev/null +++ b/src/test/java/org/webeid/security/validator/SubjectCertificatePolicyValidatorTest.java @@ -0,0 +1,34 @@ +package org.webeid.security.validator; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.webeid.security.exceptions.UserCertificateDisallowedPolicyException; +import org.webeid.security.testutil.AbstractTestWithMockedDateAndCorrectNonce; +import org.webeid.security.testutil.Tokens; +import org.webeid.security.validator.AuthTokenValidator; + +import java.security.cert.CertificateException; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.webeid.security.testutil.AuthTokenValidators.getAuthTokenValidatorWithDisallowedESTEIDPolicy; + +class SubjectCertificatePolicyValidatorTest extends AbstractTestWithMockedDateAndCorrectNonce { + + private AuthTokenValidator validator; + + @BeforeEach + void setUp() { + try { + validator = getAuthTokenValidatorWithDisallowedESTEIDPolicy(cache); + } catch (CertificateException e) { + throw new RuntimeException(e); + } + } + + @Test + void testX5cDisallowedPolicyCertificate() { + // Tokens.SIGNED has EST IDEMIA policy which is configured as disallowed in setUp(). + assertThatThrownBy(() -> validator.validate(Tokens.SIGNED)) + .isInstanceOf(UserCertificateDisallowedPolicyException.class); + } +} diff --git a/src/test/java/org/webeid/security/validator/X5cTest.java b/src/test/java/org/webeid/security/validator/X5cTest.java index 787d6efd..a1a2f929 100644 --- a/src/test/java/org/webeid/security/validator/X5cTest.java +++ b/src/test/java/org/webeid/security/validator/X5cTest.java @@ -24,9 +24,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.webeid.security.exceptions.TokenParseException; -import org.webeid.security.exceptions.UserCertificateMissingPurposeException; -import org.webeid.security.exceptions.UserCertificateWrongPurposeException; +import org.webeid.security.exceptions.*; import org.webeid.security.testutil.AbstractTestWithValidatorAndCorrectNonce; import org.webeid.security.testutil.Dates; import org.webeid.security.testutil.Tokens; @@ -96,4 +94,15 @@ void testX5cWrongPurposeCertificate() { .isInstanceOf(UserCertificateWrongPurposeException.class); } + @Test + void testX5cWrongPolicyCertificate() { + assertThatThrownBy(() -> validator.validate(Tokens.X5C_WRONG_POLICY_CERTIFICATE)) + .isInstanceOf(UserCertificateDisallowedPolicyException.class); + } + + @Test + void testMobileIDCertificate() { + assertThatThrownBy(() -> validator.validate(Tokens.X5C_MOBILE_ID_CERTIFICATE)) + .isInstanceOf(UserCertificateMissingPurposeException.class); + } }