Skip to content

Commit

Permalink
Adding more work on salt encryption
Browse files Browse the repository at this point in the history
  • Loading branch information
cody-constine-ttd committed Dec 6, 2024
1 parent 6885a54 commit 36235b0
Show file tree
Hide file tree
Showing 9 changed files with 221 additions and 7 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<!-- check micrometer.version vertx-micrometer-metrics consumes before bumping up -->
<micrometer.version>1.12.2</micrometer.version>
<junit-jupiter.version>5.11.2</junit-jupiter.version>
<uid2-shared.version>8.0.6</uid2-shared.version>
<uid2-shared.version>8.0.10-alpha-172-SNAPSHOT</uid2-shared.version>
<okta-jwt.version>0.5.10</okta-jwt.version>
<image.version>${project.version}</image.version>
</properties>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public String getId() {
public void execute() throws Exception {
PrivateSiteDataMap<LegacyClientKey> desiredPrivateState = PrivateSiteUtil.getClientKeys(globalOperators, globalClientKeys);
multiScopeStoreWriter.uploadPrivateWithEncryption(desiredPrivateState, null);
PrivateSiteDataMap<LegacyClientKey> desiredPublicState = PublicSiteUtil.getPublicClients(globalClientKeys,globalOperators);
PrivateSiteDataMap<LegacyClientKey> desiredPublicState = PublicSiteUtil.getPublicClients(globalClientKeys, globalOperators);
multiScopeStoreWriter.uploadPublicWithEncryption(desiredPublicState, null);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.uid2.admin.job.EncryptionJob;

import com.uid2.admin.job.model.Job;
import com.uid2.admin.model.PrivateSiteDataMap;
import com.uid2.admin.store.MultiScopeStoreWriter;
import com.uid2.admin.util.PrivateSiteUtil;
import com.uid2.admin.util.PublicSiteUtil;
import com.uid2.shared.auth.OperatorKey;
import com.uid2.shared.model.SaltEntry;

import java.util.Collection;

public class SaltEncryptionJob extends Job {
private final Collection<OperatorKey> globalOperators;
private final Collection<SaltEntry> saltEntries;
private final MultiScopeStoreWriter<Collection<SaltEntry>> multiScopeStoreWriter;

public SaltEncryptionJob(Collection<OperatorKey> globalOperators,
Collection<SaltEntry> saltEntries,
MultiScopeStoreWriter<Collection<SaltEntry>> multiScopeStoreWriter) {
this.globalOperators = globalOperators;
this.saltEntries = saltEntries;
this.multiScopeStoreWriter = multiScopeStoreWriter;
}


@Override
public String getId() {
return "cloud-encryption-sync-salts";
}

@Override
public void execute() throws Exception {
PrivateSiteDataMap<SaltEntry> desiredPrivateState = PrivateSiteUtil.getPrivateSaltEntries(saltEntries, globalOperators);
multiScopeStoreWriter.uploadPrivateWithEncryption(desiredPrivateState, null);
PrivateSiteDataMap<SaltEntry> desiredPublicState = PublicSiteUtil.getPublicSaltEntries(saltEntries, globalOperators);
multiScopeStoreWriter.uploadPublicWithEncryption(desiredPublicState, null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import com.fasterxml.jackson.databind.ObjectWriter;
import com.uid2.admin.job.EncryptionJob.*;
import com.uid2.admin.job.EncryptionJob.ClientKeyEncryptionJob;
import com.uid2.admin.job.model.Job;
import com.uid2.admin.store.*;
import com.uid2.admin.store.factory.*;
Expand All @@ -23,7 +22,6 @@
import com.uid2.shared.store.CloudPath;
import com.uid2.admin.legacy.LegacyClientKey;
import com.uid2.shared.store.reader.RotatingCloudEncryptionKeyProvider;
import com.uid2.shared.store.reader.RotatingCloudEncryptionKeyProvider;
import com.uid2.shared.store.scope.GlobalScope;
import io.vertx.core.json.JsonObject;

Expand Down
66 changes: 66 additions & 0 deletions src/main/java/com/uid2/admin/store/factory/SaltStoreFactory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package com.uid2.admin.store.factory;

import com.uid2.admin.store.FileManager;
import com.uid2.admin.store.version.VersionGenerator;
import com.uid2.admin.store.writer.EncyptedSaltStoreWriter;
import com.uid2.admin.store.writer.StoreWriter;
import com.uid2.shared.cloud.TaggableCloudStorage;
import com.uid2.shared.store.CloudPath;
import com.uid2.shared.store.RotatingEncryptedSaltProvider;
import com.uid2.shared.store.RotatingSaltProvider;
import com.uid2.shared.store.reader.RotatingCloudEncryptionKeyProvider;
import com.uid2.shared.store.reader.StoreReader;
import com.uid2.shared.store.scope.EncryptedScope;
import io.vertx.core.json.JsonObject;

import java.util.Collection;

public class SaltStoreFactory implements EncryptedStoreFactory<Collection<RotatingSaltProvider.SaltSnapshot>> {
JsonObject config;
CloudPath rootMetadatapath;
RotatingSaltProvider saltProvider;
FileManager fileManager;
TaggableCloudStorage taggableCloudStorage;
VersionGenerator versionGenerator;
RotatingCloudEncryptionKeyProvider cloudEncryptionKeyProvider;

public SaltStoreFactory(JsonObject config, CloudPath rootMetadataPath, RotatingSaltProvider saltProvider, FileManager fileManager,
TaggableCloudStorage taggableCloudStorage, VersionGenerator versionGenerator,
RotatingCloudEncryptionKeyProvider cloudEncryptionKeyProvider) {
this.config = config;
this.rootMetadatapath = rootMetadataPath;
this.saltProvider = saltProvider;
this.fileManager = fileManager;
this.taggableCloudStorage = taggableCloudStorage;
this.versionGenerator = versionGenerator;
this.cloudEncryptionKeyProvider = cloudEncryptionKeyProvider;
}

@Override
public StoreWriter<Collection<RotatingSaltProvider.SaltSnapshot>> getEncryptedWriter(Integer siteId, boolean isPublic) {
return new EncyptedSaltStoreWriter(config, saltProvider, fileManager, taggableCloudStorage, versionGenerator,
new EncryptedScope(rootMetadatapath, siteId, isPublic), cloudEncryptionKeyProvider, siteId);
}

@Override
public StoreReader<Collection<RotatingSaltProvider.SaltSnapshot>> getEncryptedReader(Integer siteId, boolean isPublic) {
return new RotatingEncryptedSaltProvider(taggableCloudStorage,
new EncryptedScope(rootMetadatapath, siteId, isPublic).getMetadataPath().toString(),
cloudEncryptionKeyProvider);
}

@Override
public RotatingCloudEncryptionKeyProvider getCloudEncryptionProvider() {
return cloudEncryptionKeyProvider;
}

@Override
public StoreReader<Collection<RotatingSaltProvider.SaltSnapshot>> getReader(Integer siteId) {
return null;
}

@Override
public StoreWriter<Collection<RotatingSaltProvider.SaltSnapshot>> getWriter(Integer siteId) {
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package com.uid2.admin.store.writer;

import com.uid2.admin.store.FileManager;
import com.uid2.admin.store.version.VersionGenerator;
import com.uid2.shared.cloud.TaggableCloudStorage;
import com.uid2.shared.encryption.AesGcm;
import com.uid2.shared.model.CloudEncryptionKey;
import com.uid2.shared.store.CloudPath;
import com.uid2.shared.store.RotatingSaltProvider;
import com.uid2.shared.store.reader.RotatingCloudEncryptionKeyProvider;
import com.uid2.shared.store.scope.StoreScope;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.vertx.core.json.JsonObject;

import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class EncyptedSaltStoreWriter extends SaltStoreWriter implements StoreWriter {
private StoreScope scope;
private RotatingCloudEncryptionKeyProvider cloudEncryptionKeyProvider;
private Integer siteId;

private static final Logger LOGGER = LoggerFactory.getLogger(EncyptedSaltStoreWriter.class);
public EncyptedSaltStoreWriter(JsonObject config, RotatingSaltProvider provider, FileManager fileManager,
TaggableCloudStorage cloudStorage, VersionGenerator versionGenerator, StoreScope scope,
RotatingCloudEncryptionKeyProvider cloudEncryptionKeyProvider, Integer siteId) {
super(config, provider, fileManager, cloudStorage, versionGenerator);
this.scope = scope;
this.cloudEncryptionKeyProvider = cloudEncryptionKeyProvider;
this.siteId = siteId;
}

@Override
protected java.lang.String getSaltSnapshotLocation(RotatingSaltProvider.SaltSnapshot snapshot) {
return scope.resolve(new CloudPath(saltSnapshotLocationPrefix + snapshot.getEffective().toEpochMilli())).toString();
}

@Override
protected void upload(String data, String location) throws Exception {
if (siteId == null) {
throw new IllegalStateException("Site ID is not set.");
}

CloudEncryptionKey encryptionKey = null;
try {
encryptionKey = cloudEncryptionKeyProvider.getEncryptionKeyForSite(siteId);
} catch (IllegalStateException e) {
LOGGER.error("Error: No Cloud Encryption keys available for encryption for site ID: {}", siteId, e);
}
JsonObject encryptedJson = new JsonObject();
if (encryptionKey != null) {
byte[] secret = Base64.getDecoder().decode(encryptionKey.getSecret());
byte[] encryptedPayload = AesGcm.encrypt(data.getBytes(StandardCharsets.UTF_8), secret);
encryptedJson.put("key_id", encryptionKey.getId())
.put("encryption_version", "1.0")
.put("encrypted_payload", Base64.getEncoder().encodeToString(encryptedPayload));
} else {
throw new IllegalStateException("No Cloud Encryption keys available for encryption for site ID: " + siteId);
}


super.upload(encryptedJson.encodePrettily(), location);
}

@Override
public void upload(Object data, JsonObject extraMeta) throws Exception {
super.upload((RotatingSaltProvider.SaltSnapshot) data);
}

@Override
public void rewriteMeta() throws Exception {

}
}
12 changes: 9 additions & 3 deletions src/main/java/com/uid2/admin/store/writer/SaltStoreWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public class SaltStoreWriter {
private static final Logger LOGGER = LoggerFactory.getLogger(SaltStoreWriter.class);
private final RotatingSaltProvider provider;
private final FileManager fileManager;
private final String saltSnapshotLocationPrefix;
protected final String saltSnapshotLocationPrefix;
private final VersionGenerator versionGenerator;

private final TaggableCloudStorage cloudStorage;
Expand Down Expand Up @@ -111,7 +111,7 @@ public void archiveSaltLocations() throws Exception {
});
}

private String getSaltSnapshotLocation(RotatingSaltProvider.SaltSnapshot snapshot) {
protected String getSaltSnapshotLocation(RotatingSaltProvider.SaltSnapshot snapshot) {
return saltSnapshotLocationPrefix + snapshot.getEffective().toEpochMilli();
}

Expand All @@ -130,7 +130,13 @@ private void uploadSaltsSnapshot(RotatingSaltProvider.SaltSnapshot snapshot, Str
}
}

cloudStorage.upload(newSaltsFile.toString(), location, this.currentTags);
//cloudStorage.upload(newSaltsFile.toString(), location, this.currentTags);
this.upload(newSaltsFile.toString(), location);
}

protected void upload(String data, String location) throws Exception {
cloudStorage.upload(data, location, this.currentTags);

}

private void setStatusTagToCurrent(String location) throws CloudStorageException {
Expand Down
15 changes: 15 additions & 0 deletions src/main/java/com/uid2/admin/util/PrivateSiteUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.uid2.shared.auth.*;
import com.uid2.shared.model.EncryptionKey;
import com.uid2.shared.model.KeysetKey;
import com.uid2.shared.model.SaltEntry;
import com.uid2.shared.model.Site;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -310,4 +311,18 @@ public static PrivateSiteDataMap<KeysetKey> getKeysetKeys(Collection<OperatorKey
});
return result;
}

public static PrivateSiteDataMap<SaltEntry> getPrivateSaltEntries(
Collection<SaltEntry> globalSaltEntries,
Collection<OperatorKey> operators) {
final PrivateSiteDataMap<SaltEntry> result = getPrivateSites(operators);

globalSaltEntries.forEach(saltEntry -> {
result.forEach((publicSiteId, publicSiteData) -> {
publicSiteData.add(saltEntry);
});
});

return result;
}
}
15 changes: 15 additions & 0 deletions src/main/java/com/uid2/admin/util/PublicSiteUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.uid2.shared.auth.OperatorType;
import com.uid2.shared.model.EncryptionKey;
import com.uid2.shared.model.KeysetKey;
import com.uid2.shared.model.SaltEntry;
import com.uid2.shared.model.Site;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -128,4 +129,18 @@ public static PrivateSiteDataMap<KeysetKey> getPublicKeysetKeys(

return result;
}

public static PrivateSiteDataMap<SaltEntry> getPublicSaltEntries(
Collection<SaltEntry> globalSaltEntries,
Collection<OperatorKey> operators) {
final PrivateSiteDataMap<SaltEntry> result = getPublicSitesMap(operators);

globalSaltEntries.forEach(saltEntry -> {
result.forEach((publicSiteId, publicSiteData) -> {
publicSiteData.add(saltEntry);
});
});

return result;
}
}

0 comments on commit 36235b0

Please sign in to comment.