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
74 changes: 37 additions & 37 deletions .github/docker-compose.platform.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -129,15 +129,15 @@ services:
KC_HTTPS_CLIENT_AUTH: "request"
###
# The following environment variable resolves SIGILL with Code 134 when running Java processes on Apple M4 chips
#
#
# On Apple Silicon (M4 chip):
# export JAVA_OPTS_APPEND="-XX:UseSVE=0"
# docker-compose up
#
#
# On other architectures:
# export JAVA_OPTS_APPEND=""
# docker-compose up
#
#
# Or set directly: JAVA_OPTS_APPEND="-XX:UseSVE=0" docker-compose up
JAVA_OPTS_APPEND: "${JAVA_OPTS_APPEND:-}"
###
Expand All @@ -149,21 +149,21 @@ services:
test:
- CMD-SHELL
- |
[ -f /tmp/HealthCheck.java ] || echo "public class HealthCheck {
public static void main(String[] args) throws java.lang.Throwable {
javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> true);
javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext.getInstance(\"SSL\");
sc.init(null, new javax.net.ssl.TrustManager[]{
new javax.net.ssl.X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; }
public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {}
public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {}
}
}, new java.security.SecureRandom());
javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
java.net.HttpURLConnection conn = (java.net.HttpURLConnection)new java.net.URL(args[0]).openConnection();
System.exit(java.net.HttpURLConnection.HTTP_OK == conn.getResponseCode() ? 0 : 1);
}
[ -f /tmp/HealthCheck.java ] || echo "public class HealthCheck {
public static void main(String[] args) throws java.lang.Throwable {
javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> true);
javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext.getInstance(\"SSL\");
sc.init(null, new javax.net.ssl.TrustManager[]{
new javax.net.ssl.X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; }
public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {}
public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {}
}
}, new java.security.SecureRandom());
javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
java.net.HttpURLConnection conn = (java.net.HttpURLConnection)new java.net.URL(args[0]).openConnection();
System.exit(java.net.HttpURLConnection.HTTP_OK == conn.getResponseCode() ? 0 : 1);
}
}" > /tmp/HealthCheck.java && java ${JAVA_OPTS_APPEND} /tmp/HealthCheck.java http://localhost:8888/auth 2>/dev/null
interval: 10s
timeout: 10s
Expand Down Expand Up @@ -238,7 +238,7 @@ services:
ln -sf /configs/service/internal/fixtures ./service
restart: "no"

# Add sample attributes and metadata
# Add sample attributes and metadata
platform-provision-fixtures:
image: registry.opentdf.io/platform:${PLATFORM_VERSION}
command: ["provision", "fixtures", "--config-file", "/configs/opentdf.yaml"]
Expand Down Expand Up @@ -390,13 +390,13 @@ services:
URL='https://raw.githubusercontent.com/opentdf/platform/main/service/cmd/keycloak_data.yaml'
OUTPUT='/configs/keycloak_data.yaml'
MAX_ATTEMPTS=3

for i in $$(seq 1 $$MAX_ATTEMPTS); do
echo "Attempt $$i of $$MAX_ATTEMPTS: Downloading keycloak_data.yaml..."

if wget -O "$$OUTPUT" "$$URL"; then
echo "Download successful"

# Validate the downloaded file
if [ -f "$$OUTPUT" ] && [ -s "$$OUTPUT" ]; then
if head -1 "$$OUTPUT" | grep -q -E '^(---|\w+:)'; then
Expand All @@ -412,13 +412,13 @@ services:
else
echo "Download failed (attempt $$i)"
fi

if [ $$i -lt $$MAX_ATTEMPTS ]; then
echo "Retrying in 2 seconds..."
sleep 2
fi
done

echo "ERROR: Failed to download and validate keycloak_data.yaml after $$MAX_ATTEMPTS attempts"
exit 1
restart: "no"
Expand Down Expand Up @@ -449,13 +449,13 @@ services:
URL='https://raw.githubusercontent.com/opentdf/platform/main/.github/scripts/init-temp-keys.sh'
OUTPUT='/configs/init-temp-keys.sh'
MAX_ATTEMPTS=3

