Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import com.sun.management.OperatingSystemMXBean;

import io.aklivity.zilla.runtime.engine.internal.layouts.BudgetsLayout;
import io.aklivity.zilla.runtime.engine.security.RevocationStrategy;

public class EngineConfiguration extends Configuration
{
Expand Down Expand Up @@ -91,6 +92,7 @@ public class EngineConfiguration extends Configuration
public static final PropertyDef<String> ENGINE_CACERTS_STORE;
public static final PropertyDef<String> ENGINE_CACERTS_STORE_PASS;
public static final PropertyDef<ErrorReporter> ENGINE_ERROR_REPORTER;
public static final PropertyDef<RevocationStrategy> ENGINE_CERTIFICATE_REVOCATION_STRATEGY;

private static final ConfigurationDef ENGINE_CONFIG;

Expand Down Expand Up @@ -143,6 +145,8 @@ public class EngineConfiguration extends Configuration
ENGINE_CACERTS_STORE_PASS = config.property("cacerts.store.pass");
ENGINE_ERROR_REPORTER = config.property(ErrorReporter.class, "error.reporter",
EngineConfiguration::decodeErrorReporter, EngineConfiguration::defaultErrorReporter);
ENGINE_CERTIFICATE_REVOCATION_STRATEGY = config.property(RevocationStrategy.class, "certificate.revocation.strategy",
EngineConfiguration::decodeRevocationStrategy, RevocationStrategy.NONE);
ENGINE_CONFIG = config;
}

Expand Down Expand Up @@ -607,4 +611,10 @@ private static ErrorReporter decodeErrorReporter(

return reporter;
}

