Skip to content

Commit

Permalink
fix(sdk): option to disable assertion verification (#205)
Browse files Browse the repository at this point in the history
  • Loading branch information
sujankota authored Oct 29, 2024
1 parent ac13a0a commit 78d7b66
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 8 deletions.
8 changes: 7 additions & 1 deletion sdk/src/main/java/io/opentdf/platform/sdk/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -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<TDFReaderConfig>... options) {
TDFReaderConfig config = new TDFReaderConfig();
config.disableAssertionVerification = false;
for (Consumer<TDFReaderConfig> option : options) {
option.accept(config);
}
Expand All @@ -108,6 +110,10 @@ public static Consumer<TDFReaderConfig> withAssertionVerificationKeys(
return (TDFReaderConfig config) -> config.assertionVerificationKeys = assertionVerificationKeys;
}

public static Consumer<TDFReaderConfig> withDisableAssertionVerification(boolean disable) {
return (TDFReaderConfig config) -> config.disableAssertionVerification = disable;
}

public static class TDFConfig {
public Boolean autoconfigure;
public int defaultSegmentSize;
Expand Down
18 changes: 15 additions & 3 deletions sdk/src/main/java/io/opentdf/platform/sdk/TDF.java
Original file line number Diff line number Diff line change
Expand Up @@ -550,8 +550,14 @@ public List<String> 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 NotValidateRootSignature, SegmentSizeMismatch,
IOException, FailedToCreateGMAC, JOSEException, ParseException, NoSuchAlgorithmException, DecoderException {

Expand Down Expand Up @@ -672,10 +678,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;
}
Expand Down
2 changes: 1 addition & 1 deletion sdk/src/test/java/io/opentdf/platform/sdk/TDFE2ETest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
67 changes: 64 additions & 3 deletions sdk/src/test/java/io/opentdf/platform/sdk/TDFTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -192,15 +195,72 @@ 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))
.withFailMessage("extracted data does not match")
.isEqualTo(plainText);
}

@Test
void testWithAssertionVerificationDisabled() throws Exception {

ListenableFuture<GetAttributeValuesByFqnsResponse> 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 {

Expand Down Expand Up @@ -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))
Expand Down

0 comments on commit 78d7b66

Please sign in to comment.