Skip to content

Commit 1f3d1d2

Browse files
authored
Merge pull request #8 from imabhichow/main
Add KMS Legacy Keyring
2 parents b587868 + 130d177 commit 1f3d1d2

File tree

1 file changed

+98
-0
lines changed
  • src/main/java/software/amazon/encryption/s3/legacy/materials

1 file changed

+98
-0
lines changed
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
package software.amazon.encryption.s3.legacy.materials;
2+
3+
import java.util.List;
4+
import software.amazon.awssdk.core.ApiName;
5+
import software.amazon.awssdk.core.SdkBytes;
6+
import software.amazon.awssdk.services.kms.KmsClient;
7+
import software.amazon.awssdk.services.kms.model.DecryptRequest;
8+
import software.amazon.awssdk.services.kms.model.DecryptResponse;
9+
import software.amazon.encryption.s3.S3EncryptionClientException;
10+
import software.amazon.encryption.s3.internal.ApiNameVersion;
11+
import software.amazon.encryption.s3.materials.*;
12+
13+
/**
14+
* KmsKeyring is a legacy, decrypt-only keyring and will use a KMS Master key to unwrap the data key
15+
* used to encrypt content.
16+
*/
17+
public class KmsKeyring implements Keyring {
18+
19+
private static final String KEY_PROVIDER_ID = "kms";
20+
21+
private static final ApiName API_NAME = ApiNameVersion.apiNameWithVersion();
22+
23+
private final KmsClient _kmsClient;
24+
private final String _wrappingKeyId;
25+
private final DataKeyGenerator _dataKeyGenerator;
26+
27+
public KmsKeyring(Builder builder) {
28+
_kmsClient = builder._kmsClient;
29+
_wrappingKeyId = builder._wrappingKeyId;
30+
_dataKeyGenerator = builder._dataKeyGenerator;
31+
}
32+
33+
public static Builder builder() {
34+
return new Builder();
35+
}
36+
37+
@Override
38+
public EncryptionMaterials onEncrypt(EncryptionMaterials materials) {
39+
throw new S3EncryptionClientException("Encrypt not supported for " + KEY_PROVIDER_ID);
40+
}
41+
42+
@Override
43+
public DecryptionMaterials onDecrypt(final DecryptionMaterials materials, List<EncryptedDataKey> encryptedDataKeys) {
44+
if (materials.plaintextDataKey() != null) {
45+
throw new S3EncryptionClientException("Decryption materials already contains a plaintext data key.");
46+
}
47+
48+
for (EncryptedDataKey encryptedDataKey : encryptedDataKeys) {
49+
if (!encryptedDataKey.keyProviderId().equals(KEY_PROVIDER_ID)) {
50+
continue;
51+
}
52+
53+
try {
54+
DecryptRequest request = DecryptRequest.builder()
55+
.keyId(_wrappingKeyId)
56+
.encryptionContext(materials.encryptionContext())
57+
.ciphertextBlob(SdkBytes.fromByteArray(encryptedDataKey.ciphertext()))
58+
.overrideConfiguration(builder -> builder.addApiName(API_NAME))
59+
.build();
60+
61+
DecryptResponse response = _kmsClient.decrypt(request);
62+
63+
return materials.toBuilder().plaintextDataKey(response.plaintext().asByteArray()).build();
64+
} catch (Exception e) {
65+
throw new S3EncryptionClientException("Unable to " + KEY_PROVIDER_ID + " unwrap", e);
66+
}
67+
}
68+
69+
return materials;
70+
}
71+
72+
public static class Builder {
73+
private KmsClient _kmsClient;
74+
private String _wrappingKeyId;
75+
private DataKeyGenerator _dataKeyGenerator = new DefaultDataKeyGenerator();
76+
77+
private Builder() {}
78+
79+
public Builder kmsClient(KmsClient kmsClient) {
80+
_kmsClient = kmsClient;
81+
return this;
82+
}
83+
84+
public Builder wrappingKeyId(String wrappingKeyId) {
85+
_wrappingKeyId = wrappingKeyId;
86+
return this;
87+
}
88+
89+
public Builder dataKeyGenerator(DataKeyGenerator dataKeyGenerator) {
90+
_dataKeyGenerator = dataKeyGenerator;
91+
return this;
92+
}
93+
94+
public KmsKeyring build() {
95+
return new KmsKeyring(this);
96+
}
97+
}
98+
}

0 commit comments

Comments
 (0)