Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clean up code (minor refactorings, removal of unused code, etc.) #5

Open
wants to merge 1 commit into
base: workingBranch
Choose a base branch
from
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
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ plugins {
alias libs.plugins.dokka apply false
alias libs.plugins.dependency.license.report apply false
alias libs.plugins.dependencycheck apply false
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,12 @@ object Constants {
// mDL
const val MDL_DOCTYPE = "org.iso.18013.5.1.mDL"
const val MDL_NAMESPACE = "org.iso.18013.5.1"

// mdoc
const val MDOC_FORMAT = "mso_mdoc"
const val MDOC_FORMAT_ZKP = "mso_mdoc+zkp"

// sdjwt
const val SDJWT_FORMAT = "vc+sd-jwt"
const val SDJWT_FORMAT_ZKP = "vc+sd-jwt+zkp"
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ package eu.europa.ec.eudi.wallet.issue.openid4vci
* @constructor Creates a new [AuthorizationResponse] instance.
* @param authorizationCode the authorization code
* @param serverState the server state
* @param dpopNonce the dpopNonce
*/
public data class AuthorizationResponse(
data class AuthorizationResponse(
val authorizationCode: String,
val serverState: String,
val dpopNonce: String
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ internal fun interface CredentialConfigurationFilter {

/**
* Companion object for [CredentialConfigurationFilter] instances.
* @property MsoMdocFormatFilter filter for [CredentialConfiguration] instances for mso_mdoc format
* @property SdJwtOrMsoMdocFormatFilter filter for [CredentialConfiguration] instances for mso_mdoc or sdjwt format
*/
companion object {

Expand All @@ -47,12 +47,8 @@ internal fun interface CredentialConfigurationFilter {
}

/**
* Filter for [CredentialConfiguration] instances for mso_mdoc format
* Filter for [CredentialConfiguration] instances for mso_mdoc format and sdjwt
*/
@JvmSynthetic
internal val MsoMdocFormatFilter: CredentialConfigurationFilter =
FormatFilter(MsoMdocCredential::class)

internal val SdJwtOrMsoMdocFormatFilter: CredentialConfigurationFilter =
CredentialConfigurationFilter {
it.instanceOf(SdJwtVcCredential::class) || it.instanceOf(MsoMdocCredential::class)
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package eu.europa.ec.eudi.wallet.issue.openid4vci

import eu.europa.ec.eudi.openid4vci.*
import eu.europa.ec.eudi.wallet.document.Constants.EU_PID_DOCTYPE

/**
* Default implementation of [Offer].
Expand All @@ -41,9 +42,6 @@ internal data class DefaultOffer(

override val offeredDocuments: List<Offer.OfferedDocument>
get() = issuerMetadata.credentialConfigurationsSupported
// TODO temporarily removed to make it work
//.filterKeys { it in credentialOffer.credentialConfigurationIdentifiers }
//.filterValues { credentialConfigurationFilter(it) }
.map { (id, conf) -> DefaultOfferedDocument(id, conf) }

override val txCodeSpec: Offer.TxCodeSpec?
Expand Down Expand Up @@ -93,7 +91,7 @@ internal val CredentialConfiguration.name: String
internal val CredentialConfiguration.docType: String
@JvmSynthetic get() = when (this) {
is MsoMdocCredential -> docType
is SdJwtVcCredential -> "eu.europa.ec.eudi.pid.1"
is SdJwtVcCredential -> EU_PID_DOCTYPE
else -> "unknown"
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ private fun String.toDocument(

val vct = payloadJson.getString("vct")
val docName = "Personalausweis"
val data = payloadJson.toString()

SdJwtDocument(
id = id,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,6 @@ internal class OfferCreator(
DocTypeFilter(docType),
ProofTypeFilter(config.proofTypes)
)
// TODO temporarily removed to make it work
// val credentialConfigurationId =
// credentialIssuerMetadata.credentialConfigurationsSupported.filterValues { conf ->
// credentialConfigurationFilter(conf)
// }.keys.firstOrNull() ?: throw IllegalStateException("No suitable configuration found")

val credentialOffer = CredentialOffer(
credentialIssuerIdentifier = credentialIssuerId,
credentialIssuerMetadata = credentialIssuerMetadata,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,9 @@ package eu.europa.ec.eudi.wallet.issue.openid4vci

import eu.europa.ec.eudi.openid4vci.CredentialOfferRequestResolver
import eu.europa.ec.eudi.wallet.issue.openid4vci.CredentialConfigurationFilter.Companion.Compose
import eu.europa.ec.eudi.wallet.issue.openid4vci.CredentialConfigurationFilter.Companion.MsoMdocFormatFilter
import eu.europa.ec.eudi.wallet.issue.openid4vci.CredentialConfigurationFilter.Companion.ProofTypeFilter
import eu.europa.ec.eudi.wallet.issue.openid4vci.CredentialConfigurationFilter.Companion.SdJwtOrMsoMdocFormatFilter
import io.ktor.client.*
import io.ktor.client.HttpClient
import org.jetbrains.annotations.VisibleForTesting

internal class OfferResolver(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ import eu.europa.ec.eudi.wallet.document.StoreDocumentResult
import eu.europa.ec.eudi.wallet.document.UnsignedDocument
import eu.europa.ec.eudi.wallet.issue.openid4vci.IssueEvent.Companion.documentFailed
import eu.europa.ec.eudi.wallet.logging.Logger
import eu.europa.ec.eudi.wallet.logging.d
import eu.europa.ec.eudi.wallet.transfer.openid4vp.OpenId4vpManager.Companion.TAG
import eu.europa.ec.eudi.wallet.util.parseCertificateFromSdJwt
import kotlinx.coroutines.CancellableContinuation
import kotlinx.coroutines.CoroutineScope
Expand All @@ -38,7 +36,6 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.serialization.json.Json
import org.bouncycastle.util.encoders.Hex
import org.json.JSONObject
import java.io.Closeable
import java.util.Base64
Expand All @@ -64,7 +61,7 @@ internal class ProcessResponse(
}
}

suspend fun process(
private suspend fun process(
unsignedDocument: UnsignedDocument,
outcomeResult: Result<SubmissionOutcome>
) {
Expand All @@ -90,61 +87,15 @@ internal class ProcessResponse(
continuations.values.forEach { it.cancel() }
}

fun processSubmittedRequest(unsignedDocument: UnsignedDocument, outcome: SubmissionOutcome) {
private fun processSubmittedRequest(
unsignedDocument: UnsignedDocument,
outcome: SubmissionOutcome
) {
when (outcome) {
is SubmissionOutcome.Success -> when (val credential = outcome.credentials[0]) {
is IssuedCredential.Issued -> try {
if (isSdJwt(credential.credential)) {
val certificate = parseCertificateFromSdJwt(credential.credential)

val ecKey = ECKey.parse(certificate)
val jwtSignatureVerifier = ECDSAVerifier(ecKey).asJwtVerifier()

CoroutineScope(Dispatchers.IO).launch {
SdJwtVerifier.verifyIssuance(
jwtSignatureVerifier,
credential.credential
).getOrThrow()

DocumentManagerSdJwt.storeDocument(
unsignedDocument.id,
credential.credential
)
documentManager.deleteDocumentById(unsignedDocument.id)
listener.invoke(
IssueEvent.DocumentIssued(
unsignedDocument.id,
unsignedDocument.name,
unsignedDocument.docType
)
)
}
} else {
val cborBytes = Base64.getUrlDecoder().decode(credential.credential)

documentManager.storeIssuedDocument(
unsignedDocument,
cborBytes
).notifyListener(unsignedDocument)
}
} catch (e: Throwable) {
if (isSdJwt(credential.credential)) {
documentManager.deleteDocumentById(unsignedDocument.id)
} else {
DocumentManagerSdJwt.deleteDocument(unsignedDocument.id)
}
listener(documentFailed(unsignedDocument, e))
}

is IssuedCredential.Deferred -> {
val contextToStore = deferredContextCreator.create(credential)
documentManager.storeDeferredDocument(
unsignedDocument,
contextToStore.toByteArray()
)
.notifyListener(unsignedDocument, isDeferred = true)
}
}
is SubmissionOutcome.Success -> processSubmittedRequestSuccess(
outcome,
unsignedDocument
)

is SubmissionOutcome.InvalidProof -> {
documentManager.deleteDocumentById(unsignedDocument.id)
Expand All @@ -163,16 +114,89 @@ internal class ProcessResponse(
}
}

private fun processSubmittedRequestSuccess(
outcome: SubmissionOutcome.Success,
unsignedDocument: UnsignedDocument
) {
when (val credential = outcome.credentials[0]) {
is IssuedCredential.Issued -> try {
if (isSdJwt(credential.credential)) {
processIssuedSdjwt(credential, unsignedDocument)
} else {
processIssuedMdoc(credential, unsignedDocument)
}
} catch (e: Throwable) {
if (isSdJwt(credential.credential)) {
documentManager.deleteDocumentById(unsignedDocument.id)
} else {
DocumentManagerSdJwt.deleteDocument(unsignedDocument.id)
}
listener(documentFailed(unsignedDocument, e))
}

is IssuedCredential.Deferred -> {
val contextToStore = deferredContextCreator.create(credential)
documentManager.storeDeferredDocument(
unsignedDocument,
contextToStore.toByteArray()
).notifyListener(unsignedDocument, isDeferred = true)
}
}
}

private fun isSdJwt(credential: String): Boolean {
return try {
val headerString = credential.split(".").first()
val headerJson = JSONObject(String(Base64.getUrlDecoder().decode(headerString)))
// try to parse to header json
JSONObject(String(Base64.getUrlDecoder().decode(headerString)))
true
} catch (e: Exception) {
false
}
}

private fun processIssuedSdjwt(
credential: IssuedCredential.Issued,
unsignedDocument: UnsignedDocument
) {
val certificate = parseCertificateFromSdJwt(credential.credential)

val ecKey = ECKey.parse(certificate)
val jwtSignatureVerifier = ECDSAVerifier(ecKey).asJwtVerifier()

CoroutineScope(Dispatchers.IO).launch {
SdJwtVerifier.verifyIssuance(
jwtSignatureVerifier,
credential.credential
).getOrThrow()

DocumentManagerSdJwt.storeDocument(
unsignedDocument.id,
credential.credential
)
documentManager.deleteDocumentById(unsignedDocument.id)
listener.invoke(
IssueEvent.DocumentIssued(
unsignedDocument.id,
unsignedDocument.name,
unsignedDocument.docType
)
)
}
}

private fun processIssuedMdoc(
credential: IssuedCredential.Issued,
unsignedDocument: UnsignedDocument
) {
val cborBytes = Base64.getUrlDecoder().decode(credential.credential)

documentManager.storeIssuedDocument(
unsignedDocument,
cborBytes
).notifyListener(unsignedDocument)
}

private fun UserAuthRequiredException.toIssueEvent(
unsignedDocument: UnsignedDocument,
): IssueEvent.DocumentRequiresUserAuth {
Expand Down
Loading
Loading