Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
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
4 changes: 4 additions & 0 deletions .github/release-please/release-please-config.main.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
{
"type": "generic",
"path": "cmdline/src/main/java/io/opentdf/platform/Command.java"
},
{
"type": "generic",
"path": "sdk/src/main/java/io/opentdf/platform/sdk/Version.java"
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
{
"type": "generic",
"path": "cmdline/src/main/java/io/opentdf/platform/Command.java"
},
{
"type": "generic",
"path": "sdk/src/main/java/io/opentdf/platform/sdk/Version.java"
}
]
}
74 changes: 43 additions & 31 deletions cmdline/src/main/java/io/opentdf/platform/Command.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,11 @@ class Versions {
public static final String TDF_SPEC = "4.3.0";
}

@CommandLine.Command(
name = "tdf",
subcommands = {HelpCommand.class},
version =
"{\"version\":\"" + Versions.SDK + "\",\"tdfSpecVersion\":\"" + Versions.TDF_SPEC + "\"}"
)
@CommandLine.Command(name = "tdf", subcommands = { HelpCommand.class }, version = "{\"version\":\"" + Versions.SDK
+ "\",\"tdfSpecVersion\":\"" + Versions.TDF_SPEC + "\"}")
class Command {

@Option(names = {"-V", "--version"}, versionHelp = true, description = "display version info")
@Option(names = { "-V", "--version" }, versionHelp = true, description = "display version info")
boolean versionInfoRequested;

private static final String PRIVATE_KEY_HEADER = "-----BEGIN PRIVATE KEY-----";
Expand All @@ -85,7 +81,8 @@ class Command {
@Option(names = { "-p", "--platform-endpoint" }, required = true)
private String platformEndpoint;

private Object correctKeyType(AssertionConfig.AssertionKeyAlg alg, Object key, boolean publicKey) throws RuntimeException{
private Object correctKeyType(AssertionConfig.AssertionKeyAlg alg, Object key, boolean publicKey)
throws RuntimeException {
if (alg == AssertionConfig.AssertionKeyAlg.HS256) {
if (key instanceof String) {
key = ((String) key).getBytes(StandardCharsets.UTF_8);
Expand All @@ -101,14 +98,14 @@ private Object correctKeyType(AssertionConfig.AssertionKeyAlg alg, Object key, b
}
String pem = (String) key;
String pemWithNewlines = pem.replace("\\n", "\n");
if (publicKey){
String base64EncodedPem= pemWithNewlines
.replaceAll(PEM_HEADER, "")
.replaceAll(PEM_FOOTER, "")
.replaceAll("\\s", "")
.replaceAll("\r\n", "")
.replaceAll("\n", "")
.trim();
if (publicKey) {
String base64EncodedPem = pemWithNewlines
.replaceAll(PEM_HEADER, "")
.replaceAll(PEM_FOOTER, "")
.replaceAll("\\s", "")
.replaceAll("\r\n", "")
.replaceAll("\n", "")
.trim();
byte[] decoded = Base64.getDecoder().decode(base64EncodedPem);
X509EncodedKeySpec spec = new X509EncodedKeySpec(decoded);
KeyFactory kf = null;
Expand All @@ -122,7 +119,7 @@ private Object correctKeyType(AssertionConfig.AssertionKeyAlg alg, Object key, b
} catch (InvalidKeySpecException e) {
throw new RuntimeException(e);
}
}else {
} else {
String privateKeyPEM = pemWithNewlines
.replace(PRIVATE_KEY_HEADER, "")
.replace(PRIVATE_KEY_FOOTER, "")
Expand Down Expand Up @@ -174,6 +171,7 @@ void encrypt(
List<Consumer<Config.TDFConfig>> configs = new ArrayList<>();
configs.add(Config.withKasInformation(kasInfos));
metadata.map(Config::withMetaData).ifPresent(configs::add);
configs.add(Config.withSystemMetadataAssertion());
autoconfigure.map(Config::withAutoconfigure).ifPresent(configs::add);
encapKeyType.map(Config::WithWrappingKeyAlg).ifPresent(configs::add);
mimeType.map(Config::withMimeType).ifPresent(configs::add);
Expand All @@ -191,8 +189,9 @@ void encrypt(
String fileJson = new String(Files.readAllBytes(Paths.get(assertionConfig)));
assertionConfigs = gson.fromJson(fileJson, AssertionConfig[].class);
} catch (JsonSyntaxException e2) {
throw new RuntimeException("Failed to parse assertion from file, expects an list of assertions", e2);
} catch(Exception e3) {
throw new RuntimeException("Failed to parse assertion from file, expects an list of assertions",
e2);
} catch (Exception e3) {
throw new RuntimeException("Could not parse assertion as json string or path to file", e3);
}
}
Expand Down Expand Up @@ -238,11 +237,15 @@ private SDK buildSDK() {

@CommandLine.Command(name = "decrypt")
void decrypt(@Option(names = { "-f", "--file" }, required = true) Path tdfPath,
@Option(names = { "--rewrap-key-type" }, defaultValue = Option.NULL_VALUE, description = "Preferred rewrap algorithm, one of ${COMPLETION-CANDIDATES}") Optional<KeyType> rewrapKeyType,
@Option(names = { "--with-assertion-verification-disabled" }, defaultValue = "false") boolean disableAssertionVerification,
@Option(names = { "--with-assertion-verification-keys" }, defaultValue = Option.NULL_VALUE) Optional<String> assertionVerification,
@Option(names = {
"--rewrap-key-type" }, defaultValue = Option.NULL_VALUE, description = "Preferred rewrap algorithm, one of ${COMPLETION-CANDIDATES}") Optional<KeyType> rewrapKeyType,
@Option(names = {
"--with-assertion-verification-disabled" }, defaultValue = "false") boolean disableAssertionVerification,
@Option(names = {
"--with-assertion-verification-keys" }, defaultValue = Option.NULL_VALUE) Optional<String> assertionVerification,
@Option(names = { "--kas-allowlist" }, defaultValue = Option.NULL_VALUE) Optional<String> kasAllowlistStr,
@Option(names = { "--ignore-kas-allowlist" }, defaultValue = Option.NULL_VALUE) Optional<Boolean> ignoreAllowlist)
@Option(names = {
"--ignore-kas-allowlist" }, defaultValue = Option.NULL_VALUE) Optional<Boolean> ignoreAllowlist)
throws Exception {
try (var sdk = buildSDK()) {
var opts = new ArrayList<Consumer<Config.TDFReaderConfig>>();
Expand All @@ -254,7 +257,8 @@ void decrypt(@Option(names = { "-f", "--file" }, required = true) Path tdfPath,

AssertionVerificationKeys assertionVerificationKeys;
try {
assertionVerificationKeys = gson.fromJson(assertionVerificationInput, AssertionVerificationKeys.class);
assertionVerificationKeys = gson.fromJson(assertionVerificationInput,
AssertionVerificationKeys.class);
} catch (JsonSyntaxException e) {
// try it as a file path
try {
Expand All @@ -263,16 +267,20 @@ void decrypt(@Option(names = { "-f", "--file" }, required = true) Path tdfPath,
} catch (JsonSyntaxException e2) {
throw new RuntimeException("Failed to parse assertion verification keys from file", e2);
} catch (Exception e3) {
throw new RuntimeException("Could not parse assertion verification keys as json string or path to file", e3);
throw new RuntimeException(
"Could not parse assertion verification keys as json string or path to file",
e3);
}
}

for (Map.Entry<String, AssertionConfig.AssertionKey> entry : assertionVerificationKeys.keys.entrySet()) {
for (Map.Entry<String, AssertionConfig.AssertionKey> entry : assertionVerificationKeys.keys
.entrySet()) {
try {
Object correctedKey = correctKeyType(entry.getValue().alg, entry.getValue().key, true);
entry.setValue(new AssertionConfig.AssertionKey(entry.getValue().alg, correctedKey));
} catch (Exception e) {
throw new RuntimeException("Error with assertion verification key: " + e.getMessage(), e);
throw new RuntimeException("Error with assertion verification key: " + e.getMessage(),
e);
}
}
opts.add(Config.withAssertionVerificationKeys(assertionVerificationKeys));
Expand All @@ -296,8 +304,10 @@ void decrypt(@Option(names = { "-f", "--file" }, required = true) Path tdfPath,

@CommandLine.Command(name = "metadata")
void readMetadata(@Option(names = { "-f", "--file" }, required = true) Path tdfPath,
@Option(names = { "--kas-allowlist" }, defaultValue = Option.NULL_VALUE) Optional<String> kasAllowlistStr,
@Option(names = { "--ignore-kas-allowlist" }, defaultValue = Option.NULL_VALUE) Optional<Boolean> ignoreAllowlist) throws IOException {
@Option(names = { "--kas-allowlist" }, defaultValue = Option.NULL_VALUE) Optional<String> kasAllowlistStr,
@Option(names = {
"--ignore-kas-allowlist" }, defaultValue = Option.NULL_VALUE) Optional<Boolean> ignoreAllowlist)
throws IOException {
var sdk = buildSDK();
var opts = new ArrayList<Consumer<Config.TDFReaderConfig>>();
try (var in = FileChannel.open(tdfPath, StandardOpenOption.READ)) {
Expand Down Expand Up @@ -344,8 +354,10 @@ void createNanoTDF(

@CommandLine.Command(name = "decryptnano")
void readNanoTDF(@Option(names = { "-f", "--file" }, required = true) Path nanoTDFPath,
@Option(names = { "--kas-allowlist" }, defaultValue = Option.NULL_VALUE) Optional<String> kasAllowlistStr,
@Option(names = { "--ignore-kas-allowlist" }, defaultValue = Option.NULL_VALUE) Optional<Boolean> ignoreAllowlist) throws Exception {
@Option(names = { "--kas-allowlist" }, defaultValue = Option.NULL_VALUE) Optional<String> kasAllowlistStr,
@Option(names = {
"--ignore-kas-allowlist" }, defaultValue = Option.NULL_VALUE) Optional<Boolean> ignoreAllowlist)
throws Exception {
var sdk = buildSDK();
try (var in = FileChannel.open(nanoTDFPath, StandardOpenOption.READ)) {
try (var stdout = new BufferedOutputStream(System.out)) {
Expand Down
Loading