Skip to content

Commit 249fdd0

Browse files
Adding in client side keypair encryption
1 parent fc62e0e commit 249fdd0

File tree

10 files changed

+166
-10
lines changed

10 files changed

+166
-10
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
<!-- check micrometer.version vertx-micrometer-metrics consumes before bumping up -->
1717
<micrometer.version>1.12.2</micrometer.version>
1818
<junit-jupiter.version>5.11.2</junit-jupiter.version>
19-
<uid2-shared.version>8.0.10-alpha-172-SNAPSHOT</uid2-shared.version>
19+
<uid2-shared.version>8.0.11-alpha-173-SNAPSHOT</uid2-shared.version>
2020
<okta-jwt.version>0.5.10</okta-jwt.version>
2121
<image.version>${project.version}</image.version>
2222
</properties>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package com.uid2.admin.job.EncryptionJob;
2+
3+
import com.uid2.admin.job.model.Job;
4+
import com.uid2.admin.model.PrivateSiteDataMap;
5+
import com.uid2.admin.store.MultiScopeStoreWriter;
6+
import com.uid2.admin.util.PublicSiteUtil;
7+
import com.uid2.shared.auth.OperatorKey;
8+
import com.uid2.shared.model.ClientSideKeypair;
9+
10+
import java.util.Collection;
11+
12+
public class ClientSideKeypairEncryptionJob extends Job {
13+
private final Collection<OperatorKey> globalOperators;
14+
private final Collection<ClientSideKeypair> globalClientSideKeypairs;
15+
16+
private final MultiScopeStoreWriter<Collection<ClientSideKeypair>> multiScopeStoreWriter;
17+
18+
public ClientSideKeypairEncryptionJob(Collection<OperatorKey> globalOperators, Collection<ClientSideKeypair> globalClientSideKeypairs,
19+
MultiScopeStoreWriter<Collection<ClientSideKeypair>> multiScopeStoreWriter) {
20+
this.globalOperators = globalOperators;
21+
this.globalClientSideKeypairs = globalClientSideKeypairs;
22+
this.multiScopeStoreWriter = multiScopeStoreWriter;
23+
}
24+
25+
@Override
26+
public String getId() {
27+
return "cloud-encryption-sync-clientside-keypair";
28+
}
29+
30+
@Override
31+
public void execute() throws Exception {
32+
// Only public operators support clientside keypair
33+
PrivateSiteDataMap<ClientSideKeypair> desiredPublicState = PublicSiteUtil.getPublicClientKeypairs(globalClientSideKeypairs, globalOperators);
34+
multiScopeStoreWriter.uploadPublicWithEncryption(desiredPublicState, null);
35+
}
36+
}

src/main/java/com/uid2/admin/job/jobsync/EncryptedFilesSyncJob.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,13 @@
1717
import com.uid2.shared.cloud.CloudUtils;
1818
import com.uid2.shared.cloud.ICloudStorage;
1919
import com.uid2.shared.cloud.TaggableCloudStorage;
20+
import com.uid2.shared.model.ClientSideKeypair;
2021
import com.uid2.shared.model.EncryptionKey;
2122
import com.uid2.shared.model.KeysetKey;
2223
import com.uid2.shared.model.Site;
2324
import com.uid2.shared.store.CloudPath;
2425
import com.uid2.admin.legacy.LegacyClientKey;
25-
import com.uid2.shared.store.RotatingEncryptedSaltProvider;
26+
import com.uid2.shared.store.EncryptedRotatingSaltProvider;
2627
import com.uid2.shared.store.RotatingSaltProvider;
2728
import com.uid2.shared.store.reader.RotatingCloudEncryptionKeyProvider;
2829
import com.uid2.shared.store.scope.GlobalScope;
@@ -122,6 +123,15 @@ public void execute() throws Exception {
122123
rotatingCloudEncryptionKeyProvider
123124
);
124125

126+
ClientSideKeypairStoreFactory clientSideKeypairStoreFactory = new ClientSideKeypairStoreFactory(
127+
cloudStorage,
128+
new CloudPath(config.getString(Const.Config.ClientSideKeypairsMetadataPathProp)),
129+
versionGenerator,
130+
clock,
131+
rotatingCloudEncryptionKeyProvider,
132+
fileManager
133+
);
134+
125135
CloudPath operatorMetadataPath = new CloudPath(config.getString(Const.Config.OperatorsMetadataPathProp));
126136
GlobalScope operatorScope = new GlobalScope(operatorMetadataPath);
127137
RotatingOperatorKeyProvider operatorKeyProvider = new RotatingOperatorKeyProvider(cloudStorage, cloudStorage, operatorScope);
@@ -138,6 +148,7 @@ public void execute() throws Exception {
138148
keysetKeyStoreFactory.getGlobalReader().loadContent();
139149
}
140150
saltProvider.loadContent();
151+
clientSideKeypairStoreFactory.getGlobalReader().loadContent();
141152
}
142153

