Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 3 additions & 5 deletions cmdline/src/main/java/io/opentdf/platform/Command.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import io.opentdf.platform.sdk.KeyType;
import io.opentdf.platform.sdk.SDK;
import io.opentdf.platform.sdk.SDKBuilder;
import nl.altindag.ssl.SSLFactory;
import io.opentdf.platform.sdk.TrustProvider;
import picocli.CommandLine;
import picocli.CommandLine.HelpCommand;
import picocli.CommandLine.Option;
Expand Down Expand Up @@ -262,10 +262,8 @@ void encrypt(
private SDK buildSDK() {
SDKBuilder builder = new SDKBuilder();
if (insecure) {
SSLFactory sslFactory = SSLFactory.builder()
.withUnsafeTrustMaterial() // Trust all certificates
.build();
builder.sslFactory(sslFactory);
// Trust all certificates
builder.sslFactory(TrustProvider.insecure().getSslSocketFactory());
}

return builder.platformEndpoint(platformEndpoint)
Expand Down
57 changes: 23 additions & 34 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
<grpc.version>1.75.0</grpc.version>
<protobuf.version>4.29.2</protobuf.version>
<bouncycastle.version>1.82</bouncycastle.version>
<ayza.version>10.0.0</ayza.version>
<bc-fips.version>2.1.2</bc-fips.version>
<bcpkix-fips.version>2.1.11</bcpkix-fips.version>
<bctls-fips.version>2.1.23</bctls-fips.version>
<bytebuddy.version>1.18.3</bytebuddy.version>
<!-- JaCoCo Properties -->
<jacoco.version>0.8.13</jacoco.version>
Expand Down Expand Up @@ -78,39 +80,6 @@
<version>3.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.github.hakky54</groupId>
<artifactId>ayza-for-pem</artifactId>
<version>${ayza.version}</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.github.hakky54</groupId>
<artifactId>ayza</artifactId>
<version>${ayza.version}</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.github.hakky54</groupId>
<artifactId>ayza-for-netty</artifactId>
<version>${ayza.version}</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
Expand Down Expand Up @@ -157,6 +126,26 @@
<artifactId>bcprov-jdk18on</artifactId>
<version>${bouncycastle.version}</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bctls-jdk18on</artifactId>
<version>${bouncycastle.version}</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bc-fips</artifactId>
<version>${bc-fips.version}</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-fips</artifactId>
<version>${bcpkix-fips.version}</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bctls-fips</artifactId>
<version>${bctls-fips.version}</version>
</dependency>
<!--
Pin Byte Buddy for test-time Mockito instrumentation on newer JVMs (e.g. Java 21).
This does NOT add a runtime dependency; it only manages the version used by modules.
Expand Down
85 changes: 62 additions & 23 deletions sdk/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
<connect.version>0.7.2</connect.version>
<okhttp.version>4.12.0</okhttp.version>
<platform.branch>protocol/go/v0.16.0</platform.branch>
<!-- test.java.security.file is set by the `non-fips` (default) or `fips` profile -->
</properties>
<dependencies>
<!-- Logging Dependencies -->
Expand All @@ -31,18 +32,6 @@
<artifactId>oauth2-oidc-sdk</artifactId>
<version>11.10.1</version>
</dependency>
<dependency>
<groupId>io.github.hakky54</groupId>
<artifactId>ayza-for-pem</artifactId>
</dependency>
<dependency>
<groupId>io.github.hakky54</groupId>
<artifactId>ayza</artifactId>
</dependency>
<dependency>
<groupId>io.github.hakky54</groupId>
<artifactId>ayza-for-netty</artifactId>
</dependency>
<!-- Serialization and Deserialization Dependencies -->
<dependency>
<groupId>com.google.code.gson</groupId>
Expand Down Expand Up @@ -160,15 +149,7 @@
<version>6.0.53</version>
<scope>provided</scope>
</dependency>
<!-- Crypto Dependencies -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk18on</artifactId>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk18on</artifactId>
</dependency>
<!-- Crypto Dependencies are pulled in via the `non-fips` (default) or `fips` profile -->
<!-- Testing Dependencies -->
<dependency>
<groupId>org.junit.jupiter</groupId>
Expand Down Expand Up @@ -483,11 +464,69 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>-Djava.security.properties=${test.java.security.file}</argLine>
</configuration>
Comment on lines +467 to +472
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

# First, examine the specific lines in sdk/pom.xml
head -n 480 sdk/pom.xml | tail -n 30

Repository: opentdf/java-sdk

Length of output: 1159


🏁 Script executed:

# Check for JaCoCo configuration in root pom.xml
grep -n "jacoco\|prepare-agent" pom.xml -A 5 -B 2

Repository: opentdf/java-sdk

Length of output: 2443


🏁 Script executed:

# Search for all argLine definitions in pom.xml files
rg "argLine" -n pom.xml sdk/pom.xml cmdline/pom.xml examples/pom.xml 2>/dev/null || rg "argLine" -n

Repository: opentdf/java-sdk

Length of output: 169


Preserve the existing Surefire argLine instead of replacing it.

The hardcoded argLine at line 471 overwrites the argLine property injected by JaCoCo's prepare-agent execution, preventing coverage data collection when the test profile is active.

Suggested fix
 <plugin>
     <groupId>org.apache.maven.plugins</groupId>
     <artifactId>maven-surefire-plugin</artifactId>
     <configuration>
-        <argLine>-Djava.security.properties=${test.java.security.file}</argLine>
+        <argLine>@{argLine} -Djava.security.properties=${test.java.security.file}</argLine>
     </configuration>
 </plugin>
📝 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
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>-Djava.security.properties=${test.java.security.file}</argLine>
</configuration>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>@{argLine} -Djava.security.properties=${test.java.security.file}</argLine>
</configuration>
🤖 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 `@sdk/pom.xml` around lines 467 - 472, The maven-surefire-plugin configuration
is overwriting the JaCoCo-injected argLine, preventing coverage; update the
surefire <argLine> in the plugin to preserve and append to the existing value
(i.e., include the existing ${argLine} placeholder and then add the
-Djava.security.properties=${test.java.security.file} piece) so JaCoCo's
prepare-agent can inject its agent args while still setting the security
properties.

</plugin>
</plugins>
</build>
<!--profile
to execute fuzz test -->
<profiles>
<profile>
<id>non-fips</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<test.java.security.file>${project.basedir}/src/test/java.security.test</test.java.security.file>
</properties>
<dependencies>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk18on</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk18on</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bctls-jdk18on</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
</profile>
<profile>
<id>fips</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<properties>
<test.java.security.file>${project.basedir}/src/test/java.security.fips.test</test.java.security.file>
</properties>
<dependencies>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bc-fips</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-fips</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bctls-fips</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
</profile>
<!-- profile to execute fuzz test -->
<profile>
<id>fuzz</id>
<activation>
Expand Down
18 changes: 18 additions & 0 deletions sdk/src/main/java/io/opentdf/platform/sdk/AesGcm.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
Expand All @@ -20,10 +21,27 @@
public class AesGcm {
public static final int GCM_NONCE_LENGTH = 12; // in bytes
public static final int GCM_TAG_LENGTH = 16; // in bytes
public static final int GCM_KEY_SIZE_BITS = 256;
private static final String KEY_ALGORITHM = "AES";
private static final String CIPHER_TRANSFORM = "AES/GCM/NoPadding";

private final SecretKey key;

/**
* <p>Generate a fresh 256-bit AES key using the JCA {@link KeyGenerator}.</p>
*
* @return the encoded key bytes
*/
public static byte[] generateKey() {
try {
KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_ALGORITHM);
keyGenerator.init(GCM_KEY_SIZE_BITS);
return keyGenerator.generateKey().getEncoded();
} catch (NoSuchAlgorithmException e) {
throw new SDKException("error generating AES key", e);
}
}


/**
* <p>Return symmetric key</p>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package io.opentdf.platform.sdk;

import javax.net.ssl.SSLEngine;
import javax.net.ssl.X509ExtendedTrustManager;
import java.net.Socket;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

final class CompositeX509ExtendedTrustManager extends X509ExtendedTrustManager {

private final List<X509ExtendedTrustManager> delegates;
private final X509Certificate[] acceptedIssuers;

CompositeX509ExtendedTrustManager(List<X509ExtendedTrustManager> delegates) {
if (delegates == null || delegates.isEmpty()) {
throw new IllegalArgumentException("at least one trust manager is required");
}
this.delegates = Collections.unmodifiableList(new ArrayList<>(delegates));
Set<X509Certificate> issuers = new LinkedHashSet<>();
for (X509ExtendedTrustManager tm : this.delegates) {
X509Certificate[] tmIssuers = tm.getAcceptedIssuers();
if (tmIssuers != null) {
Collections.addAll(issuers, tmIssuers);
}
}
this.acceptedIssuers = issuers.toArray(new X509Certificate[0]);
}

@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
CertificateException last = null;
for (X509ExtendedTrustManager tm : delegates) {
try {
tm.checkClientTrusted(chain, authType);
return;
} catch (CertificateException e) {
last = e;
}
}
throw last;
}

@Override
public void checkClientTrusted(X509Certificate[] chain, String authType, Socket socket) throws CertificateException {
CertificateException last = null;
for (X509ExtendedTrustManager tm : delegates) {
try {
tm.checkClientTrusted(chain, authType, socket);
return;
} catch (CertificateException e) {
last = e;
}
}
throw last;
}

@Override
public void checkClientTrusted(X509Certificate[] chain, String authType, SSLEngine engine) throws CertificateException {
CertificateException last = null;
for (X509ExtendedTrustManager tm : delegates) {
try {
tm.checkClientTrusted(chain, authType, engine);
return;
} catch (CertificateException e) {
last = e;
}
}
throw last;
}

@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
CertificateException last = null;
for (X509ExtendedTrustManager tm : delegates) {
try {
tm.checkServerTrusted(chain, authType);
return;
} catch (CertificateException e) {
last = e;
}
}
throw last;
}

@Override
public void checkServerTrusted(X509Certificate[] chain, String authType, Socket socket) throws CertificateException {
CertificateException last = null;
for (X509ExtendedTrustManager tm : delegates) {
try {
tm.checkServerTrusted(chain, authType, socket);
return;
} catch (CertificateException e) {
last = e;
}
}
throw last;
}

@Override
public void checkServerTrusted(X509Certificate[] chain, String authType, SSLEngine engine) throws CertificateException {
CertificateException last = null;
for (X509ExtendedTrustManager tm : delegates) {
try {
tm.checkServerTrusted(chain, authType, engine);
return;
} catch (CertificateException e) {
last = e;
}
}
throw last;
}

@Override
public X509Certificate[] getAcceptedIssuers() {
return acceptedIssuers.clone();
}
}
Loading
Loading