Skip to content

Commit d56e23f

Browse files
authored
Add support for enforcing https, update JVM version to 17 (#153)
1 parent 2912cff commit d56e23f

File tree

21 files changed

+432
-359
lines changed

21 files changed

+432
-359
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# Changelog
22

3+
## v8.0.1
4+
5+
- We’ve removed the direct constructors for `TenantSecurityClient` and replaced them with a builder-based API. The static TenantSecurityClient.create method is still provided for convenience.
6+
- TenantSecurityClient now enforces HTTPS connections to the TSP by default. You can opt out of this restriction using the new `TenantSecurityClient.Builder`, using `allowInsecureHttp(true)`. This should only be done in the case of testing.
7+
8+
## v8.0.0
9+
10+
- Accidental release. Incomplete. Use 8.0.1 instead.
11+
312
## v7.2.3
413

514
- No code change, changed publishing to new sonatype.

examples/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@ have included this configuration in the repository as a convenience. Also note t
2020
created in IronCore's staging infrastructure.
2121

2222
The following command will get a TSP and LD running together on your computer with the provided configuration.
23-
The `docker-compose` command will pull both container images, then start them up together on a subnetwork, so they can
23+
The `docker compose` command will pull both container images, then start them up together on a subnetwork, so they can
2424
communicate with each other.
2525

2626
```bash
27-
docker-compose -f docker-compose.yml up
27+
docker compose -f docker-compose.yml up
2828
```
2929

3030
The TSP will be listening locally on port 32804.

examples/large-documents/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
<dependency>
3030
<groupId>com.ironcorelabs</groupId>
3131
<artifactId>tenant-security-java</artifactId>
32-
<version>4.0.1</version>
32+
<version>8.0.1</version>
3333
</dependency>
3434
<dependency>
3535
<groupId>com.google.guava</groupId>

examples/large-documents/src/main/java/com/ironcorelabs/large/LargeDocuments.java

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@ public static void main(String[] args) throws Exception {
4040

4141
// Initialize the client with a Tenant Security Proxy domain and API key.
4242
// Typically this would be done once when the application or service initializes
43-
TenantSecurityClient client = TenantSecurityClient.create("http://localhost:32804", API_KEY).get();
43+
TenantSecurityClient client =
44+
new TenantSecurityClient.Builder("http://localhost:32804", API_KEY)
45+
.allowInsecureHttp(true).build();
4446

4547
// Create metadata used to associate this document to a tenant, name the
4648
// document, and identify the service or user making the call
@@ -64,7 +66,8 @@ public static void main(String[] args) throws Exception {
6466
System.out.println("Writing encrypted files to: " + tmpFileDir);
6567

6668
ObjectMapper objectMapper = new ObjectMapper();
67-
BigDoc sourceObj = objectMapper.readValue(new File("./resources/" + filename), BigDoc.class);
69+
BigDoc sourceObj =
70+
objectMapper.readValue(new File("./resources/" + filename), BigDoc.class);
6871

6972
// Reduce the document to a map of all the sub documents to be encrypted with
7073
// the same key
@@ -115,14 +118,17 @@ public static void main(String[] args) throws Exception {
115118
String subDocId2 = "4e57e8bd-d88a-4083-9fac-05a635110e2a";
116119

117120
// Read the two files out first
118-
byte[] encryptedFile1 = Files.readAllBytes(Paths.get(tmpFileDir.toString(), subDocId1 + ".enc"));
119-
byte[] encryptedFile2 = Files.readAllBytes(Paths.get(tmpFileDir.toString(), subDocId2 + ".enc"));
121+
byte[] encryptedFile1 =
122+
Files.readAllBytes(Paths.get(tmpFileDir.toString(), subDocId1 + ".enc"));
123+
byte[] encryptedFile2 =
124+
Files.readAllBytes(Paths.get(tmpFileDir.toString(), subDocId2 + ".enc"));
120125

121126
// In a DB situation this edek could be stored with the large doc (if sub docs
122127
// are only decrypted in that context) or it could be stored alongside each
123128
// sub-document. In the latter case you make it harder to accidentally
124129
// cryptoshred data by de-syncing edeks at the cost of row size
125-
String edek = new String(Files.readAllBytes(Paths.get(tmpFileDir.toString(), filename + ".edek")));
130+
String edek = new String(
131+
Files.readAllBytes(Paths.get(tmpFileDir.toString(), filename + ".edek")));
126132

127133
// each of the documents could be individually decrypted with their own calls,
128134
// but by combining them into one structure we ensure we only make one call to
@@ -133,15 +139,18 @@ public static void main(String[] args) throws Exception {
133139
EncryptedDocument encryptedPartialBigDoc = new EncryptedDocument(encryptedPartDocMap, edek);
134140

135141
// Decrypt the two subdocuments
136-
PlaintextDocument decryptedPartialBigDoc = client.decrypt(encryptedPartialBigDoc, metadata).get();
142+
PlaintextDocument decryptedPartialBigDoc =
143+
client.decrypt(encryptedPartialBigDoc, metadata).get();
137144

138145
// Turn the decrypted bytes back into objects
139-
SubDoc reSubDoc1 = objectMapper
140-
.readValue(new String(decryptedPartialBigDoc.getDecryptedFields().get(subDocId1)), SubDoc.class);
141-
SubDoc reSubDoc2 = objectMapper
142-
.readValue(new String(decryptedPartialBigDoc.getDecryptedFields().get(subDocId2)), SubDoc.class);
146+
SubDoc reSubDoc1 = objectMapper.readValue(
147+
new String(decryptedPartialBigDoc.getDecryptedFields().get(subDocId1)),
148+
SubDoc.class);
149+
SubDoc reSubDoc2 = objectMapper.readValue(
150+
new String(decryptedPartialBigDoc.getDecryptedFields().get(subDocId2)),
151+
SubDoc.class);
143152
// just so we can write it out nicely
144-
BigDoc rePartialBigDoc = new BigDoc("x", "x", "x", new SubDoc[] { reSubDoc1, reSubDoc2 });
153+
BigDoc rePartialBigDoc = new BigDoc("x", "x", "x", new SubDoc[] {reSubDoc1, reSubDoc2});
145154

146155
// Write out the rehydrated docs as proof that things round tripped fine
147156
Files.write(Paths.get(tmpFileDir.toString(), "partial-large-document.json"),

examples/logging-example/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
<dependency>
3030
<groupId>com.ironcorelabs</groupId>
3131
<artifactId>tenant-security-java</artifactId>
32-
<version>4.0.0</version>
32+
<version>8.0.1</version>
3333
</dependency>
3434

3535
</dependencies>
@@ -82,4 +82,4 @@
8282
</plugin>
8383
</plugins>
8484
</build>
85-
</project>
85+
</project>

examples/logging-example/src/main/java/com/ironcorelabs/logging/LoggingExample.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ public static void main(String[] args) throws Exception {
2828

2929
// Initialize the client with a Tenant Security Proxy domain and API key.
3030
// Typically this would be done once when the application or service initializes
31-
TenantSecurityClient client = TenantSecurityClient.create("http://localhost:32804", API_KEY).get();
31+
TenantSecurityClient client =
32+
new TenantSecurityClient.Builder("http://localhost:32804", API_KEY).allowInsecureHttp(true)
33+
.build();
3234

3335
// Example 1: logging a user-related event
3436
//
@@ -38,8 +40,8 @@ public static void main(String[] args) throws Exception {
3840
Map<String, String> otherData = new HashMap<>();
3941
otherData.put("field1", "gumby");
4042
otherData.put("field2", "gumby");
41-
EventMetadata metadata1 = new EventMetadata(TENANT_ID, "userId1", "PII", otherData, "Rq8675309", "127.0.0.1",
42-
"userId1", System.currentTimeMillis());
43+
EventMetadata metadata1 = new EventMetadata(TENANT_ID, "userId1", "PII", otherData, "Rq8675309",
44+
"127.0.0.1", "userId1", System.currentTimeMillis());
4345
try {
4446
client.logSecurityEvent(UserEvent.LOGIN, metadata1).get();
4547
System.out.println("Successfully logged user login event.");

examples/rekey-example/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
<dependency>
2929
<groupId>com.ironcorelabs</groupId>
3030
<artifactId>tenant-security-java</artifactId>
31-
<version>4.1.0</version>
31+
<version>8.0.1</version>
3232
</dependency>
3333
</dependencies>
3434

@@ -80,4 +80,4 @@
8080
</plugin>
8181
</plugins>
8282
</build>
83-
</project>
83+
</project>

examples/rekey-example/src/main/java/com/ironcorelabs/rekey/RekeyExample.java

Lines changed: 72 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.ironcorelabs.tenantsecurity.kms.v1.*;
44
import com.ironcorelabs.tenantsecurity.kms.v1.exception.TenantSecurityException;
5+
import com.ironcorelabs.tenantsecurity.utils.CompletableFutures;
56
import java.nio.charset.StandardCharsets;
67
import java.util.HashMap;
78
import java.util.Map;
@@ -12,11 +13,14 @@
1213
/**
1314
* Three parts:
1415
*
15-
* <p>Encrypt a customer record
16+
* <p>
17+
* Encrypt a customer record
1618
*
17-
* <p>Rekey the encrypted record to a new tenant
19+
* <p>
20+
* Rekey the encrypted record to a new tenant
1821
*
19-
* <p>Decrypt the encrypted record using the new tenant
22+
* <p>
23+
* Decrypt the encrypted record using the new tenant
2024
*/
2125
public class RekeyExample {
2226

@@ -44,87 +48,78 @@ public static void main(String[] args) throws Exception {
4448

4549
// Initialize the client with a Tenant Security Proxy domain and API key.
4650
// Typically this would be done once when the application or service initializes.
47-
CompletableFuture<PlaintextDocument> rekeyedRoundtrip =
48-
TenantSecurityClient.create(TSP_ADDR, API_KEY)
49-
.thenCompose(
50-
client -> {
51-
try {
52-
//
53-
// Part 1: Encrypting a customer record
54-
//
55-
56-
// Create metadata used to associate this document to the first tenant, name the
57-
// document, and identify the service or user making the call
58-
DocumentMetadata metadata =
59-
new DocumentMetadata(TENANT_ID, "serviceOrUserId", "PII");
60-
61-
// Create a map containing your data
62-
Map<String, byte[]> custRecord = new HashMap<>();
63-
custRecord.put("ssn", "000-12-2345".getBytes("UTF-8"));
64-
custRecord.put(
65-
"address", "2825-519 Stone Creek Rd, Bozeman, MT 59715".getBytes("UTF-8"));
66-
custRecord.put("name", "Jim Bridger".getBytes("UTF-8"));
67-
68-
System.out.println("Encrypting using tenant " + TENANT_ID);
69-
// Request a key from the KMS and use it to encrypt the document
70-
CompletableFuture<EncryptedDocument> encryptedDocument =
71-
client.encrypt(custRecord, metadata);
72-
73-
//
74-
// Part 2: Rekey the encrypted record to a new tenant
75-
//
76-
77-
final String NEW_TENANT_ID = "tenant-aws";
78-
79-
System.out.println("Rekeying to tenant " + NEW_TENANT_ID);
80-
81-
CompletableFuture<EncryptedDocument> rekeyedDocument =
82-
encryptedDocument.thenCompose(
83-
// Rekey the document to `tenant-aws` using their primary config. The
84-
// metadata's name and identifying information could also be changed at
85-
// this time.
86-
encrypted ->
87-
client.rekeyEdek(encrypted.getEdek(), metadata, NEW_TENANT_ID)
88-
.thenApply(
89-
newDoc ->
90-
new EncryptedDocument(encrypted.getEncryptedFields(),
91-
newDoc)
92-
));
93-
94-
95-
96-
//
97-
// Part 3: Decrypt the encrypted record using the new tenant
98-
//
99-
100-
// Create new metadata for this document indicating that it was
101-
// rekeyed to the second tenant. The name and identifying information
102-
// could also be changed at this time.
103-
DocumentMetadata newMetadata =
104-
new DocumentMetadata(NEW_TENANT_ID, "serviceOrUserId", "PII");
105-
106-
System.out.println("Decrypting with tenant " + NEW_TENANT_ID);
107-
108-
CompletableFuture<PlaintextDocument> decryptedDocument =
109-
rekeyedDocument.thenCompose(
110-
// Decrypt the document encrypted to `tenant-aws`
111-
rekeyed -> client.decrypt(rekeyed, newMetadata));
112-
113-
return decryptedDocument;
114-
} catch (Exception e) {
115-
throw new CompletionException(e);
116-
}
117-
});
51+
CompletableFuture<PlaintextDocument> rekeyedRoundtrip = CompletableFutures.tryCatchNonFatal(
52+
() -> new TenantSecurityClient.Builder(TSP_ADDR, API_KEY).allowInsecureHttp(true).build())
53+
.thenCompose(client -> {
54+
try {
55+
//
56+
// Part 1: Encrypting a customer record
57+
//
58+
59+
// Create metadata used to associate this document to the first tenant, name the
60+
// document, and identify the service or user making the call
61+
DocumentMetadata metadata = new DocumentMetadata(TENANT_ID, "serviceOrUserId", "PII");
62+
63+
// Create a map containing your data
64+
Map<String, byte[]> custRecord = new HashMap<>();
65+
custRecord.put("ssn", "000-12-2345".getBytes("UTF-8"));
66+
custRecord.put("address",
67+
"2825-519 Stone Creek Rd, Bozeman, MT 59715".getBytes("UTF-8"));
68+
custRecord.put("name", "Jim Bridger".getBytes("UTF-8"));
69+
70+
System.out.println("Encrypting using tenant " + TENANT_ID);
71+
// Request a key from the KMS and use it to encrypt the document
72+
CompletableFuture<EncryptedDocument> encryptedDocument =
73+
client.encrypt(custRecord, metadata);
74+
75+
//
76+
// Part 2: Rekey the encrypted record to a new tenant
77+
//
78+
79+
final String NEW_TENANT_ID = "tenant-aws";
80+
81+
System.out.println("Rekeying to tenant " + NEW_TENANT_ID);
82+
83+
CompletableFuture<EncryptedDocument> rekeyedDocument = encryptedDocument.thenCompose(
84+
// Rekey the document to `tenant-aws` using their primary config. The
85+
// metadata's name and identifying information could also be changed at
86+
// this time.
87+
encrypted -> client.rekeyEdek(encrypted.getEdek(), metadata, NEW_TENANT_ID)
88+
.thenApply(
89+
newDoc -> new EncryptedDocument(encrypted.getEncryptedFields(), newDoc)));
90+
91+
92+
93+
//
94+
// Part 3: Decrypt the encrypted record using the new tenant
95+
//
96+
97+
// Create new metadata for this document indicating that it was
98+
// rekeyed to the second tenant. The name and identifying information
99+
// could also be changed at this time.
100+
DocumentMetadata newMetadata =
101+
new DocumentMetadata(NEW_TENANT_ID, "serviceOrUserId", "PII");
102+
103+
System.out.println("Decrypting with tenant " + NEW_TENANT_ID);
104+
105+
CompletableFuture<PlaintextDocument> decryptedDocument = rekeyedDocument.thenCompose(
106+
// Decrypt the document encrypted to `tenant-aws`
107+
rekeyed -> client.decrypt(rekeyed, newMetadata));
108+
109+
return decryptedDocument;
110+
} catch (Exception e) {
111+
throw new CompletionException(e);
112+
}
113+
});
118114

119115
try {
120116
// access decrypted fields
121117
Map<String, byte[]> decryptedValuesMap = rekeyedRoundtrip.get().getDecryptedFields();
122118

123119
System.out.println(
124120
"Decrypted SSN: " + new String(decryptedValuesMap.get("ssn"), StandardCharsets.UTF_8));
125-
System.out.println(
126-
"Decrypted address: "
127-
+ new String(decryptedValuesMap.get("address"), StandardCharsets.UTF_8));
121+
System.out.println("Decrypted address: "
122+
+ new String(decryptedValuesMap.get("address"), StandardCharsets.UTF_8));
128123
System.out.println(
129124
"Decrypted name: " + new String(decryptedValuesMap.get("name"), StandardCharsets.UTF_8));
130125
} catch (ExecutionException e) {

examples/simple-roundtrip/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
<dependency>
3030
<groupId>com.ironcorelabs</groupId>
3131
<artifactId>tenant-security-java</artifactId>
32-
<version>4.0.0</version>
32+
<version>8.0.1</version>
3333
</dependency>
3434

3535
</dependencies>
@@ -82,4 +82,4 @@
8282
</plugin>
8383
</plugins>
8484
</build>
85-
</project>
85+
</project>

0 commit comments

Comments
 (0)