Skip to content

Commit e48cdbd

Browse files
feat(sdk): KAS Allowlist (#245)
Adds an allowlist for kas urls --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 48e9376 commit e48cdbd

File tree

15 files changed

+544
-63
lines changed

15 files changed

+544
-63
lines changed

.github/workflows/checks.yaml

+21-21
Original file line numberDiff line numberDiff line change
@@ -152,21 +152,21 @@ jobs:
152152
java -jar target/cmdline.jar \
153153
--client-id=opentdf-sdk \
154154
--client-secret=secret \
155-
--platform-endpoint=localhost:8080 \
155+
--platform-endpoint=http://localhost:8080 \
156156
-h\
157-
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
157+
encrypt --kas-url=http://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
158158
159159
java -jar target/cmdline.jar \
160160
--client-id=opentdf-sdk \
161161
--client-secret=secret \
162-
--platform-endpoint=localhost:8080 \
162+
--platform-endpoint=http://localhost:8080 \
163163
-h\
164164
decrypt -f test.tdf > decrypted
165165
166166
java -jar target/cmdline.jar \
167167
--client-id=opentdf-sdk \
168168
--client-secret=secret \
169-
--platform-endpoint=localhost:8080 \
169+
--platform-endpoint=http://localhost:8080 \
170170
-h\
171171
metadata -f test.tdf > metadata
172172
@@ -188,14 +188,14 @@ jobs:
188188
java -jar target/cmdline.jar \
189189
--client-id=opentdf-sdk \
190190
--client-secret=secret \
191-
--platform-endpoint=localhost:8080 \
191+
--platform-endpoint=http://localhost:8080 \
192192
-h\
193193
encryptnano --kas-url=http://localhost:8080 --attr https://example.com/attr/attr1/value/value1 -f data -m 'here is some metadata' > nano.ntdf
194194
195195
java -jar target/cmdline.jar \
196196
--client-id=opentdf-sdk \
197197
--client-secret=secret \
198-
--platform-endpoint=localhost:8080 \
198+
--platform-endpoint=http://localhost:8080 \
199199
-h\
200200
decryptnano -f nano.ntdf > decrypted
201201
@@ -215,14 +215,14 @@ jobs:
215215
java -jar target/cmdline.jar \
216216
--client-id=opentdf-sdk \
217217
--client-secret=secret \
218-
--platform-endpoint=localhost:8080 \
218+
--platform-endpoint=http://localhost:8080 \
219219
-h\
220-
encrypt --kas-url=localhost:8080 --mime-type=text/plain --with-assertions=$ASSERTIONS --autoconfigure=false -f data -m 'here is some metadata' > test.tdf
220+
encrypt --kas-url=http://localhost:8080 --mime-type=text/plain --with-assertions=$ASSERTIONS --autoconfigure=false -f data -m 'here is some metadata' > test.tdf
221221
222222
java -jar target/cmdline.jar \
223223
--client-id=opentdf-sdk \
224224
--client-secret=secret \
225-
--platform-endpoint=localhost:8080 \
225+
--platform-endpoint=http://localhost:8080 \
226226
-h\
227227
decrypt -f test.tdf > decrypted
228228
@@ -246,14 +246,14 @@ jobs:
246246
java -jar target/cmdline.jar \
247247
--client-id=opentdf-sdk \
248248
--client-secret=secret \
249-
--platform-endpoint=localhost:8080 \
249+
--platform-endpoint=http://localhost:8080 \
250250
-h\
251-
encrypt --kas-url=localhost:8080 --mime-type=text/plain --with-assertions="$SIGNED_ASSERTIONS_HS256" --autoconfigure=false -f data -m 'here is some metadata' > test.tdf
251+
encrypt --kas-url=http://localhost:8080 --mime-type=text/plain --with-assertions="$SIGNED_ASSERTIONS_HS256" --autoconfigure=false -f data -m 'here is some metadata' > test.tdf
252252
253253
java -jar target/cmdline.jar \
254254
--client-id=opentdf-sdk \
255255
--client-secret=secret \
256-
--platform-endpoint=localhost:8080 \
256+
--platform-endpoint=http://localhost:8080 \
257257
-h\
258258
decrypt --with-assertion-verification-keys="$SIGNED_ASSERTION_VERIFICATON_HS256" -f test.tdf > decrypted
259259
@@ -267,14 +267,14 @@ jobs:
267267
java -jar target/cmdline.jar \
268268
--client-id=opentdf-sdk \
269269
--client-secret=secret \
270-
--platform-endpoint=localhost:8080 \
270+
--platform-endpoint=http://localhost:8080 \
271271
-h\
272-
encrypt --kas-url=localhost:8080 --mime-type=text/plain --with-assertions "$SIGNED_ASSERTIONS_RS256" --autoconfigure=false -f data -m 'here is some metadata' > test.tdf
272+
encrypt --kas-url=http://localhost:8080 --mime-type=text/plain --with-assertions "$SIGNED_ASSERTIONS_RS256" --autoconfigure=false -f data -m 'here is some metadata' > test.tdf
273273
274274
java -jar target/cmdline.jar \
275275
--client-id=opentdf-sdk \
276276
--client-secret=secret \
277-
--platform-endpoint=localhost:8080 \
277+
--platform-endpoint=http://localhost:8080 \
278278
-h\
279279
decrypt --with-assertion-verification-keys "$SIGNED_ASSERTION_VERIFICATON_RS256" -f test.tdf > decrypted
280280
@@ -300,23 +300,23 @@ jobs:
300300
java -jar target/cmdline.jar \
301301
--client-id=opentdf-sdk \
302302
--client-secret=secret \
303-
--platform-endpoint=localhost:8080 \
303+
--platform-endpoint=http://localhost:8080 \
304304
-h\
305-
encrypt --kas-url=localhost:8080,localhost:8282 -f data -m 'here is some metadata' > test.tdf
305+
encrypt --kas-url=http://localhost:8080,http://localhost:8282 -f data -m 'here is some metadata' > test.tdf
306306
307307
java -jar target/cmdline.jar \
308308
--client-id=opentdf-sdk \
309309
--client-secret=secret \
310-
--platform-endpoint=localhost:8080 \
310+
--platform-endpoint=http://localhost:8080 \
311311
-h\
312-
decrypt -f test.tdf > decrypted
312+
decrypt -f test.tdf --kas-allowlist http://localhost:8080,http://localhost:8282 > decrypted
313313
314314
java -jar target/cmdline.jar \
315315
--client-id=opentdf-sdk \
316316
--client-secret=secret \
317-
--platform-endpoint=localhost:8080 \
317+
--platform-endpoint=http://localhost:8080 \
318318
-h\
319-
metadata -f test.tdf > metadata
319+
metadata -f test.tdf --kas-allowlist http://localhost:8080,http://localhost:8282 > metadata
320320
321321
if ! diff -q data decrypted; then
322322
printf 'decrypted data is incorrect [%s]' "$(< decrypted)"

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public class Example {
3838
// Decrypt a file
3939
try (SeekableByteChannel in =
4040
FileChannel.open("input.ciphertext", StandardOpenOption.READ)) {
41-
TDF.Reader reader = new TDF().loadTDF(in, sdk.getServices().kas());
41+
TDF.Reader reader = new TDF().loadTDF(in, sdk.getServices().kas(), sdk.getServices().kasRegistry(), sdk.getPlatformUrl());
4242
reader.readPayload(System.out);
4343
}
4444
}}

