Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Correct null assertions when deserializing #211

Merged
merged 10 commits into from
Nov 21, 2024
17 changes: 16 additions & 1 deletion sdk/src/main/java/io/opentdf/platform/sdk/Manifest.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ public class Manifest {
private static final String kAssertionHash = "assertionHash";
private static final String kAssertionSignature = "assertionSig";

private static final Gson gson = new Gson();
private static final Gson gson = new GsonBuilder()
.registerTypeAdapter(Manifest.class, new ManifestDeserializer())
.create();

@Override
public boolean equals(Object o) {
Expand Down Expand Up @@ -458,6 +460,19 @@ private JWSVerifier createVerifier(AssertionConfig.AssertionKey assertionKey) th
public Payload payload;
public List<Assertion> assertions = new ArrayList<>();

public static class ManifestDeserializer implements JsonDeserializer<Object> {
@Override
public Manifest deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
// Let Gson handle the default deserialization of the object first
Manifest manifest = new Gson().fromJson(json, typeOfT);
// Now check if the `assertions` field is null and replace it with an empty list if necessary
if (manifest.assertions == null) {
manifest.assertions = new ArrayList<>(); // Replace null with empty list
}
return manifest;
}
}

private static Manifest readManifest(Reader reader) {
return gson.fromJson(reader, Manifest.class);
}
Expand Down
6 changes: 5 additions & 1 deletion sdk/src/main/java/io/opentdf/platform/sdk/TDF.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package io.opentdf.platform.sdk;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.nimbusds.jose.*;

import io.opentdf.platform.policy.Value;
import io.opentdf.platform.policy.attributes.AttributesServiceGrpc.AttributesServiceFutureStub;
import io.opentdf.platform.sdk.Config.TDFConfig;
import io.opentdf.platform.sdk.Manifest.ManifestDeserializer;
import io.opentdf.platform.sdk.Autoconfigure.AttributeValueFQN;
import io.opentdf.platform.sdk.Config.KASInfo;

Expand Down Expand Up @@ -75,7 +77,9 @@ public TDF() {

private static final SecureRandom sRandom = new SecureRandom();

private static final Gson gson = new Gson();
private static final Gson gson = new GsonBuilder()
.registerTypeAdapter(Manifest.class, new ManifestDeserializer())
.create();

public class SplitKeyException extends IOException {
public SplitKeyException(String errorMessage) {
Expand Down
72 changes: 71 additions & 1 deletion sdk/src/test/java/io/opentdf/platform/sdk/ManifestTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import io.opentdf.platform.sdk.Manifest.ManifestDeserializer;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;

import static org.junit.Assert.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class ManifestTest {
Expand Down Expand Up @@ -62,7 +65,9 @@ void testManifestMarshalAndUnMarshal() {
"}";

GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = gsonBuilder.setPrettyPrinting().create();
Gson gson = gsonBuilder.setPrettyPrinting()
.registerTypeAdapter(Manifest.class, new ManifestDeserializer())
.create();
Manifest manifest = gson.fromJson(kManifestJsonFromTDF, Manifest.class);

// Test payload
Expand Down Expand Up @@ -90,4 +95,69 @@ void testManifestMarshalAndUnMarshal() {

assertEquals(manifest, deserializedAgain, "something changed when we deserialized -> serialized -> deserialized");
}

@Test
void testAssertionNull() {
String kManifestJsonFromTDF = "{\n" +
" \"encryptionInformation\": {\n" +
" \"integrityInformation\": {\n" +
" \"encryptedSegmentSizeDefault\": 1048604,\n" +
" \"rootSignature\": {\n" +
" \"alg\": \"HS256\",\n" +
" \"sig\": \"N2Y1ZjJlYWE4N2EzNjc2Nzc3NzgxNGU2ZGE1NmI4NDNhZTI5ZWY5NDc2OGI1ZTMzYTIyMTU4MDBlZTY3NzQzNA==\"\n" +
" },\n" +
" \"segmentHashAlg\": \"GMAC\",\n" +
" \"segmentSizeDefault\": 1048576,\n" +
" \"segments\": [\n" +
" {\n" +
" \"encryptedSegmentSize\": 41,\n" +
" \"hash\": \"ZWEyZTkwYjZiZThmYWZhNzg5ZmNjOWIyZTA2Njg5OTQ=\",\n" +
" \"segmentSize\": 1048576\n" +
" }\n" +
" ]\n" +
" },\n" +
" \"keyAccess\": [\n" +
" {\n" +
" \"policyBinding\": {\n" +
" \"alg\": \"HS256\",\n" +
" \"hash\": \"YTgzNThhNzc5NWRhMjdjYThlYjk4ZmNmODliNzc2Y2E5ZmZiZDExZDQ3OTM5ODFjZTRjNmE3MmVjOTUzZTFlMA==\"\n" +
" },\n" +
" \"protocol\": \"kas\",\n" +
" \"type\": \"wrapped\",\n" +
" \"url\": \"http://localhost:65432/kas\",\n" +
" \"wrappedKey\": \"dJ3PdscXWvLv/juSkL7EMhl4lgLSBfI9EeoG2ct6NeSwPkPm/ieMF6ryDQjGeqZttoLlx2qBCVpik/BooGd/FtpYMIF/7a5RFTJ3G+o4Lww/zG6zIgV2APEPO+Gp7ORlFyMNJfn6Tj8ChTweKBqfXEXLihTV6sTZFtsWjdV96Z4KXbLe8tGpkXBpUAsSlmjcDJ920vrqnp3dvt2GwfmAiRWYCMXxnqUECqN5kVXMJywcvHatv2ZJSA/ixjDOrix+MocDJ69K/yFA17DXgfjf5X4SLyS0XgaZcXsdACBb+ogBlPw6vAbBrAyqI0Vi1msMRYNDS+FTl1yWEXl1HpyyCw==\"\n" +
" }\n" +
" ],\n" +
" \"method\": {\n" +
" \"algorithm\": \"AES-256-GCM\",\n" +
" \"isStreamable\": true,\n" +
" \"iv\": \"tozen81HLtZktNOP\"\n" +
" },\n" +
" \"policy\": \"eyJib2R5Ijp7ImRhdGFBdHRyaWJ1dGVzIjpbXSwiZGlzc2VtIjpbXX0sInV1aWQiOiJiNTM3MDllMy03NmE3LTRmYzctOGEwZi1mZDBhNjcyNmVhM2YifQ==\",\n" +
" \"type\": \"split\"\n" +
" },\n" +
" \"payload\": {\n" +
" \"isEncrypted\": true,\n" +
" \"mimeType\": \"application/octet-stream\",\n" +
" \"protocol\": \"zip\",\n" +
" \"type\": \"reference\",\n" +
" \"url\": \"0.payload\"\n" +
" },\n" +
" \"assertions\": null\n"+
"}";

GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = gsonBuilder.setPrettyPrinting()
.registerTypeAdapter(Manifest.class, new ManifestDeserializer())
.create();
Manifest manifest = gson.fromJson(kManifestJsonFromTDF, Manifest.class);

// Test payload for sanity check
assertEquals(manifest.payload.url, "0.payload");
assertEquals(manifest.payload.isEncrypted, true);
// Test assertion deserialization
assertNotNull(manifest.assertions);
assertEquals(manifest.assertions.size(), 0);

}
}
10 changes: 9 additions & 1 deletion sdk/src/test/java/io/opentdf/platform/sdk/ZipReaderTest.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package io.opentdf.platform.sdk;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import io.opentdf.platform.sdk.Manifest.ManifestDeserializer;

import org.apache.commons.compress.archivers.zip.Zip64Mode;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
Expand Down Expand Up @@ -36,7 +40,11 @@ public void testReadingExistingZip() throws Exception {
if (entry.getName().endsWith(".json")) {
entry.getData().transferTo(stream);
var data = stream.toString(StandardCharsets.UTF_8);
var map = new Gson().fromJson(data, Map.class);
var gson = new GsonBuilder()
.registerTypeAdapter(Manifest.class, new ManifestDeserializer())
.create();
var map = gson.fromJson(data, Map.class);

assertThat(map.get("encryptionInformation")).isNotNull();
}
}
Expand Down