Skip to content

Commit

Permalink
revert sources to 1.7.3 state
Browse files Browse the repository at this point in the history
  • Loading branch information
JesusMcCloud committed Dec 11, 2023
1 parent c1b14ae commit 9f1b14d
Show file tree
Hide file tree
Showing 53 changed files with 701 additions and 762 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,7 @@ interface CryptoService {

fun messageDigest(input: ByteArray, digest: Digest): KmmResult<ByteArray>

val identifier: String
get() = toJsonWebKey().getIdentifier()
val keyId: String

val jwsAlgorithm: JwsAlgorithm

Expand All @@ -58,10 +57,8 @@ interface VerifierCryptoService {
publicKey: JsonWebKey
): KmmResult<Boolean>

}

expect object CryptoUtils {
fun extractPublicKeyFromX509Cert(it: ByteArray): JsonWebKey?

}

data class AuthenticatedCiphertext(val ciphertext: ByteArray, val authtag: ByteArray) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,9 @@ import at.asitplus.KmmResult
object EmptyCredentialDataProvider : IssuerCredentialDataProvider {

override fun getClaim(subjectId: String, attributeName: String)
: KmmResult<IssuerCredentialDataProvider.CredentialToBeIssued> =
KmmResult.failure(NotImplementedError())
: KmmResult<IssuerCredentialDataProvider.CredentialToBeIssued> = KmmResult.failure(NullPointerException())

override fun getCredential(subjectId: String, attributeType: String)
: KmmResult<IssuerCredentialDataProvider.CredentialToBeIssued> =
KmmResult.failure(NotImplementedError())
: KmmResult<IssuerCredentialDataProvider.CredentialToBeIssued> = KmmResult.failure(NullPointerException())

override fun getCredentialWithType(subjectId: String, attributeTypes: Collection<String>)
: KmmResult<List<IssuerCredentialDataProvider.CredentialToBeIssued>> =
KmmResult.failure(NotImplementedError())
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,6 @@ import at.asitplus.wallet.lib.data.VerifiablePresentation
*/
interface Holder {

/**
* The identifier for this agent, typically the `keyId` from the cryptographic key,
* e.g. `did:key:mAB...` or `urn:ietf:params:oauth:jwk-thumbprint:sha256:...`
*/
val identifier: String

/**
* Sets the revocation list ot use for further processing of Verifiable Credentials
*
Expand Down Expand Up @@ -119,4 +113,5 @@ interface Holder {
data class Signed(val jws: String) : CreatePresentationResult()
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ package at.asitplus.wallet.lib.agent
import at.asitplus.wallet.lib.data.VerifiableCredentialJws
import at.asitplus.wallet.lib.data.VerifiablePresentation
import at.asitplus.wallet.lib.jws.DefaultJwsService
import at.asitplus.wallet.lib.jws.JwsContentTypeConstants
import at.asitplus.wallet.lib.jws.JwsContentType
import at.asitplus.wallet.lib.jws.JwsService
import io.github.aakira.napier.Napier
import kotlinx.datetime.Clock


/**
Expand All @@ -16,19 +17,20 @@ class HolderAgent constructor(
private val validator: Validator = Validator.newDefaultInstance(),
private val subjectCredentialStore: SubjectCredentialStore = InMemorySubjectCredentialStore(),
private val jwsService: JwsService,
override val identifier: String
private val keyId: String
) : Holder {

companion object {
fun newDefaultInstance(
cryptoService: CryptoService = DefaultCryptoService(),
verifierCryptoService: VerifierCryptoService = DefaultVerifierCryptoService(),
subjectCredentialStore: SubjectCredentialStore = InMemorySubjectCredentialStore(),
clock: Clock = Clock.System,
) = HolderAgent(
validator = Validator.newDefaultInstance(verifierCryptoService, Parser()),
subjectCredentialStore = subjectCredentialStore,
jwsService = DefaultJwsService(cryptoService),
identifier = cryptoService.identifier,
keyId = cryptoService.keyId
)

/**
Expand All @@ -41,7 +43,7 @@ class HolderAgent constructor(
validator = Validator.newDefaultInstance(DefaultVerifierCryptoService(), Parser()),
subjectCredentialStore = subjectCredentialStore,
jwsService = DefaultJwsService(cryptoService),
identifier = cryptoService.identifier,
keyId = cryptoService.keyId
)
}

Expand All @@ -65,7 +67,7 @@ class HolderAgent constructor(
val rejected = mutableListOf<String>()
val attachments = mutableListOf<Holder.StoredAttachmentResult>()
credentialList.forEach { cred ->
when (val vc = validator.verifyVcJws(cred.vcJws, identifier)) {
when (val vc = validator.verifyVcJws(cred.vcJws, keyId)) {
is Verifier.VerifyCredentialResult.InvalidStructure -> rejected += vc.input
is Verifier.VerifyCredentialResult.Revoked -> rejected += vc.input
is Verifier.VerifyCredentialResult.Success -> accepted += vc.jws
Expand Down Expand Up @@ -147,9 +149,9 @@ class HolderAgent constructor(
audienceId: String,
): Holder.CreatePresentationResult? {
val vp = VerifiablePresentation(validCredentials.toTypedArray())
val vpSerialized = vp.toJws(challenge, identifier, audienceId).serialize()
val vpSerialized = vp.toJws(challenge, keyId, audienceId).serialize()
val jwsPayload = vpSerialized.encodeToByteArray()
val jws = jwsService.createSignedJwt(JwsContentTypeConstants.JWT, jwsPayload)
val jws = jwsService.createSignedJwt(JwsContentType.JWT, jwsPayload)
?: return null
return Holder.CreatePresentationResult.Signed(jws)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package at.asitplus.wallet.lib.agent

import at.asitplus.wallet.lib.jws.JsonWebKey
import at.asitplus.wallet.lib.msg.JsonWebMessage


Expand All @@ -12,7 +11,7 @@ sealed class InternalNextMessage {

data class SendAndWrap(
val message: JsonWebMessage,
val senderKey: JsonWebKey? = null,
val senderKeyId: String? = null,
val endpoint: String? = null
) : InternalNextMessage()

Expand All @@ -22,7 +21,7 @@ sealed class InternalNextMessage {

data class SendProblemReport(
val message: JsonWebMessage,
val senderKey: JsonWebKey? = null,
val senderKeyId: String? = null,
val endpoint: String? = null
) : InternalNextMessage()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import at.asitplus.wallet.lib.data.ConstantIndex
class IssueCredentialMessenger private constructor(
private val issuer: Issuer? = null,
private val holder: Holder? = null,
private val keyId: String,
messageWrapper: MessageWrapper,
private val serviceEndpoint: String = "https://example.com/",
createProtocolWhenNotActive: Boolean = true,
Expand All @@ -21,6 +22,7 @@ class IssueCredentialMessenger private constructor(
override fun createProtocolInstance() = IssueCredentialProtocol(
issuer = issuer,
holder = holder,
keyId = keyId,
serviceEndpoint = serviceEndpoint,
credentialScheme = credentialScheme,
)
Expand All @@ -32,10 +34,12 @@ class IssueCredentialMessenger private constructor(
*/
fun newHolderInstance(
holder: Holder,
keyId: String,
messageWrapper: MessageWrapper,
credentialScheme: ConstantIndex.CredentialScheme = ConstantIndex.Generic,
) = IssueCredentialMessenger(
holder = holder,
keyId = keyId,
messageWrapper = messageWrapper,
credentialScheme = credentialScheme,
)
Expand All @@ -46,11 +50,13 @@ class IssueCredentialMessenger private constructor(
*/
fun newIssuerInstance(
issuer: Issuer,
keyId: String,
messageWrapper: MessageWrapper,
serviceEndpoint: String,
credentialScheme: ConstantIndex.CredentialScheme = ConstantIndex.Generic,
) = IssueCredentialMessenger(
issuer = issuer,
keyId = keyId,
messageWrapper = messageWrapper,
serviceEndpoint = serviceEndpoint,
credentialScheme = credentialScheme,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ package at.asitplus.wallet.lib.agent
import at.asitplus.wallet.lib.DataSourceProblem
import at.asitplus.wallet.lib.data.AttributeIndex
import at.asitplus.wallet.lib.data.ConstantIndex
import at.asitplus.wallet.lib.msg.RequestCredentialAttachment
import at.asitplus.wallet.lib.data.SchemaIndex
import at.asitplus.wallet.lib.msg.SchemaReference
import at.asitplus.wallet.lib.data.dif.CredentialDefinition
import at.asitplus.wallet.lib.data.dif.CredentialManifest
import at.asitplus.wallet.lib.data.jsonSerializer
import at.asitplus.wallet.lib.jws.JsonWebKey
import at.asitplus.wallet.lib.msg.AttachmentFormatReference
import at.asitplus.wallet.lib.msg.IssueCredential
import at.asitplus.wallet.lib.msg.IssueCredentialBody
Expand All @@ -17,9 +18,7 @@ import at.asitplus.wallet.lib.msg.OutOfBandInvitation
import at.asitplus.wallet.lib.msg.OutOfBandInvitationBody
import at.asitplus.wallet.lib.msg.OutOfBandService
import at.asitplus.wallet.lib.msg.RequestCredential
import at.asitplus.wallet.lib.msg.RequestCredentialAttachment
import at.asitplus.wallet.lib.msg.RequestCredentialBody
import at.asitplus.wallet.lib.msg.SchemaReference
import io.github.aakira.napier.Napier
import kotlinx.serialization.encodeToString

Expand All @@ -40,6 +39,7 @@ typealias IssueCredentialProtocolResult = Holder.StoredCredentialsResult
class IssueCredentialProtocol(
private val issuer: Issuer? = null,
private val holder: Holder? = null,
private val keyId: String,
private val serviceEndpoint: String? = null,
private val credentialScheme: ConstantIndex.CredentialScheme
) : ProtocolStateMachine<IssueCredentialProtocolResult> {
Expand All @@ -51,9 +51,11 @@ class IssueCredentialProtocol(
*/
fun newHolderInstance(
holder: Holder,
keyId: String,
credentialScheme: ConstantIndex.CredentialScheme = ConstantIndex.Generic,
) = IssueCredentialProtocol(
holder = holder,
keyId = keyId,
credentialScheme = credentialScheme,
)

Expand All @@ -63,10 +65,12 @@ class IssueCredentialProtocol(
*/
fun newIssuerInstance(
issuer: Issuer,
keyId: String,
serviceEndpoint: String? = null,
credentialScheme: ConstantIndex.CredentialScheme = ConstantIndex.Generic,
) = IssueCredentialProtocol(
issuer = issuer,
keyId = keyId,
serviceEndpoint = serviceEndpoint,
credentialScheme = credentialScheme,
)
Expand Down Expand Up @@ -101,13 +105,13 @@ class IssueCredentialProtocol(
return createRequestCredential()
}

override suspend fun parseMessage(body: JsonWebMessage, senderKey: JsonWebKey): InternalNextMessage {
override suspend fun parseMessage(body: JsonWebMessage, senderKeyId: String): InternalNextMessage {
when (this.state) {
State.START -> {
if (body is OutOfBandInvitation)
return createRequestCredential(body, senderKey)
return createRequestCredential(body, senderKeyId)
if (body is RequestCredential)
return issueCredential(body, senderKey)
return issueCredential(body, senderKeyId)
return InternalNextMessage.IncorrectState("messageType")
.also { Napier.w("Unexpected messageType: ${body.type}") }
}
Expand All @@ -119,7 +123,7 @@ class IssueCredentialProtocol(
if (body.parentThreadId != invitationId)
return InternalNextMessage.IncorrectState("parentThreadId")
.also { Napier.w("Unexpected parentThreadId: ${body.parentThreadId}") }
return issueCredential(body, senderKey)
return issueCredential(body, senderKeyId)
}

State.REQUEST_CREDENTIAL_SENT -> {
Expand All @@ -138,8 +142,6 @@ class IssueCredentialProtocol(
}

private fun createOobInvitation(): InternalNextMessage {
val recipientKey = issuer?.identifier
?: return InternalNextMessage.IncorrectState("issuer")
val message = OutOfBandInvitation(
body = OutOfBandInvitationBody(
handshakeProtocols = arrayOf(SchemaIndex.PROT_ISSUE_CRED),
Expand All @@ -148,7 +150,7 @@ class IssueCredentialProtocol(
services = arrayOf(
OutOfBandService(
type = "did-communication",
recipientKeys = arrayOf(recipientKey),
recipientKeys = arrayOf(keyId),
serviceEndpoint = serviceEndpoint ?: "https://example.com",
)
)
Expand All @@ -161,34 +163,30 @@ class IssueCredentialProtocol(

private fun createRequestCredential(): InternalNextMessage {
val message = buildRequestCredentialMessage(credentialScheme)
?: return InternalNextMessage.IncorrectState("holder")
return InternalNextMessage.SendAndWrap(message)
.also { this.threadId = message.threadId }
.also { this.state = State.REQUEST_CREDENTIAL_SENT }
}

private fun createRequestCredential(invitation: OutOfBandInvitation, senderKey: JsonWebKey): InternalNextMessage {
private fun createRequestCredential(invitation: OutOfBandInvitation, senderKeyId: String): InternalNextMessage {
val credentialScheme = ConstantIndex.Parser.parseGoalCode(invitation.body.goalCode)
?: return problemReporter.problemLastMessage(invitation.threadId, "goal-code-unknown")
val message = buildRequestCredentialMessage(credentialScheme, invitation.id)
?: return InternalNextMessage.IncorrectState("holder")
val serviceEndpoint = invitation.body.services?.let {
if (it.isNotEmpty()) it[0].serviceEndpoint else null
}
return InternalNextMessage.SendAndWrap(message, senderKey, serviceEndpoint)
return InternalNextMessage.SendAndWrap(message, senderKeyId, serviceEndpoint)
.also { this.threadId = message.threadId }
.also { this.state = State.REQUEST_CREDENTIAL_SENT }
}

private fun buildRequestCredentialMessage(
credentialScheme: ConstantIndex.CredentialScheme,
parentThreadId: String? = null,
): RequestCredential? {
val subject = holder?.identifier
?: return null
): RequestCredential {
val credentialManifest = CredentialManifest(
issuer = "somebody",
subject = subject,
subject = keyId,
credential = CredentialDefinition(
name = credentialScheme.credentialDefinitionName,
schema = SchemaReference(uri = credentialScheme.schemaUri),
Expand All @@ -214,7 +212,7 @@ class IssueCredentialProtocol(
)
}

private suspend fun issueCredential(lastMessage: RequestCredential, senderKey: JsonWebKey): InternalNextMessage {
private suspend fun issueCredential(lastMessage: RequestCredential, senderKeyId: String): InternalNextMessage {
val lastJwmAttachment = lastMessage.attachments?.firstOrNull()
?: return problemReporter.problemLastMessage(lastMessage.threadId, "attachments-missing")
val requestCredentialAttachment = lastJwmAttachment.decodeString()?.let {
Expand All @@ -223,13 +221,16 @@ class IssueCredentialProtocol(
val uri = requestCredentialAttachment.credentialManifest.credential.schema.uri

//default pupilID use case: binding key outside JWM, no subject in JWM. set subject to override
val subjectIdentifier = requestCredentialAttachment.credentialManifest.subject ?: senderKey.getIdentifier()
val subjectKeyId = requestCredentialAttachment.credentialManifest.subject ?: senderKeyId

val requestedAttributeType = AttributeIndex.getTypeOfAttributeForSchemaUri(uri)
?: return problemReporter.problemLastMessage(lastMessage.threadId, "requested-attributes-empty")
val requestedAttributes = AttributeIndex.getListOfAttributesForSchemaUri(uri)

val issuedCredentials = issuer?.issueCredentialWithTypes(subjectIdentifier, listOf(requestedAttributeType))
?: return problemReporter.problemInternal(lastMessage.threadId, "credentials-empty")
val issuedCredentials = when {
requestedAttributeType != null -> issuer?.issueCredential(subjectKeyId, requestedAttributeType)
requestedAttributes.isNotEmpty() -> issuer?.issueCredentials(subjectKeyId, requestedAttributes)
else -> return problemReporter.problemLastMessage(lastMessage.threadId, "requested-attributes-empty")
} ?: return problemReporter.problemInternal(lastMessage.threadId, "credentials-empty")

//TODO: Pack this info into `args` or `comment`
if (issuedCredentials.failed.isNotEmpty()) {
Expand Down Expand Up @@ -272,7 +273,7 @@ class IssueCredentialProtocol(
threadId = lastMessage.threadId!!, //is allowed to fail horribly
attachments = (fulfillmentAttachments + binaryAttachments).toTypedArray()
)
return InternalNextMessage.SendAndWrap(message, senderKey)
return InternalNextMessage.SendAndWrap(message, senderKeyId)
.also { this.threadId = message.threadId }
.also { this.state = State.FINISHED }
}
Expand Down
Loading

0 comments on commit 9f1b14d

Please sign in to comment.