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 670531c8..15452d95 100644 --- a/sdk/src/main/java/io/opentdf/platform/sdk/Config.java +++ b/sdk/src/main/java/io/opentdf/platform/sdk/Config.java @@ -16,6 +16,7 @@ public class Config { public static final int TDF3_KEY_SIZE = 2048; public static final int DEFAULT_SEGMENT_SIZE = 2 * 1024 * 1024; // 2mb public static final String KAS_PUBLIC_KEY_PATH = "/kas_public_key"; + public static final String DEFAULT_MIME_TYPE = "application/octet-stream"; public enum TDFFormat { JSONFormat, @@ -65,6 +66,7 @@ public static class TDFConfig { public List kasInfoList; public List assertionList; public AssertionConfig assertionConfig; + public String mimeType; public TDFConfig() { this.defaultSegmentSize = DEFAULT_SEGMENT_SIZE; @@ -75,6 +77,7 @@ public TDFConfig() { this.attributes = new ArrayList<>(); this.kasInfoList = new ArrayList<>(); this.assertionList = new ArrayList<>(); + this.mimeType = DEFAULT_MIME_TYPE; } } @@ -125,6 +128,10 @@ public static Consumer withDisableEncryption() { return (TDFConfig config) -> config.enableEncryption = false; } + public static Consumer withMimeType(String mimeType) { + return (TDFConfig config) -> config.mimeType = mimeType; + } + public static class NanoTDFConfig { public ECCMode eccMode; public NanoTDFType.Cipher cipher; 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 ae33577c..1d18732f 100644 --- a/sdk/src/main/java/io/opentdf/platform/sdk/TDF.java +++ b/sdk/src/main/java/io/opentdf/platform/sdk/TDF.java @@ -60,7 +60,6 @@ public TDF() { private static final String kSha256Hash = "SHA256"; private static final String kHmacIntegrityAlgorithm = "HS256"; - private static final String kDefaultMimeType = "application/octet-stream"; private static final String kTDFAsZip = "zip"; private static final String kTDFZipReference = "reference"; private static final String kAssertionHash = "assertionHash"; @@ -241,6 +240,10 @@ public String getMetadata() { return unencryptedMetadata; } + public Manifest getManifest() { + return manifest; + } + private final String unencryptedMetadata; private final AesGcm aesGcm; @@ -422,7 +425,7 @@ public TDFObject createTDF(InputStream payload, // Add payload info tdfObject.manifest.payload = new Manifest.Payload(); - tdfObject.manifest.payload.mimeType = kDefaultMimeType; + tdfObject.manifest.payload.mimeType = tdfConfig.mimeType; tdfObject.manifest.payload.protocol = kTDFAsZip; tdfObject.manifest.payload.type = kTDFZipReference; tdfObject.manifest.payload.url = TDFWriter.TDF_PAYLOAD_FILE_NAME; diff --git a/sdk/src/test/java/io/opentdf/platform/sdk/ConfigTest.java b/sdk/src/test/java/io/opentdf/platform/sdk/ConfigTest.java index 3eb9ecbc..0f079f81 100644 --- a/sdk/src/test/java/io/opentdf/platform/sdk/ConfigTest.java +++ b/sdk/src/test/java/io/opentdf/platform/sdk/ConfigTest.java @@ -49,4 +49,11 @@ void withSegmentSize_shouldSetSegmentSize() { Config.TDFConfig config = Config.newTDFConfig(Config.withSegmentSize(1024)); assertEquals(1024, config.defaultSegmentSize); } + + @Test + void withMimeType_shouldSetMimeType() { + final String mimeType = "application/pdf"; + Config.TDFConfig config = Config.newTDFConfig(Config.withMimeType(mimeType)); + assertEquals(mimeType, config.mimeType); + } } \ No newline at end of file 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 6a64f9b5..bc97302a 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,8 @@ import com.nimbusds.jose.jwk.RSAKey; + +import io.opentdf.platform.sdk.TDF.TDFObject; import io.opentdf.platform.sdk.nanotdf.NanoTDFType; import org.apache.commons.compress.utils.SeekableInMemoryByteChannel; import org.junit.jupiter.api.BeforeAll; @@ -99,6 +101,8 @@ void testSimpleTDFEncryptAndDecrypt() throws Exception { var unwrappedData = new ByteArrayOutputStream(); var reader = tdf.loadTDF(new SeekableInMemoryByteChannel(tdfOutputStream.toByteArray()), new Config.AssertionConfig(), kas); + assertThat(reader.getManifest().payload.mimeType).isEqualTo("application/octet-stream"); + reader.readPayload(unwrappedData); assertThat(unwrappedData.toString(StandardCharsets.UTF_8)) @@ -257,6 +261,27 @@ public void write(byte[] b, int off, int len) {} .isEqualTo(maxSize + 1); } + @Test + public void testCreateTDFWithMimeType() throws Exception { + + final String mimeType = "application/pdf"; + + Config.TDFConfig config = Config.newTDFConfig( + Config.withKasInformation(getKASInfos()), + Config.withMimeType(mimeType) + ); + + 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); + + var reader = tdf.loadTDF(new SeekableInMemoryByteChannel(tdfOutputStream.toByteArray()), new Config.AssertionConfig(), kas); + assertThat(reader.getManifest().payload.mimeType).isEqualTo(mimeType); + } + @Nonnull private static Config.KASInfo[] getKASInfos() { var kasInfos = new ArrayList<>();