11package software .amazon .encryption .s3 ;
22
3+ import java .security .KeyPair ;
4+ import java .security .SecureRandom ;
5+ import javax .crypto .SecretKey ;
36import software .amazon .awssdk .awscore .exception .AwsServiceException ;
47import software .amazon .awssdk .core .exception .SdkClientException ;
58import software .amazon .awssdk .core .sync .RequestBody ;
1114import software .amazon .awssdk .services .s3 .model .PutObjectResponse ;
1215import software .amazon .encryption .s3 .internal .GetEncryptedObjectPipeline ;
1316import software .amazon .encryption .s3 .internal .PutEncryptedObjectPipeline ;
14- import software .amazon .encryption .s3 .legacy .materials .LegacyDecryptCryptoMaterialsManager ;
15- import software .amazon .encryption .s3 .legacy .materials .LegacyKeyring ;
17+ import software .amazon .encryption .s3 .materials .AesKeyring ;
1618import software .amazon .encryption .s3 .materials .CryptographicMaterialsManager ;
17- import software .amazon .encryption .s3 .materials .DecryptMaterialsRequest ;
18- import software .amazon .encryption .s3 .materials .DecryptionMaterials ;
19+ import software .amazon .encryption .s3 .materials .DataKeyGenerator ;
1920import software .amazon .encryption .s3 .materials .DefaultCryptoMaterialsManager ;
20- import software .amazon .encryption .s3 .materials .EncryptedDataKey ;
21+ import software .amazon .encryption .s3 .materials .DefaultDataKeyGenerator ;
2122import software .amazon .encryption .s3 .materials .Keyring ;
23+ import software .amazon .encryption .s3 .materials .KmsKeyring ;
24+ import software .amazon .encryption .s3 .materials .RsaKeyring ;
2225
2326public class S3EncryptionClient implements S3Client {
2427
@@ -74,6 +77,9 @@ public static class Builder {
7477 private S3Client _wrappedClient = S3Client .builder ().build ();
7578 private CryptographicMaterialsManager _cryptoMaterialsManager ;
7679 private Keyring _keyring ;
80+ private SecretKey _aesKey ;
81+ private KeyPair _rsaKeyPair ;
82+ private String _kmsKeyId ;
7783 private boolean _enableLegacyModes = false ;
7884
7985 private Builder () {}
@@ -83,40 +89,100 @@ public Builder wrappedClient(S3Client wrappedClient) {
8389 return this ;
8490 }
8591
92+ public Builder cryptoMaterialsManager (CryptographicMaterialsManager cryptoMaterialsManager ) {
93+ this ._cryptoMaterialsManager = cryptoMaterialsManager ;
94+ checkKeyOptions ();
95+
96+ return this ;
97+ }
98+
8699 public Builder keyring (Keyring keyring ) {
87100 this ._keyring = keyring ;
101+ checkKeyOptions ();
102+
88103 return this ;
89104 }
90105
91- public Builder cryptoMaterialsManager (CryptographicMaterialsManager cryptoMaterialsManager ) {
92- this ._cryptoMaterialsManager = cryptoMaterialsManager ;
106+ public Builder aesKey (SecretKey aesKey ) {
107+ this ._aesKey = aesKey ;
108+ checkKeyOptions ();
109+
110+ return this ;
111+ }
112+
113+ public Builder rsaKeyPair (KeyPair rsaKeyPair ) {
114+ this ._rsaKeyPair = rsaKeyPair ;
115+ checkKeyOptions ();
116+
93117 return this ;
94118 }
95119
120+ public Builder kmsKeyId (String kmsKeyId ) {
121+ this ._kmsKeyId = kmsKeyId ;
122+ checkKeyOptions ();
123+
124+ return this ;
125+ }
126+
127+ // We only want one way to use a key, if more than one is set, throw an error
128+ private void checkKeyOptions () {
129+ if (onlyOneNonNull (_cryptoMaterialsManager , _keyring , _aesKey , _rsaKeyPair , _kmsKeyId )) {
130+ return ;
131+ }
132+
133+ throw new S3EncryptionClientException ("Only one may be set of: crypto materials manager, keyring, AES key, RSA key pair, KMS key id" );
134+ }
135+
136+ private boolean onlyOneNonNull (Object ... values ) {
137+ boolean haveOneNonNull = false ;
138+ for (Object o : values ) {
139+ if (o != null ) {
140+ if (haveOneNonNull ) {
141+ return false ;
142+ }
143+
144+ haveOneNonNull = true ;
145+ }
146+ }
147+
148+ return haveOneNonNull ;
149+ }
150+
96151 public Builder enableLegacyModes (boolean shouldEnableLegacyModes ) {
97152 this ._enableLegacyModes = shouldEnableLegacyModes ;
98153 return this ;
99154 }
100155
101156 public S3EncryptionClient build () {
102- if (_keyring != null && _cryptoMaterialsManager != null ) {
103- throw new S3EncryptionClientException ("Only one of: a keyring or a crypto materials manager can be supplied " );
157+ if (! onlyOneNonNull ( _cryptoMaterialsManager , _keyring , _aesKey , _rsaKeyPair , _kmsKeyId ) ) {
158+ throw new S3EncryptionClientException ("Exactly one must be set of: crypto materials manager, keyring, AES key, RSA key pair, KMS key id " );
104159 }
105160
106- if (_keyring != null ) {
107- if (_keyring instanceof LegacyKeyring ) {
108- throw new S3EncryptionClientException ("Configure manually a crypto materials manager when using a legacy keyring" );
161+ if (_keyring == null ) {
162+ if (_aesKey != null ) {
163+ _keyring = AesKeyring .builder ()
164+ .wrappingKey (_aesKey )
165+ .enableLegacyModes (_enableLegacyModes )
166+ .build ();
167+ } else if (_rsaKeyPair != null ) {
168+ _keyring = RsaKeyring .builder ()
169+ .wrappingKeyPair (_rsaKeyPair )
170+ .enableLegacyModes (_enableLegacyModes )
171+ .build ();
172+ } else if (_kmsKeyId != null ) {
173+ _keyring = KmsKeyring .builder ()
174+ .wrappingKeyId (_kmsKeyId )
175+ .enableLegacyModes (_enableLegacyModes )
176+ .build ();
109177 }
178+ }
110179
111- this ._cryptoMaterialsManager = DefaultCryptoMaterialsManager .builder ()
180+ if (_cryptoMaterialsManager == null ) {
181+ _cryptoMaterialsManager = DefaultCryptoMaterialsManager .builder ()
112182 .keyring (_keyring )
113183 .build ();
114184 }
115185
116- if (!_enableLegacyModes && _cryptoMaterialsManager instanceof LegacyDecryptCryptoMaterialsManager ) {
117- throw new S3EncryptionClientException ("Enable legacy modes to use a legacy crypto materials manager" );
118- }
119-
120186 return new S3EncryptionClient (this );
121187 }
122188 }
0 commit comments