Skip to content

Commit b1dec75

Browse files
use a readresolve
1 parent 2342df3 commit b1dec75

File tree

3 files changed

+142
-26
lines changed

3 files changed

+142
-26
lines changed

sdk/src/main/java/io/opentdf/platform/sdk/Manifest.java

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515

1616
import org.apache.commons.codec.binary.Hex;
1717
import org.erdtman.jcs.JsonCanonicalizer;
18+
import org.slf4j.Logger;
19+
import org.slf4j.LoggerFactory;
20+
import org.slf4j.Logger;
21+
import org.slf4j.LoggerFactory;
1822

1923
import java.io.IOException;
2024
import java.io.Reader;
@@ -454,10 +458,58 @@ private JWSVerifier createVerifier(AssertionConfig.AssertionKey assertionKey) th
454458
}
455459
}
456460

461+
// // Cpublic static Logger logger = LoggerFactory.getLogger(TDF.class);ustom deserializer for the assertions field
462+
// private static class AssertionSerializer implements JsonDeserializer<Object>, JsonSerializer<Object> {
463+
// public static Logger logger = LoggerFactory.getLogger(AssertionSerializer.class);
464+
// @Override
465+
// public List<Assertion> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
466+
// logger.info("deserializing json assertions");
467+
// logger.info(json.toString());
468+
// if (json == null || json.isJsonNull()) {
469+
// logger.info("found null");
470+
// return new ArrayList<>(); // Replace null with an empty list
471+
// }
472+
// // Deserialize the list normally if it exists
473+
// return new Gson().fromJson(json, typeOfT);
474+
// }
475+
// @Override
476+
// public JsonElement serialize(Object src, Type typeOfSrc, JsonSerializationContext context) {
477+
// return context.serialize(src, typeOfSrc);
478+
// }
479+
// }
480+
481+
// private static class PolicyBindingSerializer implements JsonDeserializer<Object>, JsonSerializer<Object> {
482+
// @Override
483+
// public Object deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
484+
// throws JsonParseException {
485+
// if (json.isJsonObject()) {
486+
// return context.deserialize(json, Manifest.PolicyBinding.class);
487+
// } else if (json.isJsonPrimitive() && json.getAsJsonPrimitive().isString()) {
488+
// return json.getAsString();
489+
// } else {
490+
// throw new JsonParseException("Unexpected type for policyBinding");
491+
// }
492+
// }
493+
494+
// @Override
495+
// public JsonElement serialize(Object src, Type typeOfSrc, JsonSerializationContext context) {
496+
// return context.serialize(src, typeOfSrc);
497+
// }
498+
// }
499+
457500
public EncryptionInformation encryptionInformation;
458501
public Payload payload;
502+
// @JsonAdapter(AssertionSerializer.class)
459503
public List<Assertion> assertions = new ArrayList<>();
460504

505+
// Ensure assertions is never null after deserialization
506+
private Object readResolve() {
507+
if (assertions == null) {
508+
assertions = new ArrayList<>();
509+
}
510+
return this;
511+
}
512+
461513
private static Manifest readManifest(Reader reader) {
462514
return gson.fromJson(reader, Manifest.class);
463515
}

sdk/src/main/java/io/opentdf/platform/sdk/TDF.java

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -695,37 +695,37 @@ public Reader loadTDF(SeekableByteChannel tdf, SDK.KAS kas,
695695
}
696696

