Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DGS-7826 DGS-7828 DGS-7830 Add kek/dek timestamp, dek version #2730

Merged
merged 1 commit into from Aug 18, 2023
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -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 {
Expand Down Expand Up @@ -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()) {
Expand Down
Expand Up @@ -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;
}
Expand All @@ -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);
Expand All @@ -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) {
Expand All @@ -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) {
Expand Down Expand Up @@ -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;
}
Expand All @@ -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);
}
}
Expand All @@ -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);
}
}
Expand Down Expand Up @@ -349,8 +353,8 @@ static class KekInfo extends Kek {
private final boolean deleted;

public KekInfo(String name, String kmsType, String kmsKeyId, Map<String, String> 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;
}

Expand Down Expand Up @@ -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;
}

Expand Down
Expand Up @@ -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
rayokota marked this conversation as resolved.
Show resolved Hide resolved
) {
this.kekName = kekName;
this.subject = subject;
this.version = version;
this.algorithm = algorithm;
this.encryptedKeyMaterial = encryptedKeyMaterial;
this.keyMaterial = keyMaterial;
this.timestamp = timestamp;
}

@JsonProperty("kekName")
Expand All @@ -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;
Expand All @@ -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) {
Expand All @@ -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
Expand Down
Expand Up @@ -51,6 +51,7 @@ public class Kek {
private final SortedMap<String, String> kmsProps;
private final String doc;
private final boolean shared;
private final Long timestamp;

@JsonCreator
public Kek(
Expand All @@ -59,7 +60,8 @@ public Kek(
@JsonProperty("kmsKeyId") String kmsKeyId,
@JsonProperty("kmsProps") Map<String, String> kmsProps,
@JsonProperty("doc") String doc,
@JsonProperty("shared") boolean shared
@JsonProperty("shared") boolean shared,
@JsonProperty("ts") Long timestamp
) {
this.name = name;
this.kmsType = kmsType;
Expand All @@ -70,6 +72,7 @@ public Kek(
this.kmsProps = Collections.unmodifiableSortedMap(sortedKmsProps);
this.doc = doc;
this.shared = shared;
this.timestamp = timestamp;
}

@JsonProperty("name")
Expand Down Expand Up @@ -102,6 +105,11 @@ public boolean isShared() {
return this.shared;
}

@JsonProperty("ts")
public Long getTimestamp() {
return this.timestamp;
}

@JsonIgnore
public Aead toAead(Map<String, ?> configs) throws GeneralSecurityException {
String kekUrl = getKmsType() + KMS_TYPE_SUFFIX + getKmsKeyId();
Expand Down
12 changes: 9 additions & 3 deletions dek-registry/generated/swagger-ui/dek-registry-api-spec.yaml
Expand Up @@ -320,6 +320,9 @@ components:
type: string
subject:
type: string
version:
type: integer
format: int32
algorithm:
type: string
enum:
Expand All @@ -330,6 +333,9 @@ components:
type: string
keyMaterial:
type: string
ts:
type: integer
format: int64
CreateDekRequest:
type: object
properties:
Expand Down Expand Up @@ -360,6 +366,9 @@ components:
type: string
shared:
type: boolean
ts:
type: integer
format: int64
CreateKekRequest:
type: object
properties:
Expand All @@ -377,9 +386,6 @@ components:
type: string
shared:
type: boolean
kmsKeyid:
type: string
writeOnly: true
UpdateKekRequest:
type: object
properties:
Expand Down
Expand Up @@ -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;
Expand All @@ -40,13 +41,15 @@ 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
) {
super(KeyType.DEK, deleted);
this.kekName = kekName;
this.subject = subject;
this.version = version;
this.algorithm = algorithm;
this.encryptedKeyMaterial = encryptedKeyMaterial;
}
Expand All @@ -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;
Expand Down Expand Up @@ -93,18 +101,21 @@ 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);
}

@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);
}
}