diff --git a/client-encryption/src/main/java/io/confluent/kafka/schemaregistry/encryption/FieldEncryptionExecutor.java b/client-encryption/src/main/java/io/confluent/kafka/schemaregistry/encryption/FieldEncryptionExecutor.java index 62403575354..41ffc98a499 100644 --- a/client-encryption/src/main/java/io/confluent/kafka/schemaregistry/encryption/FieldEncryptionExecutor.java +++ b/client-encryption/src/main/java/io/confluent/kafka/schemaregistry/encryption/FieldEncryptionExecutor.java @@ -191,17 +191,11 @@ class FieldEncryptionExecutorTransform implements FieldTransform { private Cryptor cryptor; private String kekName; private KekInfo kek; - private DekInfo dek; public void init(RuleContext ctx) throws RuleException { - try { - cryptor = getCryptor(ctx); - kekName = getKekName(ctx); - kek = getKek(ctx, kekName); - dek = getDek(ctx, kekName, kek); - } catch (GeneralSecurityException e) { - throw new RuleException(e); - } + cryptor = getCryptor(ctx); + kekName = getKekName(ctx); + kek = getKek(ctx, kekName); } protected String getKekName(RuleContext ctx) throws RuleException { @@ -387,6 +381,7 @@ private DekInfo storeDekToRegistry(RuleContext ctx, DekId key, DekInfo dekInfo) public Object transform(RuleContext ctx, FieldContext fieldCtx, Object fieldValue) throws RuleException { try { + DekInfo dek = getDek(ctx, kekName, kek); byte[] plaintext; byte[] ciphertext; switch (ctx.ruleMode()) { diff --git a/dek-registry-client/src/main/java/io/confluent/dekregistry/client/MockDekRegistryClient.java b/dek-registry-client/src/main/java/io/confluent/dekregistry/client/MockDekRegistryClient.java index afb92ddf639..515e13cd617 100644 --- a/dek-registry-client/src/main/java/io/confluent/dekregistry/client/MockDekRegistryClient.java +++ b/dek-registry-client/src/main/java/io/confluent/dekregistry/client/MockDekRegistryClient.java @@ -123,7 +123,8 @@ public Kek createKek( if (keks.containsKey(keyId)) { throw new RestClientException("Key " + name + " already exists", 409, 40972); } - KekInfo key = new KekInfo(name, kmsType, kmsKeyId, kmsProps, doc, shared, false); + KekInfo key = new KekInfo(name, kmsType, kmsKeyId, + kmsProps, doc, shared, System.currentTimeMillis(), false); keks.put(keyId, key); return key; } @@ -139,7 +140,10 @@ public Dek createDek( if (deks.containsKey(keyId)) { throw new RestClientException("Key " + subject + " already exists", 409, 40972); } - DekInfo key = new DekInfo(kekName, subject, algorithm, encryptedKeyMaterial, null, false); + // NOTE (version): in the future we may allow a version to be passed + int version = 1; + DekInfo key = new DekInfo(kekName, subject, version, algorithm, + encryptedKeyMaterial, null, System.currentTimeMillis(), false); key = maybeGenerateEncryptedDek(key); if (key.getEncryptedKeyMaterial() == null) { throw new RestClientException("Could not generate dek for " + subject, 500, 50070); @@ -160,8 +164,8 @@ protected DekInfo maybeGenerateEncryptedDek(DekInfo key) byte[] encryptedDek = aead.encrypt(rawDek, EMPTY_AAD); String encryptedDekStr = new String(Base64.getEncoder().encode(encryptedDek), StandardCharsets.UTF_8); - key = new DekInfo(key.getKekName(), key.getSubject(), key.getAlgorithm(), - encryptedDekStr, null, key.isDeleted()); + key = new DekInfo(key.getKekName(), key.getSubject(), key.getVersion(), key.getAlgorithm(), + encryptedDekStr, null, key.getTimestamp(), key.isDeleted()); } return key; } catch (GeneralSecurityException e) { @@ -182,8 +186,8 @@ protected DekInfo maybeGenerateRawDek(DekInfo key) String rawDekStr = new String(Base64.getEncoder().encode(rawDek), StandardCharsets.UTF_8); // Copy dek - key = new DekInfo(key.getKekName(), key.getSubject(), key.getAlgorithm(), - key.getEncryptedKeyMaterial(), rawDekStr, key.isDeleted()); + key = new DekInfo(key.getKekName(), key.getSubject(), key.getVersion(), key.getAlgorithm(), + key.getEncryptedKeyMaterial(), rawDekStr, key.getTimestamp(), key.isDeleted()); } return key; } catch (GeneralSecurityException e) { @@ -212,8 +216,8 @@ public Kek updateKek( if (shared == null) { shared = key.isShared(); } - KekInfo newKey = new KekInfo(name, key.getKmsType(), - key.getKmsKeyId(), kmsProps, doc, shared, false); + KekInfo newKey = new KekInfo(name, key.getKmsType(), key.getKmsKeyId(), + kmsProps, doc, shared, System.currentTimeMillis(), false); keks.put(keyId, newKey); return key; } @@ -229,8 +233,8 @@ public void deleteKek(String kekName, boolean permanentDelete) if (permanentDelete) { keks.remove(keyId); } else { - KekInfo newKey = new KekInfo(kekName, key.getKmsType(), - key.getKmsKeyId(), key.getKmsProps(), key.getDoc(), key.isShared(), true); + KekInfo newKey = new KekInfo(kekName, key.getKmsType(), key.getKmsKeyId(), + key.getKmsProps(), key.getDoc(), key.isShared(), System.currentTimeMillis(), true); keks.put(keyId, newKey); } } @@ -257,8 +261,8 @@ public void deleteDek( if (permanentDelete) { deks.remove(keyId); } else { - DekInfo newKey = new DekInfo(kekName, key.getSubject(), key.getAlgorithm(), - key.getEncryptedKeyMaterial(), key.getKeyMaterial(), true); + DekInfo newKey = new DekInfo(kekName, key.getSubject(), key.getVersion(), key.getAlgorithm(), + key.getEncryptedKeyMaterial(), key.getKeyMaterial(), System.currentTimeMillis(), true); deks.put(keyId, newKey); } } @@ -349,8 +353,8 @@ static class KekInfo extends Kek { private final boolean deleted; public KekInfo(String name, String kmsType, String kmsKeyId, Map kmsProps, - String doc, boolean shared, boolean deleted) { - super(name, kmsType, kmsKeyId, kmsProps, doc, shared); + String doc, boolean shared, Long timestamp, boolean deleted) { + super(name, kmsType, kmsKeyId, kmsProps, doc, shared, timestamp); this.deleted = deleted; } @@ -383,9 +387,9 @@ static class DekInfo extends Dek { private final boolean deleted; - public DekInfo(String kekName, String subject, DekFormat algorithm, - String encryptedKeyMaterial, String keyMaterial, boolean deleted) { - super(kekName, subject, algorithm, encryptedKeyMaterial, keyMaterial); + public DekInfo(String kekName, String subject, int version, DekFormat algorithm, + String encryptedKeyMaterial, String keyMaterial, Long timestamp, boolean deleted) { + super(kekName, subject, version, algorithm, encryptedKeyMaterial, keyMaterial, timestamp); this.deleted = deleted; } diff --git a/dek-registry-client/src/main/java/io/confluent/dekregistry/client/rest/entities/Dek.java b/dek-registry-client/src/main/java/io/confluent/dekregistry/client/rest/entities/Dek.java index 1a8df25bb8f..fa83e34356e 100644 --- a/dek-registry-client/src/main/java/io/confluent/dekregistry/client/rest/entities/Dek.java +++ b/dek-registry-client/src/main/java/io/confluent/dekregistry/client/rest/entities/Dek.java @@ -32,23 +32,29 @@ public class Dek { private final String kekName; private final String subject; + private final int version; private final DekFormat algorithm; private final String encryptedKeyMaterial; private final String keyMaterial; + private final Long timestamp; @JsonCreator public Dek( @JsonProperty("kekName") String kekName, @JsonProperty("subject") String subject, + @JsonProperty("version") int version, @JsonProperty("algorithm") DekFormat algorithm, @JsonProperty("encryptedKeyMaterial") String encryptedKeyMaterial, - @JsonProperty("keyMaterial") String keyMaterial + @JsonProperty("keyMaterial") String keyMaterial, + @JsonProperty("ts") Long timestamp ) { this.kekName = kekName; this.subject = subject; + this.version = version; this.algorithm = algorithm; this.encryptedKeyMaterial = encryptedKeyMaterial; this.keyMaterial = keyMaterial; + this.timestamp = timestamp; } @JsonProperty("kekName") @@ -61,6 +67,11 @@ public String getSubject() { return this.subject; } + @JsonProperty("version") + public int getVersion() { + return this.version; + } + @JsonProperty("algorithm") public DekFormat getAlgorithm() { return this.algorithm; @@ -76,6 +87,11 @@ public String getKeyMaterial() { return this.keyMaterial; } + @JsonProperty("ts") + public Long getTimestamp() { + return this.timestamp; + } + @Override public boolean equals(Object o) { if (this == o) { @@ -85,16 +101,17 @@ public boolean equals(Object o) { return false; } Dek dek = (Dek) o; - return Objects.equals(kekName, dek.kekName) + return version == dek.version + && Objects.equals(kekName, dek.kekName) && Objects.equals(subject, dek.subject) - && Objects.equals(algorithm, dek.algorithm) + && algorithm == dek.algorithm && Objects.equals(encryptedKeyMaterial, dek.encryptedKeyMaterial) && Objects.equals(keyMaterial, dek.keyMaterial); } @Override public int hashCode() { - return Objects.hash(kekName, subject, algorithm, encryptedKeyMaterial, keyMaterial); + return Objects.hash(kekName, subject, version, algorithm, encryptedKeyMaterial, keyMaterial); } @Override diff --git a/dek-registry-client/src/main/java/io/confluent/dekregistry/client/rest/entities/Kek.java b/dek-registry-client/src/main/java/io/confluent/dekregistry/client/rest/entities/Kek.java index 916fe86c5c3..df18560563c 100644 --- a/dek-registry-client/src/main/java/io/confluent/dekregistry/client/rest/entities/Kek.java +++ b/dek-registry-client/src/main/java/io/confluent/dekregistry/client/rest/entities/Kek.java @@ -51,6 +51,7 @@ public class Kek { private final SortedMap kmsProps; private final String doc; private final boolean shared; + private final Long timestamp; @JsonCreator public Kek( @@ -59,7 +60,8 @@ public Kek( @JsonProperty("kmsKeyId") String kmsKeyId, @JsonProperty("kmsProps") Map kmsProps, @JsonProperty("doc") String doc, - @JsonProperty("shared") boolean shared + @JsonProperty("shared") boolean shared, + @JsonProperty("ts") Long timestamp ) { this.name = name; this.kmsType = kmsType; @@ -70,6 +72,7 @@ public Kek( this.kmsProps = Collections.unmodifiableSortedMap(sortedKmsProps); this.doc = doc; this.shared = shared; + this.timestamp = timestamp; } @JsonProperty("name") @@ -102,6 +105,11 @@ public boolean isShared() { return this.shared; } + @JsonProperty("ts") + public Long getTimestamp() { + return this.timestamp; + } + @JsonIgnore public Aead toAead(Map configs) throws GeneralSecurityException { String kekUrl = getKmsType() + KMS_TYPE_SUFFIX + getKmsKeyId(); diff --git a/dek-registry/generated/swagger-ui/dek-registry-api-spec.yaml b/dek-registry/generated/swagger-ui/dek-registry-api-spec.yaml index ad0ad608c3e..37c7d004f34 100644 --- a/dek-registry/generated/swagger-ui/dek-registry-api-spec.yaml +++ b/dek-registry/generated/swagger-ui/dek-registry-api-spec.yaml @@ -320,6 +320,9 @@ components: type: string subject: type: string + version: + type: integer + format: int32 algorithm: type: string enum: @@ -330,6 +333,9 @@ components: type: string keyMaterial: type: string + ts: + type: integer + format: int64 CreateDekRequest: type: object properties: @@ -360,6 +366,9 @@ components: type: string shared: type: boolean + ts: + type: integer + format: int64 CreateKekRequest: type: object properties: @@ -377,9 +386,6 @@ components: type: string shared: type: boolean - kmsKeyid: - type: string - writeOnly: true UpdateKekRequest: type: object properties: diff --git a/dek-registry/src/main/java/io/confluent/dekregistry/storage/DataEncryptionKey.java b/dek-registry/src/main/java/io/confluent/dekregistry/storage/DataEncryptionKey.java index 6a0feac6f8f..75265b8a88c 100644 --- a/dek-registry/src/main/java/io/confluent/dekregistry/storage/DataEncryptionKey.java +++ b/dek-registry/src/main/java/io/confluent/dekregistry/storage/DataEncryptionKey.java @@ -32,6 +32,7 @@ public class DataEncryptionKey extends EncryptionKey { private final String kekName; private final String subject; + private final int version; private final DekFormat algorithm; private final String encryptedKeyMaterial; private String keyMaterial; @@ -40,6 +41,7 @@ public class DataEncryptionKey extends EncryptionKey { public DataEncryptionKey( @JsonProperty("kekName") String kekName, @JsonProperty("subject") String subject, + @JsonProperty("version") int version, @JsonProperty("algorithm") DekFormat algorithm, @JsonProperty("encryptedKeyMaterial") String encryptedKeyMaterial, @JsonProperty("deleted") boolean deleted @@ -47,6 +49,7 @@ public DataEncryptionKey( super(KeyType.DEK, deleted); this.kekName = kekName; this.subject = subject; + this.version = version; this.algorithm = algorithm; this.encryptedKeyMaterial = encryptedKeyMaterial; } @@ -61,6 +64,11 @@ public String getSubject() { return this.subject; } + @JsonProperty("version") + public int getVersion() { + return this.version; + } + @JsonProperty("algorithm") public DekFormat getAlgorithm() { return this.algorithm; @@ -93,7 +101,8 @@ public boolean equals(Object o) { return false; } DataEncryptionKey that = (DataEncryptionKey) o; - return Objects.equals(kekName, that.kekName) + return version == that.version + && Objects.equals(kekName, that.kekName) && Objects.equals(subject, that.subject) && algorithm == that.algorithm && Objects.equals(encryptedKeyMaterial, that.encryptedKeyMaterial); @@ -101,10 +110,12 @@ public boolean equals(Object o) { @Override public int hashCode() { - return Objects.hash(super.hashCode(), kekName, subject, algorithm, encryptedKeyMaterial); + return Objects.hash( + super.hashCode(), kekName, subject, version, algorithm, encryptedKeyMaterial); } public Dek toDekEntity() { - return new Dek(kekName, subject, algorithm, encryptedKeyMaterial, keyMaterial); + return new Dek( + kekName, subject, version, algorithm, encryptedKeyMaterial, keyMaterial, timestamp); } } diff --git a/dek-registry/src/main/java/io/confluent/dekregistry/storage/DataEncryptionKeyId.java b/dek-registry/src/main/java/io/confluent/dekregistry/storage/DataEncryptionKeyId.java index 4537e022de8..db9b072024e 100644 --- a/dek-registry/src/main/java/io/confluent/dekregistry/storage/DataEncryptionKeyId.java +++ b/dek-registry/src/main/java/io/confluent/dekregistry/storage/DataEncryptionKeyId.java @@ -30,6 +30,7 @@ public class DataEncryptionKeyId extends EncryptionKeyId { private final String kekName; private final String subject; + private final int version; private final DekFormat algorithm; @JsonCreator @@ -37,11 +38,13 @@ public DataEncryptionKeyId( @JsonProperty("tenant") String tenant, @JsonProperty("kekName") String kekName, @JsonProperty("subject") String subject, + @JsonProperty("version") int version, @JsonProperty("algorithm") DekFormat algorithm ) { super(tenant, KeyType.DEK); this.kekName = kekName; this.subject = subject; + this.version = version; this.algorithm = algorithm; } @@ -55,6 +58,11 @@ public String getSubject() { return this.subject; } + @JsonProperty("version") + public int getVersion() { + return this.version; + } + @JsonProperty("algorithm") public DekFormat getAlgorithm() { return this.algorithm; @@ -72,14 +80,15 @@ public boolean equals(Object o) { return false; } DataEncryptionKeyId that = (DataEncryptionKeyId) o; - return Objects.equals(kekName, that.kekName) + return version == that.version + && Objects.equals(kekName, that.kekName) && Objects.equals(subject, that.subject) && algorithm == that.algorithm; } @Override public int hashCode() { - return Objects.hash(super.hashCode(), kekName, subject, algorithm); + return Objects.hash(super.hashCode(), kekName, subject, version, algorithm); } @Override @@ -97,22 +106,9 @@ public int compareTo(EncryptionKeyId o) { } else if (that.getKekName() == null) { return 1; } else { - int kmsTypeComparison = this.getKekName().compareTo(that.getKekName()); - if (kmsTypeComparison != 0) { - return kmsTypeComparison < 0 ? -1 : 1; - } - } - - if (this.getKekName() == null && that.getKekName() == null) { - // pass - } else if (this.getKekName() == null) { - return -1; - } else if (that.getKekName() == null) { - return 1; - } else { - int kmsKeyIdComparison = this.getKekName().compareTo(that.getKekName()); - if (kmsKeyIdComparison != 0) { - return kmsKeyIdComparison < 0 ? -1 : 1; + int kekNameComparison = this.getKekName().compareTo(that.getKekName()); + if (kekNameComparison != 0) { + return kekNameComparison < 0 ? -1 : 1; } } @@ -129,6 +125,10 @@ public int compareTo(EncryptionKeyId o) { } } + if (this.getVersion() != that.getVersion()) { + return (this.getVersion() < that.getVersion() ? -1 : 1); + } + if (this.getAlgorithm() == null && that.getAlgorithm() == null) { return 0; } else if (this.getAlgorithm() == null) { diff --git a/dek-registry/src/main/java/io/confluent/dekregistry/storage/DekRegistry.java b/dek-registry/src/main/java/io/confluent/dekregistry/storage/DekRegistry.java index abdfb7cde88..4d21a80cb1e 100644 --- a/dek-registry/src/main/java/io/confluent/dekregistry/storage/DekRegistry.java +++ b/dek-registry/src/main/java/io/confluent/dekregistry/storage/DekRegistry.java @@ -88,6 +88,7 @@ public class DekRegistry implements Closeable { private static final Logger log = LoggerFactory.getLogger(DekRegistry.class); + public static final int MIN_VERSION = 1; public static final byte[] EMPTY_AAD = new byte[0]; public static final String X_FORWARD_HEADER = DekRegistryRestService.X_FORWARD_HEADER; @@ -303,10 +304,10 @@ protected List> getDeks(String tenant) List> result = new ArrayList<>(); DataEncryptionKeyId key1 = new DataEncryptionKeyId( tenant, String.valueOf(Character.MIN_VALUE), - String.valueOf(Character.MIN_VALUE), DekFormat.AES128_GCM); + String.valueOf(Character.MIN_VALUE), MIN_VERSION, DekFormat.AES128_GCM); DataEncryptionKeyId key2 = new DataEncryptionKeyId( tenant, String.valueOf(Character.MAX_VALUE), - String.valueOf(Character.MAX_VALUE), DekFormat.AES256_SIV); + String.valueOf(Character.MAX_VALUE), Integer.MAX_VALUE, DekFormat.AES256_SIV); try (KeyValueIterator iter = keys().range(key1, true, key2, false)) { while (iter.hasNext()) { @@ -319,9 +320,11 @@ protected List> getDeks(String tenant) protected List> getDeks(String tenant, String kekName) { List> result = new ArrayList<>(); DataEncryptionKeyId key1 = new DataEncryptionKeyId( - tenant, kekName, String.valueOf(Character.MIN_VALUE), DekFormat.AES128_GCM); + tenant, kekName, String.valueOf(Character.MIN_VALUE), + MIN_VERSION, DekFormat.AES128_GCM); DataEncryptionKeyId key2 = new DataEncryptionKeyId( - tenant, kekName, String.valueOf(Character.MAX_VALUE), DekFormat.AES256_SIV); + tenant, kekName, String.valueOf(Character.MAX_VALUE), + Integer.MAX_VALUE, DekFormat.AES256_SIV); try (KeyValueIterator iter = keys().range(key1, true, key2, false)) { while (iter.hasNext()) { @@ -337,7 +340,10 @@ public DataEncryptionKey getDek(String kekName, String subject, DekFormat algori if (algorithm == null) { algorithm = DekFormat.AES256_GCM; } - DataEncryptionKeyId keyId = new DataEncryptionKeyId(tenant, kekName, subject, algorithm); + // NOTE (version): in the future we may allow a version to be passed + int version = MIN_VERSION; + DataEncryptionKeyId keyId = new DataEncryptionKeyId( + tenant, kekName, subject, version, algorithm); DataEncryptionKey key = (DataEncryptionKey) keys.get(keyId); if (key != null && (!key.isDeleted() || lookupDeleted)) { key = maybeGenerateRawDek(key); @@ -483,14 +489,16 @@ private DataEncryptionKey createDek(String kekName, CreateDekRequest request) DekFormat algorithm = request.getAlgorithm() != null ? request.getAlgorithm() : DekFormat.AES256_GCM; + // NOTE (version): in the future we may allow a version to be passed + int version = MIN_VERSION; DataEncryptionKeyId keyId = new DataEncryptionKeyId( - tenant, kekName, request.getSubject(), algorithm); + tenant, kekName, request.getSubject(), version, algorithm); if (keys.containsKey(keyId)) { throw new AlreadyExistsException(request.getSubject()); } DataEncryptionKey key = new DataEncryptionKey(kekName, request.getSubject(), - request.getAlgorithm(), request.getEncryptedKeyMaterial(), false); + version, request.getAlgorithm(), request.getEncryptedKeyMaterial(), false); key = maybeGenerateEncryptedDek(key); if (key.getEncryptedKeyMaterial() == null) { throw new DekGenerationException("Could not generate dek for " + request.getSubject()); @@ -510,8 +518,8 @@ protected DataEncryptionKey maybeGenerateEncryptedDek(DataEncryptionKey key) { byte[] encryptedDek = aead.encrypt(rawDek, EMPTY_AAD); String encryptedDekStr = new String(Base64.getEncoder().encode(encryptedDek), StandardCharsets.UTF_8); - key = new DataEncryptionKey(key.getKekName(), key.getSubject(), key.getAlgorithm(), - encryptedDekStr, key.isDeleted()); + key = new DataEncryptionKey(key.getKekName(), key.getSubject(), key.getVersion(), + key.getAlgorithm(), encryptedDekStr, key.isDeleted()); } return key; } catch (GeneralSecurityException e) { @@ -532,8 +540,8 @@ protected DataEncryptionKey maybeGenerateRawDek(DataEncryptionKey key) { String rawDekStr = new String(Base64.getEncoder().encode(rawDek), StandardCharsets.UTF_8); // Copy dek - key = new DataEncryptionKey(key.getKekName(), key.getSubject(), key.getAlgorithm(), - key.getEncryptedKeyMaterial(), key.isDeleted()); + key = new DataEncryptionKey(key.getKekName(), key.getSubject(), key.getVersion(), + key.getAlgorithm(), key.getEncryptedKeyMaterial(), key.isDeleted()); key.setKeyMaterial(rawDekStr); } return key; @@ -737,7 +745,9 @@ private void deleteDek(String name, String subject, DekFormat algorithm, boolean algorithm = DekFormat.AES256_GCM; } String tenant = schemaRegistry.tenant(); - DataEncryptionKeyId keyId = new DataEncryptionKeyId(tenant, name, subject, algorithm); + // NOTE (version): in the future we may allow a version to be passed + int version = MIN_VERSION; + DataEncryptionKeyId keyId = new DataEncryptionKeyId(tenant, name, subject, version, algorithm); DataEncryptionKey key = (DataEncryptionKey) keys.get(keyId); if (key == null) { return; @@ -750,7 +760,7 @@ private void deleteDek(String name, String subject, DekFormat algorithm, boolean } else { if (!key.isDeleted()) { DataEncryptionKey newKey = new DataEncryptionKey(name, key.getSubject(), - key.getAlgorithm(), key.getEncryptedKeyMaterial(), true); + key.getVersion(), key.getAlgorithm(), key.getEncryptedKeyMaterial(), true); keys.put(keyId, newKey); } } diff --git a/dek-registry/src/main/java/io/confluent/dekregistry/storage/EncryptionKey.java b/dek-registry/src/main/java/io/confluent/dekregistry/storage/EncryptionKey.java index 8b4460ad6cf..851714c56e3 100644 --- a/dek-registry/src/main/java/io/confluent/dekregistry/storage/EncryptionKey.java +++ b/dek-registry/src/main/java/io/confluent/dekregistry/storage/EncryptionKey.java @@ -34,10 +34,10 @@ }) public abstract class EncryptionKey { - private final KeyType type; - private final boolean deleted; - private Long offset; - private Long timestamp; + protected final KeyType type; + protected final boolean deleted; + protected Long offset; + protected Long timestamp; @JsonCreator public EncryptionKey( diff --git a/dek-registry/src/main/java/io/confluent/dekregistry/storage/KeyEncryptionKey.java b/dek-registry/src/main/java/io/confluent/dekregistry/storage/KeyEncryptionKey.java index e54bb353fac..02a33ab918b 100644 --- a/dek-registry/src/main/java/io/confluent/dekregistry/storage/KeyEncryptionKey.java +++ b/dek-registry/src/main/java/io/confluent/dekregistry/storage/KeyEncryptionKey.java @@ -116,6 +116,6 @@ public int hashCode() { } public Kek toKekEntity() { - return new Kek(name, kmsType, kmsKeyId, kmsProps, doc, shared); + return new Kek(name, kmsType, kmsKeyId, kmsProps, doc, shared, timestamp); } } diff --git a/dek-registry/src/test/java/io/confluent/dekregistry/web/rest/RestApiTest.java b/dek-registry/src/test/java/io/confluent/dekregistry/web/rest/RestApiTest.java index 73edecf333b..cf7f24d3649 100644 --- a/dek-registry/src/test/java/io/confluent/dekregistry/web/rest/RestApiTest.java +++ b/dek-registry/src/test/java/io/confluent/dekregistry/web/rest/RestApiTest.java @@ -82,7 +82,7 @@ public void testBasic() throws Exception { String subject2 = "mysubject2"; String subject3 = "mysubject3"; DekFormat algorithm = DekFormat.AES256_GCM; - Kek kek = new Kek(kekName, kmsType, kmsKeyId, null, null, false); + Kek kek = new Kek(kekName, kmsType, kmsKeyId, null, null, false, null); // Create kek Kek newKek = client.createKek(kekName, kmsType, kmsKeyId, null, null, false); @@ -165,7 +165,7 @@ public void testBasic() throws Exception { byte[] encryptedDek = aead.encrypt(rawDek, new byte[0]); String encryptedDekStr = new String(Base64.getEncoder().encode(encryptedDek), StandardCharsets.UTF_8); - Dek dek = new Dek(kekName, subject, algorithm, encryptedDekStr, null); + Dek dek = new Dek(kekName, subject, 1, algorithm, encryptedDekStr, null, null); // Create dek Dek newDek = client.createDek(kekName, subject, algorithm, encryptedDekStr); @@ -182,7 +182,7 @@ public void testBasic() throws Exception { newDek = client.getDek(kekName, subject, algorithm, false); assertEquals(dek, newDek); - Kek kek2 = new Kek(kekName, kmsType, kmsKeyId, kmsProps, doc, true); + Kek kek2 = new Kek(kekName, kmsType, kmsKeyId, kmsProps, doc, true, null); // Set shared flag to true newKek = client.updateKek(kekName, kmsProps, doc, true); @@ -192,7 +192,7 @@ public void testBasic() throws Exception { fakeTicker.advance(61, TimeUnit.SECONDS); // Dek now has decrypted key material - Dek dek2 = new Dek(kekName, subject, algorithm, encryptedDekStr, rawDekStr); + Dek dek2 = new Dek(kekName, subject, 1, algorithm, encryptedDekStr, rawDekStr, null); newDek = client.getDek(kekName, subject, algorithm, true); assertEquals(dek2, newDek); @@ -274,7 +274,7 @@ public void testUnknownKmsType() throws Exception { String subject = "mysubject"; String subject2 = "mysubject2"; DekFormat algorithm = DekFormat.AES256_GCM; - Kek kek = new Kek(kekName, kmsType, kmsKeyId, null, null, false); + Kek kek = new Kek(kekName, kmsType, kmsKeyId, null, null, false, null); // Create kek Kek newKek = client.createKek(kekName, kmsType, kmsKeyId, null, null, false); @@ -287,13 +287,13 @@ public void testUnknownKmsType() throws Exception { assertEquals(Collections.singletonList(kekName), keks); // Use the test-kms type to generate a dummy dek locally - Kek testKek = new Kek(kekName, "test-kms", kmsKeyId, null, null, false); + Kek testKek = new Kek(kekName, "test-kms", kmsKeyId, null, null, false, null); byte[] rawDek = new Cryptor(algorithm).generateKey(); Aead aead = testKek.toAead(Collections.emptyMap()); byte[] encryptedDek = aead.encrypt(rawDek, new byte[0]); String encryptedDekStr = new String(Base64.getEncoder().encode(encryptedDek), StandardCharsets.UTF_8); - Dek dek = new Dek(kekName, subject, algorithm, encryptedDekStr, null); + Dek dek = new Dek(kekName, subject, 1, algorithm, encryptedDekStr, null, null); // Create dek Dek newDek = client.createDek(kekName, subject, algorithm, encryptedDekStr); @@ -312,7 +312,7 @@ public void testUnknownKmsType() throws Exception { Map kmsProps = Collections.singletonMap("hi", "there"); String doc = "mydoc"; - Kek kek2 = new Kek(kekName, kmsType, kmsKeyId, kmsProps, doc, true); + Kek kek2 = new Kek(kekName, kmsType, kmsKeyId, kmsProps, doc, true, null); // Set shared flag to true newKek = client.updateKek(kekName, kmsProps, doc, true); @@ -322,7 +322,7 @@ public void testUnknownKmsType() throws Exception { fakeTicker.advance(61, TimeUnit.SECONDS); // Dek still does not have decrypted key material because kms type is unknown - Dek dek2 = new Dek(kekName, subject, algorithm, encryptedDekStr, null); + Dek dek2 = new Dek(kekName, subject, 1, algorithm, encryptedDekStr, null, null); newDek = client.getDek(kekName, subject, algorithm, true); assertEquals(dek2, newDek); }