Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
9bf8ebc
set bc in approved only
mkleene Jun 9, 2026
47d455c
feat(sdk): use cipher wrap/unwrap for RSA key operations
mkleene Jun 9, 2026
ff37ca6
add an empty default key store in FIPS mode
mkleene Jun 10, 2026
335cfd4
add new module
mkleene Jun 11, 2026
25d4b2a
use a good envvar
mkleene Jun 11, 2026
debc0cf
deal with the CP correctly
mkleene Jun 11, 2026
9d75430
do this faster
mkleene Jun 11, 2026
49aae55
set this up
mkleene Jun 11, 2026
0d79a1f
include the main class
mkleene Jun 11, 2026
057d260
get the property right
mkleene Jun 11, 2026
f272301
one more segment
mkleene Jun 11, 2026
1c80757
print stuff out
mkleene Jun 11, 2026
f00598d
see if this works
mkleene Jun 11, 2026
7e08117
oops
mkleene Jun 11, 2026
6a137c4
one more
mkleene Jun 11, 2026
af427fc
one more
mkleene Jun 11, 2026
e4b4aa1
try this
mkleene Jun 11, 2026
81afe20
move this back to the right place
mkleene Jun 11, 2026
d03af4b
one more
mkleene Jun 11, 2026
2014c3d
make sure to get output it
mkleene Jun 11, 2026
2629f07
debug
mkleene Jun 11, 2026
2309106
maybe this
mkleene Jun 11, 2026
f24d41a
see about this
mkleene Jun 11, 2026
c999916
crazy
mkleene Jun 11, 2026
027ab7d
one more try
mkleene Jun 11, 2026
fad0435
one more
mkleene Jun 11, 2026
8f1fd51
more logging
mkleene Jun 11, 2026
36b7141
ok
mkleene Jun 11, 2026
6669843
more logging
mkleene Jun 11, 2026
da712ee
more logging
mkleene Jun 11, 2026
815be2a
one more
mkleene Jun 11, 2026
3511f02
one more log
mkleene Jun 11, 2026
fa5c26f
try changing the log level
mkleene Jun 12, 2026
f3c811b
more explicit logging
mkleene Jun 12, 2026
6dd35f2
get some logs
mkleene Jun 12, 2026
32d7d42
yikes
mkleene Jun 12, 2026
d24c1a9
one more
mkleene Jun 12, 2026
54752b9
just run it in FIPS mode all the time
mkleene Jun 12, 2026
b5e820f
sonarcloud
mkleene Jun 12, 2026
5b07fa8
fix mvnverify
mkleene Jun 12, 2026
887ba9d
refer to the module in a simpler way
mkleene Jun 12, 2026
d7621b7
refactor scripts some
mkleene Jun 12, 2026
2a8bd54
update permissions
mkleene Jun 12, 2026
9369d07
Update TDFReader.java
mkleene Jun 12, 2026
46d1d87
Remove static logger from TDFReader
mkleene Jun 12, 2026
baee611
Update log4j2.xml
mkleene Jun 12, 2026
9d21147
Update TDF.java
mkleene Jun 12, 2026
a8c39b4
Remove blank lines in TDF.java
mkleene Jun 12, 2026
517bd27
fix label
mkleene Jun 12, 2026
4683cc5
Merge remote-tracking branch 'origin/enhance-fips-tests' into enhance…
mkleene Jun 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions .github/scripts/verify_assertions_basic.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/usr/bin/env bash
set -euo pipefail

echo "basic assertions"
printf 'here is some data to encrypt' > data

ASSERTIONS='[{"id":"assertion1","type":"handling","scope":"tdo","appliesToState":"encrypted","statement":{"format":"json+stanag5636","schema":"urn:nato:stanag:5636:A:1:elements:json","value":"{\"ocl\":\"2024-10-21T20:47:36Z\"}"}}]'

