Skip to content

Commit

Permalink
feat: SDK Encrypt (with mocked rewrap) (#45)
Browse files Browse the repository at this point in the history
Co-authored-by: sujan kota <sujankota@gmail.com>
Co-authored-by: Morgan Kleene <mkleene@virtru.com>
  • Loading branch information
3 people committed May 28, 2024
1 parent af51404 commit d67daa2
Show file tree
Hide file tree
Showing 14 changed files with 997 additions and 5 deletions.
22 changes: 22 additions & 0 deletions sdk/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,18 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<name>sdk</name>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
</plugins>
</build>
<artifactId>sdk</artifactId>
<parent>
<artifactId>sdk-pom</artifactId>
Expand Down Expand Up @@ -83,6 +95,16 @@
<version>4.13.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.17.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
Expand Down
17 changes: 15 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 @@ -11,7 +11,7 @@
import java.util.Base64;

public class AesGcm {
private static final int GCM_NONCE_LENGTH = 12; // in bytes
public static final int GCM_NONCE_LENGTH = 12; // in bytes
private static final int GCM_TAG_LENGTH = 16; // in bytes
private static final String CIPHER_TRANSFORM = "AES/GCM/NoPadding";

Expand All @@ -37,13 +37,26 @@ public AesGcm(byte[] key) {
*/
public byte[] encrypt(byte[] plaintext) throws NoSuchPaddingException, NoSuchAlgorithmException,
InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
return encrypt(plaintext, 0, plaintext.length);
}

/**
* <p>encrypt.</p>
*
* @param plaintext the plaintext byte array to encrypt
* @param offset where the input start
* @param len input length
* @return the encrypted text
*/
public byte[] encrypt(byte[] plaintext, int offset, int len) throws NoSuchPaddingException, NoSuchAlgorithmException,
InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
Cipher cipher = Cipher.getInstance(CIPHER_TRANSFORM);
byte[] nonce = new byte[GCM_NONCE_LENGTH];
SecureRandom.getInstanceStrong().nextBytes(nonce);
GCMParameterSpec spec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, nonce);
cipher.init(Cipher.ENCRYPT_MODE, key, spec);

byte[] cipherText = cipher.doFinal(plaintext);
byte[] cipherText = cipher.doFinal(plaintext, offset, len);
byte[] cipherTextWithNonce = new byte[nonce.length + cipherText.length];
System.arraycopy(nonce, 0, cipherTextWithNonce, 0, nonce.length);
System.arraycopy(cipherText, 0, cipherTextWithNonce, nonce.length, cipherText.length);
Expand Down
82 changes: 82 additions & 0 deletions sdk/src/main/java/io/opentdf/platform/sdk/Config.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package io.opentdf.platform.sdk;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;

public class Config {

public static final int TDF3_KEY_SIZE = 2048;
public static final int DEFAULT_SEGMENT_SIZE = 2 * 1024 * 1024; // 2mb
public static final String KAS_PUBLIC_KEY_PATH = "/kas_public_key";

public enum TDFFormat {
JSONFormat,
XMLFormat
}

public enum IntegrityAlgorithm {
HS256,
GMAC
}

public static final int K_HTTP_OK = 200;

public static class KASInfo {
public String URL;
public String PublicKey;
}

public static class TDFConfig {
public int defaultSegmentSize;
public boolean enableEncryption;
public TDFFormat tdfFormat;
public String tdfPublicKey;
public String tdfPrivateKey;
public String metaData;
public IntegrityAlgorithm integrityAlgorithm;
public IntegrityAlgorithm segmentIntegrityAlgorithm;
public List<String> attributes;
public List<KASInfo> kasInfoList;

public TDFConfig() {
this.defaultSegmentSize = DEFAULT_SEGMENT_SIZE;
this.enableEncryption = true;
this.tdfFormat = TDFFormat.JSONFormat;
this.integrityAlgorithm = IntegrityAlgorithm.HS256;
this.segmentIntegrityAlgorithm = IntegrityAlgorithm.GMAC;
this.attributes = new ArrayList<>();
this.kasInfoList = new ArrayList<>();
}
}

@SafeVarargs
public static TDFConfig newTDFConfig(Consumer<TDFConfig>... options) {
TDFConfig config = new TDFConfig();
for (Consumer<TDFConfig> option : options) {
option.accept(config);
}
return config;
}

public static Consumer<TDFConfig> withDataAttributes(String... attributes) {
return (TDFConfig config) -> {
Collections.addAll(config.attributes, attributes);
};
}

public static Consumer<TDFConfig> withKasInformation(KASInfo... kasInfoList) {
return (TDFConfig config) -> {
Collections.addAll(config.kasInfoList, kasInfoList);
};
}

public static Consumer<TDFConfig> withMetaData(String metaData) {
return (TDFConfig config) -> config.metaData = metaData;
}

public static Consumer<TDFConfig> withSegmentSize(int size) {
return (TDFConfig config) -> config.defaultSegmentSize = size;
}
}
18 changes: 18 additions & 0 deletions sdk/src/main/java/io/opentdf/platform/sdk/CryptoUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package io.opentdf.platform.sdk;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

public class CryptoUtils {
public static byte[] CalculateSHA256Hmac(byte[] key, byte[] data) throws NoSuchAlgorithmException,
InvalidKeyException {
Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(key, "HmacSHA256");
sha256_HMAC.init(secret_key);

return sha256_HMAC.doFinal(data);
}
}
65 changes: 65 additions & 0 deletions sdk/src/main/java/io/opentdf/platform/sdk/Manifest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package io.opentdf.platform.sdk;

import com.google.gson.annotations.SerializedName;

import java.util.List;

public class Manifest {
static public class Segment {
public String hash;
public long segmentSize;
public long encryptedSegmentSize;
}

static public class RootSignature {
@SerializedName(value = "alg")
public String algorithm;
@SerializedName(value = "sig")
public String signature;
}

static public class IntegrityInformation {
public RootSignature rootSignature;
public String segmentHashAlg;
public int segmentSizeDefault;
public int encryptedSegmentSizeDefault;
public List<Segment> segments;
}

static public class KeyAccess {
@SerializedName(value = "type")
public String keyType;
public String url;
public String protocol;
public String wrappedKey;
public String policyBinding;
public String encryptedMetadata;
}

static public class Method {
public String algorithm;
public String iv;
public Boolean IsStreamable;
}

static public class EncryptionInformation {
@SerializedName(value = "type")
public String keyAccessType;
public String policy;

@SerializedName(value = "keyAccess")
public List<KeyAccess> keyAccessObj;
public Method method;
public IntegrityInformation integrityInformation;
}

static public class Payload {
public String type;
public String url;
public String protocol;
public String mimeType;
public Boolean isEncrypted;
}
public EncryptionInformation encryptionInformation;
public Payload payload;
}
22 changes: 22 additions & 0 deletions sdk/src/main/java/io/opentdf/platform/sdk/PolicyObject.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.opentdf.platform.sdk;

import java.util.List;
import java.util.UUID;

public class PolicyObject {
static public class AttributeObject {
public String attribute;
public String displayName;
public boolean isDefault;
public String pubKey;
public String kasURL;
}

static public class Body {
public List<AttributeObject> dataAttributes;
public List<String> dissem;
}

public String uuid;
public Body body;
}
Loading

0 comments on commit d67daa2

Please sign in to comment.