Skip to content

Commit 1a78169

Browse files
committed
feat: make using nonce extension configurable during OCSP requests
Signed-off-by: Mart Somermaa <[email protected]>
1 parent 508fe20 commit 1a78169

File tree

7 files changed

+53
-11
lines changed

7 files changed

+53
-11
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ The token validation process consists of three stages:
242242

243243
## Basic usage
244244

245-
The builder class need a *javax.cache.Cache* instance (use *Hazelcast* or *Infinispan* if you do use a cluster, or *Caffeine* if you don't):
245+
The builder class needs a *javax.cache.Cache* instance (use *Hazelcast* or *Infinispan* if you use a cluster, or *Caffeine* or *Ehcache* if you don't):
246246
```java
247247
Cache<String, Nonce> cache = // TODO: create new cache instance here
248248
```

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<modelVersion>4.0.0</modelVersion>
66
<artifactId>authtoken-validation</artifactId>
77
<groupId>org.webeid.security</groupId>
8-
<version>1.0.0</version>
8+
<version>1.0.1</version>
99
<packaging>jar</packaging>
1010
<name>authtoken-validation</name>
1111
<description>Web eID authentication token validation library for Java</description>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package org.webeid.security.util;
2+
3+
import java.net.URI;
4+
5+
public class OcspUrls {
6+
public static final URI ESTEID_2015 = URI.create("http://aia.sk.ee/esteid2015");
7+
8+
private OcspUrls() {
9+
throw new IllegalStateException("Constants class");
10+
}
11+
12+
}

src/main/java/org/webeid/security/validator/AuthTokenValidationConfiguration.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import java.util.Objects;
3737

3838
import static org.webeid.security.nonce.NonceGeneratorBuilder.requirePositiveDuration;
39+
import static org.webeid.security.util.OcspUrls.ESTEID_2015;
3940
import static org.webeid.security.util.SubjectCertificatePolicies.EST_MOBILE_ID_POLICY;
4041

4142
/**
@@ -53,6 +54,8 @@ final class AuthTokenValidationConfiguration {
5354
private String siteCertificateSha256Fingerprint;
5455
// Don't allow Estonian Mobile-ID policy by default.
5556
private Collection<ASN1ObjectIdentifier> disallowedSubjectCertificatePolicies = Sets.newHashSet(EST_MOBILE_ID_POLICY);
57+
// Disable OCSP nonce extension for EstEID 2015 cards by default.
58+
private Collection<URI> nonceDisabledOcspUrls = Sets.newHashSet(ESTEID_2015);
5659

5760
AuthTokenValidationConfiguration() {
5861
}
@@ -67,6 +70,7 @@ private AuthTokenValidationConfiguration(AuthTokenValidationConfiguration other)
6770
this.isSiteCertificateFingerprintValidationEnabled = other.isSiteCertificateFingerprintValidationEnabled;
6871
this.siteCertificateSha256Fingerprint = other.siteCertificateSha256Fingerprint;
6972
this.disallowedSubjectCertificatePolicies = new HashSet<>(other.disallowedSubjectCertificatePolicies);
73+
this.nonceDisabledOcspUrls = new HashSet<>(other.nonceDisabledOcspUrls);
7074
}
7175

7276
void setSiteOrigin(URI siteOrigin) {
@@ -126,6 +130,14 @@ public String getSiteCertificateSha256Fingerprint() {
126130
return siteCertificateSha256Fingerprint;
127131
}
128132

133+
public Collection<ASN1ObjectIdentifier> getDisallowedSubjectCertificatePolicies() {
134+
return disallowedSubjectCertificatePolicies;
135+
}
136+
137+
public Collection<URI> getNonceDisabledOcspUrls() {
138+
return nonceDisabledOcspUrls;
139+
}
140+
129141
/**
130142
* Checks that the configuration parameters are valid.
131143
*
@@ -151,8 +163,4 @@ AuthTokenValidationConfiguration copy() {
151163
return new AuthTokenValidationConfiguration(this);
152164
}
153165

154-
public Collection<ASN1ObjectIdentifier> getDisallowedSubjectCertificatePolicies() {
155-
return disallowedSubjectCertificatePolicies;
156-
}
157-
158166
}

src/main/java/org/webeid/security/validator/AuthTokenValidatorImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ private ValidatorBatch getCertTrustValidators() {
132132
return ValidatorBatch.createFrom(
133133
certTrustedValidator::validateCertificateTrusted
134134
).addOptional(configuration.isUserCertificateRevocationCheckWithOcspEnabled(),
135-
new SubjectCertificateNotRevokedValidator(certTrustedValidator, httpClientSupplier.get())::validateCertificateNotRevoked
135+
new SubjectCertificateNotRevokedValidator(certTrustedValidator, httpClientSupplier.get(), configuration.getNonceDisabledOcspUrls())::validateCertificateNotRevoked
136136
);
137137
}
138138
}

src/main/java/org/webeid/security/validator/ocsp/OcspRequestBuilder.java

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ public final class OcspRequestBuilder {
7070
private DigestCalculator digestCalculator = Digester.sha1();
7171
private X509Certificate subjectCertificate;
7272
private X509Certificate issuerCertificate;
73+
private boolean ocspNonceEnabled = true;
7374

7475
public OcspRequestBuilder generator(SecureRandom generator) {
7576
this.randomGenerator = generator;
@@ -91,12 +92,16 @@ public OcspRequestBuilder issuer(X509Certificate issuer) {
9192
return this;
9293
}
9394

95+
public OcspRequestBuilder enableOcspNonce(boolean ocspNonceEnabled) {
96+
this.ocspNonceEnabled = ocspNonceEnabled;
97+
return this;
98+
}
99+
94100
/**
95101
* ATTENTION: The returned {@link OCSPReq} is not re-usable/cacheable! It contains a one-time nonce
96102
* and CA's will (should) reject subsequent requests that have the same nonce value.
97103
*/
98104
public OCSPReq build() throws OCSPException, IOException, CertificateEncodingException {
99-
final SecureRandom generator = Objects.requireNonNull(this.randomGenerator, "randomGenerator");
100105
final DigestCalculator calculator = Objects.requireNonNull(this.digestCalculator, "digestCalculator");
101106
final X509Certificate certificate = Objects.requireNonNull(this.subjectCertificate, "subjectCertificate");
102107
final X509Certificate issuer = Objects.requireNonNull(this.issuerCertificate, "issuerCertificate");
@@ -109,6 +114,16 @@ public OCSPReq build() throws OCSPException, IOException, CertificateEncodingExc
109114
final OCSPReqBuilder builder = new OCSPReqBuilder();
110115
builder.addRequest(certId);
111116

117+
if (ocspNonceEnabled) {
118+
addNonce(builder);
119+
}
120+
121+
return builder.build();
122+
}
123+
124+
private void addNonce(OCSPReqBuilder builder) {
125+
final SecureRandom generator = Objects.requireNonNull(this.randomGenerator, "randomGenerator");
126+
112127
final byte[] nonce = new byte[8];
113128
generator.nextBytes(nonce);
114129

@@ -118,7 +133,6 @@ public OCSPReq build() throws OCSPException, IOException, CertificateEncodingExc
118133
};
119134

120135
builder.setRequestExtensions(new Extensions(extensions));
121-
122-
return builder.build();
123136
}
137+
124138
}

