diff --git a/build.gradle b/build.gradle index 01815d0b..cac9f1cf 100644 --- a/build.gradle +++ b/build.gradle @@ -112,7 +112,9 @@ configure(project(':seedprovider')) { } dependencies { - compile 'org.apache.cassandra:cassandra-all:3.0.10' + compile 'org.apache.cassandra:cassandra-all:3.9' + compile ('com.amazonaws:aws-java-sdk-core:1.11.49'){force = true} + compile 'com.amazonaws:aws-java-sdk:1.11.49' } } diff --git a/seedprovider/build.gradle b/seedprovider/build.gradle index 7f900dd0..b6f7b816 100644 --- a/seedprovider/build.gradle +++ b/seedprovider/build.gradle @@ -1,4 +1,5 @@ apply plugin: 'maven-publish' +apply plugin: 'eclipse' publishing { publications { @@ -8,11 +9,27 @@ publishing { } } +dependencies { + compile ('com.amazonaws:aws-java-sdk-core:1.11.49'){force = true} + compile 'com.amazonaws:aws-java-sdk:1.11.49' + } + +task fatJar(type: Jar) { + manifest { + attributes 'Implementation-Title': 'Gradle Jar File Example', + 'Implementation-Version': 'version' + } + baseName = 'seedprovider' + from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } + with jar +} + publishing { repositories { maven parent.mavenRep } } + publishToMavenLocal.dependsOn(build) publish.dependsOn(build) diff --git a/seedprovider/src/main/java/com/mesosphere/dcos/cassandra/keyprovider/AdobeKmsKeyProvider.java b/seedprovider/src/main/java/com/mesosphere/dcos/cassandra/keyprovider/AdobeKmsKeyProvider.java new file mode 100644 index 00000000..12c6bcfa --- /dev/null +++ b/seedprovider/src/main/java/com/mesosphere/dcos/cassandra/keyprovider/AdobeKmsKeyProvider.java @@ -0,0 +1,113 @@ +package com.mesosphere.dcos.cassandra.keyprovider; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.nio.ByteBuffer; +import java.security.Key; +import java.security.KeyStore; +import java.util.Base64; + +import javax.crypto.spec.SecretKeySpec; + +import org.apache.cassandra.config.TransparentDataEncryptionOptions; +import org.apache.cassandra.security.KeyProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.amazonaws.auth.AWSCredentials; +import com.amazonaws.auth.BasicAWSCredentials; +import com.amazonaws.regions.Region; +import com.amazonaws.regions.Regions; +import com.amazonaws.services.kms.AWSKMSClient; +import com.amazonaws.services.kms.model.AWSKMSException; +import com.amazonaws.services.kms.model.DecryptRequest; +import com.amazonaws.services.kms.model.DecryptResult; +import com.mesosphere.dcos.cassandra.keyprovider.exception.KmsAccessException; + +public class AdobeKmsKeyProvider implements KeyProvider +{ + private static final Logger logger = LoggerFactory.getLogger(AdobeKmsKeyProvider.class); + static final String PROP_KEYSTORE = "keystore"; + static final String PROP_KEYSTORE_PW = "keystore_password"; + static final String PROP_KEYSTORE_TYPE = "store_type"; + static final String PROP_KEY_PW = "key_password"; + private final KeyStore store; + private final boolean isJceks; + private final TransparentDataEncryptionOptions options; + public AdobeKmsKeyProvider(TransparentDataEncryptionOptions options) + { + logger.info("arun: key adobekeyprovider"); + this.options = options; + store= null; + isJceks = true; +// logger.info("initializing keystore from file {}", options.get(PROP_KEYSTORE)); +// try +// { +// +// URL url = new URL("https://s3-us-west-1.amazonaws.com/cassandra-arun-bucket/adobe.keystore"); +// InputStream is = url.openStream(); +// store = KeyStore.getInstance(options.get(PROP_KEYSTORE_TYPE)); +// store.load(is, options.get(PROP_KEYSTORE_PW).toCharArray()); +// isJceks = store.getType().equalsIgnoreCase("jceks"); +// } +// catch (Exception e) +// { +// throw new RuntimeException("couldn't load keystore", e); +// } + } + public Key getSecretKey(String keyAlias) throws IOException + { + // there's a lovely behavior with jceks files that all aliases are lower-cased +// if (isJceks) +// keyAlias = keyAlias.toLowerCase(); +// Key key; +// try +// { +// String password = options.get(PROP_KEY_PW); +// if (password == null || password.isEmpty()) +// password = options.get(PROP_KEYSTORE_PW); +// key = store.getKey(keyAlias, password.toCharArray()); +// } +// catch (Exception e) +// { +// throw new IOException("unable to load key from keystore"); +// } +// if (key == null) +// throw new IOException(String.format("key %s was not found in keystore", keyAlias)); +// return key; + + logger.info("AdobeKmsKeyProvider going to load key from AWSKMS"); + try{ + String decryptDataKey = "AQEDAHgbHAx5l16Yxh+2rJYL40KbyL53JpAAJ64JrRkw4iA2RQAAAG4wbAYJKoZIhvcNAQcGoF8wXQIBADBYBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDMqDqemUdlfQC1EQGAIBEIArhWoMmXK07/BcnRbMyWCVurtAUknUH3nUyRLObCxZbTu3b5cfyTgFTF5Akw==";//Base64.getEncoder().encodeToString(generateDatakey.getCiphertextBlob().array()); + ByteBuffer decryptDataKeyByte = ByteBuffer.wrap(Base64.getDecoder().decode(decryptDataKey)); + + ByteBuffer datakey = getDatakeyDecrypted(decryptDataKeyByte); + final SecretKeySpec encryptionKey = new SecretKeySpec(datakey.array(), "AES"); + return encryptionKey; + }catch (KmsAccessException e) { + logger.error("Could not decrypt/load KMS:"+e.getMessage()); + throw new IOException("Could not decrypt/load KMS:"+e.getMessage()); + } + } + private static AWSKMSClient getKMSClient() { + AWSCredentials awsCredentials = new BasicAWSCredentials( + "AKIAILEX5VDPIBNW7U4Q", + "jPxpQ1zeBFVb6iDJIvc05RqBzYwjpdImxKCCKzIr"); + AWSKMSClient awskmsClient = new AWSKMSClient(awsCredentials); + awskmsClient.setRegion(Region.getRegion(Regions.fromName("us-west-1"))); + return awskmsClient; + } + + private static ByteBuffer getDatakeyDecrypted(ByteBuffer encryptedDatakey) throws KmsAccessException { + DecryptRequest decryptRequest = new DecryptRequest(); + decryptRequest.setCiphertextBlob(encryptedDatakey); + DecryptResult decryptResult; + try { + decryptResult = getKMSClient().decrypt(decryptRequest); + } catch (AWSKMSException e) { + throw new KmsAccessException("Could not decrypt KMS", e); + } + return decryptResult.getPlaintext(); + } +} diff --git a/seedprovider/src/main/java/com/mesosphere/dcos/cassandra/keyprovider/exception/KmsAccessException.java b/seedprovider/src/main/java/com/mesosphere/dcos/cassandra/keyprovider/exception/KmsAccessException.java new file mode 100644 index 00000000..f31ea229 --- /dev/null +++ b/seedprovider/src/main/java/com/mesosphere/dcos/cassandra/keyprovider/exception/KmsAccessException.java @@ -0,0 +1,19 @@ +package com.mesosphere.dcos.cassandra.keyprovider.exception; + +public class KmsAccessException extends Exception { + + public KmsAccessException() { + } + + public KmsAccessException(String message) { + super(message); + } + + public KmsAccessException(String message, Throwable cause) { + super(message, cause); + } + + public KmsAccessException(Throwable cause) { + super(cause); + } +}