java -jar target/cmdline.jar \
--client-id=opentdf-sdk \
--client-secret=secret \
--platform-endpoint=http://localhost:8080 \
-h \
encrypt \
--kas-url=http://localhost:8080 \
--mime-type=text/plain \
--with-assertions="$ASSERTIONS" \
--autoconfigure=false \
-f data \
-m 'here is some metadata' > test.tdf

java -jar target/cmdline.jar \
--client-id=opentdf-sdk \
--client-secret=secret \
--platform-endpoint=http://localhost:8080 \
-h \
decrypt \
-f test.tdf > decrypted

if ! diff -q data decrypted; then
printf 'decrypted data is incorrect [%s]\n' "$(< decrypted)"
exit 1
fi

36 changes: 36 additions & 0 deletions .github/scripts/verify_assertions_hs256.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/usr/bin/env bash
set -euo pipefail

echo "hs256 assertions"
printf 'here is some data to encrypt' > data

HS256_KEY=$(openssl rand -base64 32)
SIGNED_ASSERTIONS_HS256='[{"id":"assertion1","type":"handling","scope":"tdo","appliesToState":"encrypted","statement":{"format":"json+stanag5636","schema":"urn:nato:stanag:5636:A:1:elements:json","value":"{\"ocl\":\"2024-10-21T20:47:36Z\"}"},"signingKey":{"alg":"HS256","key":"'"$HS256_KEY"'"}}]'
SIGNED_ASSERTION_VERIFICATON_HS256='{"keys":{"assertion1":{"alg":"HS256","key":"'"$HS256_KEY"'"}}}'

java -jar target/cmdline.jar \
--client-id=opentdf-sdk \
--client-secret=secret \
--platform-endpoint=http://localhost:8080 \
-h \
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

java -jar target/cmdline.jar \
--client-id=opentdf-sdk \
--client-secret=secret \
--platform-endpoint=http://localhost:8080 \
-h \
decrypt \
--with-assertion-verification-keys="$SIGNED_ASSERTION_VERIFICATON_HS256" \
-f test.tdf > decrypted

if ! diff -q data decrypted; then
printf 'decrypted data is incorrect [%s]\n' "$(< decrypted)"
exit 1
fi
41 changes: 41 additions & 0 deletions .github/scripts/verify_assertions_rs256.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/usr/bin/env bash
set -euo pipefail

echo "rs256 assertions"
printf 'here is some data to encrypt' > data

openssl genpkey -algorithm RSA -out rs_private_key.pem -pkeyopt rsa_keygen_bits:2048
openssl rsa -pubout -in rs_private_key.pem -out rs_public_key.pem

RS256_PRIVATE_KEY=$(awk '{printf "%s\\n", $0}' rs_private_key.pem)
RS256_PUBLIC_KEY=$(awk '{printf "%s\\n", $0}' rs_public_key.pem)
SIGNED_ASSERTIONS_RS256='[{"id":"assertion1","type":"handling","scope":"tdo","appliesToState":"encrypted","statement":{"format":"json+stanag5636","schema":"urn:nato:stanag:5636:A:1:elements:json","value":"{\"ocl\":\"2024-10-21T20:47:36Z\"}"},"signingKey":{"alg":"RS256","key":"'"$RS256_PRIVATE_KEY"'"}}]'
SIGNED_ASSERTION_VERIFICATON_RS256='{"keys":{"assertion1":{"alg":"RS256","key":"'"$RS256_PUBLIC_KEY"'"}}}'

java -jar target/cmdline.jar \
--client-id=opentdf-sdk \
--client-secret=secret \
--platform-endpoint=http://localhost:8080 \
-h \
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

java -jar target/cmdline.jar \
--client-id=opentdf-sdk \
--client-secret=secret \
--platform-endpoint=http://localhost:8080 \
-h \
decrypt \
--with-assertion-verification-keys "$SIGNED_ASSERTION_VERIFICATON_RS256" \
-f test.tdf > decrypted

if ! diff -q data decrypted; then
printf 'decrypted data is incorrect [%s]\n' "$(< decrypted)"
exit 1
fi