for i in $$(seq 1 $$MAX_ATTEMPTS); do
echo "Attempt $$i of $$MAX_ATTEMPTS: Downloading init-temp-keys.sh..."

if wget -O "$$OUTPUT" "$$URL"; then
echo "Download successful"

# Validate the downloaded file
if [ -f "$$OUTPUT" ] && [ -s "$$OUTPUT" ]; then
if head -1 "$$OUTPUT" | grep -q '^#!/'; then
Expand All @@ -471,13 +471,13 @@ services:
else
echo "Download failed (attempt $$i)"
fi

if [ $$i -lt $$MAX_ATTEMPTS ]; then
echo "Retrying in 2 seconds..."
sleep 2
fi
done

echo "ERROR: Failed to download and validate init-temp-keys.sh after $$MAX_ATTEMPTS attempts"
exit 1
restart: "no"
Expand All @@ -499,31 +499,31 @@ services:
- |
apk add --no-cache openssl openjdk11-jre bash
cd /keys

# Generate KAS RSA private key
openssl genpkey -algorithm RSA -out /keys/kas-private.pem -pkeyopt rsa_keygen_bits:2048
openssl rsa -in /keys/kas-private.pem -pubout -out /keys/kas-cert.pem

# Generate ECC Key
openssl ecparam -name prime256v1 > /tmp/ecparams.tmp
openssl req -x509 -nodes -newkey ec:/tmp/ecparams.tmp -subj "/CN=kas" -keyout /keys/kas-ec-private.pem -out /keys/kas-ec-cert.pem -days 365

# Generate CA
openssl req -x509 -nodes -newkey RSA:2048 -subj "/CN=ca" -keyout /keys/keycloak-ca-private.pem -out /keys/keycloak-ca.pem -days 365

# Generate localhost certificate
printf "subjectAltName=DNS:localhost,IP:127.0.0.1" > /tmp/sanX509.conf
printf "[req]\ndistinguished_name=req_distinguished_name\n[req_distinguished_name]\n[alt_names]\nDNS.1=localhost\nIP.1=127.0.0.1" > /tmp/req.conf
openssl req -new -nodes -newkey rsa:2048 -keyout /keys/localhost.key -out /tmp/localhost.req -batch -subj "/CN=localhost" -config /tmp/req.conf
openssl x509 -req -in /tmp/localhost.req -CA /keys/keycloak-ca.pem -CAkey /keys/keycloak-ca-private.pem -CAcreateserial -out /keys/localhost.crt -days 3650 -sha256 -extfile /tmp/sanX509.conf

# Generate sample user certificate
openssl req -new -nodes -newkey rsa:2048 -keyout /keys/sampleuser.key -out /tmp/sampleuser.req -batch -subj "/CN=sampleuser"
openssl x509 -req -in /tmp/sampleuser.req -CA /keys/keycloak-ca.pem -CAkey /keys/keycloak-ca-private.pem -CAcreateserial -out /keys/sampleuser.crt -days 3650

# Convert to PKCS12
openssl pkcs12 -export -in /keys/keycloak-ca.pem -inkey /keys/keycloak-ca-private.pem -out /keys/ca.p12 -nodes -passout pass:password

# Convert PKCS12 to JKS using keytool (no Docker needed)
keytool -importkeystore \
-srckeystore /keys/ca.p12 \
Expand All @@ -533,7 +533,7 @@ services:
-srcstorepass "password" \
-deststorepass "password" \
-noprompt

echo "Keys generated successfully"
environment:
JAVA_OPTS_APPEND: "${JAVA_OPTS_APPEND:-}"
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ repos:

- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.15.20
rev: v0.15.21
hooks:
# Run the linter.
- id: ruff-check
Expand Down
2 changes: 1 addition & 1 deletion conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def project_root(request) -> Path:


