Skip to content

Commit

Permalink
cleanup android key agreement auth
Browse files Browse the repository at this point in the history
  • Loading branch information
JesusMcCloud committed Jan 14, 2025
1 parent 496dd0b commit f77d295
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 32 deletions.
1 change: 1 addition & 0 deletions docs/docs/features.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ from certain (otherwise) hard requirements for Devices launched with later Andro
Hence, a device launched with Android 10, and later updated to Android 12 may still not support key agreement in
hardware.
The Supreme crypto provider will return a failure, in if key agreement is not supported in hardware.
TODO: will fail for auth on every use! Bug in Android; fix hidden behind a feature flag

## Supported Algorithms

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import at.asitplus.signum.supreme.os.PlatformSigningProvider
import at.asitplus.signum.supreme.os.PlatformSigningProviderSignerSigningConfigurationBase
import at.asitplus.signum.supreme.os.needsAuthenticationForEveryUse
import at.asitplus.signum.supreme.sign.Signer
import org.w3c.dom.Notation

actual suspend fun Signer.ECDSA.performAgreement(
publicKey: CryptoPublicKey.EC,
Expand All @@ -24,31 +25,22 @@ actual suspend fun Signer.ECDSA.performAgreement(

return if (this is AndroidKeystoreSigner) {
val resolvedConfig = DSL.resolve(::AndroidSignerSigningConfiguration, config)
javax.crypto.KeyAgreement.getInstance("ECDH", "AndroidKeyStore").also {

if (needsAuthenticationForEveryUse) {
val agreement = javax.crypto.KeyAgreement.getInstance("ECDH", "AndroidKeyStore").also {
try {
it.init(jcaPrivateKey)
} catch (_: UserNotAuthenticatedException) {
attemptBiometry(
DSL.ConfigStack(resolvedConfig.unlockPrompt.v, resolvedConfig.unlockPrompt.v),
null //TODO ????
DSL.ConfigStack(
resolvedConfig.unlockPrompt.v,
resolvedConfig.unlockPrompt.v //TODO
),
null
)
} else {
try {
it.init(jcaPrivateKey)
} catch (_: UserNotAuthenticatedException) {
attemptBiometry(
DSL.ConfigStack(
resolvedConfig.unlockPrompt.v,
resolvedConfig.unlockPrompt.v
),
null
)
it.init(jcaPrivateKey)
}
it.init(jcaPrivateKey)
}
it.doPhase(publicKey.toJcaPublicKey().getOrThrow(), true)
}.generateSecret()

}
agreement.doPhase(publicKey.toJcaPublicKey().getOrThrow(), true)
agreement.generateSecret()
} else {
javax.crypto.KeyAgreement.getInstance("ECDH", "AndroidKeyStore").also {
@OptIn(HazardousMaterials::class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ object AndroidKeyStoreProvider:
KeyPairGenerator.getInstance(when(config._algSpecific.v) {
is SigningKeyConfiguration.RSAConfiguration -> KeyProperties.KEY_ALGORITHM_RSA
is SigningKeyConfiguration.ECConfiguration -> KeyProperties.KEY_ALGORITHM_EC
}, "AndroidKeyStore").apply {
}, "AndroidKeyStore"/*TODO not for ephemeral key*/).apply {
initialize(spec)
}.generateKeyPair()
return@catching getSignerForKey(alias, config.signer.v).getOrThrow()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,18 @@ suspend fun Signer.ECDSA.keyAgreement(
performAgreement(publicKey, config)
}

/**
* Elliptic-curve Diffie-Hellman key agreement.
* Curves of public key and signer need to match!
*
* [config] can be used to display a custom authentication prompt
*/
suspend fun CryptoPublicKey.EC.keyAgreement(
signer: Signer.ECDSA,
config: DSLConfigureFn<PlatformSigningProviderSignerSigningConfigurationBase> = null
) = signer.keyAgreement(this, config)


/**
* Elliptic-curve Diffie-Hellman key agreement.
* Curves of public key and signer need to match!
Expand All @@ -44,16 +56,6 @@ suspend fun CryptoPrivateKey.WithPublicKey<CryptoPublicKey.EC>.keyAgreement(publ
suspend fun CryptoPublicKey.EC.keyAgreement(privateKey: CryptoPrivateKey.WithPublicKey<CryptoPublicKey.EC>) =
privateKey.keyAgreement(this)

/**
* Elliptic-curve Diffie-Hellman key agreement.
* Curves of public key and signer need to match!
*
* [config] can be used to display a custom authentication prompt
*/
suspend fun CryptoPublicKey.EC.keyAgreement(
signer: Signer.ECDSA,
config: DSLConfigureFn<PlatformSigningProviderSignerSigningConfigurationBase> = null
) = signer.keyAgreement(this, config)

internal expect suspend fun Signer.ECDSA.performAgreement(
publicKey: CryptoPublicKey.EC,
Expand Down

0 comments on commit f77d295

Please sign in to comment.