diff --git a/cmdline/pom.xml b/cmdline/pom.xml
index 897f5658..55916094 100644
--- a/cmdline/pom.xml
+++ b/cmdline/pom.xml
@@ -4,7 +4,7 @@
io.opentdf.platform
sdk-pom
- 0.7.4
+ 0.7.5-SNAPSHOT
cmdline
diff --git a/examples/pom.xml b/examples/pom.xml
index 28915c44..922f6b8b 100644
--- a/examples/pom.xml
+++ b/examples/pom.xml
@@ -4,12 +4,12 @@
sdk-pom
io.opentdf.platform
- 0.7.4
+ 0.7.5-SNAPSHOT
io.opentdf.platform
examples
- 0.7.4
+ 0.7.5-SNAPSHOT
examples
diff --git a/pom.xml b/pom.xml
index e1b0ec0f..d37b49cf 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
io.opentdf.platform
sdk-pom
- 0.7.4
+ 0.7.5-SNAPSHOT
io.opentdf.platform:sdk-pom
OpenTDF Java SDK
https://github.com/opentdf/java-sdk
diff --git a/sdk/pom.xml b/sdk/pom.xml
index db01dbc2..5dfe5539 100644
--- a/sdk/pom.xml
+++ b/sdk/pom.xml
@@ -6,7 +6,7 @@
sdk-pom
io.opentdf.platform
- 0.7.4
+ 0.7.5-SNAPSHOT
jar
diff --git a/sdk/src/main/java/io/opentdf/platform/sdk/Config.java b/sdk/src/main/java/io/opentdf/platform/sdk/Config.java
index c7d4f092..1f44854a 100644
--- a/sdk/src/main/java/io/opentdf/platform/sdk/Config.java
+++ b/sdk/src/main/java/io/opentdf/platform/sdk/Config.java
@@ -91,12 +91,14 @@ AssertionConfig.AssertionKey getKey(String key) {
public static class TDFReaderConfig {
// Optional Map of Assertion Verification Keys
- AssertionVerificationKeys assertionVerificationKeys;
+ AssertionVerificationKeys assertionVerificationKeys = new AssertionVerificationKeys();
+ boolean disableAssertionVerification;
}
@SafeVarargs
public static TDFReaderConfig newTDFReaderConfig(Consumer... options) {
TDFReaderConfig config = new TDFReaderConfig();
+ config.disableAssertionVerification = false;
for (Consumer option : options) {
option.accept(config);
}
@@ -108,6 +110,10 @@ public static Consumer withAssertionVerificationKeys(
return (TDFReaderConfig config) -> config.assertionVerificationKeys = assertionVerificationKeys;
}
+ public static Consumer withDisableAssertionVerification(boolean disable) {
+ return (TDFReaderConfig config) -> config.disableAssertionVerification = disable;
+ }
+
public static class TDFConfig {
public Boolean autoconfigure;
public int defaultSegmentSize;
diff --git a/sdk/src/main/java/io/opentdf/platform/sdk/TDF.java b/sdk/src/main/java/io/opentdf/platform/sdk/TDF.java
index 41f1eb40..4c6eb6da 100644
--- a/sdk/src/main/java/io/opentdf/platform/sdk/TDF.java
+++ b/sdk/src/main/java/io/opentdf/platform/sdk/TDF.java
@@ -568,8 +568,14 @@ public List defaultKases(TDFConfig config) {
return defk;
}
+ public Reader loadTDF(SeekableByteChannel tdf, SDK.KAS kas)
+ throws DecoderException, IOException, ParseException, NoSuchAlgorithmException, JOSEException {
+ return loadTDF(tdf, kas, new Config.TDFReaderConfig());
+ }
+
+
public Reader loadTDF(SeekableByteChannel tdf, SDK.KAS kas,
- Config.AssertionVerificationKeys... assertionVerificationKeys)
+ Config.TDFReaderConfig tdfReaderConfig)
throws RootSignatureValidationException, SegmentSizeMismatch,
IOException, FailedToCreateGMAC, JOSEException, ParseException, NoSuchAlgorithmException, DecoderException {
@@ -690,10 +696,16 @@ public Reader loadTDF(SeekableByteChannel tdf, SDK.KAS kas,
// Validate assertions
for (var assertion : manifest.assertions) {
+ // Skip assertion verification if disabled
+ if (tdfReaderConfig.disableAssertionVerification) {
+ break;
+ }
+
// Set default to HS256
var assertionKey = new AssertionConfig.AssertionKey(AssertionConfig.AssertionKeyAlg.HS256, payloadKey);
- if (assertionVerificationKeys != null && assertionVerificationKeys.length > 0) {
- var keyForAssertion = assertionVerificationKeys[0].getKey(assertion.id);
+ Config.AssertionVerificationKeys assertionVerificationKeys = tdfReaderConfig.assertionVerificationKeys;
+ if (!assertionVerificationKeys.isEmpty()) {
+ var keyForAssertion = assertionVerificationKeys.getKey(assertion.id);
if (keyForAssertion != null) {
assertionKey = keyForAssertion;
}
diff --git a/sdk/src/test/java/io/opentdf/platform/sdk/TDFE2ETest.java b/sdk/src/test/java/io/opentdf/platform/sdk/TDFE2ETest.java
index fb44663c..11a41bc8 100644
--- a/sdk/src/test/java/io/opentdf/platform/sdk/TDFE2ETest.java
+++ b/sdk/src/test/java/io/opentdf/platform/sdk/TDFE2ETest.java
@@ -38,7 +38,7 @@ public void createAndDecryptTdfIT() throws Exception {
tdf.createTDF(plainTextInputStream, tdfOutputStream, config, sdk.kas(), sdk.attributes());
var unwrappedData = new java.io.ByteArrayOutputStream();
- var reader = tdf.loadTDF(new SeekableInMemoryByteChannel(tdfOutputStream.toByteArray()), sdk.kas());
+ var reader = tdf.loadTDF(new SeekableInMemoryByteChannel(tdfOutputStream.toByteArray()), sdk.kas());
reader.readPayload(unwrappedData);
assertThat(unwrappedData.toString(StandardCharsets.UTF_8)).isEqualTo("text");
diff --git a/sdk/src/test/java/io/opentdf/platform/sdk/TDFTest.java b/sdk/src/test/java/io/opentdf/platform/sdk/TDFTest.java
index 48264b5c..ae4746b2 100644
--- a/sdk/src/test/java/io/opentdf/platform/sdk/TDFTest.java
+++ b/sdk/src/test/java/io/opentdf/platform/sdk/TDFTest.java
@@ -2,6 +2,7 @@
import com.google.common.util.concurrent.ListenableFuture;
+import com.nimbusds.jose.JOSEException;
import io.opentdf.platform.policy.attributes.GetAttributeValuesByFqnsRequest;
import io.opentdf.platform.policy.attributes.GetAttributeValuesByFqnsResponse;
import io.opentdf.platform.policy.attributes.AttributesServiceGrpc;
@@ -136,8 +137,10 @@ void testSimpleTDFEncryptAndDecrypt() throws Exception {
key);
var unwrappedData = new ByteArrayOutputStream();
+ Config.TDFReaderConfig readerConfig = Config.newTDFReaderConfig(
+ Config.withAssertionVerificationKeys(assertionVerificationKeys));
var reader = tdf.loadTDF(new SeekableInMemoryByteChannel(tdfOutputStream.toByteArray()), kas,
- assertionVerificationKeys);
+ readerConfig);
assertThat(reader.getManifest().payload.mimeType).isEqualTo("application/octet-stream");
reader.readPayload(unwrappedData);
@@ -192,8 +195,10 @@ void testSimpleTDFWithAssertionWithRS256() throws Exception {
new AssertionConfig.AssertionKey(AssertionConfig.AssertionKeyAlg.RS256, keypair.getPublic()));
var unwrappedData = new ByteArrayOutputStream();
+ Config.TDFReaderConfig readerConfig = Config.newTDFReaderConfig(
+ Config.withAssertionVerificationKeys(assertionVerificationKeys));
var reader = tdf.loadTDF(new SeekableInMemoryByteChannel(tdfOutputStream.toByteArray()), kas,
- assertionVerificationKeys);
+ readerConfig);
reader.readPayload(unwrappedData);
assertThat(unwrappedData.toString(StandardCharsets.UTF_8))
@@ -201,6 +206,61 @@ void testSimpleTDFWithAssertionWithRS256() throws Exception {
.isEqualTo(plainText);
}
+ @Test
+ void testWithAssertionVerificationDisabled() throws Exception {
+
+ ListenableFuture resp1 = mock(ListenableFuture.class);
+ lenient().when(resp1.get()).thenReturn(GetAttributeValuesByFqnsResponse.newBuilder().build());
+ lenient().when(attributeGrpcStub.getAttributeValuesByFqns(any(GetAttributeValuesByFqnsRequest.class)))
+ .thenReturn(resp1);
+
+ String assertion1Id = "assertion1";
+ var keypair = CryptoUtils.generateRSAKeypair();
+ var assertionConfig = new AssertionConfig();
+ assertionConfig.id = assertion1Id;
+ assertionConfig.type = AssertionConfig.Type.BaseAssertion;
+ assertionConfig.scope = AssertionConfig.Scope.TrustedDataObj;
+ assertionConfig.appliesToState = AssertionConfig.AppliesToState.Unencrypted;
+ assertionConfig.statement = new AssertionConfig.Statement();
+ assertionConfig.statement.format = "base64binary";
+ assertionConfig.statement.schema = "text";
+ assertionConfig.statement.value = "ICAgIDxlZGoOkVkaD4=";
+ assertionConfig.assertionKey = new AssertionConfig.AssertionKey(AssertionConfig.AssertionKeyAlg.RS256,
+ keypair.getPrivate());
+
+ Config.TDFConfig config = Config.newTDFConfig(
+ Config.withAutoconfigure(false),
+ Config.withKasInformation(getKASInfos()),
+ Config.withAssertionConfig(assertionConfig));
+
+ String plainText = "this is extremely sensitive stuff!!!";
+ InputStream plainTextInputStream = new ByteArrayInputStream(plainText.getBytes());
+ ByteArrayOutputStream tdfOutputStream = new ByteArrayOutputStream();
+
+ TDF tdf = new TDF();
+ tdf.createTDF(plainTextInputStream, tdfOutputStream, config, kas, attributeGrpcStub);
+
+ var assertionVerificationKeys = new Config.AssertionVerificationKeys();
+ assertionVerificationKeys.keys.put(assertion1Id,
+ new AssertionConfig.AssertionKey(AssertionConfig.AssertionKeyAlg.RS256, keypair.getPublic()));
+
+ var unwrappedData = new ByteArrayOutputStream();
+ assertThrows(JOSEException.class, () -> {
+ tdf.loadTDF(new SeekableInMemoryByteChannel(tdfOutputStream.toByteArray()), kas,
+ new Config.TDFReaderConfig());
+ });
+
+ // try with assertion verification disabled and not passing the assertion verification keys
+ Config.TDFReaderConfig readerConfig = Config.newTDFReaderConfig(
+ Config.withDisableAssertionVerification(true));
+ var reader = tdf.loadTDF(new SeekableInMemoryByteChannel(tdfOutputStream.toByteArray()), kas,
+ readerConfig);
+ reader.readPayload(unwrappedData);
+
+ assertThat(unwrappedData.toString(StandardCharsets.UTF_8))
+ .withFailMessage("extracted data does not match")
+ .isEqualTo(plainText);
+ }
@Test
void testSimpleTDFWithAssertionWithHS256() throws Exception {
@@ -244,7 +304,8 @@ void testSimpleTDFWithAssertionWithHS256() throws Exception {
tdf.createTDF(plainTextInputStream, tdfOutputStream, config, kas, attributeGrpcStub);
var unwrappedData = new ByteArrayOutputStream();
- var reader = tdf.loadTDF(new SeekableInMemoryByteChannel(tdfOutputStream.toByteArray()), kas);
+ var reader = tdf.loadTDF(new SeekableInMemoryByteChannel(tdfOutputStream.toByteArray()),
+ kas, new Config.TDFReaderConfig());
reader.readPayload(unwrappedData);
assertThat(unwrappedData.toString(StandardCharsets.UTF_8))