Skip to content

Commit

Permalink
InMemoryKmsService - this code will be thrown away.
Browse files Browse the repository at this point in the history
deploy helm to kube and enable transit secrets engine
  • Loading branch information
k-wall committed Nov 27, 2023
1 parent 69ec0ec commit 505c780
Show file tree
Hide file tree
Showing 24 changed files with 687 additions and 49 deletions.
5 changes: 1 addition & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ FROM registry.access.redhat.com/ubi9/openjdk-17:1.15 AS builder
USER root
WORKDIR /opt/kroxylicious
COPY . .
RUN ./mvnw -B clean verify -Pdist,withAdditionalFilters -Dquick -pl :kroxylicious-bom,:kroxylicious-app,:kroxylicious-multitenant,:kroxylicious-record-validation,:kroxylicious-encryption -am
RUN ./mvnw -B clean verify -Pdist,withAdditionalFilters -Dquick -am -pl !kroxylicious-integration-tests
USER 185
FROM registry.access.redhat.com/ubi9/ubi-minimal:9.2

Expand Down Expand Up @@ -52,7 +52,4 @@ RUN set -ex; \
chmod +x /usr/bin/tini; \
fi
COPY --from=builder /opt/kroxylicious/kroxylicious-app/target/kroxylicious-app-${KROXYLICIOUS_VERSION}-bin/kroxylicious-app-${KROXYLICIOUS_VERSION}/ /opt/kroxylicious/
COPY --from=builder /opt/kroxylicious/kroxylicious-filters/kroxylicious-multitenant/target/kroxylicious-multitenant-${KROXYLICIOUS_VERSION}.jar /opt/kroxylicious/libs/
COPY --from=builder /opt/kroxylicious/kroxylicious-filters/kroxylicious-record-validation/target/kroxylicious-record-validation-${KROXYLICIOUS_VERSION}.jar /opt/kroxylicious/libs/
COPY --from=builder /opt/kroxylicious/kroxylicious-filters/kroxylicious-encryption/target/kroxylicious-encryption-${KROXYLICIOUS_VERSION}.jar /opt/kroxylicious/libs/
ENTRYPOINT ["/usr/bin/tini", "--", "/opt/kroxylicious/bin/kroxylicious-start.sh" ]
22 changes: 22 additions & 0 deletions kroxylicious-app/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -195,5 +195,27 @@
</plugins>
</build>
</profile>
<profile>
<id>withAdditionalFilters</id>
<dependencies>
<dependency>
<groupId>io.kroxylicious</groupId>
<artifactId>kroxylicious-multitenant</artifactId>
</dependency>
<dependency>
<groupId>io.kroxylicious</groupId>
<artifactId>kroxylicious-record-validation</artifactId>
</dependency>
<dependency>
<groupId>io.kroxylicious</groupId>
<artifactId>kroxylicious-encryption</artifactId>
</dependency>
<!-- Temporary -->
<dependency>
<groupId>io.kroxylicious</groupId>
<artifactId>kroxylicious-kms-provider-kroxylicious-inmemory</artifactId>
</dependency>
</dependencies>
</profile>
</profiles>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,7 @@ public EncryptionException(Throwable e) {
public EncryptionException(String message) {
super(message);
}
public EncryptionException(String message, Throwable t) {
super(message, t);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@

import edu.umd.cs.findbugs.annotations.NonNull;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@NotThreadSafe
class AesGcmEncryptor implements Destroyable {

Expand Down Expand Up @@ -50,6 +53,9 @@ private AesGcmEncryptor(int ivSizeBytes, AesGcmIvGenerator ivGenerator, @NonNull
}
}

private static final Logger LOGGER = LoggerFactory.getLogger(AesGcmEncryptor.class);


public static AesGcmEncryptor forEncrypt(@NonNull AesGcmIvGenerator ivGenerator, @NonNull SecretKey key) {
Objects.requireNonNull(ivGenerator);
var result = new AesGcmEncryptor(ivGenerator.sizeBytes(), ivGenerator, key);
Expand Down Expand Up @@ -116,7 +122,8 @@ private void init(int encryptMode) {
this.cipher.init(encryptMode, key, spec);
}
catch (GeneralSecurityException e) {
throw new EncryptionException(e);
LOGGER.error("key " + key.getEncoded().length, e);
throw new EncryptionException("key length " + key.getEncoded().length, e);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,33 +121,6 @@ static void destroy(Destroyable destroyable) {
}
}

private Supplier<CompletionStage<KeyContext>> makeKeyContext(@NonNull K kekId) {
return () -> kms.generateDekPair(kekId)
.thenApply(dekPair -> {
E edek = dekPair.edek();
short kekIdSize = (short) kekIdSerde.sizeOf(kekId);
short edekSize = (short) edekSerde.sizeOf(edek);
ByteBuffer prefix = bufferPool.acquire(
Short.BYTES + // kekId size
kekIdSize + // the kekId
Short.BYTES + // DEK size
edekSize); // the DEK
prefix.putShort(kekIdSize);
kekIdSerde.serialize(kekId, prefix);
prefix.putShort(edekSize);
edekSerde.serialize(edek, prefix);
prefix.flip();

return new KeyContext(prefix,
System.nanoTime() + dekTtlNanos,
maxEncryptionsPerDek,
// Either we have a different Aes encryptor for each thread
// or we need mutex
// or we externalize the state
AesGcmEncryptor.forEncrypt(new AesGcmIvGenerator(new SecureRandom()), dekPair.dek()));
});
}

@NonNull
@Override
@SuppressWarnings("java:S2445")
Expand Down Expand Up @@ -175,6 +148,33 @@ public CompletionStage<Void> encrypt(@NonNull EncryptionScheme<K> encryptionSche
});
}

private Supplier<CompletionStage<KeyContext>> makeKeyContext(@NonNull K kekId) {
return () -> kms.generateDekPair(kekId)
.thenApply(dekPair -> {
E edek = dekPair.edek();
short kekIdSize = (short) kekIdSerde.sizeOf(kekId);
short edekSize = (short) edekSerde.sizeOf(edek);
ByteBuffer prefix = bufferPool.acquire(
Short.BYTES + // kekId size
kekIdSize + // the kekId
Short.BYTES + // DEK size
edekSize); // the DEK
prefix.putShort(kekIdSize);
kekIdSerde.serialize(kekId, prefix);
prefix.putShort(edekSize);
edekSerde.serialize(edek, prefix);
prefix.flip();

return new KeyContext(prefix,
System.nanoTime() + dekTtlNanos,
maxEncryptionsPerDek,
// Either we have a different Aes encryptor for each thread
// or we need mutex
// or we externalize the state
AesGcmEncryptor.forEncrypt(new AesGcmIvGenerator(new SecureRandom()), dekPair.dek()));
});
}

private void encryptRecords(@NonNull EncryptionScheme<K> encryptionScheme,
@NonNull KeyContext keyContext,
@NonNull List<? extends Record> records,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@

import edu.umd.cs.findbugs.annotations.NonNull;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* An in-memory KMS to be used only for testing.
* Note that this exposes public methods that are not part of the {@link Kms} interface which are used for those
Expand Down Expand Up @@ -63,6 +66,7 @@ public class InMemoryKms implements
this.numAuthBits = numAuthBits;
try {
this.aes = KeyGenerator.getInstance(AES_KEY_ALGO);
this.aes.init(256);
}
catch (NoSuchAlgorithmException e) {
// This should be impossible, because JCA guarantees that AES is available
Expand Down Expand Up @@ -104,7 +108,8 @@ public int numDeksGenerated() {
@Override
public CompletableFuture<InMemoryEdek> generateDek(@NonNull UUID kekRef) {
try {
CompletableFuture<InMemoryEdek> result = CompletableFuture.completedFuture(wrap(kekRef, this.aes::generateKey));
Supplier<SecretKey> generateKey = this.aes::generateKey;
CompletableFuture<InMemoryEdek> result = CompletableFuture.completedFuture(wrap(kekRef, generateKey));
numDeksGenerated.incrementAndGet();
return result;
}
Expand All @@ -113,11 +118,20 @@ public CompletableFuture<InMemoryEdek> generateDek(@NonNull UUID kekRef) {
}
}


private static final Logger LOGGER = LoggerFactory.getLogger(InMemoryKms.class);



private InMemoryEdek wrap(UUID kekRef, Supplier<SecretKey> generator) {
SecretKey kek = lookupKey(kekRef);
Cipher aesCipher = aesGcm();
GCMParameterSpec spec = initializeForWrap(kek, aesCipher);
var dek = generator.get();
LOGGER.warn("KWDEBUG created dek " + System.identityHashCode(dek) + " Len: + " + dek.getEncoded().length);
LOGGER.warn("KWDEBUG created dek " + dek);


byte[] edek;
try {
edek = aesCipher.wrap(dek);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright Kroxylicious Authors.
*
* Licensed under the Apache Software License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
*/

package io.kroxylicious.kms.provider.kroxylicious.inmemory;

import java.util.Map;
import java.util.ServiceLoader;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
import javax.crypto.SecretKey;

import edu.umd.cs.findbugs.annotations.NonNull;

import io.kroxylicious.kms.service.KmsService;
import io.kroxylicious.proxy.plugin.Plugin;

@Plugin(configType = InMemoryKmsService.Config.class)
public class InMemoryKmsService implements KmsService<InMemoryKmsService.Config, UUID, InMemoryEdek> {

// public static void main(String argv[]) throws Exception {
// String string = UUID.randomUUID().toString();
// System.out.println(string);
//
// KeyGenerator aes = KeyGenerator.getInstance("AES");
// aes.init(256);
// var key = aes.generateKey().getEncoded();
// System.out.println(key.length);
//
// String s = Base64.getEncoder().encodeToString(key);
// System.out.println(s);
//
// }

public static InMemoryKmsService newInstance() {
return (InMemoryKmsService) ServiceLoader.load(KmsService.class).stream()
.filter(p -> p.type() == InMemoryKmsService.class)
.findFirst()
.map(ServiceLoader.Provider::get)
.orElse(null);
}

public record Config(
Map<UUID, SecretKey> keys,
Map<String, UUID> aliases) {}

@NonNull
@Override
public InMemoryKms buildKms(Config options) {
var numGeneratedDeks = new AtomicInteger();
return new InMemoryKms(12,
128,
options.keys(),
options.aliases(),
numGeneratedDeks);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@
#

io.kroxylicious.kms.provider.kroxylicious.inmemory.UnitTestingKmsService
io.kroxylicious.kms.provider.kroxylicious.inmemory.IntegrationTestingKmsService
io.kroxylicious.kms.provider.kroxylicious.inmemory.IntegrationTestingKmsService
io.kroxylicious.kms.provider.kroxylicious.inmemory.InMemoryKmsService
13 changes: 0 additions & 13 deletions kroxylicious-runtime/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -278,19 +278,6 @@
</build>

<profiles>
<profile>
<id>withAdditionalFilters</id>
<dependencies>
<dependency>
<groupId>io.kroxylicious</groupId>
<artifactId>kroxylicious-multitenant</artifactId>
</dependency>
<dependency>
<groupId>io.kroxylicious</groupId>
<artifactId>kroxylicious-record-validation</artifactId>
</dependency>
</dependencies>
</profile>
<profile>
<id>debug</id>
<dependencyManagement>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import java.lang.reflect.Constructor;
import java.lang.reflect.Parameter;

import javax.crypto.SecretKey;

import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.PropertyAccessor;
Expand Down Expand Up @@ -87,6 +89,8 @@ public static ObjectMapper createObjectMapper() {
.registerModule(new ParameterNamesModule())
.registerModule(new Jdk8Module())
.registerModule(new SimpleModule().addSerializer(HostPort.class, new ToStringSerializer()))
.registerModule(new SimpleModule().addSerializer(SecretKey.class, new SecretKeySerializer()))
.registerModule(new SimpleModule().addDeserializer(SecretKey.class, new SecretKeyDeserializer()))
.setVisibility(PropertyAccessor.ALL, Visibility.NONE)
.setVisibility(PropertyAccessor.FIELD, Visibility.ANY)
.setVisibility(PropertyAccessor.CREATOR, Visibility.ANY)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright Kroxylicious Authors.
*
* Licensed under the Apache Software License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
*/

package io.kroxylicious.proxy.config;

import java.io.IOException;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.TreeNode;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.node.ValueNode;

class SecretKeyDeserializer extends StdDeserializer<SecretKey> {
private final ObjectMapper MAPPER = new ObjectMapper();

protected SecretKeyDeserializer() {
super(SecretKey.class);
}

public SecretKey deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
TreeNode tree = p.getCodec().readTree(p);
TreeNode algoNode = tree.get("algo");
TreeNode keyNode = tree.get("key");
if (algoNode != null && algoNode.isValueNode()) {
if (keyNode != null && keyNode.isValueNode()) {
String algo = ((ValueNode) algoNode).textValue();
byte[] key = ((ValueNode) keyNode).binaryValue();
return new SecretKeySpec(key, algo);
}
else {
throw new IllegalArgumentException("key field is absent or is not a value");
}
}
else {
throw new IllegalArgumentException("algo field is absent or is not text");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright Kroxylicious Authors.
*
* Licensed under the Apache Software License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
*/

package io.kroxylicious.proxy.config;

import java.io.IOException;

import javax.crypto.SecretKey;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;

class SecretKeySerializer extends StdSerializer<SecretKey> {
protected SecretKeySerializer() {
super(SecretKey.class);
}

public void serialize(SecretKey value, JsonGenerator gen, SerializerProvider provider) throws IOException {
gen.writeStringField("algo", value.getAlgorithm());
gen.writeBinaryField("key", value.getEncoded());
}
}
Loading

0 comments on commit 505c780

Please sign in to comment.