Misc cleanup

This commit is contained in:
Oracle 2026-04-29 16:59:33 +02:00
parent 9b5fa56215
commit 084ce14451
Signed by: Oracle
SSH key fingerprint: SHA256:x4/RtnjUyuHkdvmwNDsWSfcfF1V5PNr3OpriZqOvCX8
17 changed files with 101 additions and 620 deletions

View file

@ -1,6 +1,5 @@
package ai.nomyo;
import java.util.Set;
/**
@ -26,7 +25,6 @@ public final class Constants {
* AES-256-GCM payload encryption algorithm.
*/
public static final String PAYLOAD_ALGORITHM = "AES-256-GCM";
// Cryptographic Constants
/**
@ -53,7 +51,6 @@ public final class Constants {
* Minimum RSA key size for validation (bits).
*/
public static final int MIN_RSA_KEY_SIZE = 2048;
// Payload Limits
/**
@ -75,7 +72,6 @@ public final class Constants {
* Retryable HTTP status codes.
*/
public static final Set<Integer> RETRYABLE_STATUS_CODES = Set.of(429, 500, 502, 503, 504);
// File Permission Constants
/**
@ -86,7 +82,6 @@ public final class Constants {
* Public key file permission (owner rw, group/others r).
*/
public static final String PUBLIC_KEY_FILE_MODE = "rw-r--r--";
// Security Tier Constants
/**
@ -105,7 +100,6 @@ public final class Constants {
* CPU only for PHI/classified data.
*/
public static final String SECURITY_TIER_MAXIMUM = "maximum";
// Endpoint Paths
/**
@ -116,7 +110,6 @@ public final class Constants {
* Secure chat completion endpoint.
*/
public static final String SECURE_COMPLETION_PATH = "/v1/chat/secure_completion";
// HTTP Headers
/**
@ -139,7 +132,6 @@ public final class Constants {
* Bearer token prefix.
*/
public static final String AUTHORIZATION_BEARER_PREFIX = "Bearer ";
// Default Values
/**
@ -158,7 +150,6 @@ public final class Constants {
* Default public key file name.
*/
public static final String DEFAULT_PUBLIC_KEY_FILE = "public_key.pem";
// Memory Protection Constants
/**

View file

@ -15,7 +15,6 @@ public class EncryptedRequest {
private static final Gson GSON = new GsonBuilder().create();
// Getters and Setters
@SerializedName("version")
private String version;
@ -26,7 +25,7 @@ public class EncryptedRequest {
private EncryptedPayload encryptedPayload;
@SerializedName("encrypted_aes_key")
private String encryptedAESKey; // Java variable name corrected to proper spelling
private String encryptedAESKey;
@SerializedName("key_algorithm")
private String keyAlgorithm;
@ -41,7 +40,6 @@ public class EncryptedRequest {
@Getter
public static class EncryptedPayload {
// Getters and Setters
@SerializedName("ciphertext")
private String ciphertext;

View file

@ -146,24 +146,11 @@ public class SecureChatCompletion {
/**
* Convenience variant with no additional parameters.
*/
@SuppressWarnings("UnusedReturnValue")
public Map<String, Object> create(String model, List<Map<String, Object>> messages) {
return create(model, messages, null);
}
/**
* Async alias for {@link #create(String, List, Map)}.
*/
public Map<String, Object> acreate(String model, List<Map<String, Object>> messages, Map<String, Object> kwargs) {
return create(model, messages, kwargs);
}
/**
* Async alias for {@link #create(String, List)}.
*/
public Map<String, Object> acreate(String model, List<Map<String, Object>> messages) {
return create(model, messages);
}
/**
* Delegates to {@link SecureCompletionClient#close()}.
*/

View file

