com.distelli.crypto.impl.KeyProviderImpl Maven / Gradle / Ivy
The newest version!
package com.distelli.crypto.impl;
import com.amazonaws.ClientConfiguration;
import com.amazonaws.services.kms.AWSKMS;
import com.amazonaws.services.kms.AWSKMSClient;
import com.amazonaws.services.kms.model.DecryptRequest;
import com.distelli.aws.AWSCredentialsProviderFactory;
import com.distelli.aws.AmazonWebServiceClients;
import com.distelli.aws.ClientConfigurations;
import com.distelli.cred.CredProvider;
import com.distelli.crypto.KeyId;
import com.distelli.crypto.KeyProvider;
import java.net.URI;
import java.nio.ByteBuffer;
import java.security.Key;
import javax.crypto.spec.SecretKeySpec;
import javax.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class KeyProviderImpl implements KeyProvider {
private static final Logger LOG = LoggerFactory.getLogger(KeyProviderImpl.class);
private Key _key;
public static class Builder implements KeyProvider.Builder {
@Inject
private AWSCredentialsProviderFactory _credProviderFactory;
@Inject
private ClientConfigurations _clientConfigurations;
@Inject
private AmazonWebServiceClients _amazonWebServiceClients;
private URI endpoint;
private URI proxy;
private CredProvider credProvider;
private byte[] key;
@Override
public Builder withCredProvider(CredProvider credProvider) {
this.credProvider = credProvider;
return this;
}
@Override
public Builder withEndpoint(URI uri) {
this.endpoint = uri;
return this;
}
@Override
public Builder withProxy(URI uri) {
this.proxy = uri;
return this;
}
@Override
public Builder withKey(byte[] key) {
this.key = key;
return this;
}
@Override
public KeyProvider build() {
if ( null == key || 0 == key.length ) {
return new KeyProviderImpl(null);
} else if ( 16 == key.length ) {
return new KeyProviderImpl(new SecretKeySpec(key, "AES"));
}
AWSKMS kms = _amazonWebServiceClients.withEndpoint(
new AWSKMSClient(
_credProviderFactory.create(credProvider),
_clientConfigurations.withProxy(new ClientConfiguration(), proxy)),
endpoint);
key = kms.decrypt(new DecryptRequest()
.withCiphertextBlob(ByteBuffer.wrap(key)))
.getPlaintext().array();
if ( 16 != key.length ) {
LOG.warn("Expected decrypted key to be exactly 16 bytes, got "+key.length+" bytes. Please "+
"verify the key was not base64 encoded before encrypting with KMS");
return new KeyProviderImpl(null);
}
return new KeyProviderImpl(new SecretKeySpec(key, "AES"));
}
}
private KeyProviderImpl(Key key) {
_key = key;
}
@Override
public Key getKey(long id) {
if ( id != 1 ) throw new UnsupportedOperationException("Currently only key id=1 is supported, got key id="+id);
return _key;
}
@Override
public KeyId getLatestKey() {
if ( null == _key ) return null;
return new KeyId().withId(1L).withKey(_key);
}
}