cmdline/src/main/java/io/opentdf/platform/Command.java

+40-9
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import java.io.FileInputStream;
2525
import java.io.IOException;
2626
import java.io.PrintWriter;
27+
import java.net.URISyntaxException;
2728
import java.nio.ByteBuffer;
2829
import java.nio.channels.FileChannel;
2930
import java.nio.charset.StandardCharsets;
@@ -245,8 +246,10 @@ private SDK buildSDK() {
245246
void decrypt(@Option(names = { "-f", "--file" }, required = true) Path tdfPath,
246247
@Option(names = { "--rewrap-key-type" }, defaultValue = Option.NULL_VALUE, description = "Preferred rewrap algorithm, one of ${COMPLETION-CANDIDATES}") Optional<KeyType> rewrapKeyType,
247248
@Option(names = { "--with-assertion-verification-disabled" }, defaultValue = "false") boolean disableAssertionVerification,
248-
@Option(names = { "--with-assertion-verification-keys" }, defaultValue = Option.NULL_VALUE) Optional<String> assertionVerification)
249-
throws IOException, TDF.FailedToCreateGMAC, JOSEException, ParseException, NoSuchAlgorithmException, DecoderException {
249+
@Option(names = { "--with-assertion-verification-keys" }, defaultValue = Option.NULL_VALUE) Optional<String> assertionVerification,
250+
@Option(names = { "--kas-allowlist" }, defaultValue = Option.NULL_VALUE) Optional<String> kasAllowlistStr,
251+
@Option(names = { "--ignore-kas-allowlist" }, defaultValue = Option.NULL_VALUE) Optional<Boolean> ignoreAllowlist)
252+
throws IOException, TDF.FailedToCreateGMAC, JOSEException, ParseException, NoSuchAlgorithmException, DecoderException, InterruptedException, ExecutionException, URISyntaxException {
250253
var sdk = buildSDK();
251254
var opts = new ArrayList<Consumer<Config.TDFReaderConfig>>();
252255
try (var in = FileChannel.open(tdfPath, StandardOpenOption.READ)) {
@@ -286,21 +289,39 @@ void decrypt(@Option(names = { "-f", "--file" }, required = true) Path tdfPath,
286289
}
287290
rewrapKeyType.map(Config::WithSessionKeyType).ifPresent(opts::add);
288291

292+
if (ignoreAllowlist.isPresent()) {
293+
opts.add(Config.WithIgnoreKasAllowlist(ignoreAllowlist.get()));
294+
}
295+
if (kasAllowlistStr.isPresent()) {
296+
opts.add(Config.WithKasAllowlist(kasAllowlistStr.get().split(",")));
297+
}
298+
289299
var readerConfig = Config.newTDFReaderConfig(opts.toArray(new Consumer[0]));
290-
var reader = new TDF().loadTDF(in, sdk.getServices().kas(), readerConfig);
300+
var reader = new TDF().loadTDF(in, sdk.getServices().kas(), readerConfig, sdk.getServices().kasRegistry(), sdk.getPlatformUrl());
291301
reader.readPayload(stdout);
292302
}
293303
}
294304
}
295305