@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item, call):
def pytest_runtest_makereport(item):
"""Collect server logs when test fails after each test phase.

This hook automatically collects server logs when a test fails.
Expand Down
10 changes: 5 additions & 5 deletions packages/otdf-python-proto/tests/test_generate_connect_proto.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ def _run_with_tag(self, tmp_path: Path, tag: str):

captured: list[list] = []

def fake_run(cmd, **kwargs):
def fake_run(cmd, **_kwargs):
captured.append(cmd)
if cmd[0] == "git":
# Simulate a successful clone by creating the service dir with one proto.
Expand Down Expand Up @@ -155,7 +155,7 @@ def test_default_tag_is_used_when_no_tag_is_provided(self, tmp_path):

captured: list[list] = []

def fake_run(cmd, **kwargs):
def fake_run(cmd, **_kwargs):
captured.append(cmd)
if cmd[0] == "git":
temp_repo = tmp_path / "temp_platform_repo"
Expand Down Expand Up @@ -248,7 +248,7 @@ def test_function_returns_false_on_subprocess_error(self, tmp_path):
assert result is False

def test_function_returns_false_when_no_protos_copied(self, tmp_path):
def fake_run(cmd, **kwargs):
def fake_run(cmd, **_kwargs):
if cmd[0] == "git":
# Clone succeeds but leaves an empty service dir (no .proto files)
service_dir = tmp_path / "temp_platform_repo" / "service"
Expand All @@ -265,7 +265,7 @@ def test_temp_dir_cleaned_up_on_success(self, tmp_path):
"""finally block must clean up temp_platform_repo regardless of outcome."""
temp_repo = tmp_path / "temp_platform_repo"

def fake_run(cmd, **kwargs):
def fake_run(cmd, **_kwargs):
if cmd[0] == "git":
service_dir = temp_repo / "service" / "kas"
service_dir.mkdir(parents=True)
Expand All @@ -280,7 +280,7 @@ def fake_run(cmd, **kwargs):
def test_temp_dir_cleaned_up_on_failure(self, tmp_path):
temp_repo = tmp_path / "temp_platform_repo"

def fake_run(cmd, **kwargs):
def fake_run(cmd, **_kwargs):
if cmd[0] == "git":
temp_repo.mkdir(exist_ok=True)
raise gen.subprocess.CalledProcessError(1, "git")
Expand Down
2 changes: 1 addition & 1 deletion packages/otdf-python/hatch_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
class CustomBuildHook(BuildHookInterface):
"""Dynamically resolves proto sources for wheel builds from source tree or sdist."""

def initialize(self, version, build_data):
def initialize(self, _version, build_data):
"""Set force_include for otdf_python_proto based on build context."""
if self.target_name != "wheel":
return
Expand Down
11 changes: 9 additions & 2 deletions packages/otdf-python/src/otdf_python/aesgcm.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ def encrypt(
def encrypt_with_iv(
self,
iv: bytes,
auth_tag_len: int,
# Kept for signature parity with the Java SDK; the cryptography lib
# derives the tag length itself.
auth_tag_len: int, # noqa: ARG002
plaintext: bytes,
offset: int = 0,
length: int | None = None,
Expand All @@ -58,6 +60,11 @@ def decrypt(self, encrypted: "AesGcm.Encrypted") -> bytes:
return self.aesgcm.decrypt(encrypted.iv, encrypted.ciphertext, None)

def decrypt_with_iv(
self, iv: bytes, auth_tag_len: int, cipher_data: bytes
self,
iv: bytes,
# Kept for signature parity with the Java SDK; the cryptography lib
# derives the tag length itself.
auth_tag_len: int, # noqa: ARG002
cipher_data: bytes,
) -> bytes:
return self.aesgcm.decrypt(iv, cipher_data, None)
2 changes: 1 addition & 1 deletion packages/otdf-python/src/otdf_python/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ def create_tdf_config(sdk: SDK, args) -> TDFConfig:
return config


def create_nano_tdf_config(sdk: SDK, args) -> NanoTDFConfig:
def create_nano_tdf_config(_sdk: SDK, args) -> NanoTDFConfig:
"""Create NanoTDF configuration from CLI arguments."""
attributes = (
parse_attributes(args.attributes)
Expand Down
2 changes: 1 addition & 1 deletion packages/otdf-python/src/otdf_python/collection_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class NoOpCollectionStore(CollectionStore):
def store(self, header, key: CollectionKey):
"""Discard key operation (no-op)."""

def get_key(self, header) -> CollectionKey:
def get_key(self, _header) -> CollectionKey:
return self.NO_PRIVATE_KEY


Expand Down
2 changes: 1 addition & 1 deletion packages/otdf-python/src/otdf_python/kas_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,7 @@ def _normalize_session_key_type(self, session_key_type):
return RSA_KEY_TYPE
return session_key_type

def _prepare_ec_keypair(self, session_key_type):
def _prepare_ec_keypair(self, _session_key_type):
"""Prepare EC key pair for unwrapping.

