Merge pull request #60 from yarivt/AMATERASU-81-82
CryptoUtil + AwsKms client for encryption/decryption
diff --git a/common/build.gradle b/common/build.gradle
index 38f2393..7a13c39 100644
--- a/common/build.gradle
+++ b/common/build.gradle
@@ -55,7 +55,10 @@
compile group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: '2.9.4'
compile group: 'com.fasterxml.jackson.module', name: 'jackson-module-kotlin', version: '2.9.8'
compile group: 'commons-validator', name: 'commons-validator', version: '1.6'
- compile group: 'software.amazon.awssdk', name: 's3', version: '2.5.23'
+
+ compile group: 'software.amazon.awssdk', name: 's3', version: '2.6.5'
+ compile group: 'software.amazon.awssdk', name: 'kms', version: '2.6.5'
+
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
compile "org.jetbrains.kotlin:kotlin-reflect"
diff --git a/common/src/main/kotlin/org/apache/amaterasu/common/crypto/AwsKmsCryptoProvider.kt b/common/src/main/kotlin/org/apache/amaterasu/common/crypto/AwsKmsCryptoProvider.kt
new file mode 100644
index 0000000..9be9e50
--- /dev/null
+++ b/common/src/main/kotlin/org/apache/amaterasu/common/crypto/AwsKmsCryptoProvider.kt
@@ -0,0 +1,53 @@
+package org.apache.amaterasu.common.crypto
+
+import com.amazonaws.services.identitymanagement.model.AccessKey
+import software.amazon.awssdk.auth.credentials.AwsBasicCredentials
+import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider
+import software.amazon.awssdk.auth.credentials.InstanceProfileCredentialsProvider
+import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider
+import software.amazon.awssdk.core.SdkBytes
+import software.amazon.awssdk.services.kms.KmsClient
+import software.amazon.awssdk.services.kms.model.DecryptRequest
+import software.amazon.awssdk.services.kms.model.EncryptRequest
+import software.amazon.awssdk.regions.Region
+
+class AwsKmsCryptoProvider(override val accessKeyId: String = "",
+ override val secretAccessKey: String = "",
+ override val region: String) : CryptoKeyProvider {
+
+ private var credentials: AwsCredentialsProvider = if (accessKeyId.isNotEmpty()) {
+ StaticCredentialsProvider.create(AwsBasicCredentials.create(accessKeyId, secretAccessKey))
+ } else {
+ InstanceProfileCredentialsProvider.builder().build()
+ }
+
+ val kmsClient = KmsClient.builder().apply {
+ credentialsProvider(credentials)
+ region(Region.of(region))
+ }.build()
+
+ override fun decryptKey(cipherText: ByteArray): String {
+
+ val decryptRequest = DecryptRequest.builder().apply {
+ ciphertextBlob(SdkBytes.fromByteArray(cipherText))
+ }.build()
+
+ val decryptedValue = kmsClient.decrypt(decryptRequest).plaintext()
+
+ return decryptedValue.asUtf8String()
+
+ }
+
+ override fun encryptKey(keyId: String, value: String): ByteArray? {
+
+ val encryptRequest = EncryptRequest.builder().apply {
+ keyId(keyId)
+ plaintext(SdkBytes.fromUtf8String(value))
+ }.build()
+
+ val encryptResponse = kmsClient.encrypt(encryptRequest)
+
+ return encryptResponse.ciphertextBlob().asByteArray()
+ }
+
+}
\ No newline at end of file
diff --git a/common/src/main/kotlin/org/apache/amaterasu/common/crypto/CryptoKeyProvider.kt b/common/src/main/kotlin/org/apache/amaterasu/common/crypto/CryptoKeyProvider.kt
new file mode 100644
index 0000000..dfa80bb
--- /dev/null
+++ b/common/src/main/kotlin/org/apache/amaterasu/common/crypto/CryptoKeyProvider.kt
@@ -0,0 +1,13 @@
+package org.apache.amaterasu.common.crypto
+
+interface CryptoKeyProvider {
+
+ val accessKeyId: String
+ val secretAccessKey: String
+ val region: String
+
+ fun decryptKey(cipherText: ByteArray): String
+
+ fun encryptKey(keyId: String, value: String): ByteArray?
+
+}
\ No newline at end of file
diff --git a/common/src/main/kotlin/org/apache/amaterasu/common/utils/CryptoUtils.kt b/common/src/main/kotlin/org/apache/amaterasu/common/utils/CryptoUtils.kt
new file mode 100644
index 0000000..599996f
--- /dev/null
+++ b/common/src/main/kotlin/org/apache/amaterasu/common/utils/CryptoUtils.kt
@@ -0,0 +1,15 @@
+package org.apache.amaterasu.common.utils
+
+import org.apache.amaterasu.common.crypto.CryptoKeyProvider
+
+class CryptoUtils(private val keyProvider: CryptoKeyProvider) {
+
+ fun decryptKey(encryptedKey: ByteArray): String {
+ return keyProvider.decryptKey(encryptedKey)
+ }
+
+ fun encryptKey(keyId: String, value: String): ByteArray? {
+ return keyProvider.encryptKey(keyId, value)
+ }
+
+}
\ No newline at end of file
diff --git a/common/src/test/kotlin/org/apache/amaterasu/common/utils/CryptoUtilsTest.kt b/common/src/test/kotlin/org/apache/amaterasu/common/utils/CryptoUtilsTest.kt
new file mode 100644
index 0000000..2cd23cb
--- /dev/null
+++ b/common/src/test/kotlin/org/apache/amaterasu/common/utils/CryptoUtilsTest.kt
@@ -0,0 +1,33 @@
+package org.apache.amaterasu.common.utils
+
+import org.apache.amaterasu.common.crypto.AwsKmsCryptoProvider
+import org.jetbrains.spek.api.Spek
+import org.jetbrains.spek.api.dsl.given
+import org.jetbrains.spek.api.dsl.it
+import org.jetbrains.spek.api.dsl.on
+import org.junit.Assert.*
+
+
+//class CryptoUtilsTest : Spek({
+//
+// given("an aws key and value") {
+// val keyId = "arn:aws:kms:"
+// val clearText = "Value to encrypt"
+//
+// on ("encrypting and decrypting") {
+//
+// val kmsClient = CryptoUtils(AwsKmsCryptoProvider(
+// accessKeyId = "",
+// secretAccessKey = "",
+// region = "ap-southeast-2"))
+// val encryptedText = kmsClient.encryptKey(keyId, clearText)!!
+//
+// val decryptedText = kmsClient.decryptKey(encryptedText)
+//
+// it("decrypted value is the same as the clear text") {
+// assertEquals(clearText, decryptedText)
+// }
+// }
+// }
+//
+//})
\ No newline at end of file