Skip to content

Commit 03d5d41

Browse files
fix(sdk): add methods to examine Manifest and Policy (#278)
These capabilities were removed during a previous refactoring Also change `Manifest.readManfest` to take in a `String` since that's the only way it's ever used. --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
1 parent bfe454f commit 03d5d41

File tree

7 files changed

+80
-20
lines changed

7 files changed

+80
-20
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package io.opentdf.platform;
2+
3+
import io.opentdf.platform.sdk.Manifest;
4+
import io.opentdf.platform.sdk.PolicyObject;
5+
import io.opentdf.platform.sdk.SDK;
6+
7+
import java.io.IOException;
8+
import java.nio.channels.FileChannel;
9+
import java.nio.file.Path;
10+
import java.nio.file.StandardOpenOption;
11+
12+
public class GetManifestInformation {
13+
public static void main(String[] args) throws IOException {
14+
if (args.length < 1) {
15+
System.err.println("TDF file path must be provided as an argument.");
16+
return;
17+
}
18+
19+
try (FileChannel tdfStream = FileChannel.open(Path.of(args[0]), StandardOpenOption.READ)) {
20+
Manifest manifest = SDK.readManifest(tdfStream);
21+
System.out.println("loaded a TDF with key access type: " + manifest.encryptionInformation.keyAccessType);
22+
23+
PolicyObject policyObject = SDK.decodePolicyObject(manifest);
24+
System.out.println("the policy has uuid: " + policyObject.uuid);
25+
}
26+
}
27+
}
28+

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

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
import org.erdtman.jcs.JsonCanonicalizer;
2828

2929
import java.io.IOException;
30-
import java.io.Reader;
3130
import java.lang.reflect.Type;
3231
import java.nio.charset.StandardCharsets;
3332
import java.security.MessageDigest;
@@ -500,8 +499,8 @@ public AssertionConfig.Statement deserialize(JsonElement json, Type typeOfT, Jso
500499
public EncryptionInformation encryptionInformation;
501500
public Payload payload;
502501
public List<Assertion> assertions = new ArrayList<>();
503-
protected static Manifest readManifest(Reader reader) {
504-
Manifest result = gson.fromJson(reader, Manifest.class);
502+
protected static Manifest readManifest(String manifestJson) {
503+
Manifest result = gson.fromJson(manifestJson, Manifest.class);
505504
if (result.assertions == null) {
506505
result.assertions = new ArrayList<>();
507506
}
@@ -539,8 +538,7 @@ protected static Manifest readManifest(Reader reader) {
539538
return result;
540539
}
541540

542-
static PolicyObject readPolicyObject(Reader reader) {
543-
var manifest = readManifest(reader);
541+
static PolicyObject decodePolicyObject(Manifest manifest) {
544542
var policyBase64 = manifest.encryptionInformation.policy;
545543
var policyBytes = Base64.getDecoder().decode(policyBase64);
546544
var policyJson = new String(policyBytes, StandardCharsets.UTF_8);

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,30 @@ public static boolean isTDF(SeekableByteChannel channel) {
145145
&& entries.stream().anyMatch(e -> "0.payload".equals(e.getName()));
146146
}
147147

148+
/**
149+
* Reads the {@link Manifest} without decrypting the TDF
150+
* @param tdfBytes A SeekableByteChannel containing the TDF data
151+
* @return The parsed {@link Manifest} object
152+
* @throws SDKException if an SDK-specific error occurs
153+
* @throws IOException if an I/O error occurs
154+
*/
155+
public static Manifest readManifest(SeekableByteChannel tdfBytes) throws SDKException, IOException {
156+
TDFReader reader = new TDFReader(tdfBytes);
157+
String manifestJson = reader.manifest();
158+
return Manifest.readManifest(manifestJson);
159+
}
160+
161+
/**
162+
* Decodes a PolicyObject from the manifest. Use {@link SDK#readManifest(SeekableByteChannel)}
163+
* to get the {@link Manifest} from a TDF.
164+
* @param manifest The {@link Manifest} containing the policy.
165+
* @return The decoded {@link PolicyObject}.
166+
* @throws SDKException if there is an error during decoding.
167+
*/
168+
public static PolicyObject decodePolicyObject(Manifest manifest) throws SDKException {
169+
return Manifest.decodePolicyObject(manifest);
170+
}
171+
148172
public String getPlatformUrl() {
149173
return platformUrl;
150174
}

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import java.io.IOException;
2323
import java.io.InputStream;
2424
import java.io.OutputStream;
25-
import java.io.StringReader;
2625
import java.nio.channels.SeekableByteChannel;
2726
import java.nio.charset.StandardCharsets;
2827
import java.security.*;
@@ -607,7 +606,7 @@ Reader loadTDF(SeekableByteChannel tdf, Config.TDFReaderConfig tdfReaderConfig)
607606
TDFReader tdfReader = new TDFReader(tdf);
608607
String manifestJson = tdfReader.manifest();
609608
// use Manifest.readManifest in order to validate the Manifest input
610-
Manifest manifest = Manifest.readManifest(new StringReader(manifestJson));
609+
Manifest manifest = Manifest.readManifest(manifestJson);
611610
byte[] payloadKey = new byte[GCM_KEY_SIZE];
612611
String unencryptedMetadata = null;
613612

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

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
package io.opentdf.platform.sdk;
22

3-
import java.io.BufferedReader;
43
import java.io.ByteArrayOutputStream;
54
import java.io.IOException;
65
import java.io.InputStream;
7-
import java.io.InputStreamReader;
86
import java.nio.channels.SeekableByteChannel;
97
import java.nio.charset.StandardCharsets;
108
import java.util.Map;
@@ -64,10 +62,8 @@ int readPayloadBytes(byte[] buf) {
6462
}
6563

6664
PolicyObject readPolicyObject() {
67-
try (var reader = new BufferedReader(new InputStreamReader(manifestEntry.getData()))){
68-
return Manifest.readPolicyObject(reader);
69-
} catch (IOException e) {
70-
throw new SDKException("error reading policy object", e);
71-
}
65+
String manifestJson = manifest();
66+
Manifest manifest = Manifest.readManifest(manifestJson);
67+
return Manifest.decodePolicyObject(manifest);
7268
}
7369
}

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@
44
import org.junit.jupiter.api.Test;
55

66
import java.io.IOException;
7-
import java.io.InputStreamReader;
8-
import java.io.StringReader;
7+
import java.nio.charset.StandardCharsets;
98
import java.util.List;
109
import java.util.Map;
1110

@@ -62,7 +61,7 @@ void testManifestMarshalAndUnMarshal() {
6261
" }\n" +
6362
"}";
6463

65-
Manifest manifest = Manifest.readManifest(new StringReader(kManifestJsonFromTDF));
64+
Manifest manifest = Manifest.readManifest(kManifestJsonFromTDF);
6665

6766
// Test payload
6867
assertEquals(manifest.payload.url, "0.payload");
@@ -85,7 +84,7 @@ void testManifestMarshalAndUnMarshal() {
8584
assertEquals(manifest.encryptionInformation.integrityInformation.segments.get(0).segmentSize, 1048576);
8685

8786
var serialized = Manifest.toJson(manifest);
88-
var deserializedAgain = Manifest.readManifest(new StringReader(serialized));
87+
var deserializedAgain = Manifest.readManifest(serialized);
8988

9089
assertEquals(manifest, deserializedAgain, "something changed when we deserialized -> serialized -> deserialized");
9190
}
@@ -140,7 +139,7 @@ void testAssertionNull() {
140139
" \"assertions\": null\n"+
141140
"}";
142141

143-
Manifest manifest = Manifest.readManifest(new StringReader(kManifestJsonFromTDF));
142+
Manifest manifest = Manifest.readManifest(kManifestJsonFromTDF);
144143

145144
// Test payload for sanity check
146145
assertEquals(manifest.payload.url, "0.payload");
@@ -155,7 +154,8 @@ void testReadingManifestWithObjectStatementValue() throws IOException {
155154
final Manifest manifest;
156155
try (var mStream = getClass().getResourceAsStream("/io.opentdf.platform.sdk.TestData/manifest-with-object-statement-value.json")) {
157156
assert mStream != null;
158-
manifest = Manifest.readManifest(new InputStreamReader(mStream)) ;
157+
var manifestJson = new String(mStream.readAllBytes(), StandardCharsets.UTF_8);
158+
manifest = Manifest.readManifest(manifestJson);
159159
}
160160

161161
assertThat(manifest.assertions).hasSize(2);

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,21 @@ public SeekableByteChannel truncate(long size) {
7777
assertThat(SDK.isTDF(chan)).isFalse();
7878
}
7979

80+
@Test
81+
void testExaminingManifest() throws IOException {
82+
try (var tdfStream = SDKTest.class.getClassLoader().getResourceAsStream("sample.txt.tdf")) {
83+
assertThat(tdfStream)
84+
.withFailMessage("sample.txt.tdf not found in classpath")
85+
.isNotNull();
86+
var manifest = SDK.readManifest(new SeekableInMemoryByteChannel(tdfStream.readAllBytes()));
87+
assertThat(manifest).isNotNull();
88+
assertThat(manifest.encryptionInformation.integrityInformation.encryptedSegmentSizeDefault)
89+
.isEqualTo(1048604);
90+
var policyObject = SDK.decodePolicyObject(manifest);
91+
assertThat(policyObject.uuid).isEqualTo("98bb8a81-5217-4a31-8852-932d29d71aac");
92+
}
93+
}
94+
8095
@Test
8196
void testReadingRandomBytes() {
8297
var tdf = new byte[2023];

0 commit comments

Comments
 (0)