Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
plain java key management for non aws environment

move from postgres to aws/ non aws profile
  • Loading branch information
mrFlick72 committed Nov 1, 2024
1 parent 17db58c commit f7117c9
Show file tree
Hide file tree
Showing 15 changed files with 177 additions and 31 deletions.
9 changes: 3 additions & 6 deletions local-environment/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,8 @@ cd ../../../../../communication/default/mail
cp * ../../../dist/mail/templates
```

## Postgres usage
## Installation in a NON AWS Environment

Postgres is an available option as storage, it is experimental right now, and it is supported only for account and roles.
Postgres and plain java key management is an available option

In order to activate it is needed to add the corresponding spring profile '''experimental_database_persistence''' and
for the init process add to the docker run the environment variable '''experimental_database_persistence=true'''with the command like below:

> docker run --pull=always -e experimental_database_persistence=true -it mrflick72/vauthenticator-local-tenant-installer:latest
In order to activate aws native service usage like KMS, DynamoDB and so on please use the spring profile '''aws''' default otherwise
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class AccountConfig {


@Bean("accountRepository")
@Profile("experimental_database_persistence")
@Profile("aws")
fun jdbcAccountRepository(
jdbcTemplate: JdbcTemplate
) = JdbcAccountRepository(jdbcTemplate)
Expand All @@ -68,7 +68,7 @@ class AccountConfig {
havingValue = "false",
matchIfMissing = true
)
@Profile("!experimental_database_persistence")
@Profile("!aws")
fun dynamoDbAccountRepository(
mapper: ObjectMapper,
dynamoDbClient: DynamoDbClient,
Expand All @@ -85,7 +85,7 @@ class AccountConfig {
havingValue = "true",
matchIfMissing = false
)
@Profile("!experimental_database_persistence")
@Profile("!aws")
fun cachedDynamoDbAccountRepository(
mapper: ObjectMapper,
dynamoDbClient: DynamoDbClient,
Expand All @@ -106,7 +106,7 @@ class AccountConfig {
havingValue = "true",
matchIfMissing = false
)
@Profile("!experimental_database_persistence")
@Profile("!aws")
fun accountCacheOperation(
redisTemplate: RedisTemplate<*, *>,
@Value("\${vauthenticator.dynamo-db.account.cache.ttl}") ttl: Duration,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,14 @@ class AuthorizationServerConfig {
}

@Bean("oAuth2AuthorizationService")
@Profile("!experimental_database_persistence")
@Profile("!aws")
fun redisOAuth2AuthorizationService(redisTemplate: RedisTemplate<Any, Any>): OAuth2AuthorizationService {
return RedisOAuth2AuthorizationService(redisTemplate)
}


@Bean("oAuth2AuthorizationService")
@Profile("experimental_database_persistence")
@Profile("aws")
fun jdbcOAuth2AuthorizationService(
jdbcTemplate : JdbcTemplate,
registeredClientRepository : RegisteredClientRepository
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ import org.springframework.context.annotation.Profile

@Configuration
@EnableAutoConfiguration(exclude = [DataSourceAutoConfiguration::class, DataSourceTransactionManagerAutoConfiguration::class, HibernateJpaAutoConfiguration::class])
@Profile("!experimental_database_persistence")
@Profile("!aws")
class ExcludeDatabaseConfig

34 changes: 28 additions & 6 deletions src/main/kotlin/com/vauthenticator/server/keys/KeyConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ import com.vauthenticator.server.keys.adapter.dynamo.DynamoDbKeyStorage
import com.vauthenticator.server.keys.adapter.jdbc.JdbcKeyStorage
import com.vauthenticator.server.keys.adapter.kms.KmsKeyDecrypter
import com.vauthenticator.server.keys.adapter.kms.KmsKeyGenerator
import com.vauthenticator.server.keys.adapter.local.BouncyCastleKeyDecrypter
import com.vauthenticator.server.keys.adapter.local.BouncyCastleKeyGenerator
import com.vauthenticator.server.keys.adapter.local.BouncyCastleKeyGeneratorMasterKeyRepository
import com.vauthenticator.server.keys.adapter.local.KeyCryptographicOperations
import com.vauthenticator.server.keys.domain.*
import org.springframework.beans.factory.annotation.Value
import org.springframework.context.annotation.Bean
Expand All @@ -18,14 +22,32 @@ import java.util.*
@Configuration(proxyBeanMethods = false)
class KeyConfig {

@Bean
fun keyGenerator(kmsClient: KmsClient): KeyGenerator = KmsKeyGenerator(kmsClient)
@Profile("aws")
@Bean("keyGenerator")
fun kmsKeyGenerator(kmsClient: KmsClient): KeyGenerator = KmsKeyGenerator(kmsClient)

@Bean
fun keyDecrypter(kmsClient: KmsClient): KeyDecrypter = KmsKeyDecrypter(kmsClient)
@Profile("!aws")
@Bean("keyGenerator")
fun bouncyCastleKeyGenerator(kmsClient: KmsClient): KeyGenerator = BouncyCastleKeyGenerator(
KeyCryptographicOperations(
BouncyCastleKeyGeneratorMasterKeyRepository()
)
)

@Profile("aws")
@Bean("keyDecrypter")
fun kmsKeyDecrypter(kmsClient: KmsClient): KeyDecrypter = KmsKeyDecrypter(kmsClient)

@Profile("!aws")
@Bean("keyDecrypter")
fun bouncyCastleKeyDecrypter(): KeyDecrypter = BouncyCastleKeyDecrypter(
KeyCryptographicOperations(
BouncyCastleKeyGeneratorMasterKeyRepository()
)
)

@Bean("keyStorage")
@Profile("!experimental_database_persistence")
@Profile("!aws")
fun dynamoDbKeyStorage(
clock: Clock,
dynamoDbClient: DynamoDbClient,
Expand All @@ -34,7 +56,7 @@ class KeyConfig {
) = DynamoDbKeyStorage(clock, dynamoDbClient, signatureTableName, mfaTableName)

@Bean("keyStorage")
@Profile("experimental_database_persistence")
@Profile("aws")
fun jdbcKeyStorage(jdbcTemplate: JdbcTemplate, clock: Clock) = JdbcKeyStorage(jdbcTemplate, clock)

@Bean("keyRepository")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.vauthenticator.server.keys.adapter.local

import com.vauthenticator.server.extentions.encoder
import com.vauthenticator.server.keys.domain.KeyDecrypter
import com.vauthenticator.server.keys.domain.MasterKid

class BouncyCastleKeyDecrypter(private val keyCryptographicOperations: KeyCryptographicOperations) : KeyDecrypter {
override fun decryptKey(encrypted: String): String {
return encoder.encode(keyCryptographicOperations.decryptKeyWith(MasterKid(""), encrypted.toByteArray()))
.decodeToString()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.vauthenticator.server.keys.adapter.local

import com.vauthenticator.server.keys.domain.DataKey
import com.vauthenticator.server.keys.domain.KeyGenerator
import com.vauthenticator.server.keys.domain.MasterKid
import java.util.*


class BouncyCastleKeyGenerator(
private val keyCryptographicOperations: KeyCryptographicOperations
) : KeyGenerator {


override fun dataKeyPairFor(masterKid: MasterKid): DataKey {
val generateRSAKeyPair = keyCryptographicOperations.generateRSAKeyPair()
return DataKey(
keyCryptographicOperations.encryptKeyWith(masterKid, generateRSAKeyPair.private.encoded),
Optional.of(generateRSAKeyPair.public.encoded)
)
}

override fun dataKeyFor(masterKid: MasterKid): DataKey {
val generateRSAKeyPair = keyCryptographicOperations.generateRSAKeyPair()
return DataKey(
keyCryptographicOperations.encryptKeyWith(masterKid, generateRSAKeyPair.private.encoded),
Optional.empty()
)
}



}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.vauthenticator.server.keys.adapter.local

import com.vauthenticator.server.extentions.toSha256
import com.vauthenticator.server.keys.domain.MasterKid
val toSha256 = "secret".toSha256()

class BouncyCastleKeyGeneratorMasterKeyRepository {

//TODO to improve
fun maskerKeyFor(masterKeyId: MasterKid): String {
return toSha256
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.vauthenticator.server.keys.adapter.local

import com.vauthenticator.server.extentions.decoder
import com.vauthenticator.server.keys.domain.MasterKid
import org.bouncycastle.jce.provider.BouncyCastleProvider
import java.security.KeyPair
import java.security.KeyPairGenerator
import java.security.Security
import java.security.spec.RSAKeyGenParameterSpec
import javax.crypto.Cipher
import javax.crypto.spec.SecretKeySpec


class KeyCryptographicOperations(
private val repository: BouncyCastleKeyGeneratorMasterKeyRepository,
) {
companion object {
init {
Security.addProvider(BouncyCastleProvider());
}
}

fun generateRSAKeyPair(): KeyPair {
val keyPair: KeyPair
try {
val keyPairGenerator = KeyPairGenerator.getInstance("RSA", "BC")
keyPairGenerator.initialize(RSAKeyGenParameterSpec(2048, RSAKeyGenParameterSpec.F4))
keyPair = keyPairGenerator.generateKeyPair()
} catch (ex: Exception) {
throw IllegalStateException(ex)
}
return keyPair
}

fun encryptKeyWith(masterKid: MasterKid, encodedPlainText: ByteArray): ByteArray {
val masterKey = repository.maskerKeyFor(masterKid);
val key = SecretKeySpec(masterKey.toByteArray(), "AES")
val cipher = Cipher.getInstance("AES")
cipher.init(Cipher.ENCRYPT_MODE, key)
return cipher.doFinal(decoder.decode(encodedPlainText))
}

fun decryptKeyWith(masterKid: MasterKid, encodedEncryptedText: ByteArray): ByteArray {
val masterKey = repository.maskerKeyFor(masterKid);
val key = SecretKeySpec(masterKey.toByteArray(), "AES")
val cipher = Cipher.getInstance("AES")
cipher.init(Cipher.DECRYPT_MODE, key)
return cipher.doFinal(decoder.decode(encodedEncryptedText))
}


}
4 changes: 2 additions & 2 deletions src/main/kotlin/com/vauthenticator/server/mfa/MfaConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import java.util.*
class MfaConfig {

@Bean("mfaAccountMethodsRepository")
@Profile("!experimental_database_persistence")
@Profile("!aws")
fun dynamoDbMfaAccountMethodsRepository(
keyRepository: KeyRepository,
dynamoDbClient: DynamoDbClient,
Expand All @@ -52,7 +52,7 @@ class MfaConfig {
) { MfaDeviceId(UUID.randomUUID().toString()) }

@Bean("mfaAccountMethodsRepository")
@Profile("experimental_database_persistence")
@Profile("aws")
fun jdbcMfaAccountMethodsRepository(
keyRepository: KeyRepository,
jdbcTemplate: JdbcTemplate,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class ClientApplicationConfig {


@Bean("clientApplicationRepository")
@Profile("experimental_database_persistence")
@Profile("aws")
fun jdbcClientApplicationRepository(jdbcTemplate: JdbcTemplate, objectMapper: ObjectMapper) : ClientApplicationRepository =
JdbcClientApplicationRepository(jdbcTemplate, objectMapper)

Expand All @@ -39,7 +39,7 @@ class ClientApplicationConfig {
havingValue = "false",
matchIfMissing = true
)
@Profile("!experimental_database_persistence")
@Profile("!aws")
fun dynamoDbClientApplicationRepository(
dynamoDbClient: DynamoDbClient,
@Value("\${vauthenticator.dynamo-db.client-application.table-name}") clientAppTableName: String
Expand All @@ -51,7 +51,7 @@ class ClientApplicationConfig {
havingValue = "true",
matchIfMissing = false
)
@Profile("!experimental_database_persistence")
@Profile("!aws")
fun cachedClientApplicationRepository(
dynamoDbClient: DynamoDbClient,
clientApplicationCacheOperation: CacheOperation<String, String>,
Expand All @@ -70,7 +70,7 @@ class ClientApplicationConfig {
havingValue = "true",
matchIfMissing = false
)
@Profile("!experimental_database_persistence")
@Profile("!aws")
fun clientApplicationCacheOperation(
redisTemplate: RedisTemplate<*, *>,
@Value("\${vauthenticator.dynamo-db.client-application.cache.ttl}") ttl: Duration,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import java.time.Duration
class PermissionConfig {

@Bean("roleRepository")
@Profile("experimental_database_persistence")
@Profile("aws")
fun jdbcRoleRepository(
jdbcTemplate: JdbcTemplate,
@Value("\${vauthenticator.dynamo-db.role.protected-from-delete}") protectedRoleFromDeletion: List<String>
Expand All @@ -35,7 +35,7 @@ class PermissionConfig {
havingValue = "false",
matchIfMissing = true
)
@Profile("!experimental_database_persistence")
@Profile("!aws")
fun dynamoDbRoleRepository(
dynamoDbClient: DynamoDbClient,
@Value("\${vauthenticator.dynamo-db.role.table-name}") roleTableName: String,
Expand All @@ -49,7 +49,7 @@ class PermissionConfig {
havingValue = "true",
matchIfMissing = false
)
@Profile("!experimental_database_persistence")
@Profile("!aws")
fun cachedDynamoDbRoleRepository(
mapper: ObjectMapper,
roleCacheOperation: CacheOperation<String, String>,
Expand All @@ -68,7 +68,7 @@ class PermissionConfig {
havingValue = "true",
matchIfMissing = false
)
@Profile("!experimental_database_persistence")
@Profile("!aws")
fun roleCacheOperation(
redisTemplate: RedisTemplate<*, *>,
@Value("\${vauthenticator.dynamo-db.role.cache.ttl}") ttl: Duration,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ import java.util.*
class TicketConfig {

@Bean("ticketRepository")
@Profile("!experimental_database_persistence")
@Profile("!aws")
fun dynamoDbTicketRepository(
@Value("\${vauthenticator.dynamo-db.ticket.table-name}") tableName: String,
dynamoDbClient: DynamoDbClient
) = DynamoDbTicketRepository(dynamoDbClient, tableName)


@Bean("ticketRepository")
@Profile("experimental_database_persistence")
@Profile("aws")
fun jdbCTicketRepository(
jdbcTemplate: JdbcTemplate,
objectMapper: ObjectMapper
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.vauthenticator.server.keys.adapter.kms

import org.junit.jupiter.api.Assertions.*

class KmsKeyGeneratorTest {


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.vauthenticator.server.keys.adapter.local

import org.junit.jupiter.api.Assertions.*

class BouncyCastleKeyGeneratorTest {



}

0 comments on commit f7117c9

Please sign in to comment.