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
22 changes: 22 additions & 0 deletions sdk/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,22 @@
<okhttp.version>4.12.0</okhttp.version>
<platform.branch>protocol/go/v0.16.0</platform.branch>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-commons</artifactId>
<version>1.11.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-engine</artifactId>
<version>1.11.0</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- Logging Dependencies -->
<dependency>
Expand Down Expand Up @@ -289,6 +305,12 @@
<version>${kotlin.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.tngtech.archunit</groupId>
<artifactId>archunit-junit5</artifactId>
<version>1.3.0</version>
<scope>test</scope>
</dependency>
</dependencies>
Comment on lines +309 to 314
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.

medium

The addition of ArchUnit is a great step for maintaining architectural integrity. Given the extensive visibility changes in this PR, you should consider adding ArchUnit rules to verify that internal implementation details (like package-private classes) do not leak through public API signatures or fields, which would help catch issues like the ones identified in Manifest.java.

<build>
<resources>
Expand Down
4 changes: 2 additions & 2 deletions sdk/src/main/java/io/opentdf/platform/sdk/AesGcm.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* It includes methods to encrypt and decrypt byte arrays using a specified
* symmetric key.
*/
public class AesGcm {
class AesGcm {
public static final int GCM_NONCE_LENGTH = 12; // in bytes
public static final int GCM_TAG_LENGTH = 16; // in bytes
private static final String CIPHER_TRANSFORM = "AES/GCM/NoPadding";
Expand All @@ -34,7 +34,7 @@ public byte[] getKey() {
return key.getEncoded();
}

public static class Encrypted {
static class Encrypted {
private final byte[] iv;
private final byte[] ciphertext;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public String toString() {
}
}

public enum BindingMethod {
enum BindingMethod {
JWS("jws");

private String method;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
/**
* Class providing functionality for asymmetric decryption using an RSA private key.
*/
public class AsymDecryption {
class AsymDecryption {
private final PrivateKey privateKey;
private static final String PRIVATE_KEY_HEADER = "-----BEGIN PRIVATE KEY-----";
private static final String PRIVATE_KEY_FOOTER = "-----END PRIVATE KEY-----";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
* AsymEncryption class provides methods for asymmetric encryption and
* handling public keys in PEM format.
*/
public class AsymEncryption {
class AsymEncryption {
private final PublicKey publicKey;
private static final String PUBLIC_KEY_HEADER = "-----BEGIN PUBLIC KEY-----";
private static final String PUBLIC_KEY_FOOTER = "-----END PUBLIC KEY-----";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class RuleType {
* This class includes functionality to create granter instances based on
* attributes either from a list of attribute values or from a service.
*/
public class Autoconfigure {
class Autoconfigure {

private static Logger logger = LoggerFactory.getLogger(Autoconfigure.class);

Expand Down Expand Up @@ -98,7 +98,7 @@ public KeySplitTemplate(String kas, String splitID, String kid, KeyType keyType)
}
}

public static class KeySplitStep {
static class KeySplitStep {
final String kas;
final String splitID;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
/**
* Utility class for cryptographic operations such as generating RSA key pairs and calculating HMAC.
*/
public class CryptoUtils {
class CryptoUtils {
private static final int KEYPAIR_SIZE = 2048;

public static byte[] CalculateSHA256Hmac(byte[] key, byte[] data) {
Expand Down
2 changes: 1 addition & 1 deletion sdk/src/main/java/io/opentdf/platform/sdk/ECCurve.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
/**
* Elliptic curve definitions for EC key operations.
*/
public enum ECCurve {
enum ECCurve {
SECP256R1("secp256r1", 32, 33, 0x00),
SECP384R1("secp384r1", 48, 49, 0x01),
SECP521R1("secp521r1", 66, 67, 0x02),
Expand Down
4 changes: 2 additions & 2 deletions sdk/src/main/java/io/opentdf/platform/sdk/ECKeyPair.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
import java.util.Objects;
// https://www.bouncycastle.org/latest_releases.html

public class ECKeyPair {
class ECKeyPair {

private static final int SHA256_BYTES = 32;

Expand All @@ -37,7 +37,7 @@ public class ECKeyPair {

private final ECCurve curve;

public enum ECAlgorithm {
enum ECAlgorithm {
ECDH,
ECDSA
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
* EntityIdentifiers.forEmail("jen@example.com");
* }</pre>
*/
public final class EntityIdentifiers {
final class EntityIdentifiers {

private EntityIdentifiers() {}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* is invalid or corrupted in some way. This exception extends RuntimeException,
* allowing it to be thrown during the normal operation of the Java Virtual Machine.
*/
public class InvalidZipException extends RuntimeException {
public class InvalidZipException extends SDKException {
public InvalidZipException(String message) {
super(message);
}
Expand Down
12 changes: 6 additions & 6 deletions sdk/src/main/java/io/opentdf/platform/sdk/Manifest.java
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public JsonElement serialize(Object src, Type typeOfSrc, JsonSerializationContex
}
}

static public class Segment {
static class Segment {
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.

high

The Segment class is used in the segments field of IntegrityInformation (line 148). Since IntegrityInformation is a public static inner class and segments is a public field, making Segment package-private will cause accessibility issues or compilation errors for external consumers of the SDK.

Suggested change
static class Segment {
static public class Segment {

public String hash;
public long segmentSize;
public long encryptedSegmentSize;
Expand Down Expand Up @@ -167,7 +167,7 @@ public int hashCode() {
}
}

static public class PolicyBinding {
static class PolicyBinding {
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.

medium

For consistency with other components of the Manifest structure that are intended to be accessible, PolicyBinding should remain public. While it is currently exposed via an Object field in KeyAccess, consumers may need to cast it to access its properties.

Suggested change
static class PolicyBinding {
static public class PolicyBinding {

public String alg;
public String hash;

Expand Down Expand Up @@ -298,7 +298,7 @@ public int hashCode() {
}
}

static public class Binding {
static class Binding {
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.

high

The Binding class is used in the binding field of the Assertion class. If Assertion is restored to public visibility to resolve the API leak, Binding must also be public.

Suggested change
static class Binding {
static public class Binding {

public String method;
public String signature;

Expand All @@ -318,14 +318,14 @@ public int hashCode() {
}
}

static public class Assertion {
static class Assertion {
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.

high

The Assertion class is used in the assertions field of the public Manifest class (line 560). In Java, a public field cannot expose a package-private type. This change will cause a compilation error and prevents external users from interacting with the assertions in a manifest.

Suggested change
static class Assertion {
static public class Assertion {

public String id;
public String type;
public String scope;
public String appliesToState;
public AssertionConfig.Statement statement;
public Binding binding;
static public class HashValues {
static class HashValues {
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.

high

The HashValues class is used as a return type for the verify method (line 406) and as a parameter for the sign method (line 379). Since these methods are public members of the Assertion class, HashValues must also be public to avoid compilation errors and ensure API usability.

Suggested change
static class HashValues {
static public class HashValues {

private final String assertionHash;
private final String signature;

Expand Down Expand Up @@ -528,7 +528,7 @@ private JWSVerifier createVerifier(RSAPublicKey publicKey) {
}
}

public static class AssertionValueAdapter implements JsonDeserializer<AssertionConfig.Statement> {
static class AssertionValueAdapter implements JsonDeserializer<AssertionConfig.Statement> {
@Override
public AssertionConfig.Statement deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
if (!json.isJsonObject()) {
Expand Down
2 changes: 1 addition & 1 deletion sdk/src/main/java/io/opentdf/platform/sdk/Planner.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import java.util.stream.Collectors;


public class Planner {
class Planner {
private static final String BASE_KEY = "base_key";
private final Config.TDFConfig tdfConfig;
private final SDK.Services services;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
* .setOperator(OPERATOR_IN);
* }</pre>
*/
public final class PolicyEnums {
final class PolicyEnums {

private PolicyEnums() {}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* The PolicyObject class represents a policy with a unique identifier and a body containing data attributes.
*/
public class PolicyObject {
static public class AttributeObject {
static class AttributeObject {
public String attribute;
public String displayName;
public boolean isDefault;
Expand Down
2 changes: 1 addition & 1 deletion sdk/src/main/java/io/opentdf/platform/sdk/Resources.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
* Resources.forAttributeValues("https://example.com/attr/department/value/finance");
* }</pre>
*/
public final class Resources {
final class Resources {

private Resources() {}

Expand Down
2 changes: 1 addition & 1 deletion sdk/src/main/java/io/opentdf/platform/sdk/TDFReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* The class initializes with a TDF file channel, extracts the manifest and payload entries,
* and provides methods to retrieve the manifest content, read payload bytes, and read policy objects.
*/
public class TDFReader {
class TDFReader {

private final ZipReader.Entry manifestEntry;
private final InputStream payload;
Expand Down
2 changes: 1 addition & 1 deletion sdk/src/main/java/io/opentdf/platform/sdk/TDFWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* The TDFWriter class provides functionalities for creating a TDF (Trusted Data Format) archive.
* This includes appending a manifest file and appending payload data to the archive.
*/
public class TDFWriter {
class TDFWriter {
public static final String TDF_PAYLOAD_FILE_NAME = "0.payload";
public static final String TDF_MANIFEST_FILE_NAME = "0.manifest.json";
private final ZipWriter archiveWriter;
Expand Down
4 changes: 2 additions & 2 deletions sdk/src/main/java/io/opentdf/platform/sdk/ZipReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
* Local File Header. This class supports standard ZIP archives as well
* as ZIP64 format.
*/
public class ZipReader {
class ZipReader {

public static final Logger logger = LoggerFactory.getLogger(ZipReader.class);
public static final int END_OF_CENTRAL_DIRECTORY_SIZE = 22;
Expand Down Expand Up @@ -148,7 +148,7 @@ private CentralDirectoryRecord extractZIP64CentralDirectoryInfo() throws IOExcep
return new CentralDirectoryRecord(totalNumCDEntries, cdOffset);
}

public class Entry {
class Entry {
private final long fileSize;
private final String fileName;
final long offsetToLocalHeader;
Expand Down
2 changes: 1 addition & 1 deletion sdk/src/main/java/io/opentdf/platform/sdk/ZipWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* The ZipWriter class provides functionalities to create ZIP archive files.
* It writes files and data to an underlying output stream in the ZIP file format.
*/
public class ZipWriter {
class ZipWriter {

private static final int ZIP_VERSION = 0x2D;
private static final int ZIP_64_MAGIC_VAL = 0xFFFFFFFF;
Expand Down
2 changes: 1 addition & 1 deletion sdk/src/test/java/io/opentdf/platform/sdk/Fuzzing.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public void fuzzTDF(FuzzedDataProvider data) {
Reader reader = tdf.loadTDF(new SeekableInMemoryByteChannel(fuzzBytes), readerConfig);

reader.readPayload(IGNORE_OUTPUT_STREAM);
} catch (SDKException | InvalidZipException | JsonParseException | IOException | IllegalArgumentException e) {
} catch (SDKException | JsonParseException | IOException | IllegalArgumentException e) {
// expected failure cases
}
}
Expand Down
Loading