44 changes: 44 additions & 0 deletions .github/scripts/verify_cmdline_roundtrip.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#!/usr/bin/env bash
set -euo pipefail

printf 'here is some data to encrypt' > data

java -jar target/cmdline.jar \
--client-id=opentdf-sdk \
--client-secret=secret \
--platform-endpoint=http://localhost:8080 \
-h \
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

java -jar target/cmdline.jar \
--client-id=opentdf-sdk \
--client-secret=secret \
--platform-endpoint=http://localhost:8080 \
-h \
decrypt \
-f test.tdf > decrypted

java -jar target/cmdline.jar \
--client-id=opentdf-sdk \
--client-secret=secret \
--platform-endpoint=http://localhost:8080 \
-h \
metadata \
-f test.tdf > metadata

if ! diff -q data decrypted; then
printf 'decrypted data is incorrect [%s]\n' "$(< decrypted)"
exit 1
fi

if [ "$(< metadata)" != 'here is some metadata' ]; then
printf 'metadata is incorrect [%s]\n' "$(< metadata)"
exit 1
fi

144 changes: 29 additions & 115 deletions .github/workflows/checks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,14 @@ jobs:
BUF_INPUT_HTTPS_PASSWORD: ${{ secrets.PERSONAL_ACCESS_TOKEN_OPENTDF }}
run: mvn clean --batch-mode clean generate-sources
- name: Tests and enforcer (fips)
run: mvn --batch-mode test enforcer:enforce -P 'fips,!non-fips' -Dmaven.antrun.skip
run: |
# install the the sdk-fips-bouncycastle jar so that FIPS mode tests work

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix typo in comment.

The comment contains a duplicated word: "install the the sdk-fips-bouncycastle jar" should be "install the sdk-fips-bouncycastle jar".