Args:
Expand Down
4 changes: 2 additions & 2 deletions packages/otdf-python/src/otdf_python/nanotdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ def create_nano_tdf(
return len(header_bytes) + 3 + payload_length

def _kas_unwrap(
self, nano_tdf_data: bytes, header_len: int, wrapped_key: bytes
self, nano_tdf_data: bytes, header_len: int, _wrapped_key: bytes
) -> bytes | None:
try:
# For NanoTDF, send the entire header to KAS
Expand Down Expand Up @@ -622,7 +622,7 @@ def read_nano_tdf( # noqa: C901
# Try KAS unwrap first if services available
if self.services:
try:
key = self._kas_unwrap(nano_tdf_data, header_len, wrapped_key=b"")
key = self._kas_unwrap(nano_tdf_data, header_len, b"")
if key:
logging.info(
"Successfully unwrapped NanoTDF key via KAS (ECDH mode)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class PolicyBindingSerializer:

@staticmethod
def deserialize(
json_data: Any, typeofT: type | None = None, context: Any = None
json_data: Any, _typeof_t: type | None = None, _context: Any = None
) -> Any:
if isinstance(json_data, dict):
return PolicyBinding(**json_data)
Expand All @@ -35,7 +35,7 @@ def deserialize(

@staticmethod
def serialize(
src: Any, typeofSrc: type | None = None, context: Any = None
src: Any, _typeof_src: type | None = None, _context: Any = None
) -> dict | str:
if isinstance(src, PolicyBinding):
return vars(src)
Expand Down
2 changes: 1 addition & 1 deletion packages/otdf-python/src/otdf_python/policy_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def write_into_buffer(self, buffer: bytearray, offset: int = 0) -> int:
return offset - start

@staticmethod
def from_bytes_with_size(buffer: bytes, ecc_mode):
def from_bytes_with_size(buffer: bytes, _ecc_mode):
# Parse policy_type (1 byte), body_len (2 bytes), body
# Note: binding is NOT part of PolicyInfo - it's read separately in Header
offset = 0
Expand Down
6 changes: 3 additions & 3 deletions packages/otdf-python/src/otdf_python/sdk.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,9 @@ def unwrap(self, key_access: Any, policy: str, session_key_type: Any) -> bytes:

def unwrap_nanotdf(
self,
curve: Any,
header: str,
kas_url: str,
curve: Any, # noqa: ARG002
header: str, # noqa: ARG002
kas_url: str, # noqa: ARG002
wrapped_key: bytes | None = None,
kas_private_key: str | None = None,
mock: bool = False,
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ lint.ignore = [
"E501",
]
lint.select = [
"ARG", # flake8-unused-arguments
"B", # flake8-bugbear
"C4", # flake8-comprehensions
"C90", # McCabe complexity
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
run_otdfctl_encrypt_command,
)

pytestmark = pytest.mark.skip(reason="NanoTDF tests are disabled")

logger = logging.getLogger(__name__)


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
validate_plaintext_file_created,
)

pytestmark = pytest.mark.skip(reason="NanoTDF tests are disabled")

logger = logging.getLogger(__name__)


Expand Down
2 changes: 2 additions & 0 deletions tests/test_ecdh.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
get_curve,
)

pytestmark = pytest.mark.skip(reason="NanoTDF tests are disabled")


class TestCurveOperations:
"""Test basic curve operations."""
Expand Down
Loading
Loading