Skip to content

Commit c299dbd

Browse files
authored
fix(sdk): assertion support in tdf3 (#82)
1 parent 862460a commit c299dbd

File tree

10 files changed

+500
-84
lines changed

10 files changed

+500
-84
lines changed

cmdline/src/main/java/io/opentdf/platform/Command.java

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package io.opentdf.platform;
22

3+
import com.nimbusds.jose.JOSEException;
34
import io.opentdf.platform.sdk.*;
45
import io.opentdf.platform.sdk.TDF;
6+
import org.apache.commons.codec.DecoderException;
57
import picocli.CommandLine;
68
import picocli.CommandLine.Option;
79

@@ -23,6 +25,7 @@
2325
import java.security.InvalidAlgorithmParameterException;
2426
import java.security.InvalidKeyException;
2527
import java.security.NoSuchAlgorithmException;
28+
import java.text.ParseException;
2629
import java.util.ArrayList;
2730
import java.util.List;
2831
import java.util.Optional;
@@ -47,7 +50,8 @@ class Command {
4750
void encrypt(
4851
@Option(names = {"-f", "--file"}, defaultValue = Option.NULL_VALUE) Optional<File> file,
4952
@Option(names = {"-k", "--kas-url"}, required = true) List<String> kas,
50-
@Option(names = {"-m", "--metadata"}, defaultValue = Option.NULL_VALUE) Optional<String> metadata) throws IOException {
53+
@Option(names = {"-m", "--metadata"}, defaultValue = Option.NULL_VALUE) Optional<String> metadata) throws
54+
IOException, JOSEException {
5155

5256
var sdk = buildSDK();
5357
var kasInfos = kas.stream().map(k -> {
@@ -77,22 +81,26 @@ private SDK buildSDK() {
7781
}
7882

7983
@CommandLine.Command(name = "decrypt")
80-
void decrypt(@Option(names = {"-f", "--file"}, required = true) Path tdfPath) throws IOException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException {
84+
void decrypt(@Option(names = {"-f", "--file"}, required = true) Path tdfPath) throws IOException,
85+
InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException,
86+
BadPaddingException, InvalidKeyException, TDF.FailedToCreateGMAC,
87+
JOSEException, ParseException, NoSuchAlgorithmException, DecoderException {
8188
var sdk = buildSDK();
8289
try (var in = FileChannel.open(tdfPath, StandardOpenOption.READ)) {
8390
try (var stdout = new BufferedOutputStream(System.out)) {
84-
var reader = new TDF().loadTDF(in, sdk.getServices().kas());
91+
var reader = new TDF().loadTDF(in, new Config.AssertionConfig(), sdk.getServices().kas());
8592
reader.readPayload(stdout);
8693
}
8794
}
8895
}
8996
@CommandLine.Command(name = "metadata")
90-
void readMetadata(@Option(names = {"-f", "--file"}, required = true) Path tdfPath) throws IOException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException {
97+
void readMetadata(@Option(names = {"-f", "--file"}, required = true) Path tdfPath) throws IOException,
98+
TDF.FailedToCreateGMAC, JOSEException, NoSuchAlgorithmException, ParseException, DecoderException {
9199
var sdk = buildSDK();
92100

93101
try (var in = FileChannel.open(tdfPath, StandardOpenOption.READ)) {
94102
try (var stdout = new PrintWriter(System.out)) {
95-
var reader = new TDF().loadTDF(in, sdk.getServices().kas());
103+
var reader = new TDF().loadTDF(in, new Config.AssertionConfig(), sdk.getServices().kas());
96104
stdout.write(reader.getMetadata() == null ? "" : reader.getMetadata());
97105
}
98106
}

sdk/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,5 +121,10 @@
121121
<version>5.0.0-alpha.14</version>
122122
<scope>test</scope>
123123
</dependency>
124+
<dependency>
125+
<groupId>io.github.erdtman</groupId>
126+
<artifactId>java-json-canonicalization</artifactId>
127+
<version>1.1</version>
128+
</dependency>
124129
</dependencies>
125130
</project>

sdk/src/main/java/io/opentdf/platform/sdk/AesGcm.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,16 @@ public class AesGcm {
1919

2020
private final SecretKey key;
2121

22+
23+
/**
24+
* <p>Return symmetric key</p>
25+
*
26+
* @return
27+
*/
28+
public byte[] getKey() {
29+
return key.getEncoded();
30+
}
31+
2232
public static class Encrypted {
2333
private final byte[] iv;
2434
private final byte[] ciphertext;
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package io.opentdf.platform.sdk;
2+
3+
public class Assertion {
4+
5+
public enum Type {
6+
HandlingAssertion("Handling"),
7+
BaseAssertion("Base");
8+
9+
private final String type;
10+
11+
Type(String assertionType) {
12+
this.type = assertionType;
13+
}
14+
15+
@Override
16+
public String toString() {
17+
return type;
18+
}
19+
}
20+
21+
public enum Scope {
22+
TrustedDataObj("TDO"),
23+
Payload("PAYL"),
24+
Explicit("EXPLICIT");
25+
26+
private final String scope;
27+
28+
Scope(String scope) {
29+
this.scope = scope;
30+
}
31+
}
32+
33+
public enum AppliesToState {
34+
Encrypted("encrypted"),
35+
Unencrypted("unencrypted");
36+
37+
private final String state;
38+
39+
AppliesToState(String state) {
40+
this.state = state;
41+
}
42+
}
43+
44+
public enum StatementFormat {
45+
ReferenceStatement("ReferenceStatement"),
46+
StructuredStatement("StructuredStatement"),
47+
StringStatement("StringStatement"),
48+
Base64BinaryStatement("Base64BinaryStatement"),
49+
XMLBase64("XMLBase64"),
50+
HandlingStatement("HandlingStatement"),
51+
StringType("String");
52+
53+
private String format;
54+
55+
StatementFormat(String format) {
56+
this.format = format;
57+
}
58+
}
59+
60+
61+
public enum BindingMethod {
62+
JWT("jwt");
63+
64+
private String method;
65+
66+
BindingMethod(String method) {
67+
this.method = method;
68+
}
69+
}
70+
71+
static public class Statement {
72+
public String format;
73+
public String value;
74+
}
75+
76+
static public class Binding {
77+
public String method;
78+
public String signature;
79+
}
80+
81+
public String id;
82+
public String type;
83+
public String scope;
84+
public String appliesToState;
85+
public Statement statement;
86+
public Binding binding;
87+
}

sdk/src/main/java/io/opentdf/platform/sdk/Config.java

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import io.opentdf.platform.sdk.nanotdf.NanoTDFType;
55
import io.opentdf.platform.sdk.nanotdf.SymmetricAndPayloadConfig;
66

7+
import com.nimbusds.jose.jwk.RSAKey;
8+
import java.security.Key;
79
import java.util.ArrayList;
810
import java.util.Collections;
911
import java.util.List;
@@ -33,6 +35,23 @@ public static class KASInfo {
3335
public String KID;
3436
}
3537

38+
public static class AssertionConfig {
39+
public enum KeyType {
40+
RS256,
41+
HS256PayloadKey,
42+
HS256UserDefined;
43+
}
44+
45+
public RSAKey rs256PrivateKeyForSigning;
46+
public RSAKey rs256PublicKeyForVerifying;
47+
public byte[] hs256SymmetricKey;
48+
public KeyType keyType;
49+
50+
public AssertionConfig() {
51+
this.keyType = KeyType.HS256PayloadKey;
52+
}
53+
}
54+
3655
public static class TDFConfig {
3756
public int defaultSegmentSize;
3857
public boolean enableEncryption;
@@ -44,6 +63,8 @@ public static class TDFConfig {
4463
public IntegrityAlgorithm segmentIntegrityAlgorithm;
4564
public List<String> attributes;
4665
public List<KASInfo> kasInfoList;
66+
public List<Assertion> assertionList;
67+
public AssertionConfig assertionConfig;
4768

4869
public TDFConfig() {
4970
this.defaultSegmentSize = DEFAULT_SEGMENT_SIZE;
@@ -53,6 +74,7 @@ public TDFConfig() {
5374
this.segmentIntegrityAlgorithm = IntegrityAlgorithm.GMAC;
5475
this.attributes = new ArrayList<>();
5576
this.kasInfoList = new ArrayList<>();
77+
this.assertionList = new ArrayList<>();
5678
}
5779
}
5880

@@ -77,14 +99,32 @@ public static Consumer<TDFConfig> withKasInformation(KASInfo... kasInfoList) {
7799
};
78100
}
79101

102+
public static Consumer<TDFConfig> WithAssertions(Assertion... assertionList) {
103+
return (TDFConfig config) -> {
104+
Collections.addAll(config.assertionList, assertionList);
105+
};
106+
}
107+
108+
public static Consumer<TDFConfig> WithAssertion(Assertion assertion) {
109+
return (TDFConfig config) -> config.assertionList.add(assertion);
110+
}
111+
80112
public static Consumer<TDFConfig> withMetaData(String metaData) {
81113
return (TDFConfig config) -> config.metaData = metaData;
82114
}
83115

116+
public static Consumer<TDFConfig> withAssertionConfig(AssertionConfig assertionConfig) {
117+
return (TDFConfig config) -> config.assertionConfig = assertionConfig;
118+
}
119+
84120
public static Consumer<TDFConfig> withSegmentSize(int size) {
85121
return (TDFConfig config) -> config.defaultSegmentSize = size;
86122
}
87123

124+
public static Consumer<TDFConfig> withDisableEncryption() {
125+
return (TDFConfig config) -> config.enableEncryption = false;
126+
}
127+
88128
public static class NanoTDFConfig {
89129
public ECCMode eccMode;
90130
public NanoTDFType.Cipher cipher;

sdk/src/main/java/io/opentdf/platform/sdk/CryptoUtils.java

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@
22

33
import javax.crypto.Mac;
44
import javax.crypto.spec.SecretKeySpec;
5-
import java.security.InvalidKeyException;
6-
import java.security.KeyPair;
7-
import java.security.KeyPairGenerator;
8-
import java.security.NoSuchAlgorithmException;
9-
import java.security.PublicKey;
5+
import java.security.*;
106
import java.util.Base64;
117

128
public class CryptoUtils {
@@ -49,4 +45,16 @@ public static String getRSAPublicKeyPEM(PublicKey publicKey) {
4945
Base64.getMimeEncoder().encodeToString(publicKey.getEncoded()) +
5046
"\r\n-----END PUBLIC KEY-----";
5147
}
48+
49+
public static String getRSAPrivateKeyPEM(PrivateKey privateKey) {
50+
if (!"RSA".equals(privateKey.getAlgorithm())) {
51+
throw new IllegalArgumentException("can't get private key PEM for algorithm [" + privateKey.getAlgorithm() + "]");
52+
}
53+
54+
return "-----BEGIN PRIVATE KEY-----\r\n" +
55+
Base64.getMimeEncoder().encodeToString(privateKey.getEncoded()) +
56+
"\r\n-----END PRIVATE KEY-----";
57+
}
58+
59+
5260
}

sdk/src/main/java/io/opentdf/platform/sdk/Manifest.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,15 @@ static public class EncryptionInformation {
5454
public IntegrityInformation integrityInformation;
5555
}
5656

57-
static public class Payload {
57+
static public class Payload {
5858
public String type;
5959
public String url;
6060
public String protocol;
6161
public String mimeType;
6262
public Boolean isEncrypted;
6363
}
64+
6465
public EncryptionInformation encryptionInformation;
6566
public Payload payload;
67+
public List<Assertion> assertions;
6668
}

0 commit comments

Comments
 (0)