src/main/java/org/webeid/security/validator/validators/SubjectCertificateNotRevokedValidator.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import java.net.URI;
3939
import java.security.cert.CertificateEncodingException;
4040
import java.security.cert.X509Certificate;
41+
import java.util.Collection;
4142
import java.util.Objects;
4243

4344
public final class SubjectCertificateNotRevokedValidator {
@@ -46,10 +47,12 @@ public final class SubjectCertificateNotRevokedValidator {
4647

4748
private final SubjectCertificateTrustedValidator trustValidator;
4849
private final OkHttpClient httpClient;
50+
private final Collection<URI> nonceDisabledOcspUrls;
4951

50-
public SubjectCertificateNotRevokedValidator(SubjectCertificateTrustedValidator trustValidator, OkHttpClient httpClient) {
52+
public SubjectCertificateNotRevokedValidator(SubjectCertificateTrustedValidator trustValidator, OkHttpClient httpClient, Collection<URI> nonceDisabledOcspUrls) {
5153
this.trustValidator = trustValidator;
5254
this.httpClient = httpClient;
55+
this.nonceDisabledOcspUrls = nonceDisabledOcspUrls;
5356
}
5457

5558
/**
@@ -66,9 +69,14 @@ public void validateCertificateNotRevoked(AuthTokenValidatorData actualTokenData
6669
if (uri == null) {
6770
throw new UserCertificateRevocationCheckFailedException("The CA/certificate doesn't have an OCSP responder");
6871
}
72+
final boolean ocspNonceDisabled = nonceDisabledOcspUrls.contains(uri);
73+
if (ocspNonceDisabled) {
74+
LOG.debug("Disabling OCSP nonce extension");
75+
}
6976

7077
final OCSPReq request = new OcspRequestBuilder()
7178
.certificate(certificate)
79+
.enableOcspNonce(!ocspNonceDisabled)
7280
.issuer(Objects.requireNonNull(trustValidator.getSubjectCertificateIssuerCertificate()))
7381
.build();
7482

0 commit comments

Comments
 (0)