From 71147335acc7572a748190cacfabc87b5e1f2b3b Mon Sep 17 00:00:00 2001 From: vkanellopoulos Date: Wed, 5 Jun 2024 10:27:09 +0300 Subject: [PATCH] minor changes; kdoc; update docs --- .../-unsupported-algorithm-exception.md | 6 ++ .../-unsupported-algorithm-exception/index.md | 32 +++++++++ .../-unsupported-proof-type-exception.md | 6 ++ .../index.md | 32 +++++++++ .../index.md | 14 ++-- docs/wallet-core/package-list | 4 ++ .../wallet/issue/openid4vci/CWTProofSigner.kt | 20 ++++++ .../wallet/issue/openid4vci/Exceptions.kt | 2 +- .../wallet/issue/openid4vci/JWSDPoPSigner.kt | 60 +++++++++------- .../wallet/issue/openid4vci/JWSProofSigner.kt | 11 +++ .../wallet/issue/openid4vci/ProofSigner.kt | 70 ++++++++++++++++++- .../ec/eudi/wallet/issue/openid4vci/Utils.kt | 2 +- 12 files changed, 222 insertions(+), 37 deletions(-) create mode 100644 docs/wallet-core/eu.europa.ec.eudi.wallet.issue.openid4vci/-unsupported-algorithm-exception/-unsupported-algorithm-exception.md create mode 100644 docs/wallet-core/eu.europa.ec.eudi.wallet.issue.openid4vci/-unsupported-algorithm-exception/index.md create mode 100644 docs/wallet-core/eu.europa.ec.eudi.wallet.issue.openid4vci/-unsupported-proof-type-exception/-unsupported-proof-type-exception.md create mode 100644 docs/wallet-core/eu.europa.ec.eudi.wallet.issue.openid4vci/-unsupported-proof-type-exception/index.md diff --git a/docs/wallet-core/eu.europa.ec.eudi.wallet.issue.openid4vci/-unsupported-algorithm-exception/-unsupported-algorithm-exception.md b/docs/wallet-core/eu.europa.ec.eudi.wallet.issue.openid4vci/-unsupported-algorithm-exception/-unsupported-algorithm-exception.md new file mode 100644 index 00000000..1b7810a7 --- /dev/null +++ b/docs/wallet-core/eu.europa.ec.eudi.wallet.issue.openid4vci/-unsupported-algorithm-exception/-unsupported-algorithm-exception.md @@ -0,0 +1,6 @@ +//[wallet-core](../../../index.md)/[eu.europa.ec.eudi.wallet.issue.openid4vci](../index.md)/[UnsupportedAlgorithmException](index.md)/[UnsupportedAlgorithmException](-unsupported-algorithm-exception.md) + +# UnsupportedAlgorithmException + +[androidJvm]\ +constructor() diff --git a/docs/wallet-core/eu.europa.ec.eudi.wallet.issue.openid4vci/-unsupported-algorithm-exception/index.md b/docs/wallet-core/eu.europa.ec.eudi.wallet.issue.openid4vci/-unsupported-algorithm-exception/index.md new file mode 100644 index 00000000..9524be8a --- /dev/null +++ b/docs/wallet-core/eu.europa.ec.eudi.wallet.issue.openid4vci/-unsupported-algorithm-exception/index.md @@ -0,0 +1,32 @@ +//[wallet-core](../../../index.md)/[eu.europa.ec.eudi.wallet.issue.openid4vci](../index.md)/[UnsupportedAlgorithmException](index.md) + +# UnsupportedAlgorithmException + +[androidJvm]\ +class [UnsupportedAlgorithmException](index.md) : [Throwable](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-throwable/index.html) + +## Constructors + +| | | +|----------------------------------------------------------------------|-------------------------------| +| [UnsupportedAlgorithmException](-unsupported-algorithm-exception.md) | [androidJvm]
constructor() | + +## Functions + +| Name | Summary | +|----------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| [addSuppressed](../-unsupported-proof-type-exception/index.md#282858770%2FFunctions%2F1615067946) | [androidJvm]
fun [addSuppressed](../-unsupported-proof-type-exception/index.md#282858770%2FFunctions%2F1615067946)(p0: [Throwable](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-throwable/index.html)) | +| [fillInStackTrace](../-unsupported-proof-type-exception/index.md#-1102069925%2FFunctions%2F1615067946) | [androidJvm]
open fun [fillInStackTrace](../-unsupported-proof-type-exception/index.md#-1102069925%2FFunctions%2F1615067946)(): [Throwable](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-throwable/index.html) | +| [getLocalizedMessage](../-unsupported-proof-type-exception/index.md#1043865560%2FFunctions%2F1615067946) | [androidJvm]
open fun [getLocalizedMessage](../-unsupported-proof-type-exception/index.md#1043865560%2FFunctions%2F1615067946)(): [String](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-string/index.html) | +| [getStackTrace](../-unsupported-proof-type-exception/index.md#2050903719%2FFunctions%2F1615067946) | [androidJvm]
open fun [getStackTrace](../-unsupported-proof-type-exception/index.md#2050903719%2FFunctions%2F1615067946)(): [Array](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-array/index.html)<[StackTraceElement](https://developer.android.com/reference/kotlin/java/lang/StackTraceElement.html)> | +| [getSuppressed](../-unsupported-proof-type-exception/index.md#672492560%2FFunctions%2F1615067946) | [androidJvm]
fun [getSuppressed](../-unsupported-proof-type-exception/index.md#672492560%2FFunctions%2F1615067946)(): [Array](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-array/index.html)<[Throwable](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-throwable/index.html)> | +| [initCause](../-unsupported-proof-type-exception/index.md#-418225042%2FFunctions%2F1615067946) | [androidJvm]
open fun [initCause](../-unsupported-proof-type-exception/index.md#-418225042%2FFunctions%2F1615067946)(p0: [Throwable](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-throwable/index.html)): [Throwable](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-throwable/index.html) | +| [printStackTrace](../-unsupported-proof-type-exception/index.md#-1769529168%2FFunctions%2F1615067946) | [androidJvm]
open fun [printStackTrace](../-unsupported-proof-type-exception/index.md#-1769529168%2FFunctions%2F1615067946)()
open fun [printStackTrace](../-unsupported-proof-type-exception/index.md#1841853697%2FFunctions%2F1615067946)(p0: [PrintStream](https://developer.android.com/reference/kotlin/java/io/PrintStream.html))
open fun [printStackTrace](../-unsupported-proof-type-exception/index.md#1175535278%2FFunctions%2F1615067946)(p0: [PrintWriter](https://developer.android.com/reference/kotlin/java/io/PrintWriter.html)) | +| [setStackTrace](../-unsupported-proof-type-exception/index.md#2135801318%2FFunctions%2F1615067946) | [androidJvm]
open fun [setStackTrace](../-unsupported-proof-type-exception/index.md#2135801318%2FFunctions%2F1615067946)(p0: [Array](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-array/index.html)<[StackTraceElement](https://developer.android.com/reference/kotlin/java/lang/StackTraceElement.html)>) | + +## Properties + +| Name | Summary | +|-----------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| [cause](../-unsupported-proof-type-exception/index.md#-654012527%2FProperties%2F1615067946) | [androidJvm]
open val [cause](../-unsupported-proof-type-exception/index.md#-654012527%2FProperties%2F1615067946): [Throwable](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-throwable/index.html)? | +| [message](../-unsupported-proof-type-exception/index.md#1824300659%2FProperties%2F1615067946) | [androidJvm]
open val [message](../-unsupported-proof-type-exception/index.md#1824300659%2FProperties%2F1615067946): [String](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-string/index.html)? | diff --git a/docs/wallet-core/eu.europa.ec.eudi.wallet.issue.openid4vci/-unsupported-proof-type-exception/-unsupported-proof-type-exception.md b/docs/wallet-core/eu.europa.ec.eudi.wallet.issue.openid4vci/-unsupported-proof-type-exception/-unsupported-proof-type-exception.md new file mode 100644 index 00000000..a293315b --- /dev/null +++ b/docs/wallet-core/eu.europa.ec.eudi.wallet.issue.openid4vci/-unsupported-proof-type-exception/-unsupported-proof-type-exception.md @@ -0,0 +1,6 @@ +//[wallet-core](../../../index.md)/[eu.europa.ec.eudi.wallet.issue.openid4vci](../index.md)/[UnsupportedProofTypeException](index.md)/[UnsupportedProofTypeException](-unsupported-proof-type-exception.md) + +# UnsupportedProofTypeException + +[androidJvm]\ +constructor() diff --git a/docs/wallet-core/eu.europa.ec.eudi.wallet.issue.openid4vci/-unsupported-proof-type-exception/index.md b/docs/wallet-core/eu.europa.ec.eudi.wallet.issue.openid4vci/-unsupported-proof-type-exception/index.md new file mode 100644 index 00000000..29c8bb0a --- /dev/null +++ b/docs/wallet-core/eu.europa.ec.eudi.wallet.issue.openid4vci/-unsupported-proof-type-exception/index.md @@ -0,0 +1,32 @@ +//[wallet-core](../../../index.md)/[eu.europa.ec.eudi.wallet.issue.openid4vci](../index.md)/[UnsupportedProofTypeException](index.md) + +# UnsupportedProofTypeException + +[androidJvm]\ +class [UnsupportedProofTypeException](index.md) : [Throwable](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-throwable/index.html) + +## Constructors + +| | | +|-----------------------------------------------------------------------|-------------------------------| +| [UnsupportedProofTypeException](-unsupported-proof-type-exception.md) | [androidJvm]
constructor() | + +## Functions + +| Name | Summary | +|---------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| [addSuppressed](index.md#282858770%2FFunctions%2F1615067946) | [androidJvm]
fun [addSuppressed](index.md#282858770%2FFunctions%2F1615067946)(p0: [Throwable](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-throwable/index.html)) | +| [fillInStackTrace](index.md#-1102069925%2FFunctions%2F1615067946) | [androidJvm]
open fun [fillInStackTrace](index.md#-1102069925%2FFunctions%2F1615067946)(): [Throwable](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-throwable/index.html) | +| [getLocalizedMessage](index.md#1043865560%2FFunctions%2F1615067946) | [androidJvm]
open fun [getLocalizedMessage](index.md#1043865560%2FFunctions%2F1615067946)(): [String](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-string/index.html) | +| [getStackTrace](index.md#2050903719%2FFunctions%2F1615067946) | [androidJvm]
open fun [getStackTrace](index.md#2050903719%2FFunctions%2F1615067946)(): [Array](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-array/index.html)<[StackTraceElement](https://developer.android.com/reference/kotlin/java/lang/StackTraceElement.html)> | +| [getSuppressed](index.md#672492560%2FFunctions%2F1615067946) | [androidJvm]
fun [getSuppressed](index.md#672492560%2FFunctions%2F1615067946)(): [Array](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-array/index.html)<[Throwable](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-throwable/index.html)> | +| [initCause](index.md#-418225042%2FFunctions%2F1615067946) | [androidJvm]
open fun [initCause](index.md#-418225042%2FFunctions%2F1615067946)(p0: [Throwable](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-throwable/index.html)): [Throwable](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-throwable/index.html) | +| [printStackTrace](index.md#-1769529168%2FFunctions%2F1615067946) | [androidJvm]
open fun [printStackTrace](index.md#-1769529168%2FFunctions%2F1615067946)()
open fun [printStackTrace](index.md#1841853697%2FFunctions%2F1615067946)(p0: [PrintStream](https://developer.android.com/reference/kotlin/java/io/PrintStream.html))
open fun [printStackTrace](index.md#1175535278%2FFunctions%2F1615067946)(p0: [PrintWriter](https://developer.android.com/reference/kotlin/java/io/PrintWriter.html)) | +| [setStackTrace](index.md#2135801318%2FFunctions%2F1615067946) | [androidJvm]
open fun [setStackTrace](index.md#2135801318%2FFunctions%2F1615067946)(p0: [Array](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-array/index.html)<[StackTraceElement](https://developer.android.com/reference/kotlin/java/lang/StackTraceElement.html)>) | + +## Properties + +| Name | Summary | +|----------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| [cause](index.md#-654012527%2FProperties%2F1615067946) | [androidJvm]
open val [cause](index.md#-654012527%2FProperties%2F1615067946): [Throwable](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-throwable/index.html)? | +| [message](index.md#1824300659%2FProperties%2F1615067946) | [androidJvm]
open val [message](index.md#1824300659%2FProperties%2F1615067946): [String](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-string/index.html)? | diff --git a/docs/wallet-core/eu.europa.ec.eudi.wallet.issue.openid4vci/index.md b/docs/wallet-core/eu.europa.ec.eudi.wallet.issue.openid4vci/index.md index d3dfc06b..015adbb0 100644 --- a/docs/wallet-core/eu.europa.ec.eudi.wallet.issue.openid4vci/index.md +++ b/docs/wallet-core/eu.europa.ec.eudi.wallet.issue.openid4vci/index.md @@ -4,9 +4,11 @@ ## Types -| Name | Summary | -|---|---| -| [IssueEvent](-issue-event/index.md) | [androidJvm]
interface [IssueEvent](-issue-event/index.md) | -| [Offer](-offer/index.md) | [androidJvm]
interface [Offer](-offer/index.md)
An offer of credentials to be issued. | -| [OfferResult](-offer-result/index.md) | [androidJvm]
interface [OfferResult](-offer-result/index.md)
The result of an offer operation. | -| [OpenId4VciManager](-open-id4-vci-manager/index.md) | [androidJvm]
interface [OpenId4VciManager](-open-id4-vci-manager/index.md)
OpenId4VciManager is the main entry point to issue documents using the OpenId4Vci protocol It provides methods to issue documents using a document type or an offer, and to resolve an offer | +| Name | Summary | +|-----------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| [IssueEvent](-issue-event/index.md) | [androidJvm]
interface [IssueEvent](-issue-event/index.md) | +| [Offer](-offer/index.md) | [androidJvm]
interface [Offer](-offer/index.md)
An offer of credentials to be issued. | +| [OfferResult](-offer-result/index.md) | [androidJvm]
interface [OfferResult](-offer-result/index.md)
The result of an offer operation. | +| [OpenId4VciManager](-open-id4-vci-manager/index.md) | [androidJvm]
interface [OpenId4VciManager](-open-id4-vci-manager/index.md)
OpenId4VciManager is the main entry point to issue documents using the OpenId4Vci protocol It provides methods to issue documents using a document type or an offer, and to resolve an offer | +| [UnsupportedAlgorithmException](-unsupported-algorithm-exception/index.md) | [androidJvm]
class [UnsupportedAlgorithmException](-unsupported-algorithm-exception/index.md) : [Throwable](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-throwable/index.html) | +| [UnsupportedProofTypeException](-unsupported-proof-type-exception/index.md) | [androidJvm]
class [UnsupportedProofTypeException](-unsupported-proof-type-exception/index.md) : [Throwable](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-throwable/index.html) | diff --git a/docs/wallet-core/package-list b/docs/wallet-core/package-list index ff216ba2..7ec9b09e 100644 --- a/docs/wallet-core/package-list +++ b/docs/wallet-core/package-list @@ -96,6 +96,10 @@ $dokka.location:eu.europa.ec.eudi.wallet.issue.openid4vci/OpenId4VciManager/reso $dokka.location:eu.europa.ec.eudi.wallet.issue.openid4vci/OpenId4VciManager/resumeWithAuthorization/#android.content.Intent/PointingToDeclaration/wallet-core/eu.europa.ec.eudi.wallet.issue.openid4vci/-open-id4-vci-manager/resume-with-authorization.md $dokka.location:eu.europa.ec.eudi.wallet.issue.openid4vci/OpenId4VciManager/resumeWithAuthorization/#android.net.Uri/PointingToDeclaration/wallet-core/eu.europa.ec.eudi.wallet.issue.openid4vci/-open-id4-vci-manager/resume-with-authorization.md $dokka.location:eu.europa.ec.eudi.wallet.issue.openid4vci/OpenId4VciManager/resumeWithAuthorization/#kotlin.String/PointingToDeclaration/wallet-core/eu.europa.ec.eudi.wallet.issue.openid4vci/-open-id4-vci-manager/resume-with-authorization.md +$dokka.location:eu.europa.ec.eudi.wallet.issue.openid4vci/UnsupportedAlgorithmException///PointingToDeclaration/wallet-core/eu.europa.ec.eudi.wallet.issue.openid4vci/-unsupported-algorithm-exception/index.md +$dokka.location:eu.europa.ec.eudi.wallet.issue.openid4vci/UnsupportedAlgorithmException/UnsupportedAlgorithmException/#/PointingToDeclaration/wallet-core/eu.europa.ec.eudi.wallet.issue.openid4vci/-unsupported-algorithm-exception/-unsupported-algorithm-exception.md +$dokka.location:eu.europa.ec.eudi.wallet.issue.openid4vci/UnsupportedProofTypeException///PointingToDeclaration/wallet-core/eu.europa.ec.eudi.wallet.issue.openid4vci/-unsupported-proof-type-exception/index.md +$dokka.location:eu.europa.ec.eudi.wallet.issue.openid4vci/UnsupportedProofTypeException/UnsupportedProofTypeException/#/PointingToDeclaration/wallet-core/eu.europa.ec.eudi.wallet.issue.openid4vci/-unsupported-proof-type-exception/-unsupported-proof-type-exception.md $dokka.location:eu.europa.ec.eudi.wallet.transfer.openid4vp////PointingToDeclaration/wallet-core/eu.europa.ec.eudi.wallet.transfer.openid4vp/index.md $dokka.location:eu.europa.ec.eudi.wallet.transfer.openid4vp/ClientIdScheme.Preregistered///PointingToDeclaration/wallet-core/eu.europa.ec.eudi.wallet.transfer.openid4vp/-client-id-scheme/-preregistered/index.md $dokka.location:eu.europa.ec.eudi.wallet.transfer.openid4vp/ClientIdScheme.Preregistered/Preregistered/#kotlin.collections.List[eu.europa.ec.eudi.wallet.transfer.openid4vp.PreregisteredVerifier]/PointingToDeclaration/wallet-core/eu.europa.ec.eudi.wallet.transfer.openid4vp/-client-id-scheme/-preregistered/-preregistered.md diff --git a/wallet-core/src/main/java/eu/europa/ec/eudi/wallet/issue/openid4vci/CWTProofSigner.kt b/wallet-core/src/main/java/eu/europa/ec/eudi/wallet/issue/openid4vci/CWTProofSigner.kt index 62c8545c..970b36d8 100644 --- a/wallet-core/src/main/java/eu/europa/ec/eudi/wallet/issue/openid4vci/CWTProofSigner.kt +++ b/wallet-core/src/main/java/eu/europa/ec/eudi/wallet/issue/openid4vci/CWTProofSigner.kt @@ -24,12 +24,25 @@ import eu.europa.ec.eudi.openid4vci.PopSigner import eu.europa.ec.eudi.wallet.document.Algorithm import eu.europa.ec.eudi.wallet.document.IssuanceRequest +/** + * A [ProofSigner] implementation for CWT. + * @property issuanceRequest the issuance request + * @property coseAlgorithm the COSE algorithm to use + * @property coseCurve the COSE curve to use + * @constructor Creates a CWT proof signer. + * @param issuanceRequest The issuance request. + * @param coseAlgorithm The COSE algorithm to use. + * @param coseCurve The COSE curve to use. + */ internal class CWTProofSigner( private val issuanceRequest: IssuanceRequest, private val coseAlgorithm: CoseAlgorithm, private val coseCurve: CoseCurve ) : ProofSigner() { + /** + * The JWK of the public key. + */ private val jwk = JWK.parseFromPEMEncodedObjects(issuanceRequest.publicKey.pem) override val popSigner: PopSigner.Cwt = PopSigner.Cwt( algorithm = coseAlgorithm, @@ -43,6 +56,13 @@ internal class CWTProofSigner( CWTAlgorithmMap[it] ?: throw UnsupportedAlgorithmException() } + /** + * Signs the signing input with the authentication key from issuance request for the given algorithm and curve. + * @param signingInput The input to sign. + * @throws UserAuthRequiredException If user authentication is required. + * @throws Throwable If an error occurs during signing. + * @return The signature of the signing input. + */ fun sign(signingInput: ByteArray): ByteArray { return doSign(issuanceRequest, signingInput, algorithm) } diff --git a/wallet-core/src/main/java/eu/europa/ec/eudi/wallet/issue/openid4vci/Exceptions.kt b/wallet-core/src/main/java/eu/europa/ec/eudi/wallet/issue/openid4vci/Exceptions.kt index f6e5a9e6..119de4a9 100644 --- a/wallet-core/src/main/java/eu/europa/ec/eudi/wallet/issue/openid4vci/Exceptions.kt +++ b/wallet-core/src/main/java/eu/europa/ec/eudi/wallet/issue/openid4vci/Exceptions.kt @@ -16,6 +16,6 @@ package eu.europa.ec.eudi.wallet.issue.openid4vci -class UserAuthRequiredException : Throwable() +internal class UserAuthRequiredException : Throwable() class UnsupportedAlgorithmException : Throwable() class UnsupportedProofTypeException : Throwable() \ No newline at end of file diff --git a/wallet-core/src/main/java/eu/europa/ec/eudi/wallet/issue/openid4vci/JWSDPoPSigner.kt b/wallet-core/src/main/java/eu/europa/ec/eudi/wallet/issue/openid4vci/JWSDPoPSigner.kt index 2f2a0436..fa2793d1 100644 --- a/wallet-core/src/main/java/eu/europa/ec/eudi/wallet/issue/openid4vci/JWSDPoPSigner.kt +++ b/wallet-core/src/main/java/eu/europa/ec/eudi/wallet/issue/openid4vci/JWSDPoPSigner.kt @@ -35,7 +35,15 @@ import java.security.Signature import java.time.Instant import java.util.* -class JWSDPoPSigner private constructor() { +/** + * A [JWSSigner] implementation for DPoP. + * @property popSigner the DPoP signer [PopSigner.Jwt] + */ +internal class JWSDPoPSigner private constructor() : JWSSigner { + + private val jcaContext = JCAContext() + + override fun getJCAContext(): JCAContext = jcaContext private val keyStore: KeyStore get() = KeyStore.getInstance("AndroidKeyStore").apply { load(null) } @@ -47,38 +55,30 @@ class JWSDPoPSigner private constructor() { get() = PopSigner.Jwt( algorithm = SupportedAlgorithms.keys.first(), bindingKey = JwtBindingKey.Jwk(jwk), - jwsSigner = jwsSigner + jwsSigner = this ) init { generateKeyPair() } - private val jwsSigner: JWSSigner - get() = object : JWSSigner { - - private val jcaContext = JCAContext() - - override fun getJCAContext(): JCAContext = jcaContext - - override fun sign(header: JWSHeader, signingInput: ByteArray): Base64URL { - val algorithm = SupportedAlgorithms[header.algorithm] - ?: throw JOSEException( - AlgorithmSupportMessage.unsupportedJWSAlgorithm( - header.algorithm, - supportedJWSAlgorithms() - ) - ) - val privateKey = (keyStore.getEntry(KEY_ALIAS, null) as KeyStore.PrivateKeyEntry).privateKey - val signature = Signature.getInstance(algorithm).apply { - initSign(privateKey) - update(signingInput) - }.sign() - return Base64URL.encode(signature.derToJose(header.algorithm)) - } + override fun sign(header: JWSHeader, signingInput: ByteArray): Base64URL { + val algorithm = SupportedAlgorithms[header.algorithm] + ?: throw JOSEException( + AlgorithmSupportMessage.unsupportedJWSAlgorithm( + header.algorithm, + supportedJWSAlgorithms() + ) + ) + val privateKey = (keyStore.getEntry(KEY_ALIAS, null) as KeyStore.PrivateKeyEntry).privateKey + val signature = Signature.getInstance(algorithm).apply { + initSign(privateKey) + update(signingInput) + }.sign() + return Base64URL.encode(signature.derToJose(header.algorithm)) + } - override fun supportedJWSAlgorithms(): MutableSet = SupportedAlgorithms.keys.toMutableSet() - } + override fun supportedJWSAlgorithms(): MutableSet = SupportedAlgorithms.keys.toMutableSet() private fun generateKeyPair() { if (keyStore.containsAlias(KEY_ALIAS)) { @@ -101,6 +101,9 @@ class JWSDPoPSigner private constructor() { } } + /** + * Companion object for the JWSDPoPSigner class. + */ companion object { private const val KEY_ALIAS = "eu.europa.ec.eudi.wallet.issue.openid4vci.DPoPKey" @@ -108,6 +111,11 @@ class JWSDPoPSigner private constructor() { private val SupportedAlgorithms: Map get() = mapOf(JWSAlgorithm.ES256 to "SHA256withECDSA") + /** + * Creates a [PopSigner.Jwt] instance. + * @return [Result] The result of the operation. If successful, the result contains the [PopSigner.Jwt] instance. + * If unsuccessful, the result contains the exception that occurred. + */ operator fun invoke(): Result { return try { Result.success(JWSDPoPSigner().popSigner) diff --git a/wallet-core/src/main/java/eu/europa/ec/eudi/wallet/issue/openid4vci/JWSProofSigner.kt b/wallet-core/src/main/java/eu/europa/ec/eudi/wallet/issue/openid4vci/JWSProofSigner.kt index 6dd680c9..2a9201a9 100644 --- a/wallet-core/src/main/java/eu/europa/ec/eudi/wallet/issue/openid4vci/JWSProofSigner.kt +++ b/wallet-core/src/main/java/eu/europa/ec/eudi/wallet/issue/openid4vci/JWSProofSigner.kt @@ -31,6 +31,14 @@ import eu.europa.ec.eudi.openid4vci.ProofTypeMeta import eu.europa.ec.eudi.wallet.document.Algorithm import eu.europa.ec.eudi.wallet.document.IssuanceRequest +/** + * A [ProofSigner] and [JWSSigner] implementation for JWS. + * @property issuanceRequest the issuance request + * @constructor Creates a JWS proof signer. + * @param issuanceRequest The issuance request. + * @param jwsAlgorithm The JWS algorithm to use. + * + */ internal class JWSProofSigner( private val issuanceRequest: IssuanceRequest, jwsAlgorithm: JWSAlgorithm @@ -38,6 +46,9 @@ internal class JWSProofSigner( private val jcaContext = JCAContext() + /** + * The JWK of the public key. + */ private val jwk = JWK.parseFromPEMEncodedObjects(issuanceRequest.publicKey.pem) override val popSigner: PopSigner.Jwt = PopSigner.Jwt( diff --git a/wallet-core/src/main/java/eu/europa/ec/eudi/wallet/issue/openid4vci/ProofSigner.kt b/wallet-core/src/main/java/eu/europa/ec/eudi/wallet/issue/openid4vci/ProofSigner.kt index 07956cc2..ed7e4864 100644 --- a/wallet-core/src/main/java/eu/europa/ec/eudi/wallet/issue/openid4vci/ProofSigner.kt +++ b/wallet-core/src/main/java/eu/europa/ec/eudi/wallet/issue/openid4vci/ProofSigner.kt @@ -23,11 +23,26 @@ import eu.europa.ec.eudi.wallet.document.Algorithm import eu.europa.ec.eudi.wallet.document.IssuanceRequest import eu.europa.ec.eudi.wallet.document.SignedWithAuthKeyResult +/** + * Abstract class for signing proofs. + * + * @property popSigner The signer for the proof of possession as required by the vci library. + * @property userAuthStatus The status of the user authentication. + */ internal abstract class ProofSigner { abstract val popSigner: PopSigner var userAuthStatus: UserAuthStatus = UserAuthStatus.NotRequired protected set + /** + * Signs the signing input with the authentication key from issuance request for the given algorithm. + * @param issuanceRequest The issuance request. + * @param signingInput The input to sign. + * @param algorithm The algorithm to use for signing. + * @throws UserAuthRequiredException If user authentication is required. + * @throws Throwable If an error occurs during signing. + * @return The signature of the signing input. + */ protected fun doSign( issuanceRequest: IssuanceRequest, signingInput: ByteArray, @@ -46,12 +61,22 @@ internal abstract class ProofSigner { } } - companion object Factory { + /** + * Companion object for the ProofSigner class. + * @property SupportedProofTypes The supported proof types. + */ + companion object { val SupportedProofTypes = mapOf( ProofType.JWT to ProofTypeMeta.Jwt(listOf(JWSAlgorithm.ES256)), ProofType.CWT to ProofTypeMeta.Cwt(listOf(CoseAlgorithm.ES256), listOf(CoseCurve.P_256)) ) + /** + * Selects the supported proof type from the issuer supported proof types. + * @param issuerSupportedProofTypes The issuer supported proof types. + * @return The supported proof type or null if none is supported. + */ + @JvmStatic fun selectSupportedProofType(issuerSupportedProofTypes: ProofTypesSupported): ProofTypeMeta? { return issuerSupportedProofTypes.values .firstOrNull { it.type() in SupportedProofTypes.keys } @@ -64,11 +89,23 @@ internal abstract class ProofSigner { } } + /** + * Selects the supported algorithm from given JWT proof type metadata. + * @param metadata The proof type metadata. + * @return The supported algorithm or null if none is supported. + */ + @JvmStatic fun selectSupportedAlgorithm(metadata: ProofTypeMeta.Jwt): JWSAlgorithm? { val supportedType = SupportedProofTypes[ProofType.JWT] as ProofTypeMeta.Jwt return supportedType.algorithms.firstOrNull { it in metadata.algorithms } } + /** + * Selects the supported algorithm and curve from given CWT proof type metadata. + * @param metadata The proof type metadata. + * @return The supported algorithm and curve or null if none is supported. + */ + @JvmStatic fun selectSupportedAlgorithm(metadata: ProofTypeMeta.Cwt): Pair? { val supportedType = SupportedProofTypes[ProofType.CWT] as ProofTypeMeta.Cwt return supportedType.algorithms.firstOrNull { it in metadata.algorithms } @@ -79,11 +116,27 @@ internal abstract class ProofSigner { } + /** + * Creates a proof signer for the given issuance request and credential configuration. + * @param issuanceRequest The issuance request. + * @param credentialConfiguration The credential configuration. + * @return The proof signer or a failure if the proof type is not supported. + */ + @JvmStatic operator fun invoke( issuanceRequest: IssuanceRequest, credentialConfiguration: CredentialConfiguration, ) = invoke(issuanceRequest, credentialConfiguration.proofTypesSupported) + /** + * Creates a proof signer for the given issuance request and issuer supported proof types. + * The proof signer is selected based on the issuer supported proof types and the [SupportedProofTypes] + * of the [ProofSigner]. + * @param issuanceRequest The issuance request. + * @param issuerSupportedProofTypes The issuer supported proof types. + * @return The proof signer or a failure if the proof type is not supported. + */ + @JvmStatic operator fun invoke( issuanceRequest: IssuanceRequest, issuerSupportedProofTypes: ProofTypesSupported, @@ -101,14 +154,25 @@ internal abstract class ProofSigner { CWTProofSigner(issuanceRequest, alg, crv) } - else -> null + else -> null // should never happen. LDP_VP is not supported in [SupportedProofTypes] }?.let { Result.success(it) } - ?: Result.failure(UnsupportedProofTypeException()) + ?: Result.failure(UnsupportedAlgorithmException()) } } + /** + * Sealed interface for the user authentication status. + */ sealed interface UserAuthStatus { + /** + * User authentication is not required. + */ object NotRequired : UserAuthStatus + + /** + * User authentication is required. + * @property cryptoObject The crypto object to use for authentication. + */ data class Required(val cryptoObject: CryptoObject? = null) : UserAuthStatus } } \ No newline at end of file diff --git a/wallet-core/src/main/java/eu/europa/ec/eudi/wallet/issue/openid4vci/Utils.kt b/wallet-core/src/main/java/eu/europa/ec/eudi/wallet/issue/openid4vci/Utils.kt index 0a0998ad..9390c0bd 100644 --- a/wallet-core/src/main/java/eu/europa/ec/eudi/wallet/issue/openid4vci/Utils.kt +++ b/wallet-core/src/main/java/eu/europa/ec/eudi/wallet/issue/openid4vci/Utils.kt @@ -23,7 +23,7 @@ import eu.europa.ec.eudi.openid4vci.MsoMdocCredential import eu.europa.ec.eudi.wallet.document.CreateIssuanceRequestResult import eu.europa.ec.eudi.wallet.document.DocumentManager import eu.europa.ec.eudi.wallet.document.IssuanceRequest -import eu.europa.ec.eudi.wallet.issue.openid4vci.ProofSigner.Factory.selectSupportedProofType +import eu.europa.ec.eudi.wallet.issue.openid4vci.ProofSigner.Companion.selectSupportedProofType import org.bouncycastle.util.io.pem.PemObject import org.bouncycastle.util.io.pem.PemWriter import java.io.StringWriter