Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ open class IssuerSignedItemSerializer(

val elementValueContainer = first { (it.key as CborText).value == PROP_ELEMENT_VALUE }.value
val elementValue = CborCredentialSerializer.lookupSerializer(namespace, elementId)?.let {
runCatching {
catchingUnwrapped {
coseCompliantSerializer.decodeFromByteArray(it, elementValueContainer.cbor)
}.getOrElse {
decodeGenericElementValue(elementValueContainer.cbor)
Expand All @@ -197,14 +197,14 @@ open class IssuerSignedItemSerializer(
}

private fun decodeGenericElementValue(bytes: ByteArray): Any {
runCatching { return coseCompliantSerializer.decodeFromByteArray(LocalDate.serializer(), bytes) }
runCatching { return coseCompliantSerializer.decodeFromByteArray(InstantStringSerializer, bytes) }
runCatching { return coseCompliantSerializer.decodeFromByteArray(String.serializer(), bytes) }
runCatching { return coseCompliantSerializer.decodeFromByteArray(Long.serializer(), bytes) }
runCatching { return coseCompliantSerializer.decodeFromByteArray(Float.serializer(), bytes) }
runCatching { return coseCompliantSerializer.decodeFromByteArray(Double.serializer(), bytes) }
runCatching { return coseCompliantSerializer.decodeFromByteArray(Boolean.serializer(), bytes) }
runCatching { return coseCompliantSerializer.decodeFromByteArray(ByteArraySerializer(), bytes) }
catchingUnwrapped { return coseCompliantSerializer.decodeFromByteArray(LocalDate.serializer(), bytes) }
catchingUnwrapped { return coseCompliantSerializer.decodeFromByteArray(InstantStringSerializer, bytes) }
catchingUnwrapped { return coseCompliantSerializer.decodeFromByteArray(String.serializer(), bytes) }
catchingUnwrapped { return coseCompliantSerializer.decodeFromByteArray(Long.serializer(), bytes) }
catchingUnwrapped { return coseCompliantSerializer.decodeFromByteArray(Float.serializer(), bytes) }
catchingUnwrapped { return coseCompliantSerializer.decodeFromByteArray(Double.serializer(), bytes) }
catchingUnwrapped { return coseCompliantSerializer.decodeFromByteArray(Boolean.serializer(), bytes) }
catchingUnwrapped { return coseCompliantSerializer.decodeFromByteArray(ByteArraySerializer(), bytes) }
return bytes
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package at.asitplus.openid

import at.asitplus.catchingUnwrapped
import at.asitplus.signum.indispensable.josef.JsonWebToken
import at.asitplus.signum.indispensable.josef.JwsCompact
import at.asitplus.signum.indispensable.josef.JwsCompactStringSerializer
Expand Down Expand Up @@ -33,13 +34,13 @@ data class CredentialRequestProofContainer(

val jwtParsed: Collection<JwsCompactTyped<JsonWebToken>>? by lazy {
jwt?.mapNotNull {
runCatching<JwsCompactTyped<JsonWebToken>> { it.typed() }.getOrNull()
catchingUnwrapped<JwsCompactTyped<JsonWebToken>> { it.typed() }.getOrNull()
}
}

val attestationParsed: Collection<JwsCompactTyped<KeyAttestationJwt>>? by lazy {
attestation?.mapNotNull {
runCatching<JwsCompactTyped<KeyAttestationJwt>> { it.typed() }.getOrNull()
catchingUnwrapped<JwsCompactTyped<KeyAttestationJwt>> { it.typed() }.getOrNull()
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package at.asitplus.openid

import at.asitplus.catchingUnwrapped
import at.asitplus.signum.indispensable.SignatureAlgorithm
import kotlinx.serialization.KSerializer
import kotlinx.serialization.SerialName
Expand Down Expand Up @@ -195,7 +196,7 @@ sealed interface SupportedCredentialFormat {
}
val jsonObject = decoder.decodeJsonElement().jsonObject
val formatIdentifier = jsonObject[SerialNames.FORMAT]?.jsonPrimitive
val format = formatIdentifier?.runCatching {
val format = formatIdentifier?.catchingUnwrapped {
CredentialFormatEnum.parse(formatIdentifier.content)
}?.getOrNull()

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package at.asitplus.csp2

import at.asitplus.catchingUnwrapped
import at.asitplus.rfc3986uri.Rfc3986UriSchemeName

sealed interface ContentSecurityPolicySourceExpression {
Expand All @@ -23,22 +24,22 @@ sealed interface ContentSecurityPolicySourceExpression {
*/
operator fun invoke(string: String): ContentSecurityPolicySourceExpression {
if (string.isNeitherSchemeNorHostSource()) {
runCatching {
catchingUnwrapped {
return ContentSecurityPolicySourceExpressionKeyword(
ContentSecurityPolicySourceExpressionKeywordContent.valueOf(string.removePrefix("'").removeSuffix("'"))
ContentSecurityPolicySourceExpressionKeywordContent.valueOf(
string.removePrefix("'").removeSuffix("'")
)
)
}
runCatching {
catchingUnwrapped {
return ContentSecurityPolicySourceExpressionNonce.parse(string)
}
runCatching {
catchingUnwrapped {
return ContentSecurityPolicySourceExpressionHash(string)
}
} else if (string.isSchemeSource()) {
runCatching {
return ContentSecurityPolicySourceExpressionScheme(
Rfc3986UriSchemeName(string.removeSuffix(":"))
)
catchingUnwrapped {
return ContentSecurityPolicySourceExpressionScheme(Rfc3986UriSchemeName(string.removeSuffix(":")))
}
} else {
return ContentSecurityPolicySourceExpressionHost(string)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package at.asitplus.csp2

import at.asitplus.catchingUnwrapped
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
Expand Down Expand Up @@ -85,9 +86,7 @@ data class ContentSecurityPolicySourceList(
listOf()
} else {
it.split(*asciiWhitespaces).mapNotNull {
runCatching {
ContentSecurityPolicySourceExpression.Companion(it)
}.getOrNull()
catchingUnwrapped { ContentSecurityPolicySourceExpression(it) }.getOrNull()
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ value class W3cSubresourceIntegrityMetadata(
val expression: ContentSecurityPolicySourceExpressionHash
) {
constructor(string: String): this(
ContentSecurityPolicySourceExpressionHash.Companion("'$string'")
ContentSecurityPolicySourceExpressionHash("'$string'")
)

constructor(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package at.asitplus.wallet.lib.ktor.openid

import at.asitplus.catching
import at.asitplus.catchingUnwrapped
import at.asitplus.openid.OpenIdConstants.Errors.USE_DPOP_NONCE
import at.asitplus.wallet.lib.oidvci.OAuth2Error
import io.ktor.client.call.*
Expand Down Expand Up @@ -57,9 +58,8 @@ suspend inline fun <reified T, R> IntermediateResult<R>.onSuccess(
}

/** Extracts the header `DPoP-Nonce` if the error is `use_dpop_nonce`. */
fun OAuth2Error?.dpopNonce(response: HttpResponse) = runCatching {
authorizationServerProvidedNonce(response)
?: resourceServerProvidedNonce(response)
fun OAuth2Error?.dpopNonce(response: HttpResponse) = catchingUnwrapped {
authorizationServerProvidedNonce(response) ?: resourceServerProvidedNonce(response)
}.getOrNull()

/** [RFC 9449 8.](https://datatracker.ietf.org/doc/html/rfc9449#name-authorization-server-provid) */
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package at.asitplus.wallet.lib.ktor.openid

import at.asitplus.catchingUnwrapped
import at.asitplus.rfc3986uri.Rfc3986UniformResourceIdentifier
import at.asitplus.rfc3986uri.Rfc3986UriSchemeName
import at.asitplus.wallet.sdjwt.SdJwtTypeMetadataDefinition
Expand Down Expand Up @@ -32,18 +33,16 @@ class KtorSdJwtTypeMetadataDocumentRetriever(
val json: Json = Json.Default,
val integrityChecker: SdJwtTypeMetadataDocumentIntegrityChecker = SdJwtTypeMetadataDocumentIntegrityChecker.DEFAULT,
) : SdJwtTypeMetadataDocumentRetriever {
private val staticCache = mutableMapOf<SdJwtVcType, Pair<W3cSubresourceIntegrityMetadata, SdJwtTypeMetadataDocument>>()
private val staticCache =
mutableMapOf<SdJwtVcType, Pair<W3cSubresourceIntegrityMetadata, SdJwtTypeMetadataDocument>>()
private val dynamicCache = mutableMapOf<SdJwtVcType, Pair<Instant, SdJwtTypeMetadataDocument>>()

override suspend fun retrieve(
sdJwtVcType: SdJwtVcType,
integrityMetadata: W3cSubresourceIntegrityMetadata?,
): SdJwtTypeMetadataDocument? {
val url = locateUrl(sdJwtVcType) ?: return null

val uri = runCatching {
Rfc3986UniformResourceIdentifier.Companion(url)
}.getOrNull() ?: return null
val uri = catchingUnwrapped { Rfc3986UniformResourceIdentifier(url) }.getOrNull() ?: return null

if (uri.schemeName !in Rfc3986UriSchemeName.Common.run { listOf(HTTPS, HTTP) }) {
return null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package at.asitplus.wallet.lib.ktor.openid

import at.asitplus.KmmResult
import at.asitplus.catching
import at.asitplus.catchingUnwrapped
import at.asitplus.openid.AuthenticationRequestParameters
import at.asitplus.openid.AuthenticationResponseParameters
import at.asitplus.openid.JarRequestParameters
Expand Down Expand Up @@ -615,11 +616,11 @@ private suspend fun parseTokenIntrospectionResponse(
body: String,
verifyTokenIntrospectionJwt: suspend (JwsCompactTyped<TokenIntrospectionResponse>) -> Boolean,
requestedResponseFormat: TokenIntrospectionRequest.ResponseFormat?,
): TokenIntrospectionResponse = runCatching {
): TokenIntrospectionResponse = catchingUnwrapped {
if (requestedResponseFormat == TokenIntrospectionRequest.ResponseFormat.JWT) {
parseJwt(body, verifyTokenIntrospectionJwt)
} else {
runCatching {
catchingUnwrapped {
joseCompliantSerializer.decodeFromString(TokenIntrospectionResponse.serializer(), body)
}.getOrElse {
parseJwt(body, verifyTokenIntrospectionJwt)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ class OpenId4VpWallet(
*/
suspend fun getMatchingCredentials(
preparationState: AuthorizationResponsePreparationState,
) = catchingUnwrapped {
) = catching {
openId4VpHolder.getMatchingCredentials(preparationState).getOrThrow()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package at.asitplus.wallet.lib.oauth2

import at.asitplus.KmmResult
import at.asitplus.catching
import at.asitplus.catchingUnwrapped
import at.asitplus.iso.sha256
import at.asitplus.openid.AuthenticationRequestParameters
import at.asitplus.openid.AuthenticationResponseParameters
Expand Down Expand Up @@ -660,7 +661,7 @@ class SimpleAuthorizationService(
): KmmResult<TokenIntrospectionResult> = catching {
// TODO Which client_id to pass?
clientAuthenticationService.authenticateClient(httpRequest, null)
val response = runCatching {
val response = catchingUnwrapped {
tokenService.verification.getTokenInfo(request.token)
}.fold(
onSuccess = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package at.asitplus.wallet.lib.oidvci

import at.asitplus.catchingUnwrapped
import at.asitplus.openid.AuthorizationDetails
import at.asitplus.openid.OpenIdAuthorizationDetails
import at.asitplus.wallet.lib.data.CredentialRepresentation
Expand Down Expand Up @@ -35,7 +36,7 @@ class CredentialAuthorizationServiceStrategy(
} else {
credentials.mapNotNull { (scheme, representation) ->
if (credentialSchemes.contains(scheme)) {
runCatching { mapper.toCredentialIdentifier(scheme, representation) }.getOrNull()
catchingUnwrapped { mapper.toCredentialIdentifier(scheme, representation) }.getOrNull()
} else null
}.toSet()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package at.asitplus.wallet.lib.oidvci

import at.asitplus.KmmResult
import at.asitplus.catching
import at.asitplus.catchingUnwrapped
import at.asitplus.openid.BatchCredentialIssuanceMetadata
import at.asitplus.openid.ClientNonceResponse
import at.asitplus.openid.CredentialRequestParameters
Expand Down Expand Up @@ -73,7 +74,7 @@ class CredentialIssuer(
publicContext = publicContext,
requireKeyAttestation = requireKeyAttestation,
verifyAttestationProof = {
val tokenStatusValid = runCatching {
val tokenStatusValid = catchingUnwrapped {
it.payload.keyStorageStatus?.status?.get(StatusListInfo.SerialNames.STATUS_LIST_INFO)?.let { statusList ->
Json.decodeFromJsonElement<StatusListInfo>(statusList).let { statusListInfo ->
if (statusListTokenResolver?.toTokenStatusResolver()
Expand All @@ -84,7 +85,7 @@ class CredentialIssuer(
}
}.isSuccess

val signatureValid = runCatching {
val signatureValid = catchingUnwrapped {
VerifyJwsObject().verifyJwsSignature(it.jws, it.jws.jwsHeader.publicKey!!).isSuccess
}.getOrDefault(false)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ class WalletService(
* which may contain a direct [CredentialOffer] or a URI pointing to it.
*/
suspend fun parseCredentialOffer(input: String): KmmResult<CredentialOffer> = catching {
catching {
catchingUnwrapped {
input.extractParams().fetchCredentialOffer()
}.getOrNull() ?: catchingUnwrapped {
joseCompliantSerializer.decodeFromString<CredentialOffer>(input)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package at.asitplus.wallet.lib.openid

import at.asitplus.KmmResult
import at.asitplus.catching
import at.asitplus.catchingUnwrapped
import at.asitplus.dif.PresentationDefinition
import at.asitplus.openid.AuthenticationRequestParameters
import at.asitplus.openid.AuthenticationResponseParameters
Expand Down Expand Up @@ -42,6 +41,7 @@ import at.asitplus.wallet.lib.agent.Holder
import at.asitplus.wallet.lib.agent.HolderAgent
import at.asitplus.wallet.lib.agent.KeyMaterial
import at.asitplus.wallet.lib.agent.RandomSource
import at.asitplus.wallet.lib.agent.SubjectCredentialStore
import at.asitplus.wallet.lib.cbor.CoseHeaderNone
import at.asitplus.wallet.lib.cbor.SignCoseDetached
import at.asitplus.wallet.lib.cbor.SignCoseDetachedFun
Expand Down Expand Up @@ -135,7 +135,7 @@ class OpenId4VpHolder(
OAuth2AuthorizationServerMetadata(
issuer = clientId,
authorizationEndpoint = authorizationEndpoint,
responseTypesSupported = setOf(OpenIdConstants.ID_TOKEN, OpenIdConstants.VP_TOKEN),
responseTypesSupported = setOf(OpenIdConstants.ID_TOKEN, VP_TOKEN),
scopesSupported = setOf(OpenIdConstants.SCOPE_OPENID),
idTokenSigningAlgorithmsSupportedStrings = supportedJwsAlgorithms.toSet(),
requestObjectSigningAlgorithmsSupportedStrings = supportedJwsAlgorithms.toSet(),
Expand Down Expand Up @@ -344,12 +344,13 @@ class OpenId4VpHolder(

private fun RequestParametersFrom<AuthenticationRequestParameters>.extractLeafCertKey(): JsonWebKey? =
(this as? RequestParametersFrom.Jws<AuthenticationRequestParameters>)?.jws?.let {
(it as? JwsCompact)?.jwsHeader?.certificateChain?.firstOrNull()?.decodedPublicKey?.getOrNull()?.toJsonWebKey()
(it as? JwsCompact)?.jwsHeader?.certificateChain?.firstOrNull()?.decodedPublicKey?.getOrNull()
?.toJsonWebKey()
}

suspend fun getMatchingCredentials(
preparationState: AuthorizationResponsePreparationState,
) = catchingUnwrapped {
): KmmResult<CredentialMatchingResult<SubjectCredentialStore.StoreEntry>> = catching {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

document API change in changelog

when (val presentationRequest = preparationState.credentialPresentationRequest) {
is CredentialPresentationRequest.DCQLRequest -> holder.matchDCQLQueryAgainstCredentialStoreV2(
dcqlQuery = presentationRequest.dcqlQuery,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package at.asitplus.wallet.eupid

import at.asitplus.catchingUnwrapped
import at.asitplus.wallet.lib.data.LocalDateOrInstant
import io.matthewnelson.encoding.base64.Base64
import io.matthewnelson.encoding.core.Encoder.Companion.encodeToString
Expand Down Expand Up @@ -168,13 +169,13 @@ data class EuPidCredential(
/** One or more alpha-2 country codes as specified in ISO 3166-1, representing the nationality of the user to whom
* the person identification data relates.*/
val nationality: String? by lazy {
nationalityElement?.let { runCatching { it.jsonPrimitive.content }.getOrNull() }
nationalityElement?.let { catchingUnwrapped { it.jsonPrimitive.content }.getOrNull() }
}

/** One or more alpha-2 country codes as specified in ISO 3166-1, representing the nationality of the user to whom
* the person identification data relates.*/
val nationalities: Collection<String>? by lazy {
nationalityElement?.let { runCatching { it.jsonArray.map { it.jsonPrimitive.content } }.getOrNull() }
nationalityElement?.let { catchingUnwrapped { it.jsonArray.map { it.jsonPrimitive.content } }.getOrNull() }
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,7 @@ class HolderAgent(
private fun Holder.StoreCredentialInput.Iso.extractIssuerKey(): CoseKey? =
issuerSigned.issuerAuth.unprotectedHeader?.certificateChain?.firstOrNull()?.let {
catchingUnwrapped { X509Certificate.decodeFromDer(it) }.getOrNull()?.decodedPublicKey?.getOrNull()
?.toCoseKey()
?.getOrNull()
?.toCoseKey()?.getOrNull()
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ package at.asitplus.wallet.lib.agent
* see the "LICENSE" file for more details
*/

import at.asitplus.catchingUnwrapped
import at.asitplus.openid.OidcUserInfo
import at.asitplus.openid.OidcUserInfoExtended
import at.asitplus.signum.indispensable.cosef.io.Base16Strict
Expand Down Expand Up @@ -239,7 +240,7 @@ val AgentRevocationTest by matrixSuite {
}

"identifier list JWT should not be issued" {
runCatching {
catchingUnwrapped {
it.statusListIssuer.issueStatusListJwt(kind = RevocationList.Kind.IDENTIFIER_LIST)
}.isFailure shouldBe true
}
Expand Down
Loading