Skip to content

Commit

Permalink
Revert "Use Signed + Encrypted JWTs for CNonce."
Browse files Browse the repository at this point in the history
This reverts commit b987408.
  • Loading branch information
dzarras committed Nov 14, 2024
1 parent b987408 commit 025492e
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 78 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -362,8 +362,8 @@ fun beans(clock: Clock) = beans {
// CNonce
//
bean { DefaultGenerateCNonce(clock = clock, expiresIn = Duration.ofMinutes(5L)) }
bean { EncryptCNonceWithNimbus(issuerPublicUrl, ref(), ref<RSAKey>("cnonce-encryption-key")) }
bean { DecryptCNonceWithNimbus(issuerPublicUrl, ref<RSAKey>("cnonce-encryption-key"), ref()) }
bean { EncryptCNonceWithNimbus(issuerPublicUrl, ref<RSAKey>("cnonce-encryption-key")) }
bean { DecryptCNonceWithNimbus(issuerPublicUrl, ref<RSAKey>("cnonce-encryption-key")) }

//
// Credentials
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,16 @@ import com.nimbusds.jose.EncryptionMethod
import com.nimbusds.jose.JOSEObjectType
import com.nimbusds.jose.JWEAlgorithm
import com.nimbusds.jose.crypto.factories.DefaultJWEDecrypterFactory
import com.nimbusds.jose.crypto.factories.DefaultJWSVerifierFactory
import com.nimbusds.jose.jwk.JWKSet
import com.nimbusds.jose.jwk.RSAKey
import com.nimbusds.jose.jwk.source.ImmutableJWKSet
import com.nimbusds.jose.proc.*
import com.nimbusds.jose.proc.DefaultJOSEObjectTypeVerifier
import com.nimbusds.jose.proc.JWEDecryptionKeySelector
import com.nimbusds.jose.proc.SecurityContext
import com.nimbusds.jwt.EncryptedJWT
import com.nimbusds.jwt.JWTClaimsSet
import com.nimbusds.jwt.proc.DefaultJWTClaimsVerifier
import com.nimbusds.jwt.proc.DefaultJWTProcessor
import eu.europa.ec.eudi.pidissuer.adapter.out.IssuerSigningKey
import eu.europa.ec.eudi.pidissuer.adapter.out.signingAlgorithm
import eu.europa.ec.eudi.pidissuer.domain.CNonce
import eu.europa.ec.eudi.pidissuer.domain.CredentialIssuerId
import eu.europa.ec.eudi.pidissuer.port.out.jose.DecryptCNonce
Expand All @@ -43,36 +42,23 @@ import java.time.Duration
internal class DecryptCNonceWithNimbus(
private val issuer: CredentialIssuerId,
private val decryptionKey: RSAKey,
private val signingKey: IssuerSigningKey,
) : DecryptCNonce {
init {
require(decryptionKey.isPrivate) { "a private key is required for decryption" }
}

private val processor = DefaultJWTProcessor<SecurityContext>()
.apply {
val jcaProvider = BouncyCastleProvider()
val typeVerifier = DefaultJOSEObjectTypeVerifier<SecurityContext>(JOSEObjectType("cnonce+jwt"))

jweTypeVerifier = typeVerifier
jweTypeVerifier = DefaultJOSEObjectTypeVerifier(JOSEObjectType("cnonce+jwt"))
jweKeySelector = JWEDecryptionKeySelector(
JWEAlgorithm.RSA_OAEP_512,
EncryptionMethod.XC20P,
ImmutableJWKSet(JWKSet(decryptionKey)),
)
jweDecrypterFactory = DefaultJWEDecrypterFactory().apply {
jcaContext.provider = jcaProvider
}

jwsTypeVerifier = typeVerifier
jwsKeySelector = JWSVerificationKeySelector(
signingKey.signingAlgorithm,
ImmutableJWKSet(JWKSet(signingKey.key)),
)
jwsVerifierFactory = DefaultJWSVerifierFactory().apply {
jcaContext.provider = jcaProvider
}

jweDecrypterFactory = DefaultJWEDecrypterFactory()
.apply {
jcaContext.provider = BouncyCastleProvider()
}
jwtClaimsSetVerifier = DefaultJWTClaimsVerifier(
issuer.externalForm,
JWTClaimsSet.Builder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,10 @@ import com.nimbusds.jose.EncryptionMethod
import com.nimbusds.jose.JOSEObjectType
import com.nimbusds.jose.JWEAlgorithm
import com.nimbusds.jose.JWEHeader
import com.nimbusds.jose.JWEObject
import com.nimbusds.jose.JWSHeader
import com.nimbusds.jose.Payload
import com.nimbusds.jose.crypto.RSAEncrypter
import com.nimbusds.jose.crypto.factories.DefaultJWSSignerFactory
import com.nimbusds.jose.jwk.RSAKey
import com.nimbusds.jwt.EncryptedJWT
import com.nimbusds.jwt.JWTClaimsSet
import com.nimbusds.jwt.SignedJWT
import eu.europa.ec.eudi.pidissuer.adapter.out.IssuerSigningKey
import eu.europa.ec.eudi.pidissuer.adapter.out.signingAlgorithm
import eu.europa.ec.eudi.pidissuer.domain.CNonce
import eu.europa.ec.eudi.pidissuer.domain.CredentialIssuerId
import eu.europa.ec.eudi.pidissuer.port.out.jose.EncryptCNonce
Expand All @@ -41,20 +34,17 @@ import java.util.*
*/
internal class EncryptCNonceWithNimbus(
private val issuer: CredentialIssuerId,
private val signingKey: IssuerSigningKey,
encryptionKey: RSAKey,
) : EncryptCNonce {

private val jcaProvider = BouncyCastleProvider()
private val signer = run {
val factory = DefaultJWSSignerFactory().apply { jcaContext.provider = jcaProvider }
factory.createJWSSigner(signingKey.key, signingKey.signingAlgorithm)
}
private val encrypter = RSAEncrypter(encryptionKey).apply { jcaContext.provider = jcaProvider }
private val encrypter = RSAEncrypter(encryptionKey)
.apply {
jcaContext.provider = BouncyCastleProvider()
}

override suspend fun invoke(cnonce: CNonce): String {
val signedJwt = SignedJWT(
JWSHeader.Builder(signingKey.signingAlgorithm)
override suspend fun invoke(cnonce: CNonce): String =
EncryptedJWT(
JWEHeader.Builder(JWEAlgorithm.RSA_OAEP_512, EncryptionMethod.XC20P)
.type(JOSEObjectType("cnonce+jwt"))
.build(),
JWTClaimsSet.Builder()
Expand All @@ -67,20 +57,7 @@ internal class EncryptCNonceWithNimbus(
expirationTime(Date.from((cnonce.activatedAt + cnonce.expiresIn)))
}
.build(),
).apply {
sign(signer)
}

val encryptedJwt = JWEObject(
JWEHeader.Builder(JWEAlgorithm.RSA_OAEP_512, EncryptionMethod.XC20P)
.type(JOSEObjectType("cnonce+jwt"))
.contentType("JWT")
.build(),
Payload(signedJwt),
).apply {
encrypt(encrypter)
}

return encryptedJwt.serialize()
}
}.serialize()
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,13 @@ import com.nimbusds.jose.JOSEObjectType
import com.nimbusds.jose.JWSAlgorithm
import com.nimbusds.jose.JWSHeader
import com.nimbusds.jose.crypto.RSASSASigner
import com.nimbusds.jose.jwk.Curve
import com.nimbusds.jose.jwk.ECKey
import com.nimbusds.jose.jwk.RSAKey
import com.nimbusds.jose.jwk.gen.ECKeyGenerator
import com.nimbusds.jose.jwk.gen.RSAKeyGenerator
import com.nimbusds.jose.util.Base64
import com.nimbusds.jose.util.Base64URL
import com.nimbusds.jose.util.X509CertChainUtils
import com.nimbusds.jwt.JWTClaimsSet
import com.nimbusds.jwt.SignedJWT
import com.nimbusds.oauth2.sdk.id.Issuer
import com.nimbusds.oauth2.sdk.util.X509CertificateUtils
import eu.europa.ec.eudi.pidissuer.adapter.out.IssuerSigningKey
import eu.europa.ec.eudi.pidissuer.adapter.out.mdl.MobileDrivingLicenceV1
import eu.europa.ec.eudi.pidissuer.domain.*
import eu.europa.ec.eudi.pidissuer.loadResource
Expand All @@ -47,30 +41,16 @@ import java.security.cert.X509Certificate
import java.time.Clock
import java.util.*
import kotlin.test.*
import kotlin.time.Duration.Companion.days
import kotlin.time.Duration.Companion.minutes
import kotlin.time.toJavaDuration

internal class ValidateJwtProofTest {

private val issuer = CredentialIssuerId.unsafe("https://eudi.ec.europa.eu/issuer")
private val clock = Clock.systemDefaultZone()
private val signingKey = run {
val key = ECKeyGenerator(Curve.P_256).keyID("signing-key-0").generate()
val issuedAt = clock.instant()
val expiresAt = issuedAt + 365.days.toJavaDuration()
val x509 = X509CertificateUtils.generateSelfSigned(
Issuer(issuer.externalForm),
Date.from(issuedAt),
Date.from(expiresAt),
key.toECPublicKey(),
key.toECPrivateKey(),
)
IssuerSigningKey(ECKey.Builder(key).x509CertChain(listOf(Base64.encode(x509.encoded))).build())
}
private val encryptionKey = RSAKeyGenerator(4096, false).generate()
private val encryptCNonce = EncryptCNonceWithNimbus(issuer, signingKey, encryptionKey)
private val decryptCNonce = DecryptCNonceWithNimbus(issuer, encryptionKey, signingKey)
private val key = RSAKeyGenerator(4096, false).generate()
private val encryptCNonce = EncryptCNonceWithNimbus(issuer, key)
private val decryptCNonce = DecryptCNonceWithNimbus(issuer, key)
private val validateJwtProof = ValidateJwtProof(issuer, decryptCNonce)
private val credentialConfiguration = MobileDrivingLicenceV1.copy(
proofTypesSupported = ProofTypesSupported(
Expand Down

0 comments on commit 025492e

Please sign in to comment.