Skip to content

Commit e741256

Browse files
Addressing PR comments
1 parent 3a808a2 commit e741256

9 files changed

+448
-93
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package com.uid2.shared.store;
2+
3+
import com.uid2.shared.cloud.DownloadCloudStorage;
4+
import com.uid2.shared.model.SaltEntry;
5+
import com.uid2.shared.store.reader.RotatingCloudEncryptionKeyProvider;
6+
7+
import java.io.IOException;
8+
import java.io.InputStream;
9+
import java.util.Collection;
10+
11+
import static com.uid2.shared.util.CloudEncryptionHelpers.decryptInputStream;
12+
13+
public class EncryptedRotatingSaltProvider extends RotatingSaltProvider {
14+
private final RotatingCloudEncryptionKeyProvider cloudEncryptionKeyProvider;
15+
16+
public EncryptedRotatingSaltProvider(DownloadCloudStorage fileStreamProvider, String metadataPath, RotatingCloudEncryptionKeyProvider cloudEncryptionKeyProvider) {
17+
super(fileStreamProvider, metadataPath);
18+
this.cloudEncryptionKeyProvider = cloudEncryptionKeyProvider;
19+
}
20+
21+
@Override
22+
protected SaltEntry[] readInputStream(InputStream inputStream, SaltEntryBuilder entryBuilder, Integer size) throws IOException {
23+
String decrypted = decryptInputStream(inputStream, cloudEncryptionKeyProvider);
24+
SaltEntry[] entries = new SaltEntry[size];
25+
int idx = 0;
26+
for (String line : decrypted.split("\n")) {
27+
final SaltEntry entry = entryBuilder.toEntry(line);
28+
entries[idx] = entry;
29+
idx++;
30+
}
31+
return entries;
32+
}
33+
}
Lines changed: 3 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,18 @@
11
package com.uid2.shared.store;
22

33
import com.uid2.shared.cloud.DownloadCloudStorage;
4-
import com.uid2.shared.model.CloudEncryptionKey;
54
import com.uid2.shared.store.parser.Parser;
65
import com.uid2.shared.store.parser.ParsingResult;
76
import com.uid2.shared.store.scope.StoreScope;
87
import com.uid2.shared.store.reader.RotatingCloudEncryptionKeyProvider;
9-
import io.vertx.core.json.JsonObject;
108
import org.slf4j.Logger;
119
import org.slf4j.LoggerFactory;
1210

1311
import java.io.*;
1412

15-
import com.uid2.shared.encryption.AesGcm;
16-
1713
import java.nio.charset.StandardCharsets;
18-
import java.util.Base64;
19-
import java.util.Map;
14+
15+
import static com.uid2.shared.util.CloudEncryptionHelpers.decryptInputStream;
2016

2117
public class EncryptedScopedStoreReader<T> extends ScopedStoreReader<T> {
2218
private static final Logger LOGGER = LoggerFactory.getLogger(EncryptedScopedStoreReader.class);
@@ -31,8 +27,7 @@ public EncryptedScopedStoreReader(DownloadCloudStorage fileStreamProvider, Store
3127
@Override
3228
protected long loadContent(String path) throws Exception {
3329
try (InputStream inputStream = this.contentStreamProvider.download(path)) {
34-
String encryptedContent = inputStreamToString(inputStream);
35-
String decryptedContent = getDecryptedContent(encryptedContent);
30+
String decryptedContent = decryptInputStream(inputStream, cloudEncryptionKeyProvider);
3631
ParsingResult<T> parsed = this.parser.deserialize(new ByteArrayInputStream(decryptedContent.getBytes(StandardCharsets.UTF_8)));
3732
latestSnapshot.set(parsed.getData());
3833

@@ -45,32 +40,4 @@ protected long loadContent(String path) throws Exception {
4540
throw e;
4641
}
4742
}
48-
49-
protected String getDecryptedContent(String encryptedContent) throws Exception {
50-
JsonObject json = new JsonObject(encryptedContent);
51-
int keyId = json.getInteger("key_id");
52-
String encryptedPayload = json.getString("encrypted_payload");
53-
CloudEncryptionKey decryptionKey = cloudEncryptionKeyProvider.getKey(keyId);
54-
55-
if (decryptionKey == null) {
56-
throw new IllegalStateException("No matching S3 key found for decryption for key ID: " + keyId);
57-
}
58-
59-
byte[] secret = Base64.getDecoder().decode(decryptionKey.getSecret());
60-
byte[] encryptedBytes = Base64.getDecoder().decode(encryptedPayload);
61-
byte[] decryptedBytes = AesGcm.decrypt(encryptedBytes, 0, secret);
62-
63-
return new String(decryptedBytes, StandardCharsets.UTF_8);
64-
}
65-
66-
public static String inputStreamToString(InputStream inputStream) throws IOException {
67-
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
68-
StringBuilder stringBuilder = new StringBuilder();
69-
String line;
70-
while ((line = reader.readLine()) != null) {
71-
stringBuilder.append(line);
72-
}
73-
return stringBuilder.toString();
74-
}
75-
}
7643
}

src/main/java/com/uid2/shared/store/RotatingSaltProvider.java

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -132,28 +132,24 @@ private SaltSnapshot loadSnapshot(JsonObject spec, String firstLevelSalt, SaltEn
132132
final Instant expires = Instant.ofEpochMilli(spec.getLong("expires", defaultExpires.toEpochMilli()));
133133

134134
final String path = spec.getString("location");
135-
int idx = 0;
136-
final SaltEntry[] entries = new SaltEntry[spec.getInteger("size")];
137-
Stream<String> stream = readInputStream(this.contentStreamProvider.download(path)).lines();
138-
for (String l : stream.toList()) {
139-
final SaltEntry entry = entryBuilder.toEntry(l);
140-
entries[idx] = entry;
141-
idx++;
142-
}
135+
Integer size = spec.getInteger("size");
136+
SaltEntry[] entries = readInputStream(this.contentStreamProvider.download(path), entryBuilder, size);
143137

144-
LOGGER.info("Loaded " + idx + " salts");
138+
LOGGER.info("Loaded " + size + " salts");
145139
return new SaltSnapshot(effective, expires, entries, firstLevelSalt);
146140
}
147141

148-
protected String readInputStream(InputStream inputStream) throws IOException {
142+
protected SaltEntry[] readInputStream(InputStream inputStream, SaltEntryBuilder entryBuilder, Integer size) throws IOException {
149143
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
150-
StringBuilder stringBuilder = new StringBuilder();
151144
String line;
145+
SaltEntry[] entries = new SaltEntry[size];
146+
int idx = 0;
152147
while ((line = reader.readLine()) != null) {
153-
stringBuilder.append(line);
154-
stringBuilder.append(System.lineSeparator());
148+
final SaltEntry entry = entryBuilder.toEntry(line);
149+
entries[idx] = entry;
150+
idx++;
155151
}
156-
return stringBuilder.toString();
152+
return entries;
157153
}
158154
}
159155

@@ -225,7 +221,7 @@ public String encode(long id) {
225221
}
226222
}
227223