697697
// Validate assertions
698-
if (manifest.assertions != null) {
699-
for (var assertion : manifest.assertions) {
700-
// Skip assertion verification if disabled
701-
if (tdfReaderConfig.disableAssertionVerification) {
702-
break;
703-
}
698+
logger.info("ASS:");
699+
logger.info(manifest.assertions.toString());
700+
for (var assertion : manifest.assertions) {
701+
// Skip assertion verification if disabled
702+
if (tdfReaderConfig.disableAssertionVerification) {
703+
break;
704+
}
704705

705-
// Set default to HS256
706-
var assertionKey = new AssertionConfig.AssertionKey(AssertionConfig.AssertionKeyAlg.HS256, payloadKey);
707-
Config.AssertionVerificationKeys assertionVerificationKeys = tdfReaderConfig.assertionVerificationKeys;
708-
if (!assertionVerificationKeys.isEmpty()) {
709-
var keyForAssertion = assertionVerificationKeys.getKey(assertion.id);
710-
if (keyForAssertion != null) {
711-
assertionKey = keyForAssertion;
712-
}
706+
// Set default to HS256
707+
var assertionKey = new AssertionConfig.AssertionKey(AssertionConfig.AssertionKeyAlg.HS256, payloadKey);
708+
Config.AssertionVerificationKeys assertionVerificationKeys = tdfReaderConfig.assertionVerificationKeys;
709+
if (!assertionVerificationKeys.isEmpty()) {
710+
var keyForAssertion = assertionVerificationKeys.getKey(assertion.id);
711+
if (keyForAssertion != null) {
712+
assertionKey = keyForAssertion;
713713
}
714+
}
714715

715-
var hashValues = assertion.verify(assertionKey);
716-
var assertionAsJson = gson.toJson(assertion);
717-
JsonCanonicalizer jc = new JsonCanonicalizer(assertionAsJson);
718-
var hashOfAssertion = Hex.encodeHexString(digest.digest(jc.getEncodedUTF8()));
719-
var signature = aggregateHash + hashOfAssertion;
720-
var encodeSignature = Base64.getEncoder().encodeToString(signature.getBytes());
716+
var hashValues = assertion.verify(assertionKey);
717+
var assertionAsJson = gson.toJson(assertion);
718+
JsonCanonicalizer jc = new JsonCanonicalizer(assertionAsJson);
719+
var hashOfAssertion = Hex.encodeHexString(digest.digest(jc.getEncodedUTF8()));
720+
var signature = aggregateHash + hashOfAssertion;
721+
var encodeSignature = Base64.getEncoder().encodeToString(signature.getBytes());
721722

722-
if (!Objects.equals(hashOfAssertion, hashValues.getAssertionHash())) {
723-
throw new AssertionException("assertion hash mismatch", assertion.id);
724-
}
723+
if (!Objects.equals(hashOfAssertion, hashValues.getAssertionHash())) {
724+
throw new AssertionException("assertion hash mismatch", assertion.id);
725+
}
725726

726-
if (!Objects.equals(encodeSignature, hashValues.getSignature())) {
727-
throw new AssertionException("failed integrity check on assertion signature", assertion.id);
728-
}
727+
if (!Objects.equals(encodeSignature, hashValues.getSignature())) {
728+
throw new AssertionException("failed integrity check on assertion signature", assertion.id);
729729
}
730730
}
731731

sdk/src/test/java/io/opentdf/platform/sdk/ManifestTest.java

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import java.util.List;
1010
import java.util.Map;
1111

12+
import static org.junit.Assert.assertNotNull;
1213
import static org.junit.jupiter.api.Assertions.assertEquals;
1314

1415
public class ManifestTest {
@@ -90,4 +91,67 @@ void testManifestMarshalAndUnMarshal() {
9091

9192
assertEquals(manifest, deserializedAgain, "something changed when we deserialized -> serialized -> deserialized");
9293
}
94+
95+
@Test
96+
void testAssertionNull() {
97+
String kManifestJsonFromTDF = "{\n" +
98+
" \"encryptionInformation\": {\n" +
99+
" \"integrityInformation\": {\n" +
100+
" \"encryptedSegmentSizeDefault\": 1048604,\n" +
101+
" \"rootSignature\": {\n" +
102+
" \"alg\": \"HS256\",\n" +
103+
" \"sig\": \"N2Y1ZjJlYWE4N2EzNjc2Nzc3NzgxNGU2ZGE1NmI4NDNhZTI5ZWY5NDc2OGI1ZTMzYTIyMTU4MDBlZTY3NzQzNA==\"\n" +
104+
" },\n" +
105+
" \"segmentHashAlg\": \"GMAC\",\n" +
106+
" \"segmentSizeDefault\": 1048576,\n" +
107+
" \"segments\": [\n" +
108+
" {\n" +
109+
" \"encryptedSegmentSize\": 41,\n" +
110+
" \"hash\": \"ZWEyZTkwYjZiZThmYWZhNzg5ZmNjOWIyZTA2Njg5OTQ=\",\n" +
111+
" \"segmentSize\": 1048576\n" +
112+
" }\n" +
113+
" ]\n" +
114+
" },\n" +
115+
" \"keyAccess\": [\n" +
116+
" {\n" +
117+
" \"policyBinding\": {\n" +
118+
" \"alg\": \"HS256\",\n" +
119+
" \"hash\": \"YTgzNThhNzc5NWRhMjdjYThlYjk4ZmNmODliNzc2Y2E5ZmZiZDExZDQ3OTM5ODFjZTRjNmE3MmVjOTUzZTFlMA==\"\n" +
120+
" },\n" +
121+
" \"protocol\": \"kas\",\n" +
122+
" \"type\": \"wrapped\",\n" +
123+
" \"url\": \"http://localhost:65432/kas\",\n" +
124+
" \"wrappedKey\": \"dJ3PdscXWvLv/juSkL7EMhl4lgLSBfI9EeoG2ct6NeSwPkPm/ieMF6ryDQjGeqZttoLlx2qBCVpik/BooGd/FtpYMIF/7a5RFTJ3G+o4Lww/zG6zIgV2APEPO+Gp7ORlFyMNJfn6Tj8ChTweKBqfXEXLihTV6sTZFtsWjdV96Z4KXbLe8tGpkXBpUAsSlmjcDJ920vrqnp3dvt2GwfmAiRWYCMXxnqUECqN5kVXMJywcvHatv2ZJSA/ixjDOrix+MocDJ69K/yFA17DXgfjf5X4SLyS0XgaZcXsdACBb+ogBlPw6vAbBrAyqI0Vi1msMRYNDS+FTl1yWEXl1HpyyCw==\"\n" +
125+
" }\n" +
126+
" ],\n" +
127+
" \"method\": {\n" +
128+
" \"algorithm\": \"AES-256-GCM\",\n" +
129+
" \"isStreamable\": true,\n" +
130+
" \"iv\": \"tozen81HLtZktNOP\"\n" +
131+
" },\n" +
132+
" \"policy\": \"eyJib2R5Ijp7ImRhdGFBdHRyaWJ1dGVzIjpbXSwiZGlzc2VtIjpbXX0sInV1aWQiOiJiNTM3MDllMy03NmE3LTRmYzctOGEwZi1mZDBhNjcyNmVhM2YifQ==\",\n" +
133+
" \"type\": \"split\"\n" +
134+
" },\n" +
135+
" \"payload\": {\n" +
136+
" \"isEncrypted\": true,\n" +
137+
" \"mimeType\": \"application/octet-stream\",\n" +
138+
" \"protocol\": \"zip\",\n" +
139+
" \"type\": \"reference\",\n" +
140+
" \"url\": \"0.payload\"\n" +
141+
" },\n" +
142+
" \"assertions\": null\n"+
143+
"}";
144+
145+
GsonBuilder gsonBuilder = new GsonBuilder();
146+
Gson gson = gsonBuilder.setPrettyPrinting().create();
147+
Manifest manifest = gson.fromJson(kManifestJsonFromTDF, Manifest.class);
148+
149+
// Test payload for sanity check
150+
assertEquals(manifest.payload.url, "0.payload");
151+
assertEquals(manifest.payload.isEncrypted, true);
152+
// Test assertion deserialization
153+
assertNotNull(manifest.assertions);
154+
assertEquals(manifest.assertions.size(), 0);
155+
156+
}
93157
}

0 commit comments

Comments
 (0)