@ -295,6 +295,7 @@ public class SecureCompletionClient {
* @return encrypted bytes (JSON package)
* @throws SecurityError if encryption fails or keys not loaded
*/
@SuppressWarnings("JavadocDeclaration")
public CompletableFuture<byte[]> encryptPayload(Map<String, Object> payload) {
return CompletableFuture.supplyAsync(() -> {
try {

View file

@ -10,6 +10,7 @@ import java.util.Map;
/**
* Cross-platform memory locking and secure zeroing for sensitive cryptographic buffers. Fails gracefully if unavailable.
*/
@SuppressWarnings("SameReturnValue")
public final class SecureMemory {
@Getter
@ -75,6 +76,7 @@ public final class SecureMemory {
/**
* Wraps bytes with memory locking and guaranteed zeroing on close. AutoCloseable for try-with-resources.
*/
@SuppressWarnings("SameReturnValue")
public static class SecureBuffer implements AutoCloseable {
private final Arena arena;

View file

@ -31,5 +31,4 @@ public class APIError extends Exception {
public APIError(String message) {
this(message, null, null);
}
}

View file

@ -11,36 +11,31 @@ public class PEMConverter {
* Encodes {@code keyData} as PEM (private or public) with 64-char base64 lines.
*/
public static String toPEM(byte[] keyData, boolean privateKey) {
String publicKeyContent = Base64.getEncoder().encodeToString(keyData);
StringBuilder publicKeyFormatted = new StringBuilder(privateKey ? "-----BEGIN PRIVATE KEY-----" : "-----BEGIN PUBLIC KEY-----");
publicKeyFormatted.append(System.lineSeparator());
for (final String row : Splitter.fixedLengthString(64, publicKeyContent)) {
publicKeyFormatted.append(row);
publicKeyFormatted.append(System.lineSeparator());
String b64 = Base64.getEncoder().encodeToString(keyData);
String begin = privateKey ? "-----BEGIN PRIVATE KEY-----" : "-----BEGIN PUBLIC KEY-----";
String end = privateKey ? "-----END PRIVATE KEY-----" : "-----END PUBLIC KEY-----";
StringBuilder sb = new StringBuilder(begin).append(System.lineSeparator());
for (String row : Splitter.fixedLengthString(64, b64)) {
sb.append(row).append(System.lineSeparator());
}
publicKeyFormatted.append(privateKey ? "-----END PRIVATE KEY-----" : "-----END PUBLIC KEY-----");
return publicKeyFormatted.toString();
sb.append(end);
return sb.toString();
}
public static byte[] fromPEM(String pem) {
pem = pem.replace("-----BEGIN PRIVATE KEY-----", "")
.replace("-----BEGIN PUBLIC KEY-----", "")
.replace("-----END PRIVATE KEY-----", "")
.replace("-----END PUBLIC KEY-----", "")
.replaceAll("\\s+", "");
return Base64.getDecoder().decode(pem);
String cleaned = pem.replace("-----BEGIN PRIVATE KEY-----", "")
.replace("-----BEGIN PUBLIC KEY-----", "")
.replace("-----END PRIVATE KEY-----", "")
.replace("-----END PUBLIC KEY-----", "")
.replaceAll("\\s+", "");
return Base64.getDecoder().decode(cleaned);
}
public static boolean validatePEM(String keyIn) {
if (keyIn == null || keyIn.isBlank()) {
return false;
}
String trimmed = keyIn.trim();
return trimmed.startsWith("-----BEGIN PUBLIC KEY-----")
&& trimmed.endsWith("-----END PUBLIC KEY-----");
}

View file

@ -1,6 +1,7 @@
package ai.nomyo.util;
import ai.nomyo.errors.SecurityError;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;

View file

@ -13,12 +13,10 @@ public class Splitter {
*/
public static List<String> fixedLengthString(int length, String toSplit) {
List<String> parts = new ArrayList<>();
for (int i = 0; i < toSplit.length(); i += length) {
int endIndex = Math.min(i + length, toSplit.length());
parts.add(toSplit.substring(i, endIndex));
}
return parts;
}