diff --git a/.github/workflows/checks.yaml b/.github/workflows/checks.yaml index d985651e..947833fe 100644 --- a/.github/workflows/checks.yaml +++ b/.github/workflows/checks.yaml @@ -2,8 +2,6 @@ name: "Checks" on: pull_request: - branches: - - main push: branches: - main @@ -139,7 +137,7 @@ jobs: --client-secret=secret \ --platform-endpoint=localhost:8080 \ -i \ - encrypt --kas-url=localhost:8080 --mime-type=text/plain --attr https://example.com/attr/attr1/value/value1 -f data -m 'here is some metadata' > test.tdf + encrypt --kas-url=localhost:8080 --mime-type=text/plain --attr https://example.com/attr/attr1/value/value1 --autoconfigure=false -f data -m 'here is some metadata' > test.tdf java -jar target/cmdline.jar \ --client-id=opentdf-sdk \ diff --git a/cmdline/src/main/java/io/opentdf/platform/Command.java b/cmdline/src/main/java/io/opentdf/platform/Command.java index 64886f65..ee723844 100644 --- a/cmdline/src/main/java/io/opentdf/platform/Command.java +++ b/cmdline/src/main/java/io/opentdf/platform/Command.java @@ -13,12 +13,10 @@ import javax.crypto.NoSuchPaddingException; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; -import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.PrintWriter; -import java.io.StringWriter; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.nio.file.Path; @@ -31,7 +29,6 @@ import java.util.List; import java.util.Optional; import java.util.function.Consumer; -import java.util.stream.Stream; @CommandLine.Command(name = "tdf") class Command { @@ -55,6 +52,7 @@ void encrypt( @Option(names = {"-m", "--metadata"}, defaultValue = Option.NULL_VALUE) Optional metadata, // cant split on optional parameters @Option(names = {"-a", "--attr"}, defaultValue = Option.NULL_VALUE) Optional attributes, + @Option(names = {"-c", "--autoconfigure"}, defaultValue = Option.NULL_VALUE) Optional autoconfigure, @Option(names = {"--mime-type"}, defaultValue = Option.NULL_VALUE) Optional mimeType) throws IOException, JOSEException { @@ -68,15 +66,17 @@ void encrypt( List> configs = new ArrayList<>(); configs.add(Config.withKasInformation(kasInfos)); metadata.map(Config::withMetaData).ifPresent(configs::add); + autoconfigure.map(Config::withAutoconfigure).ifPresent(configs::add); mimeType.map(Config::withMimeType).ifPresent(configs::add); - attributes.ifPresent(attr -> { - configs.add(Config.withDataAttributes(attr.split(","))); - }); - + if (attributes.isPresent()){ + configs.add(Config.withDataAttributes(attributes.get().split(","))); + } var tdfConfig = Config.newTDFConfig(configs.toArray(Consumer[]::new)); try (var in = file.isEmpty() ? new BufferedInputStream(System.in) : new FileInputStream(file.get())) { try (var out = new BufferedOutputStream(System.out)) { - new TDF().createTDF(in, out, tdfConfig, sdk.getServices().kas()); + new TDF().createTDF(in, out, tdfConfig, + sdk.getServices().kas(), + sdk.getServices().attributes()); } } } diff --git a/sdk/src/main/java/io/opentdf/platform/sdk/Autoconfigure.java b/sdk/src/main/java/io/opentdf/platform/sdk/Autoconfigure.java index 429d36a4..9cf20edb 100644 --- a/sdk/src/main/java/io/opentdf/platform/sdk/Autoconfigure.java +++ b/sdk/src/main/java/io/opentdf/platform/sdk/Autoconfigure.java @@ -1,5 +1,6 @@ package io.opentdf.platform.sdk; +import java.io.IOException; import java.net.URLDecoder; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; @@ -31,7 +32,7 @@ import io.opentdf.platform.policy.AttributeRuleTypeEnum; // Error handling class -class AutoConfigureException extends Exception { +class AutoConfigureException extends IOException { public AutoConfigureException(String message) { super(message); } @@ -165,6 +166,20 @@ public AttributeValueFQN(String url) throws AutoConfigureException { public String toString() { return url; } + + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || !(obj instanceof AttributeValueFQN)) { + return false; + } + AttributeValueFQN afqn = (AttributeValueFQN) obj; + if ((this.url.equals(afqn.url)) && (this.key.equals(afqn.key))){ + return true; + } + return false; + } public String getKey() { return key; @@ -273,7 +288,7 @@ public interface StringOperator { } - public List plan(List defaultKas, Supplier genSplitID) throws Exception { + public List plan(List defaultKas, Supplier genSplitID) throws AutoConfigureException { AttributeBooleanExpression b = constructAttributeBoolean(); BooleanKeyExpression k = insertKeysForAttribute(b); if (k == null) { @@ -307,7 +322,7 @@ public List plan(List defaultKas, Supplier genSplitID return steps; } - public BooleanKeyExpression insertKeysForAttribute(AttributeBooleanExpression e) throws Exception { + public BooleanKeyExpression insertKeysForAttribute(AttributeBooleanExpression e) throws AutoConfigureException { List kcs = new ArrayList<>(e.must.size()); for (SingleAttributeClause clause : e.must) { @@ -316,7 +331,7 @@ public BooleanKeyExpression insertKeysForAttribute(AttributeBooleanExpression e) for (AttributeValueFQN term : clause.values) { KeyAccessGrant grant = byAttribute(term); if (grant == null) { - throw new Exception(String.format("no definition or grant found for [%s]", term)); + throw new AutoConfigureException(String.format("no definition or grant found for [%s]", term)); } List kases = grant.kases; @@ -660,7 +675,7 @@ public static String ruleToOperator(AttributeRuleTypeEnum e) { } // Gets a list of directory of KAS grants for a list of attribute FQNs - public static Granter newGranterFromService(SDK.AttributesService as, AttributeValueFQN... fqns) throws Exception { + public static Granter newGranterFromService(SDK.AttributesService as, AttributeValueFQN... fqns) throws AutoConfigureException { String[] fqnsStr = new String[fqns.length]; for (int i = 0; i < fqns.length; i++) { fqnsStr[i] = fqns[i].toString(); @@ -704,7 +719,7 @@ public static Granter newGranterFromService(SDK.AttributesService as, AttributeV // Given a policy (list of data attributes or tags), // get a set of grants from attribute values to KASes. // Unlike `NewGranterFromService`, this works offline. - public static Granter newGranterFromAttributes(Value... attrs) throws Exception { + public static Granter newGranterFromAttributes(Value... attrs) throws AutoConfigureException { List policyList = new ArrayList<>(attrs.length); Map grantsMap = new HashMap<>(); @@ -721,7 +736,7 @@ public static Granter newGranterFromAttributes(Value... attrs) throws Exception grants.policy.add(fqn); Attribute def = v.getAttribute(); if (def == null) { - throw new Exception("No associated definition with value [" + fqn.toString() + "]"); + throw new AutoConfigureException("No associated definition with value [" + fqn.toString() + "]"); } grants.addAllGrants(fqn, def.getGrantsList(), def); 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 108bfffe..a7a081c9 100644 --- a/sdk/src/main/java/io/opentdf/platform/sdk/Config.java +++ b/sdk/src/main/java/io/opentdf/platform/sdk/Config.java @@ -1,9 +1,12 @@ package io.opentdf.platform.sdk; +import io.opentdf.platform.sdk.Autoconfigure.AttributeValueFQN; import io.opentdf.platform.sdk.nanotdf.ECCMode; import io.opentdf.platform.sdk.nanotdf.NanoTDFType; import io.opentdf.platform.sdk.nanotdf.SymmetricAndPayloadConfig; +import io.opentdf.platform.policy.Value; + import java.util.*; import java.util.function.Consumer; @@ -30,6 +33,7 @@ public static class KASInfo { public String URL; public String PublicKey; public String KID; + public Boolean Default; } @@ -70,6 +74,7 @@ public static Consumer withAssertionVerificationKeys(AssertionV } public static class TDFConfig { + public Boolean autoconfigure; public int defaultSegmentSize; public boolean enableEncryption; public TDFFormat tdfFormat; @@ -78,13 +83,15 @@ public static class TDFConfig { public String metaData; public IntegrityAlgorithm integrityAlgorithm; public IntegrityAlgorithm segmentIntegrityAlgorithm; - public List attributes; + public List attributes; + public List attributeValues; public List kasInfoList; public List assertionConfigList; public String mimeType; public List splitPlan; public TDFConfig() { + this.autoconfigure = true; this.defaultSegmentSize = DEFAULT_SEGMENT_SIZE; this.enableEncryption = true; this.tdfFormat = TDFFormat.JSONFormat; @@ -107,9 +114,46 @@ public static TDFConfig newTDFConfig(Consumer... options) { return config; } - public static Consumer withDataAttributes(String... attributes) { + public static Consumer withDataAttributes(String... attributes) throws AutoConfigureException { + List attrValFqns = new ArrayList(); + for (String a : attributes){ + Autoconfigure.AttributeValueFQN attrValFqn = new Autoconfigure.AttributeValueFQN(a); + attrValFqns.add(attrValFqn); + } return (TDFConfig config) -> { - Collections.addAll(config.attributes, attributes); + config.attributeValues = null; + config.attributes.addAll(attrValFqns); + }; + } + + public static Consumer withDataAttributeValues(String... attributes) throws AutoConfigureException { + List attrValFqns = new ArrayList(); + for (String a : attributes){ + Autoconfigure.AttributeValueFQN attrValFqn = new Autoconfigure.AttributeValueFQN(a); + attrValFqns.add(attrValFqn); + } + return (TDFConfig config) -> { + config.attributeValues = null; + config.attributes.addAll(attrValFqns); + }; + } + + // WithDataAttributeValues appends the given data attributes to the bound policy. + // Unlike `WithDataAttributes`, this will not trigger an attribute definition lookup + // during autoconfigure. That is, to use autoconfigure in an 'offline' context, + // you must first store the relevant attribute information locally and load + // it to the `CreateTDF` method with this option. + public static Consumer withDataAttributeValues(Value... attributes) throws AutoConfigureException { + List attrValFqns = new ArrayList(); + List attrVals = new ArrayList(); + for (Value a : attributes) { + attrVals.add(a); + AttributeValueFQN afqn = new Autoconfigure.AttributeValueFQN(a.getFqn()); + attrValFqns.add(afqn); + } + return (TDFConfig config) -> { + config.attributes.addAll(attrValFqns); + config.attributeValues.addAll(attrVals); }; } @@ -119,6 +163,13 @@ public static Consumer withKasInformation(KASInfo... kasInfoList) { }; } + public static Consumer withSplitPlan(Autoconfigure.SplitStep... p) { + return (TDFConfig config) -> { + config.splitPlan = new ArrayList<>(Arrays.asList(p)); + config.autoconfigure = false; + }; + } + public static Consumer withAssertionConfig(io.opentdf.platform.sdk.AssertionConfig... assertionList) { return (TDFConfig config) -> { Collections.addAll(config.assertionConfigList, assertionList); @@ -133,6 +184,13 @@ public static Consumer withSegmentSize(int size) { return (TDFConfig config) -> config.defaultSegmentSize = size; } + public static Consumer withAutoconfigure(boolean enable) { + return (TDFConfig config) -> { + config.autoconfigure = enable; + config.splitPlan = null; + }; + } + // public static Consumer withDisableEncryption() { // return (TDFConfig config) -> config.enableEncryption = false; // } 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 c8638cb4..8b8b98fc 100644 --- a/sdk/src/main/java/io/opentdf/platform/sdk/TDF.java +++ b/sdk/src/main/java/io/opentdf/platform/sdk/TDF.java @@ -8,6 +8,12 @@ import com.nimbusds.jwt.JWTClaimsSet; import com.nimbusds.jwt.SignedJWT; +import io.opentdf.platform.policy.Value; + +import io.opentdf.platform.sdk.Config.TDFConfig; +import io.opentdf.platform.sdk.Autoconfigure.AttributeValueFQN; +import io.opentdf.platform.sdk.Config.KASInfo; + import com.nimbusds.jose.crypto.RSASSASigner; import com.nimbusds.jose.crypto.MACSigner; import org.apache.commons.codec.DecoderException; @@ -148,16 +154,16 @@ public TDFObject() { this.size = 0; } - PolicyObject createPolicyObject(List attributes) { + PolicyObject createPolicyObject(List attributes) { PolicyObject policyObject = new PolicyObject(); policyObject.body = new PolicyObject.Body(); policyObject.uuid = UUID.randomUUID().toString(); policyObject.body.dataAttributes = new ArrayList<>(); policyObject.body.dissem = new ArrayList<>(); - for (String attribute: attributes) { + for (Autoconfigure.AttributeValueFQN attribute: attributes) { PolicyObject.AttributeObject attributeObject = new PolicyObject.AttributeObject(); - attributeObject.attribute = attribute; + attributeObject.attribute = attribute.toString(); policyObject.body.dataAttributes.add(attributeObject); } return policyObject; @@ -172,7 +178,7 @@ private void prepareManifest(Config.TDFConfig tdfConfig, SDK.KAS kas) { String base64PolicyObject = encoder.encodeToString(gson.toJson(policyObject).getBytes(StandardCharsets.UTF_8)); List symKeys = new ArrayList<>(); Map latestKASInfo = new HashMap<>(); - if (tdfConfig.splitPlan.isEmpty()) { + if (tdfConfig.splitPlan == null || tdfConfig.splitPlan.isEmpty()) { // Default split plan: Split keys across all KASes List splitPlan = new ArrayList<>(tdfConfig.kasInfoList.size()); int i = 0; @@ -267,6 +273,7 @@ private void prepareManifest(Config.TDFConfig tdfConfig, SDK.KAS kas) { keyAccess.policyBinding = policyBinding; keyAccess.wrappedKey = encoder.encodeToString(wrappedKey); keyAccess.encryptedMetadata = encryptedMetadata; + keyAccess.sid = splitID; manifest.encryptionInformation.keyAccessObj.add(keyAccess); } @@ -369,9 +376,30 @@ private static String calculateSignature(byte[] data, byte[] secret, Config.Inte public TDFObject createTDF(InputStream payload, OutputStream outputStream, - Config.TDFConfig tdfConfig, SDK.KAS kas) throws IOException, JOSEException { - if (tdfConfig.kasInfoList.isEmpty()) { - throw new KasInfoMissing("kas information is missing"); + Config.TDFConfig tdfConfig, SDK.KAS kas, SDK.AttributesService attrService) throws IOException, JOSEException { + + if (tdfConfig.autoconfigure) { + Autoconfigure.Granter granter = new Autoconfigure.Granter(new ArrayList<>()); + if (tdfConfig.attributeValues != null && !tdfConfig.attributeValues.isEmpty()) { + granter = Autoconfigure.newGranterFromAttributes(tdfConfig.attributeValues.toArray(new Value[0])); + } else if (tdfConfig.attributes != null && !tdfConfig.attributes.isEmpty()) { + granter = Autoconfigure.newGranterFromService(attrService, tdfConfig.attributes.toArray(new AttributeValueFQN[0])); + } + + if (granter == null) { + throw new AutoConfigureException("Failed to create Granter"); // Replace with appropriate error handling + } + + List dk = defaultKases(tdfConfig); + tdfConfig.splitPlan = granter.plan(dk, () -> UUID.randomUUID().toString()); + + if (tdfConfig.splitPlan == null) { + throw new AutoConfigureException("Failed to generate Split Plan"); // Replace with appropriate error handling + } + } + + if (tdfConfig.kasInfoList.isEmpty() && (tdfConfig.splitPlan==null || tdfConfig.splitPlan.isEmpty())) { + throw new KasInfoMissing("kas information is missing, no key access template specified or inferred"); } TDFObject tdfObject = new TDFObject(); @@ -495,6 +523,23 @@ public TDFObject createTDF(InputStream payload, return tdfObject; } + public List defaultKases(TDFConfig config) { + List allk = new ArrayList<>(); + List defk = new ArrayList<>(); + + for (KASInfo kasInfo : config.kasInfoList) { + if (kasInfo.Default != null && kasInfo.Default) { + defk.add(kasInfo.URL); + } else if (defk.isEmpty()) { + allk.add(kasInfo.URL); + } + } + if (defk.isEmpty()) { + return allk; + } + return defk; + } + private void fillInPublicKeyInfo(List kasInfoList, SDK.KAS kas) { for (var kasInfo: kasInfoList) { if (kasInfo.PublicKey != null && !kasInfo.PublicKey.isBlank()) { 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 0f079f81..cae23434 100644 --- a/sdk/src/test/java/io/opentdf/platform/sdk/ConfigTest.java +++ b/sdk/src/test/java/io/opentdf/platform/sdk/ConfigTest.java @@ -20,11 +20,11 @@ void newTDFConfig_shouldCreateDefaultConfig() { } @Test - void withDataAttributes_shouldAddAttributes() { - Config.TDFConfig config = Config.newTDFConfig(Config.withDataAttributes("attr1", "attr2")); + void withDataAttributes_shouldAddAttributes() throws AutoConfigureException { + Config.TDFConfig config = Config.newTDFConfig(Config.withDataAttributes("https://example.com/attr/attr1/value/value1", "https://example.com/attr/attr2/value/value2")); assertEquals(2, config.attributes.size()); - assertTrue(config.attributes.contains("attr1")); - assertTrue(config.attributes.contains("attr2")); + assertTrue(config.attributes.contains(new Autoconfigure.AttributeValueFQN("https://example.com/attr/attr1/value/value1"))); + assertTrue(config.attributes.contains(new Autoconfigure.AttributeValueFQN("https://example.com/attr/attr2/value/value2"))); } @Test diff --git a/sdk/src/test/java/io/opentdf/platform/sdk/TDFE2ETest.java b/sdk/src/test/java/io/opentdf/platform/sdk/TDFE2ETest.java index eea443c7..fb44663c 100644 --- a/sdk/src/test/java/io/opentdf/platform/sdk/TDFE2ETest.java +++ b/sdk/src/test/java/io/opentdf/platform/sdk/TDFE2ETest.java @@ -35,7 +35,7 @@ public void createAndDecryptTdfIT() throws Exception { ByteArrayOutputStream tdfOutputStream = new ByteArrayOutputStream(); TDF tdf = new TDF(); - tdf.createTDF(plainTextInputStream, tdfOutputStream, config, sdk.kas()); + 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()); 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 8fad4ca1..ab773673 100644 --- a/sdk/src/test/java/io/opentdf/platform/sdk/TDFTest.java +++ b/sdk/src/test/java/io/opentdf/platform/sdk/TDFTest.java @@ -7,6 +7,8 @@ import com.nimbusds.jose.crypto.RSASSAVerifier; import com.nimbusds.jose.jwk.RSAKey; +import io.opentdf.platform.policy.attributes.GetAttributeValuesByFqnsRequest; +import io.opentdf.platform.policy.attributes.GetAttributeValuesByFqnsResponse; import io.opentdf.platform.sdk.nanotdf.NanoTDFType; import org.apache.commons.compress.utils.SeekableInMemoryByteChannel; import org.junit.jupiter.api.BeforeAll; @@ -69,6 +71,15 @@ public byte[] unwrapNanoTDF(NanoTDFType.ECCurve curve, String header, String kas return null; } }; + private static SDK.AttributesService attrServ = new SDK.AttributesService() { + @Override + public void close() {} + + @Override + public GetAttributeValuesByFqnsResponse getAttributeValuesByFqn(GetAttributeValuesByFqnsRequest request) { + return GetAttributeValuesByFqnsResponse.newBuilder().build(); + } + }; private static ArrayList keypairs = new ArrayList<>(); @@ -97,6 +108,7 @@ void testSimpleTDFEncryptAndDecrypt() throws Exception { assertion1.assertionKey = new AssertionConfig.AssertionKey(AssertionConfig.AssertionKeyAlg.HS256, key); Config.TDFConfig config = Config.newTDFConfig( + Config.withAutoconfigure(false), Config.withKasInformation(getKASInfos()), Config.withMetaData("here is some metadata"), Config.withAssertionConfig(assertion1) @@ -107,7 +119,7 @@ void testSimpleTDFEncryptAndDecrypt() throws Exception { ByteArrayOutputStream tdfOutputStream = new ByteArrayOutputStream(); TDF tdf = new TDF(); - tdf.createTDF(plainTextInputStream, tdfOutputStream, config, kas); + tdf.createTDF(plainTextInputStream, tdfOutputStream, config, kas, attrServ); var assertionVerificationKeys = new Config.AssertionVerificationKeys(); assertionVerificationKeys.defaultKey = new AssertionConfig.AssertionKey(AssertionConfig.AssertionKeyAlg.HS256, key); @@ -142,6 +154,7 @@ void testSimpleTDFWithAssertionWithRS256() throws Exception { keypair.getPrivate()); Config.TDFConfig config = Config.newTDFConfig( + Config.withAutoconfigure(false), Config.withKasInformation(getKASInfos()), Config.withAssertionConfig(assertionConfig) ); @@ -151,7 +164,7 @@ void testSimpleTDFWithAssertionWithRS256() throws Exception { ByteArrayOutputStream tdfOutputStream = new ByteArrayOutputStream(); TDF tdf = new TDF(); - tdf.createTDF(plainTextInputStream, tdfOutputStream, config, kas); + tdf.createTDF(plainTextInputStream, tdfOutputStream, config, kas, attrServ); var assertionVerificationKeys = new Config.AssertionVerificationKeys(); assertionVerificationKeys.keys.put(assertion1Id, @@ -181,6 +194,7 @@ void testSimpleTDFWithAssertionWithHS256() throws Exception { assertionConfig1.statement.value = "ICAgIDxlZGoOkVkaD4="; Config.TDFConfig config = Config.newTDFConfig( + Config.withAutoconfigure(false), Config.withKasInformation(getKASInfos()), Config.withAssertionConfig(assertionConfig1) ); @@ -190,7 +204,7 @@ void testSimpleTDFWithAssertionWithHS256() throws Exception { ByteArrayOutputStream tdfOutputStream = new ByteArrayOutputStream(); TDF tdf = new TDF(); - tdf.createTDF(plainTextInputStream, tdfOutputStream, config, kas); + tdf.createTDF(plainTextInputStream, tdfOutputStream, config, kas, attrServ); var unwrappedData = new ByteArrayOutputStream(); var reader = tdf.loadTDF(new SeekableInMemoryByteChannel(tdfOutputStream.toByteArray()), kas); @@ -206,6 +220,7 @@ public void testCreatingTDFWithMultipleSegments() throws Exception { var random = new Random(); Config.TDFConfig config = Config.newTDFConfig( + Config.withAutoconfigure(false), Config.withKasInformation(getKASInfos()), // use a random segment size that makes sure that we will use multiple segments Config.withSegmentSize(1 + random.nextInt(20)) @@ -217,7 +232,7 @@ public void testCreatingTDFWithMultipleSegments() throws Exception { var plainTextInputStream = new ByteArrayInputStream(data); var tdfOutputStream = new ByteArrayOutputStream(); var tdf = new TDF(); - tdf.createTDF(plainTextInputStream, tdfOutputStream, config, kas); + tdf.createTDF(plainTextInputStream, tdfOutputStream, config, kas, attrServ); var unwrappedData = new ByteArrayOutputStream(); var reader = tdf.loadTDF(new SeekableInMemoryByteChannel(tdfOutputStream.toByteArray()), kas); reader.readPayload(unwrappedData); @@ -262,10 +277,11 @@ public void write(byte[] b, int off, int len) {} var tdf = new TDF(maxSize); var tdfConfig = Config.newTDFConfig( + Config.withAutoconfigure(false), Config.withKasInformation(getKASInfos()), Config.withSegmentSize(1 + random.nextInt(128))); assertThrows(TDF.DataSizeNotSupported.class, - () -> tdf.createTDF(is, os, tdfConfig, kas), + () -> tdf.createTDF(is, os, tdfConfig, kas, attrServ), "didn't throw an exception when we created TDF that was too large"); assertThat(numReturned.get()) .withFailMessage("test returned the wrong number of bytes") @@ -278,6 +294,7 @@ public void testCreateTDFWithMimeType() throws Exception { final String mimeType = "application/pdf"; Config.TDFConfig config = Config.newTDFConfig( + Config.withAutoconfigure(false), Config.withKasInformation(getKASInfos()), Config.withMimeType(mimeType) ); @@ -287,7 +304,7 @@ public void testCreateTDFWithMimeType() throws Exception { ByteArrayOutputStream tdfOutputStream = new ByteArrayOutputStream(); TDF tdf = new TDF(); - tdf.createTDF(plainTextInputStream, tdfOutputStream, config, kas); + tdf.createTDF(plainTextInputStream, tdfOutputStream, config, kas, attrServ); var reader = tdf.loadTDF(new SeekableInMemoryByteChannel(tdfOutputStream.toByteArray()), kas); assertThat(reader.getManifest().payload.mimeType).isEqualTo(mimeType);