📝 Proposed fix
-          # install the the sdk-fips-bouncycastle jar so that FIPS mode tests work
+          # install the sdk-fips-bouncycastle jar so that FIPS mode tests work
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# install the the sdk-fips-bouncycastle jar so that FIPS mode tests work
# install the sdk-fips-bouncycastle jar so that FIPS mode tests work
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/checks.yaml at line 96, Fix the duplicated word in the
comment string "install the the sdk-fips-bouncycastle jar so that FIPS mode
tests work" by changing it to "install the sdk-fips-bouncycastle jar so that
FIPS mode tests work"; locate and update the comment in
.github/workflows/checks.yaml (the comment containing "install the the
sdk-fips-bouncycastle jar") so the duplicated "the" is removed.

mvn --batch-mode install -pl sdk-fips-bouncycastle -am \
-Dmaven.antrun.skip \
-Dmaven.test.skip
mvn --batch-mode test enforcer:enforce -P 'fips,!non-fips' \
-Dmaven.antrun.skip \
-Dorg.bouncycastle.fips.approved_only=true
- name: Tests with coverage and javadoc (non-fips)
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand All @@ -104,7 +111,15 @@ jobs:
-P 'coverage,non-fips,!fips'

platform-integration:
name: "Platform Integration ${{ matrix.label }}"
runs-on: ubuntu-22.04
strategy:
matrix:
include:
- label: ""
maven_profile: ""
- label: " (FIPS)"
maven_profile: "-P 'fips,!non-fips'"
steps:
- name: Checkout Java SDK
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
Expand All @@ -117,12 +132,6 @@ jobs:
java-version: "17"
distribution: "temurin"
server-id: github
- name: Build java SDK
run: |
mvn --batch-mode clean install -DskipTests
env:
BUF_INPUT_HTTPS_USERNAME: opentdf-bot
BUF_INPUT_HTTPS_PASSWORD: ${{ secrets.PERSONAL_ACCESS_TOKEN_OPENTDF }}

- name: Check out and start up platform with deps/containers
id: run-platform
Expand All @@ -137,121 +146,26 @@ jobs:
grpcurl -plaintext localhost:8080 list && \
grpcurl -plaintext localhost:8080 kas.AccessService/PublicKey

- name: Validate the SDK through the command line interface
- name: Build java SDK${{ matrix.label }}
run: |
printf 'here is some data to encrypt' > data

java -jar target/cmdline.jar \
--client-id=opentdf-sdk \
--client-secret=secret \
--platform-endpoint=http://localhost:8080 \
-h\
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

java -jar target/cmdline.jar \
--client-id=opentdf-sdk \
--client-secret=secret \
--platform-endpoint=http://localhost:8080 \
-h\
decrypt -f test.tdf > decrypted

java -jar target/cmdline.jar \
--client-id=opentdf-sdk \
--client-secret=secret \
--platform-endpoint=http://localhost:8080 \
-h\
metadata -f test.tdf > metadata

if ! diff -q data decrypted; then
printf 'decrypted data is incorrect [%s]' "$(< decrypted)"
exit 1
fi
mvn --batch-mode clean install -pl cmdline -am ${{ matrix.maven_profile }} -DskipTests
env:
BUF_INPUT_HTTPS_USERNAME: opentdf-bot
BUF_INPUT_HTTPS_PASSWORD: ${{ secrets.PERSONAL_ACCESS_TOKEN_OPENTDF }}

if [ "$(< metadata)" != 'here is some metadata' ]; then
printf 'metadata is incorrect [%s]\n' "$(< metadata)"
exit 1
fi
- name: Validate the SDK through the command line interface${{ matrix.label }}
run: |
../.github/scripts/verify_cmdline_roundtrip.sh
working-directory: cmdline

- name: Encrypt/Decrypt Assertions
- name: Encrypt/Decrypt Assertions${{ matrix.label }}
run: |
echo "basic assertions"
echo 'here is some data to encrypt' > data

ASSERTIONS='[{"id":"assertion1","type":"handling","scope":"tdo","appliesToState":"encrypted","statement":{"format":"json+stanag5636","schema":"urn:nato:stanag:5636:A:1:elements:json","value":"{\"ocl\":\"2024-10-21T20:47:36Z\"}"}}]'

java -jar target/cmdline.jar \
--client-id=opentdf-sdk \
--client-secret=secret \
--platform-endpoint=http://localhost:8080 \
-h\
encrypt --kas-url=http://localhost:8080 --mime-type=text/plain --with-assertions=$ASSERTIONS --autoconfigure=false -f data -m 'here is some metadata' > test.tdf

java -jar target/cmdline.jar \
--client-id=opentdf-sdk \
--client-secret=secret \
--platform-endpoint=http://localhost:8080 \
-h\
decrypt -f test.tdf > decrypted

if ! diff -q data decrypted; then
printf 'decrypted data is incorrect [%s]' "$(< decrypted)"
exit 1
fi

HS256_KEY=$(openssl rand -base64 32)
openssl genpkey -algorithm RSA -out rs_private_key.pem -pkeyopt rsa_keygen_bits:2048
openssl rsa -pubout -in rs_private_key.pem -out rs_public_key.pem
RS256_PRIVATE_KEY=$(awk '{printf "%s\\n", $0}' rs_private_key.pem)
RS256_PUBLIC_KEY=$(awk '{printf "%s\\n", $0}' rs_public_key.pem)
SIGNED_ASSERTIONS_HS256='[{"id":"assertion1","type":"handling","scope":"tdo","appliesToState":"encrypted","statement":{"format":"json+stanag5636","schema":"urn:nato:stanag:5636:A:1:elements:json","value":"{\"ocl\":\"2024-10-21T20:47:36Z\"}"},"signingKey":{"alg":"HS256","key":"'$HS256_KEY'"}}]'
SIGNED_ASSERTION_VERIFICATON_HS256='{"keys":{"assertion1":{"alg":"HS256","key":"'$HS256_KEY'"}}}'
SIGNED_ASSERTIONS_RS256='[{"id":"assertion1","type":"handling","scope":"tdo","appliesToState":"encrypted","statement":{"format":"json+stanag5636","schema":"urn:nato:stanag:5636:A:1:elements:json","value":"{\"ocl\":\"2024-10-21T20:47:36Z\"}"},"signingKey":{"alg":"RS256","key":"'$RS256_PRIVATE_KEY'"}}]'
SIGNED_ASSERTION_VERIFICATON_RS256='{"keys":{"assertion1":{"alg":"RS256","key":"'$RS256_PUBLIC_KEY'"}}}'

echo "hs256 assertions"

java -jar target/cmdline.jar \
--client-id=opentdf-sdk \
--client-secret=secret \
--platform-endpoint=http://localhost:8080 \
-h\
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

java -jar target/cmdline.jar \
--client-id=opentdf-sdk \
--client-secret=secret \
--platform-endpoint=http://localhost:8080 \
-h\
decrypt --with-assertion-verification-keys="$SIGNED_ASSERTION_VERIFICATON_HS256" -f test.tdf > decrypted

if ! diff -q data decrypted; then
printf 'decrypted data is incorrect [%s]' "$(< decrypted)"
exit 1
fi

echo "rs256 assertions"

java -jar target/cmdline.jar \
--client-id=opentdf-sdk \
--client-secret=secret \
--platform-endpoint=http://localhost:8080 \
-h\
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

java -jar target/cmdline.jar \
--client-id=opentdf-sdk \
--client-secret=secret \
--platform-endpoint=http://localhost:8080 \
-h\
decrypt --with-assertion-verification-keys "$SIGNED_ASSERTION_VERIFICATON_RS256" -f test.tdf > decrypted

if ! diff -q data decrypted; then
printf 'decrypted data is incorrect [%s]' "$(< decrypted)"
exit 1
fi
../.github/scripts/verify_assertions_basic.sh
../.github/scripts/verify_assertions_hs256.sh
../.github/scripts/verify_assertions_rs256.sh
working-directory: cmdline


platform-xtest:
permissions:
contents: read
Expand Down
15 changes: 15 additions & 0 deletions cmdline/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,19 @@
<version>${project.version}</version>
</dependency>
</dependencies>
<profiles>
<profile>
<id>fips</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<dependencies>
<dependency>
<groupId>io.opentdf.platform</groupId>
<artifactId>sdk-fips-bouncycastle</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</profile>
</profiles>
</project>
7 changes: 4 additions & 3 deletions cmdline/src/main/java/io/opentdf/platform/Command.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;

import java.security.cert.X509Certificate;
import java.text.ParseException;
import com.google.gson.JsonSyntaxException;
import io.opentdf.platform.sdk.AssertionConfig;
Expand All @@ -19,11 +18,12 @@
import io.opentdf.platform.sdk.KeyType;
import io.opentdf.platform.sdk.SDK;
import io.opentdf.platform.sdk.SDKBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import picocli.CommandLine;
import picocli.CommandLine.HelpCommand;
import picocli.CommandLine.Option;

import javax.net.ssl.X509TrustManager;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
Expand Down Expand Up @@ -63,7 +63,7 @@ class Versions {
@CommandLine.Command(name = "tdf", subcommands = { HelpCommand.class }, version = "{\"version\":\"" + Versions.SDK
+ "\",\"tdfSpecVersion\":\"" + Versions.TDF_SPEC + "\"}")
class Command {

private static final Logger LOG = LoggerFactory.getLogger(Command.class);
@Option(names = { "-V", "--version" }, versionHelp = true, description = "display version info")
boolean versionInfoRequested;

Expand Down Expand Up @@ -207,6 +207,7 @@ void encrypt(
return ki;
}).toArray(Config.KASInfo[]::new);


List<Consumer<Config.TDFConfig>> configs = new ArrayList<>();
configs.add(Config.withKasInformation(kasInfos));
metadata.map(Config::withMetaData).ifPresent(configs::add);
Expand Down
Loading
Loading