Crypto code polish. wrapped crypto stuff in try/catch
This commit is contained in:
parent
2b2e185c4a
commit
1040cf14f5
|
@ -16,7 +16,6 @@
|
|||
package dorkbox.network.connection
|
||||
|
||||
import dorkbox.netUtil.IP
|
||||
import dorkbox.network.Configuration
|
||||
import dorkbox.network.handshake.ClientConnectionInfo
|
||||
import dorkbox.network.serialization.AeronInput
|
||||
import dorkbox.network.serialization.AeronOutput
|
||||
|
@ -30,9 +29,9 @@ import java.net.InetAddress
|
|||
import java.security.KeyFactory
|
||||
import java.security.KeyPairGenerator
|
||||
import java.security.MessageDigest
|
||||
import java.security.PrivateKey
|
||||
import java.security.PublicKey
|
||||
import java.security.SecureRandom
|
||||
import java.security.interfaces.XECPrivateKey
|
||||
import java.security.interfaces.XECPublicKey
|
||||
import java.security.spec.NamedParameterSpec
|
||||
import java.security.spec.XECPrivateKeySpec
|
||||
import java.security.spec.XECPublicKeySpec
|
||||
|
@ -45,34 +44,38 @@ import javax.crypto.spec.SecretKeySpec
|
|||
/**
|
||||
* Management for all of the crypto stuff used
|
||||
*/
|
||||
internal class CryptoManagement(val logger: KLogger, private val settingsStore: SettingsStore, type: Class<*>, config: Configuration) {
|
||||
internal class CryptoManagement(val logger: KLogger,
|
||||
private val settingsStore: SettingsStore,
|
||||
type: Class<*>,
|
||||
private val enableRemoteSignatureValidation: Boolean) {
|
||||
|
||||
private val X25519 = "X25519"
|
||||
private val X25519KeySpec = NamedParameterSpec(X25519)
|
||||
private val keyFactory = KeyFactory.getInstance(X25519) // key size is 32 bytes
|
||||
|
||||
private val keyFactory = KeyFactory.getInstance(X25519) // key size is 32 bytes (256 bits)
|
||||
private val keyAgreement = KeyAgreement.getInstance("XDH")
|
||||
|
||||
private val aesCipher = Cipher.getInstance("AES/GCM/PKCS5Padding")
|
||||
private val hash = MessageDigest.getInstance("SHA-256");
|
||||
|
||||
companion object {
|
||||
const val curve25519 = "curve25519"
|
||||
const val AES_KEY_SIZE = 256
|
||||
const val GCM_IV_LENGTH = 12
|
||||
const val GCM_TAG_LENGTH = 16
|
||||
const val GCM_IV_LENGTH_BYTES = 12
|
||||
const val GCM_TAG_LENGTH_BITS = 128
|
||||
}
|
||||
|
||||
val privateKey: PrivateKey
|
||||
val publicKey: PublicKey
|
||||
val privateKey: XECPrivateKey
|
||||
val publicKey: XECPublicKey
|
||||
|
||||
val privateKeyBytes: ByteArray
|
||||
val publicKeyBytes: ByteArray
|
||||
|
||||
val secureRandom = SecureRandom(settingsStore.getSalt())
|
||||
private val secureRandom = SecureRandom(settingsStore.getSalt())
|
||||
|
||||
private val iv = ByteArray(GCM_IV_LENGTH)
|
||||
private val iv = ByteArray(GCM_IV_LENGTH_BYTES)
|
||||
val cryptOutput = AeronOutput()
|
||||
val cryptInput = AeronInput()
|
||||
|
||||
private val enableRemoteSignatureValidation = config.enableRemoteSignatureValidation
|
||||
|
||||
init {
|
||||
if (!enableRemoteSignatureValidation) {
|
||||
logger.warn("WARNING: Disabling remote key validation is a security risk!!")
|
||||
|
@ -109,8 +112,10 @@ internal class CryptoManagement(val logger: KLogger, private val settingsStore:
|
|||
|
||||
logger.info("ECC public key: ${Sys.bytesToHex(publicKeyBytes)}")
|
||||
|
||||
this.publicKey = keyFactory.generatePublic(XECPublicKeySpec(X25519KeySpec, BigInteger(publicKeyBytes)))
|
||||
this.privateKey = keyFactory.generatePrivate(XECPrivateKeySpec(X25519KeySpec, privateKeyBytes))
|
||||
this.publicKey = keyFactory.generatePublic(XECPublicKeySpec(X25519KeySpec, BigInteger(publicKeyBytes))) as XECPublicKey
|
||||
this.privateKey = keyFactory.generatePrivate(XECPrivateKeySpec(X25519KeySpec, privateKeyBytes)) as XECPrivateKey
|
||||
|
||||
this.privateKeyBytes = privateKeyBytes!!
|
||||
this.publicKeyBytes = publicKeyBytes!!
|
||||
}
|
||||
|
||||
|
@ -189,9 +194,11 @@ internal class CryptoManagement(val logger: KLogger, private val settingsStore:
|
|||
connectionStreamId: Int,
|
||||
kryoRegDetails: ByteArray): ByteArray {
|
||||
|
||||
try {
|
||||
val secretKeySpec = generateAesKey(clientPublicKeyBytes, clientPublicKeyBytes, publicKeyBytes)
|
||||
secureRandom.nextBytes(iv)
|
||||
val gcmParameterSpec = GCMParameterSpec(GCM_TAG_LENGTH * 8, iv)
|
||||
|
||||
val gcmParameterSpec = GCMParameterSpec(GCM_TAG_LENGTH_BITS, iv)
|
||||
aesCipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, gcmParameterSpec)
|
||||
|
||||
// now create the byte array that holds all our data
|
||||
|
@ -204,28 +211,22 @@ internal class CryptoManagement(val logger: KLogger, private val settingsStore:
|
|||
cryptOutput.writeBytes(kryoRegDetails)
|
||||
|
||||
return iv + aesCipher.doFinal(cryptOutput.toBytes())
|
||||
} catch (e: Exception) {
|
||||
logger.error("Error during AES encrypt", e)
|
||||
return ByteArray(0)
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: ALWAYS CALLED ON THE SAME THREAD! (from the client, mutually exclusive calls to encrypt)
|
||||
fun decrypt(registrationData: ByteArray?, serverPublicKeyBytes: ByteArray?): ClientConnectionInfo? {
|
||||
if (registrationData == null || serverPublicKeyBytes == null) {
|
||||
return null
|
||||
}
|
||||
|
||||
fun decrypt(registrationData: ByteArray, serverPublicKeyBytes: ByteArray): ClientConnectionInfo? {
|
||||
try {
|
||||
val secretKeySpec = generateAesKey(serverPublicKeyBytes, publicKeyBytes, serverPublicKeyBytes)
|
||||
|
||||
// now read the encrypted data
|
||||
registrationData.copyInto(destination = iv, endIndex = GCM_IV_LENGTH)
|
||||
|
||||
val secretBytes = ByteArray(registrationData.size - GCM_IV_LENGTH)
|
||||
registrationData.copyInto(destination = secretBytes, startIndex = GCM_IV_LENGTH)
|
||||
|
||||
|
||||
// now decrypt the data
|
||||
val gcmParameterSpec = GCMParameterSpec(GCM_TAG_LENGTH * 8, iv)
|
||||
val gcmParameterSpec = GCMParameterSpec(GCM_TAG_LENGTH_BITS, registrationData, 0, GCM_IV_LENGTH_BYTES)
|
||||
aesCipher.init(Cipher.DECRYPT_MODE, secretKeySpec, gcmParameterSpec)
|
||||
|
||||
cryptInput.buffer = aesCipher.doFinal(secretBytes)
|
||||
cryptInput.buffer = aesCipher.doFinal(registrationData, GCM_IV_LENGTH_BYTES, registrationData.size - GCM_IV_LENGTH_BYTES)
|
||||
|
||||
val sessionId = cryptInput.readInt()
|
||||
val streamId = cryptInput.readInt()
|
||||
|
@ -241,6 +242,10 @@ internal class CryptoManagement(val logger: KLogger, private val settingsStore:
|
|||
subscriptionPort = subscriptionPort,
|
||||
publicKey = serverPublicKeyBytes,
|
||||
kryoRegistrationDetails = regDetails)
|
||||
} catch (e: Exception) {
|
||||
logger.error("Error during AES decrypt!", e)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
|
|
|
@ -130,7 +130,7 @@ internal constructor(val type: Class<*>, internal val config: Configuration) : A
|
|||
// we have to be able to specify the property store
|
||||
settingsStore = createSettingsStore(logger)
|
||||
|
||||
crypto = CryptoManagement(logger, settingsStore, type, config)
|
||||
crypto = CryptoManagement(logger, settingsStore, type, config.enableRemoteSignatureValidation)
|
||||
|
||||
// Only starts the media driver if we are NOT already running!
|
||||
try {
|
||||
|
|
Loading…
Reference in New Issue
Block a user