143154
Collection<OperatorKey> globalOperators = operatorKeyProvider.getAll();
@@ -146,6 +157,8 @@ public void execute() throws Exception {
146157
Collection<EncryptionKey> globalEncryptionKeys = encryptionKeyStoreFactory.getGlobalReader().getSnapshot().getActiveKeySet();
147158
Integer globalMaxKeyId = encryptionKeyStoreFactory.getGlobalReader().getMetadata().getInteger("max_key_id");
148159
Map<Integer, EncryptionKeyAcl> globalKeyAcls = keyAclStoreFactory.getGlobalReader().getSnapshot().getAllAcls();
160+
Collection<ClientSideKeypair> globalClientSideKeypair = clientSideKeypairStoreFactory.getGlobalReader().getAll();
161+
149162
MultiScopeStoreWriter<Collection<Site>> siteWriter = new MultiScopeStoreWriter<>(
150163
fileManager,
151164
siteStoreFactory,
@@ -166,6 +179,10 @@ public void execute() throws Exception {
166179
fileManager,
167180
saltStoreFactory,
168181
MultiScopeStoreWriter::areCollectionsEqual);
182+
MultiScopeStoreWriter<Collection<ClientSideKeypair>> clientSideKeypairWriter = new MultiScopeStoreWriter<>(
183+
fileManager,
184+
clientSideKeypairStoreFactory,
185+
MultiScopeStoreWriter::areCollectionsEqual);
169186

170187
SiteEncryptionJob siteEncryptionSyncJob = new SiteEncryptionJob(siteWriter, globalSites, globalOperators);
171188
ClientKeyEncryptionJob clientEncryptionSyncJob = new ClientKeyEncryptionJob(clientWriter, globalClients, globalOperators);
@@ -179,12 +196,14 @@ public void execute() throws Exception {
179196
);
180197
KeyAclEncryptionJob keyAclEncryptionSyncJob = new KeyAclEncryptionJob(keyAclWriter, globalOperators, globalKeyAcls);
181198
SaltEncryptionJob saltEncryptionJob = new SaltEncryptionJob(globalOperators, saltProvider.getSnapshots(), saltWriter);
199+
ClientSideKeypairEncryptionJob clientSideKeypairEncryptionJob = new ClientSideKeypairEncryptionJob(globalOperators, globalClientSideKeypair, clientSideKeypairWriter);
182200

183201
siteEncryptionSyncJob.execute();
184202
clientEncryptionSyncJob.execute();
185203
encryptionKeyEncryptionSyncJob.execute();
186204
keyAclEncryptionSyncJob.execute();
187205
saltEncryptionJob.execute();
206+
clientSideKeypairEncryptionJob.execute();
188207

189208
if(config.getBoolean(enableKeysetConfigProp)) {
190209
Map<Integer, Keyset> globalKeysets = keysetStoreFactory.getGlobalReader().getSnapshot().getAllKeysets();
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package com.uid2.admin.store.factory;
2+
3+
import com.uid2.admin.store.writer.ClientSideKeypairStoreWriter;
4+
import com.uid2.admin.store.writer.StoreWriter;
5+
import com.uid2.shared.model.ClientSideKeypair;
6+
import com.uid2.shared.store.reader.RotatingClientSideKeypairStore;
7+
import com.uid2.shared.store.reader.RotatingCloudEncryptionKeyProvider;
8+
import com.uid2.shared.store.reader.StoreReader;
9+
import com.fasterxml.jackson.databind.ObjectWriter;
10+
import com.uid2.admin.store.Clock;
11+
import com.uid2.admin.store.FileManager;
12+
import com.uid2.admin.store.version.VersionGenerator;
13+
import com.uid2.shared.cloud.ICloudStorage;
14+
import com.uid2.shared.store.CloudPath;
15+
import com.uid2.shared.store.scope.EncryptedScope;
16+
import com.uid2.shared.store.scope.GlobalScope;
17+
import com.uid2.shared.store.scope.SiteScope;
18+
19+
import java.util.Collection;
20+
21+
public class ClientSideKeypairStoreFactory implements EncryptedStoreFactory<Collection<ClientSideKeypair>> {
22+
private final ICloudStorage fileStreamProvider;
23+
private final CloudPath rootMetadataPath;
24+
private final VersionGenerator versionGenerator;
25+
private final Clock clock;
26+
private final FileManager fileManager;
27+
private final RotatingClientSideKeypairStore globalReader;
28+
private final RotatingCloudEncryptionKeyProvider cloudEncryptionKeyProvider;
29+
30+
public ClientSideKeypairStoreFactory(
31+
ICloudStorage fileStreamProvider,
32+
CloudPath rootMetadataPath,
33+
VersionGenerator versionGenerator,
34+
Clock clock,
35+
RotatingCloudEncryptionKeyProvider cloudEncryptionKeyProvider,
36+
FileManager fileManager) {
37+
this.fileStreamProvider = fileStreamProvider;
38+
this.rootMetadataPath = rootMetadataPath;
39+
this.versionGenerator = versionGenerator;
40+
this.clock = clock;
41+
this.cloudEncryptionKeyProvider = cloudEncryptionKeyProvider;
42+
this.fileManager = fileManager;
43+
GlobalScope globalScope = new GlobalScope(rootMetadataPath);
44+
globalReader = new RotatingClientSideKeypairStore(fileStreamProvider, globalScope);
45+
}
46+
47+
public RotatingClientSideKeypairStore getGlobalReader() {
48+
return globalReader;
49+
}
50+
51+
@Override
52+
public StoreWriter<Collection<ClientSideKeypair>> getEncryptedWriter(Integer siteId, boolean isPublic) {
53+
return new ClientSideKeypairStoreWriter(getEncryptedReader(siteId, isPublic),
54+
fileManager,
55+
versionGenerator,
56+
clock,
57+
new EncryptedScope(rootMetadataPath, siteId, isPublic));
58+
}
59+
60+
@Override
61+
public StoreReader<Collection<ClientSideKeypair>> getEncryptedReader(Integer siteId, boolean isPublic) {
62+
return new RotatingClientSideKeypairStore(fileStreamProvider, new EncryptedScope(rootMetadataPath, siteId, isPublic));
63+
}
64+
65+
@Override
66+
public RotatingCloudEncryptionKeyProvider getCloudEncryptionProvider() {
67+
return cloudEncryptionKeyProvider;
68+
}
69+
70+
@Override
71+
public StoreReader<Collection<ClientSideKeypair>> getReader(Integer siteId) {
72+
return new RotatingClientSideKeypairStore(fileStreamProvider, new SiteScope(rootMetadataPath, siteId));
73+
}
74+
75+
@Override
76+
public StoreWriter<Collection<ClientSideKeypair>> getWriter(Integer siteId) {
77+
return new ClientSideKeypairStoreWriter(getReader(siteId), fileManager, versionGenerator, clock, new SiteScope(rootMetadataPath, siteId));
78+
}
79+
}

src/main/java/com/uid2/admin/store/factory/SaltStoreFactory.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import com.uid2.shared.Const;
88
import com.uid2.shared.cloud.TaggableCloudStorage;
99
import com.uid2.shared.store.CloudPath;
10-
import com.uid2.shared.store.RotatingEncryptedSaltProvider;
10+
import com.uid2.shared.store.EncryptedRotatingSaltProvider;
1111
import com.uid2.shared.store.RotatingSaltProvider;
1212
import com.uid2.shared.store.reader.RotatingCloudEncryptionKeyProvider;
1313
import com.uid2.shared.store.reader.StoreReader;
@@ -38,7 +38,7 @@ public SaltStoreFactory(JsonObject config, CloudPath rootMetadataPath, FileManag
3838
@Override
3939
public StoreWriter<Collection<RotatingSaltProvider.SaltSnapshot>> getEncryptedWriter(Integer siteId, boolean isPublic) {
4040
EncryptedScope scope = new EncryptedScope(rootMetadatapath, siteId, isPublic);
41-
RotatingEncryptedSaltProvider saltProvider = new RotatingEncryptedSaltProvider(taggableCloudStorage,
41+
EncryptedRotatingSaltProvider saltProvider = new EncryptedRotatingSaltProvider(taggableCloudStorage,
4242
scope.resolve(new CloudPath(config.getString(Const.Config.SaltsMetadataPathProp))).toString(), cloudEncryptionKeyProvider );
4343
return new EncyptedSaltStoreWriter(config, saltProvider, fileManager, taggableCloudStorage, versionGenerator, scope, cloudEncryptionKeyProvider, siteId);
4444
}

src/main/java/com/uid2/admin/store/writer/ClientSideKeypairStoreWriter.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import com.uid2.admin.store.version.VersionGenerator;
77
import com.uid2.shared.model.ClientSideKeypair;
88
import com.uid2.shared.store.reader.RotatingClientSideKeypairStore;
9+
import com.uid2.shared.store.reader.StoreReader;
910
import com.uid2.shared.store.scope.StoreScope;
1011
import io.vertx.core.json.JsonArray;
1112
import io.vertx.core.json.JsonObject;
@@ -17,7 +18,7 @@ public class ClientSideKeypairStoreWriter implements StoreWriter<Collection<Clie
1718

1819
private final ScopedStoreWriter writer;
1920

20-
public ClientSideKeypairStoreWriter(RotatingClientSideKeypairStore store, FileManager fileManager, VersionGenerator versionGenerator, Clock clock, StoreScope scope) {
21+
public ClientSideKeypairStoreWriter(StoreReader<Collection<ClientSideKeypair>> store, FileManager fileManager, VersionGenerator versionGenerator, Clock clock, StoreScope scope) {
2122
FileName dataFile = new FileName("client_side_keypairs", ".json");
2223
String dataType = "client_side_keypairs";
2324
writer = new ScopedStoreWriter(store, fileManager, versionGenerator, clock, scope, dataFile, dataType);

src/main/java/com/uid2/admin/store/writer/SaltStoreWriter.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,6 @@ protected void uploadSaltsSnapshot(RotatingSaltProvider.SaltSnapshot snapshot, S
141141
}
142142
}
143143

144-
//cloudStorage.upload(newSaltsFile.toString(), location, this.currentTags);
145144
this.upload(newSaltsFile.toString(), location);
146145
}
147146

src/main/java/com/uid2/admin/util/PublicSiteUtil.java

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,7 @@
66
import com.uid2.shared.auth.Keyset;
77
import com.uid2.shared.auth.OperatorKey;
88
import com.uid2.shared.auth.OperatorType;
9-
import com.uid2.shared.model.EncryptionKey;
10-
import com.uid2.shared.model.KeysetKey;
11-
import com.uid2.shared.model.SaltEntry;
12-
import com.uid2.shared.model.Site;
9+
import com.uid2.shared.model.*;
1310
import com.uid2.shared.store.RotatingSaltProvider;
1411
import org.slf4j.Logger;
1512
import org.slf4j.LoggerFactory;
@@ -144,4 +141,18 @@ public static PrivateSiteDataMap<RotatingSaltProvider.SaltSnapshot> getPublicSal
144141

145142
return result;
146143
}
144+
145+
public static PrivateSiteDataMap<ClientSideKeypair> getPublicClientKeypairs(
146+
Collection<ClientSideKeypair> globalClientSideKeypair,
147+
Collection<OperatorKey> operators) {
148+
final PrivateSiteDataMap<ClientSideKeypair> result = getPublicSitesMap(operators);
149+
150+
globalClientSideKeypair.forEach(clientSideKeypair -> {
151+
result.forEach((publicSiteId, publicSiteData) -> {
152+
publicSiteData.add(clientSideKeypair);
153+
});
154+
});
155+
156+
return result;
157+
}
147158
}

src/test/java/com/uid2/admin/store/MultiScopeStoreWriterTest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,10 @@ public void overwritesExistingDataWhenChanged() throws Exception {
109109
reader.loadContent();
110110
Long oldVersion = reader.getMetadata().getLong("version");
111111

112+
// This test relies on our version generator returning a new timestamp, but the code can execute so fast we don't get a new version
113+
// This small sleep makes this test much more stable
114+
Thread.sleep(100);
115+
112116
Site updatedSite = new Site(scopedSiteId, "site 1 updated", true);
113117
MultiScopeStoreWriter<Collection<Site>> multiStore = new MultiScopeStoreWriter<>(fileManager, siteStoreFactory, MultiScopeStoreWriter::areCollectionsEqual);
114118

@@ -204,6 +208,7 @@ public void uploadPrivateWithEncryption() throws Exception {
204208
Map<Integer, CloudEncryptionKey> allKeys = new HashMap<>();
205209
allKeys.put(1, encryptionKey);
206210
when(cloudEncryptionKeyProvider.getAll()).thenReturn(allKeys);
211+
when(cloudEncryptionKeyProvider.getKey(1)).thenReturn(encryptionKey);
207212

208213
SiteStoreFactory siteStoreFactory = new SiteStoreFactory(
209214
cloudStorage,
@@ -241,6 +246,7 @@ public void uploadPublicWithEncryption() throws Exception {
241246
Map<Integer, CloudEncryptionKey> allKeys = new HashMap<>();
242247
allKeys.put(1, encryptionKey);
243248
when(cloudEncryptionKeyProvider.getAll()).thenReturn(allKeys);
249+
when(cloudEncryptionKeyProvider.getKey(1)).thenReturn(encryptionKey);
244250

245251
SiteStoreFactory siteStoreFactory = new SiteStoreFactory(
246252
cloudStorage,
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package com.uid2.admin.store.writer;
2+
3+
public class SaltStoreWriterTest {
4+
5+
}

0 commit comments

Comments
 (0)