Skip to content

Commit 0d97d3a

Browse files
authored
Add CRL checks (#1474)
1 parent 841f9a3 commit 0d97d3a

11 files changed

Lines changed: 170 additions & 6 deletions

File tree

runtime/engine/src/main/java/io/aklivity/zilla/runtime/engine/EngineConfiguration.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import com.sun.management.OperatingSystemMXBean;
4444

4545
import io.aklivity.zilla.runtime.engine.internal.layouts.BudgetsLayout;
46+
import io.aklivity.zilla.runtime.engine.security.RevocationStrategy;
4647

4748
public class EngineConfiguration extends Configuration
4849
{
@@ -93,6 +94,7 @@ public class EngineConfiguration extends Configuration
9394
public static final PropertyDef<String> ENGINE_CACERTS_STORE;
9495
public static final PropertyDef<String> ENGINE_CACERTS_STORE_PASS;
9596
public static final PropertyDef<ErrorReporter> ENGINE_ERROR_REPORTER;
97+
public static final PropertyDef<RevocationStrategy> ENGINE_CERTIFICATE_REVOCATION_STRATEGY;
9698

9799
private static final ConfigurationDef ENGINE_CONFIG;
98100

@@ -147,6 +149,8 @@ public class EngineConfiguration extends Configuration
147149
ENGINE_CACERTS_STORE_PASS = config.property("cacerts.store.pass");
148150
ENGINE_ERROR_REPORTER = config.property(ErrorReporter.class, "error.reporter",
149151
EngineConfiguration::decodeErrorReporter, EngineConfiguration::defaultErrorReporter);
152+
ENGINE_CERTIFICATE_REVOCATION_STRATEGY = config.property(RevocationStrategy.class, "certificate.revocation.strategy",
153+
EngineConfiguration::decodeRevocationStrategy, RevocationStrategy.NONE);
150154
ENGINE_CONFIG = config;
151155
}
152156

@@ -619,4 +623,10 @@ private static ErrorReporter decodeErrorReporter(
619623

620624
return reporter;
621625
}
626+
627+
private static RevocationStrategy decodeRevocationStrategy(
628+
String value)
629+
{
630+
return RevocationStrategy.valueOf(value.toUpperCase());
631+
}
622632
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
* Copyright 2021-2024 Aklivity Inc.
3+
*
4+
* Aklivity licenses this file to you under the Apache License,
5+
* version 2.0 (the "License"); you may not use this file except in compliance
6+
* with the License. You may obtain a copy of the License at:
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13+
* License for the specific language governing permissions and limitations
14+
* under the License.
15+
*/
16+
package io.aklivity.zilla.runtime.engine.security;
17+
18+
public enum RevocationStrategy
19+
{
20+
CRL,
21+
NONE
22+
}

runtime/vault-filesystem/src/main/java/io/aklivity/zilla/runtime/vault/filesystem/config/FileSystemOptionsConfig.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,14 @@
2020
import java.util.function.Function;
2121

2222
import io.aklivity.zilla.runtime.engine.config.OptionsConfig;
23+
import io.aklivity.zilla.runtime.engine.security.RevocationStrategy;
2324

2425
public final class FileSystemOptionsConfig extends OptionsConfig
2526
{
2627
public final FileSystemStoreConfig keys;
2728
public final FileSystemStoreConfig trust;
2829
public final FileSystemStoreConfig signers;
30+
public final RevocationStrategy revocation;
2931

3032
public static FileSystemOptionsConfigBuilder<FileSystemOptionsConfig> builder()
3133
{
@@ -41,12 +43,14 @@ public static <T> FileSystemOptionsConfigBuilder<T> builder(
4143
FileSystemOptionsConfig(
4244
FileSystemStoreConfig keys,
4345
FileSystemStoreConfig trust,
44-
FileSystemStoreConfig signers)
46+
FileSystemStoreConfig signers,
47+
RevocationStrategy revocation)
4548
{
4649
super(List.of(), resolveResources(keys, trust));
4750
this.keys = keys;
4851
this.trust = trust;
4952
this.signers = signers;
53+
this.revocation = revocation;
5054
}
5155

5256
private static List<String> resolveResources(

runtime/vault-filesystem/src/main/java/io/aklivity/zilla/runtime/vault/filesystem/config/FileSystemOptionsConfigBuilder.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import io.aklivity.zilla.runtime.engine.config.ConfigBuilder;
2121
import io.aklivity.zilla.runtime.engine.config.OptionsConfig;
22+
import io.aklivity.zilla.runtime.engine.security.RevocationStrategy;
2223

2324
public final class FileSystemOptionsConfigBuilder<T> extends ConfigBuilder<T, FileSystemOptionsConfigBuilder<T>>
2425
{
@@ -27,6 +28,7 @@ public final class FileSystemOptionsConfigBuilder<T> extends ConfigBuilder<T, Fi
2728
private FileSystemStoreConfig keys;
2829
private FileSystemStoreConfig trust;
2930
private FileSystemStoreConfig signers;
31+
private RevocationStrategy revocation;
3032

3133
FileSystemOptionsConfigBuilder(
3234
Function<OptionsConfig, T> mapper)
@@ -77,9 +79,16 @@ public FileSystemOptionsConfigBuilder<T> signers(
7779
return this;
7880
}
7981

82+
public FileSystemOptionsConfigBuilder<T> revocation(
83+
RevocationStrategy revocation)
84+
{
85+
this.revocation = revocation;
86+
return this;
87+
}
88+
8089
@Override
8190
public T build()
8291
{
83-
return mapper.apply(new FileSystemOptionsConfig(keys, trust, signers));
92+
return mapper.apply(new FileSystemOptionsConfig(keys, trust, signers, revocation));
8493
}
8594
}

runtime/vault-filesystem/src/main/java/io/aklivity/zilla/runtime/vault/filesystem/internal/FileSystemContext.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,32 +15,37 @@
1515
*/
1616
package io.aklivity.zilla.runtime.vault.filesystem.internal;
1717

18+
import static io.aklivity.zilla.runtime.engine.EngineConfiguration.ENGINE_CERTIFICATE_REVOCATION_STRATEGY;
19+
1820
import java.nio.file.Path;
1921
import java.util.function.Function;
2022

2123
import io.aklivity.zilla.runtime.engine.Configuration;
2224
import io.aklivity.zilla.runtime.engine.EngineContext;
2325
import io.aklivity.zilla.runtime.engine.config.VaultConfig;
26+
import io.aklivity.zilla.runtime.engine.security.RevocationStrategy;
2427
import io.aklivity.zilla.runtime.engine.vault.VaultContext;
2528
import io.aklivity.zilla.runtime.vault.filesystem.config.FileSystemOptionsConfig;
2629

2730
final class FileSystemContext implements VaultContext
2831
{
2932
private final Function<String, Path> resolvePath;
33+
private final RevocationStrategy revocation;
3034

3135
FileSystemContext(
3236
Configuration config,
3337
EngineContext context)
3438
{
3539
this.resolvePath = context::resolvePath;
40+
this.revocation = ENGINE_CERTIFICATE_REVOCATION_STRATEGY.get(config);
3641
}
3742

3843
@Override
3944
public FileSystemVaultHandler attach(
4045
VaultConfig vault)
4146
{
4247
FileSystemOptionsConfig options = (FileSystemOptionsConfig) vault.options;
43-
return new FileSystemVaultHandler(options, resolvePath);
48+
return new FileSystemVaultHandler(options, resolvePath, revocation);
4449
}
4550

4651
@Override

runtime/vault-filesystem/src/main/java/io/aklivity/zilla/runtime/vault/filesystem/internal/FileSystemVaultHandler.java

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,37 +23,54 @@
2323
import java.security.KeyStore.Entry;
2424
import java.security.KeyStore.PrivateKeyEntry;
2525
import java.security.KeyStore.TrustedCertificateEntry;
26+
import java.security.cert.CertPathValidator;
2627
import java.security.cert.Certificate;
28+
import java.security.cert.PKIXBuilderParameters;
29+
import java.security.cert.PKIXRevocationChecker;
30+
import java.security.cert.X509CertSelector;
2731
import java.security.cert.X509Certificate;
2832
import java.util.ArrayList;
2933
import java.util.Collections;
34+
import java.util.EnumSet;
3035
import java.util.List;
3136
import java.util.Objects;
3237
import java.util.Optional;
3338
import java.util.function.BiFunction;
3439
import java.util.function.Function;
3540

41+
import javax.net.ssl.CertPathTrustManagerParameters;
3642
import javax.net.ssl.KeyManagerFactory;
3743
import javax.net.ssl.TrustManagerFactory;
3844
import javax.security.auth.x500.X500Principal;
3945

4046
import org.agrona.LangUtil;
4147

48+
import io.aklivity.zilla.runtime.engine.security.RevocationStrategy;
4249
import io.aklivity.zilla.runtime.engine.vault.VaultHandler;
4350
import io.aklivity.zilla.runtime.vault.filesystem.config.FileSystemOptionsConfig;
4451
import io.aklivity.zilla.runtime.vault.filesystem.config.FileSystemStoreConfig;
4552

4653
public class FileSystemVaultHandler implements VaultHandler
4754
{
4855
private static final String STORE_TYPE_DEFAULT = "pkcs12";
56+
private static final String PKIX_ALGORITHM = "PKIX";
4957

5058
private final Function<List<String>, KeyManagerFactory> supplyKeys;
5159
private final Function<List<String>, KeyManagerFactory> supplySigners;
5260
private final BiFunction<List<String>, KeyStore, TrustManagerFactory> supplyTrust;
61+
private final RevocationStrategy revocation;
5362

5463
public FileSystemVaultHandler(
5564
FileSystemOptionsConfig options,
5665
Function<String, Path> resolvePath)
66+
{
67+
this(options, resolvePath, RevocationStrategy.NONE);
68+
}
69+
70+
public FileSystemVaultHandler(
71+
FileSystemOptionsConfig options,
72+
Function<String, Path> resolvePath,
73+
RevocationStrategy revocation)
5774
{
5875
FileSystemStoreInfo keys = supplyStoreInfo(resolvePath, options.keys);
5976
supplyKeys = keys != null
@@ -65,6 +82,7 @@ public FileSystemVaultHandler(
6582
? aliases -> newSignersFactory(aliases, signers, keys)
6683
: aliases -> null;
6784

85+
this.revocation = options.revocation != null ? options.revocation : revocation;
6886
FileSystemStoreInfo trust = supplyStoreInfo(resolvePath, options.trust);
6987
supplyTrust = (aliases, cacerts) -> newTrustFactory(trust, aliases, cacerts);
7088
}
@@ -185,8 +203,28 @@ private TrustManagerFactory newTrustFactory(
185203
}
186204
}
187205

188-
factory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
189-
factory.init(trust);
206+
switch (revocation)
207+
{
208+
case CRL:
209+
factory = TrustManagerFactory.getInstance(PKIX_ALGORITHM);
210+
PKIXBuilderParameters pkixParams = new PKIXBuilderParameters(trust, new X509CertSelector());
211+
pkixParams.setRevocationEnabled(true);
212+
213+
CertPathValidator validator = CertPathValidator.getInstance(PKIX_ALGORITHM);
214+
PKIXRevocationChecker checker = (PKIXRevocationChecker) validator.getRevocationChecker();
215+
checker.setOptions(EnumSet.of(
216+
PKIXRevocationChecker.Option.PREFER_CRLS
217+
));
218+
pkixParams.addCertPathChecker(checker);
219+
220+
CertPathTrustManagerParameters tmParams = new CertPathTrustManagerParameters(pkixParams);
221+
factory.init(tmParams);
222+
break;
223+
default:
224+
factory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
225+
factory.init(trust);
226+
break;
227+
}
190228
}
191229
}
192230
catch (Exception ex)

runtime/vault-filesystem/src/main/java/io/aklivity/zilla/runtime/vault/filesystem/internal/config/FileSystemOptionsConfigAdapter.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
import io.aklivity.zilla.runtime.engine.config.OptionsConfig;
2424
import io.aklivity.zilla.runtime.engine.config.OptionsConfigAdapterSpi;
25+
import io.aklivity.zilla.runtime.engine.security.RevocationStrategy;
2526
import io.aklivity.zilla.runtime.vault.filesystem.config.FileSystemOptionsConfig;
2627
import io.aklivity.zilla.runtime.vault.filesystem.config.FileSystemOptionsConfigBuilder;
2728
import io.aklivity.zilla.runtime.vault.filesystem.internal.FileSystemVault;
@@ -31,6 +32,7 @@ public final class FileSystemOptionsConfigAdapter implements OptionsConfigAdapte
3132
private static final String KEYS_NAME = "keys";
3233
private static final String TRUST_NAME = "trust";
3334
private static final String SIGNERS_NAME = "signers";
35+
private static final String REVOCATION_NAME = "revocation";
3436

3537
private final FileSystemStoreConfigAdapter store = new FileSystemStoreConfigAdapter();
3638

@@ -69,6 +71,11 @@ public JsonObject adaptToJson(
6971
object.add(SIGNERS_NAME, store.adaptToJson(fsOptions.signers));
7072
}
7173

74+
if (fsOptions.revocation != null)
75+
{
76+
object.add(REVOCATION_NAME, fsOptions.revocation.name().toLowerCase());
77+
}
78+
7279
return object.build();
7380
}
7481

@@ -93,6 +100,11 @@ public OptionsConfig adaptFromJson(
93100
fsOptions.signers(store.adaptFromJson(object.getJsonObject(SIGNERS_NAME)));
94101
}
95102

103+
if (object.containsKey(REVOCATION_NAME))
104+
{
105+
fsOptions.revocation(RevocationStrategy.valueOf(object.getString(REVOCATION_NAME)));
106+
}
107+
96108
return fsOptions.build();
97109
}
98110
}

runtime/vault-filesystem/src/test/java/io/aklivity/zilla/runtime/vault/filesystem/internal/FileSystemVaultTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public void shouldResolveClient() throws Exception
7474
.build()
7575
.build();
7676

77-
FileSystemVaultHandler vault = new FileSystemVaultHandler(options, FileSystemVaultTest::resourcePath);
77+
FileSystemVaultHandler vault = new FileSystemVaultHandler(options, FileSystemVaultTest::resourcePath, null);
7878

7979
KeyManagerFactory keys = vault.initSigners(List.of("clientca"));
8080

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#
2+
# Copyright 2021-2024 Aklivity Inc.
3+
#
4+
# Aklivity licenses this file to you under the Apache License,
5+
# version 2.0 (the "License"); you may not use this file except in compliance
6+
# with the License. You may obtain a copy of the License at:
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13+
# License for the specific language governing permissions and limitations
14+
# under the License.
15+
#
16+
17+
---
18+
name: test
19+
vaults:
20+
server:
21+
type: filesystem
22+
options:
23+
keys:
24+
store: stores/server/keys
25+
type: pkcs12
26+
password: generated
27+
trust:
28+
store: stores/server/trust
29+
type: pkcs12
30+
password: generated
31+
signers:
32+
store: stores/server/signers
33+
type: pkcs12
34+
password: generated
35+
revocation: crl
36+
client:
37+
type: filesystem
38+
options:
39+
keys:
40+
store: stores/client/keys
41+
type: pkcs12
42+
password: generated
43+
trust:
44+
store: stores/client/trust
45+
type: pkcs12
46+
password: generated
47+
signers:
48+
store: stores/client/signers
49+
type: pkcs12
50+
password: generated

specs/vault-filesystem.spec/src/main/scripts/io/aklivity/zilla/specs/vault/filesystem/schema/filesystem.schema.patch.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,12 @@
9696
}
9797
},
9898
"additionalProperties": false
99+
},
100+
"revocation":
101+
{
102+
"title": "Revocation Method",
103+
"type": "string",
104+
"enum": [ "crl" ]
99105
}
100106
},
101107
"additionalProperties": false

0 commit comments

Comments
 (0)