private static RevocationStrategy decodeRevocationStrategy(
String value)
{
return RevocationStrategy.valueOf(value.toUpperCase());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright 2021-2024 Aklivity Inc.
*
* Aklivity licenses this file to you 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.aklivity.zilla.runtime.engine.security;

public enum RevocationStrategy
{
CRL,
NONE
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,14 @@
import java.util.function.Function;

import io.aklivity.zilla.runtime.engine.config.OptionsConfig;
import io.aklivity.zilla.runtime.engine.security.RevocationStrategy;

public final class FileSystemOptionsConfig extends OptionsConfig
{
public final FileSystemStoreConfig keys;
public final FileSystemStoreConfig trust;
public final FileSystemStoreConfig signers;
public final RevocationStrategy revocation;

public static FileSystemOptionsConfigBuilder<FileSystemOptionsConfig> builder()
{
Expand All @@ -41,12 +43,14 @@ public static <T> FileSystemOptionsConfigBuilder<T> builder(
FileSystemOptionsConfig(
FileSystemStoreConfig keys,
FileSystemStoreConfig trust,
FileSystemStoreConfig signers)
FileSystemStoreConfig signers,
RevocationStrategy revocation)
{
super(List.of(), resolveResources(keys, trust));
this.keys = keys;
this.trust = trust;
this.signers = signers;
this.revocation = revocation;
}

private static List<String> resolveResources(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import io.aklivity.zilla.runtime.engine.config.ConfigBuilder;
import io.aklivity.zilla.runtime.engine.config.OptionsConfig;
import io.aklivity.zilla.runtime.engine.security.RevocationStrategy;

public final class FileSystemOptionsConfigBuilder<T> extends ConfigBuilder<T, FileSystemOptionsConfigBuilder<T>>
{
Expand All @@ -27,6 +28,7 @@ public final class FileSystemOptionsConfigBuilder<T> extends ConfigBuilder<T, Fi
private FileSystemStoreConfig keys;
private FileSystemStoreConfig trust;
private FileSystemStoreConfig signers;
private RevocationStrategy revocation;

FileSystemOptionsConfigBuilder(
Function<OptionsConfig, T> mapper)
Expand Down Expand Up @@ -77,9 +79,16 @@ public FileSystemOptionsConfigBuilder<T> signers(
return this;
}

public FileSystemOptionsConfigBuilder<T> revocation(
RevocationStrategy revocation)
{
this.revocation = revocation;
return this;
}

@Override
public T build()
{
return mapper.apply(new FileSystemOptionsConfig(keys, trust, signers));
return mapper.apply(new FileSystemOptionsConfig(keys, trust, signers, revocation));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,32 +15,37 @@
*/
package io.aklivity.zilla.runtime.vault.filesystem.internal;

import static io.aklivity.zilla.runtime.engine.EngineConfiguration.ENGINE_CERTIFICATE_REVOCATION_STRATEGY;

import java.nio.file.Path;
import java.util.function.Function;

import io.aklivity.zilla.runtime.engine.Configuration;
import io.aklivity.zilla.runtime.engine.EngineContext;
import io.aklivity.zilla.runtime.engine.config.VaultConfig;
import io.aklivity.zilla.runtime.engine.security.RevocationStrategy;
import io.aklivity.zilla.runtime.engine.vault.VaultContext;
import io.aklivity.zilla.runtime.vault.filesystem.config.FileSystemOptionsConfig;

final class FileSystemContext implements VaultContext
{
private final Function<String, Path> resolvePath;
private final RevocationStrategy revocation;

FileSystemContext(
Configuration config,
EngineContext context)
{
this.resolvePath = context::resolvePath;
this.revocation = ENGINE_CERTIFICATE_REVOCATION_STRATEGY.get(config);
}

@Override
public FileSystemVaultHandler attach(
VaultConfig vault)
{
FileSystemOptionsConfig options = (FileSystemOptionsConfig) vault.options;
return new FileSystemVaultHandler(options, resolvePath);
return new FileSystemVaultHandler(options, resolvePath, revocation);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,37 +23,54 @@
import java.security.KeyStore.Entry;
import java.security.KeyStore.PrivateKeyEntry;
import java.security.KeyStore.TrustedCertificateEntry;
import java.security.cert.CertPathValidator;
import java.security.cert.Certificate;
import java.security.cert.PKIXBuilderParameters;
import java.security.cert.PKIXRevocationChecker;
import java.security.cert.X509CertSelector;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.Function;

import javax.net.ssl.CertPathTrustManagerParameters;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.TrustManagerFactory;
import javax.security.auth.x500.X500Principal;

import org.agrona.LangUtil;

import io.aklivity.zilla.runtime.engine.security.RevocationStrategy;
import io.aklivity.zilla.runtime.engine.vault.VaultHandler;
import io.aklivity.zilla.runtime.vault.filesystem.config.FileSystemOptionsConfig;
import io.aklivity.zilla.runtime.vault.filesystem.config.FileSystemStoreConfig;

public class FileSystemVaultHandler implements VaultHandler
{
private static final String STORE_TYPE_DEFAULT = "pkcs12";
private static final String PKIX_ALGORITHM = "PKIX";

private final Function<List<String>, KeyManagerFactory> supplyKeys;
private final Function<List<String>, KeyManagerFactory> supplySigners;
private final BiFunction<List<String>, KeyStore, TrustManagerFactory> supplyTrust;
private final RevocationStrategy revocation;

public FileSystemVaultHandler(
FileSystemOptionsConfig options,
Function<String, Path> resolvePath)
{
this(options, resolvePath, RevocationStrategy.NONE);
}

public FileSystemVaultHandler(
FileSystemOptionsConfig options,
Function<String, Path> resolvePath,
RevocationStrategy revocation)
{
FileSystemStoreInfo keys = supplyStoreInfo(resolvePath, options.keys);
supplyKeys = keys != null
Expand All @@ -65,6 +82,7 @@ public FileSystemVaultHandler(
? aliases -> newSignersFactory(aliases, signers, keys)
: aliases -> null;

this.revocation = options.revocation != null ? options.revocation : revocation;
FileSystemStoreInfo trust = supplyStoreInfo(resolvePath, options.trust);
supplyTrust = (aliases, cacerts) -> newTrustFactory(trust, aliases, cacerts);
}
Expand Down Expand Up @@ -185,8 +203,28 @@ private TrustManagerFactory newTrustFactory(
}
}

factory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
factory.init(trust);
switch (revocation)
{
case CRL:
factory = TrustManagerFactory.getInstance(PKIX_ALGORITHM);
PKIXBuilderParameters pkixParams = new PKIXBuilderParameters(trust, new X509CertSelector());
pkixParams.setRevocationEnabled(true);

CertPathValidator validator = CertPathValidator.getInstance(PKIX_ALGORITHM);
PKIXRevocationChecker checker = (PKIXRevocationChecker) validator.getRevocationChecker();
checker.setOptions(EnumSet.of(
PKIXRevocationChecker.Option.PREFER_CRLS
));
pkixParams.addCertPathChecker(checker);

CertPathTrustManagerParameters tmParams = new CertPathTrustManagerParameters(pkixParams);
factory.init(tmParams);
break;
default:
factory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
factory.init(trust);
break;
}
Comment thread
bmaidics marked this conversation as resolved.
}
}
catch (Exception ex)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

import io.aklivity.zilla.runtime.engine.config.OptionsConfig;
import io.aklivity.zilla.runtime.engine.config.OptionsConfigAdapterSpi;
import io.aklivity.zilla.runtime.engine.security.RevocationStrategy;
import io.aklivity.zilla.runtime.vault.filesystem.config.FileSystemOptionsConfig;
import io.aklivity.zilla.runtime.vault.filesystem.config.FileSystemOptionsConfigBuilder;
import io.aklivity.zilla.runtime.vault.filesystem.internal.FileSystemVault;
Expand All @@ -31,6 +32,7 @@ public final class FileSystemOptionsConfigAdapter implements OptionsConfigAdapte
private static final String KEYS_NAME = "keys";
private static final String TRUST_NAME = "trust";
private static final String SIGNERS_NAME = "signers";
private static final String REVOCATION_NAME = "revocation";

private final FileSystemStoreConfigAdapter store = new FileSystemStoreConfigAdapter();

Expand Down Expand Up @@ -69,6 +71,11 @@ public JsonObject adaptToJson(
object.add(SIGNERS_NAME, store.adaptToJson(fsOptions.signers));
}

if (fsOptions.revocation != null)
{
object.add(REVOCATION_NAME, fsOptions.revocation.name().toLowerCase());
}

return object.build();
}

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

if (object.containsKey(REVOCATION_NAME))
{
fsOptions.revocation(RevocationStrategy.valueOf(object.getString(REVOCATION_NAME)));
}

return fsOptions.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public void shouldResolveClient() throws Exception
.build()
.build();

FileSystemVaultHandler vault = new FileSystemVaultHandler(options, FileSystemVaultTest::resourcePath);
FileSystemVaultHandler vault = new FileSystemVaultHandler(options, FileSystemVaultTest::resourcePath, null);

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

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#
# Copyright 2021-2024 Aklivity Inc.
#
# Aklivity licenses this file to you 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.
#

---
name: test
vaults:
server:
type: filesystem
options:
keys:
store: stores/server/keys
type: pkcs12
password: generated
trust:
store: stores/server/trust
type: pkcs12
password: generated
signers:
store: stores/server/signers
type: pkcs12
password: generated
revocation: crl
client:
type: filesystem
options:
keys:
store: stores/client/keys
type: pkcs12
password: generated
trust:
store: stores/client/trust
type: pkcs12
password: generated
signers:
store: stores/client/signers
type: pkcs12
password: generated
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,12 @@
}
},
"additionalProperties": false
},
"revocation":
{
"title": "Revocation Method",
"type": "string",
"enum": [ "crl" ]
}
},
"additionalProperties": false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,12 @@ public void shouldValidateVault()

assertThat(config, not(nullValue()));
}

@Test
public void shouldValidateVaultWithCRL()
{
JsonObject config = schema.validate("vault.crl.yaml");

assertThat(config, not(nullValue()));
}
}
Loading