296306
@CommandLine.Command(name = "metadata")
297-
void readMetadata(@Option(names = { "-f", "--file" }, required = true) Path tdfPath) throws IOException,
298-
TDF.FailedToCreateGMAC, JOSEException, NoSuchAlgorithmException, ParseException, DecoderException {
307+
void readMetadata(@Option(names = { "-f", "--file" }, required = true) Path tdfPath,
308+
@Option(names = { "--kas-allowlist" }, defaultValue = Option.NULL_VALUE) Optional<String> kasAllowlistStr,
309+
@Option(names = { "--ignore-kas-allowlist" }, defaultValue = Option.NULL_VALUE) Optional<Boolean> ignoreAllowlist) throws IOException,
310+
TDF.FailedToCreateGMAC, JOSEException, NoSuchAlgorithmException, ParseException, DecoderException, InterruptedException, ExecutionException, URISyntaxException {
299311
var sdk = buildSDK();
300-
312+
var opts = new ArrayList<Consumer<Config.TDFReaderConfig>>();
301313
try (var in = FileChannel.open(tdfPath, StandardOpenOption.READ)) {
302314
try (var stdout = new PrintWriter(System.out)) {
303-
var reader = new TDF().loadTDF(in, sdk.getServices().kas());
315+
316+
if (ignoreAllowlist.isPresent()) {
317+
opts.add(Config.WithIgnoreKasAllowlist(ignoreAllowlist.get()));
318+
}
319+
if (kasAllowlistStr.isPresent()) {
320+
opts.add(Config.WithKasAllowlist(kasAllowlistStr.get().split(",")));
321+
}
322+
323+
var readerConfig = Config.newTDFReaderConfig(opts.toArray(new Consumer[0]));
324+
var reader = new TDF().loadTDF(in, sdk.getServices().kas(), readerConfig, sdk.getServices().kasRegistry(), sdk.getPlatformUrl());
304325
stdout.write(reader.getMetadata() == null ? "" : reader.getMetadata());
305326
}
306327
}
@@ -337,15 +358,25 @@ void createNanoTDF(
337358
}
338359

339360
@CommandLine.Command(name = "decryptnano")
340-
void readNanoTDF(@Option(names = { "-f", "--file" }, required = true) Path nanoTDFPath) throws Exception {
361+
void readNanoTDF(@Option(names = { "-f", "--file" }, required = true) Path nanoTDFPath,
362+
@Option(names = { "--kas-allowlist" }, defaultValue = Option.NULL_VALUE) Optional<String> kasAllowlistStr,
363+
@Option(names = { "--ignore-kas-allowlist" }, defaultValue = Option.NULL_VALUE) Optional<Boolean> ignoreAllowlist) throws Exception {
341364
var sdk = buildSDK();
342365
try (var in = FileChannel.open(nanoTDFPath, StandardOpenOption.READ)) {
343366
try (var stdout = new BufferedOutputStream(System.out)) {
344367
NanoTDF ntdf = new NanoTDF();
345368
ByteBuffer buffer = ByteBuffer.allocate((int) in.size());
346369
in.read(buffer);
347370
buffer.flip();
348-
ntdf.readNanoTDF(buffer, stdout, sdk.getServices().kas());
371+
var opts = new ArrayList<Consumer<Config.NanoTDFReaderConfig>>();
372+
if (ignoreAllowlist.isPresent()) {
373+
opts.add(Config.WithNanoIgnoreKasAllowlist(ignoreAllowlist.get()));
374+
}
375+
if (kasAllowlistStr.isPresent()) {
376+
opts.add(Config.WithNanoKasAllowlist(kasAllowlistStr.get().split(",")));
377+
}
378+
var readerConfig = Config.newNanoTDFReaderConfig(opts.toArray(new Consumer[0]));
379+
ntdf.readNanoTDF(buffer, stdout, sdk.getServices().kas(), readerConfig, sdk.getServices().kasRegistry(), sdk.getPlatformUrl());
349380
}
350381
}
351382
}

examples/src/main/java/io/opentdf/platform/DecryptCollectionExample.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,14 @@
99
import java.io.FileInputStream;
1010
import java.io.FileOutputStream;
1111
import java.io.IOException;
12+
import java.net.URISyntaxException;
1213
import java.nio.ByteBuffer;
1314
import java.nio.charset.StandardCharsets;
1415
import java.security.NoSuchAlgorithmException;
16+
import java.util.concurrent.ExecutionException;
1517

1618
public class DecryptCollectionExample {
17-
public static void main(String[] args) throws IOException, NanoTDF.NanoTDFMaxSizeLimit, NanoTDF.UnsupportedNanoTDFFeature, NanoTDF.InvalidNanoTDFConfig, NoSuchAlgorithmException, InterruptedException {
19+
public static void main(String[] args) throws IOException, NanoTDF.NanoTDFMaxSizeLimit, NanoTDF.UnsupportedNanoTDFFeature, NanoTDF.InvalidNanoTDFConfig, NoSuchAlgorithmException, InterruptedException, ExecutionException, URISyntaxException {
1820
String clientId = "opentdf-sdk";
1921
String clientSecret = "secret";
2022
String platformEndpoint = "localhost:8080";
@@ -33,7 +35,7 @@ public static void main(String[] args) throws IOException, NanoTDF.NanoTDFMaxSiz
3335

3436
for (int i = 0; i < 50; i++) {
3537
FileInputStream fis = new FileInputStream(String.format("out/my.%d_ciphertext", i));
36-
nanoTDFClient.readNanoTDF(ByteBuffer.wrap(fis.readAllBytes()), System.out, sdk.getServices().kas());
38+
nanoTDFClient.readNanoTDF(ByteBuffer.wrap(fis.readAllBytes()), System.out, sdk.getServices().kas(), sdk.getServices().kasRegistry(), sdk.getPlatformUrl());
3739
fis.close();
3840
}
3941

examples/src/main/java/io/opentdf/platform/DecryptExample.java

+5-2
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,13 @@
77
import java.nio.file.Paths;
88
import com.nimbusds.jose.JOSEException;
99
import java.io.IOException;
10+
import java.net.URISyntaxException;
1011
import java.security.InvalidAlgorithmParameterException;
1112
import java.security.InvalidKeyException;
1213
import java.security.NoSuchAlgorithmException;
1314
import java.text.ParseException;
15+
import java.util.concurrent.ExecutionException;
16+
1417
import javax.crypto.BadPaddingException;
1518
import javax.crypto.IllegalBlockSizeException;
1619
import javax.crypto.NoSuchPaddingException;
@@ -21,7 +24,7 @@ public class DecryptExample {
2124
public static void main(String[] args) throws IOException,
2225
InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException,
2326
BadPaddingException, InvalidKeyException, TDF.FailedToCreateGMAC,
24-
JOSEException, ParseException, NoSuchAlgorithmException, DecoderException, org.apache.commons.cli.ParseException {
27+
JOSEException, ParseException, NoSuchAlgorithmException, DecoderException, org.apache.commons.cli.ParseException, InterruptedException, ExecutionException, URISyntaxException {
2528

2629
// Create Options object
2730
Options options = new Options();
@@ -53,7 +56,7 @@ public static void main(String[] args) throws IOException,
5356

5457
Path path = Paths.get("my.ciphertext");
5558
try (var in = FileChannel.open(path, StandardOpenOption.READ)) {
56-
var reader = new TDF().loadTDF(in, sdk.getServices().kas(), Config.newTDFReaderConfig(Config.WithSessionKeyType(sessionKeyType)));
59+
var reader = new TDF().loadTDF(in, sdk.getServices().kas(), Config.newTDFReaderConfig(Config.WithSessionKeyType(sessionKeyType)), sdk.getServices().kasRegistry(), sdk.getPlatformUrl());
5760
reader.readPayload(System.out);
5861
}
5962

0 commit comments

Comments
 (0)