228-
static final class SaltEntryBuilder {
224+
protected static final class SaltEntryBuilder {
229225
private final IdHashingScheme idHashingScheme;
230226

231227
public SaltEntryBuilder(IdHashingScheme idHashingScheme) {

src/main/java/com/uid2/shared/store/reader/RotatingCloudEncryptionKeyProvider.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,12 @@ public Map<Integer, CloudEncryptionKey> getAll() {
6262
}
6363

6464
public CloudEncryptionKey getKey(int id) {
65-
return reader.getSnapshot().get(id);
65+
Map<Integer, CloudEncryptionKey> snapshot = reader.getSnapshot();
66+
if(snapshot == null) {
67+
return null;
68+
}
69+
70+
return snapshot.get(id);
6671
}
6772

6873
public void updateSiteToKeysMapping() {

src/main/java/com/uid2/shared/store/RotatingEncryptedSaltProvider.java renamed to src/main/java/com/uid2/shared/util/CloudEncryptionHelpers.java

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,19 @@
1-
package com.uid2.shared.store;
1+
package com.uid2.shared.util;
22

3-
import com.uid2.shared.cloud.DownloadCloudStorage;
3+
import java.io.InputStream;
44
import com.uid2.shared.encryption.AesGcm;
55
import com.uid2.shared.model.CloudEncryptionKey;
6-
import com.uid2.shared.store.reader.RotatingCloudEncryptionKeyProvider;
76

8-
import com.uid2.shared.store.reader.StoreReader;
7+
import com.uid2.shared.store.reader.RotatingCloudEncryptionKeyProvider;
98
import io.vertx.core.json.JsonObject;
10-
import java.io.IOException;
11-
import java.io.InputStream;
129
import java.nio.charset.StandardCharsets;
1310
import java.util.Base64;
14-
import java.util.Collection;
1511

16-
public class RotatingEncryptedSaltProvider extends RotatingSaltProvider implements StoreReader<Collection<RotatingSaltProvider.SaltSnapshot>> {
17-
private final RotatingCloudEncryptionKeyProvider cloudEncryptionKeyProvider;
18-
19-
public RotatingEncryptedSaltProvider(DownloadCloudStorage fileStreamProvider, String metadataPath, RotatingCloudEncryptionKeyProvider cloudEncryptionKeyProvider) {
20-
super(fileStreamProvider, metadataPath);
21-
this.cloudEncryptionKeyProvider = cloudEncryptionKeyProvider;
22-
}
23-
24-
@Override
25-
protected String readInputStream(InputStream inputStream) throws IOException {
26-
String encryptedContent = super.readInputStream(inputStream);
12+
import java.io.*;
2713

14+
public class CloudEncryptionHelpers {
15+
public static String decryptInputStream(InputStream inputStream, RotatingCloudEncryptionKeyProvider cloudEncryptionKeyProvider) throws IOException {
16+
String encryptedContent = inputStreamToString(inputStream);
2817
JsonObject json = new JsonObject(encryptedContent);
2918
int keyId = json.getInteger("key_id");
3019
String encryptedPayload = json.getString("encrypted_payload");
@@ -41,8 +30,14 @@ protected String readInputStream(InputStream inputStream) throws IOException {
4130
return new String(decryptedBytes, StandardCharsets.UTF_8);
4231
}
4332

44-
@Override
45-
public Collection<SaltSnapshot> getAll() {
46-
return super.getSnapshots();
33+
public static String inputStreamToString(InputStream inputStream) throws IOException {
34+
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
35+
StringBuilder stringBuilder = new StringBuilder();
36+
String line;
37+
while ((line = reader.readLine()) != null) {
38+
stringBuilder.append(line);
39+
}
40+
return stringBuilder.toString();
41+
}
4742
}
4843
}

0 commit comments

Comments
 (0)