Skip to content

Commit

Permalink
Process pre-authorized openid4vci credential offers.
Browse files Browse the repository at this point in the history
Signed-off-by: Peter Sorotokin <[email protected]>
  • Loading branch information
sorotokin committed Nov 10, 2024
1 parent b4ce259 commit 453c77b
Show file tree
Hide file tree
Showing 20 changed files with 637 additions and 207 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,308 @@
package com.android.identity.documenttype.knowntypes

import com.android.identity.cbor.toDataItem
import com.android.identity.cbor.toDataItemFullDate
import com.android.identity.documenttype.DocumentAttributeType
import com.android.identity.documenttype.DocumentType
import com.android.identity.documenttype.Icon

/**
* Object containing the metadata of the EU Certificate of Residency (COR) document.
*
* TODO: see if this document type still exists and how exactly it is defined. This
* definition is ad hoc and added to facilitate interoperability testing.
*/
object EUCertificateOfResidence {
const val DOCTYPE = "eu.europa.ec.eudi.cor.1"
const val NAMESPACE = "eu.europa.ec.eudi.cor.1"
const val VCT = "https://example.eudi.ec.europa.eu/cor/1"

/**
* Build the EU Personal ID Document Type.
*/
fun getDocumentType(): DocumentType {
return DocumentType.Builder("EU Certificate of Residency")
.addMdocDocumentType(DOCTYPE)
.addVcDocumentType(VCT)
.addAttribute(
DocumentAttributeType.String,
"family_name",
"Family Name",
"Current last name(s), surname(s), or primary identifier of the COR holder",
true,
NAMESPACE,
Icon.PERSON,
SampleData.FAMILY_NAME.toDataItem()
)
.addAttribute(
DocumentAttributeType.String,
"given_name",
"Given Names",
"Current first name(s), other name(s), or secondary identifier of the COR holder",
true,
NAMESPACE,
Icon.PERSON,
SampleData.GIVEN_NAME.toDataItem()
)
.addAttribute(
DocumentAttributeType.Date,
"birth_date",
"Date of Birth",
"Day, month, and year on which the COR holder was born. If unknown, approximate date of birth.",
true,
NAMESPACE,
Icon.TODAY,
SampleData.birthDate.toDataItemFullDate()
)
.addAttribute(
DocumentAttributeType.Boolean,
"age_over_18",
"Older Than 18",
"Age over 18?",
false,
NAMESPACE,
Icon.TODAY,
SampleData.AGE_OVER_18.toDataItem()
)
.addAttribute(
DocumentAttributeType.Boolean,
"age_over_21",
"Older Than 21",
"Age over 21?",
false,
NAMESPACE,
Icon.TODAY,
SampleData.AGE_OVER_21.toDataItem()
)
.addAttribute(
DocumentAttributeType.Date,
"arrival_date",
"Date of Arrival",
"Day, month, and year on which the COR holder arrived to the EU.",
false,
NAMESPACE,
Icon.DATE_RANGE,
SampleData.issueDate.toDataItemFullDate()
)
.addAttribute(
DocumentAttributeType.String,
"resident_address",
"Resident Address",
"The full address of the place where the COR holder currently resides and/or may be contacted (street/house number, municipality etc.)",
false,
NAMESPACE,
Icon.PLACE,
SampleData.RESIDENT_ADDRESS.toDataItem()
)
.addAttribute(
DocumentAttributeType.StringOptions(Options.COUNTRY_ISO_3166_1_ALPHA_2),
"resident_country",
"Resident Country",
"The country where the PID User currently resides, as an Alpha-2 country code as specified in ISO 3166-1",
false,
NAMESPACE,
Icon.PLACE,
SampleData.RESIDENT_COUNTRY.toDataItem()
)
.addAttribute(
DocumentAttributeType.String,
"resident_state",
"Resident State",
"The state, province, district, or local area where the PID User currently resides.",
false,
NAMESPACE,
Icon.PLACE,
SampleData.RESIDENT_STATE.toDataItem()
)
.addAttribute(
DocumentAttributeType.String,
"resident_city",
"Resident City",
"The city where the COR holder currently resides",
false,
NAMESPACE,
Icon.PLACE,
SampleData.RESIDENT_CITY.toDataItem()
)
.addAttribute(
DocumentAttributeType.String,
"resident_postal_code",
"Resident Postal Code",
"The postal code of the place where the COR holder currently resides",
false,
NAMESPACE,
Icon.PLACE,
SampleData.RESIDENT_POSTAL_CODE.toDataItem()
)
.addAttribute(
DocumentAttributeType.String,
"resident_street",
"Resident Street",
"The name of the street where the PID User currently resides.",
false,
NAMESPACE,
Icon.PLACE,
SampleData.RESIDENT_STREET.toDataItem()
)
.addAttribute(
DocumentAttributeType.String,
"resident_house_number",
"Resident House Number",
"The house number where the PID User currently resides, including any affix or suffix",
false,
NAMESPACE,
Icon.PLACE,
SampleData.RESIDENT_HOUSE_NUMBER.toDataItem()
)
.addAttribute(
DocumentAttributeType.String,
"birth_place",
"Place of Birth",
"The place where the COR holder was born.",
false,
NAMESPACE,
Icon.PLACE,
SampleData.RESIDENT_CITY.toDataItem()
)
.addAttribute(
DocumentAttributeType.IntegerOptions(Options.SEX_ISO_IEC_5218),
"gender",
"Gender",
"COR holder’s gender",
false,
NAMESPACE,
Icon.EMERGENCY,
SampleData.SEX_ISO218.toDataItem()
)
.addAttribute(
DocumentAttributeType.StringOptions(Options.COUNTRY_ISO_3166_1_ALPHA_2),
"nationality",
"Nationality",
"Alpha-2 country code as specified in ISO 3166-1, representing the nationality of the PID User.",
true,
NAMESPACE,
Icon.LANGUAGE,
SampleData.NATIONALITY.toDataItem()
)
.addAttribute(
DocumentAttributeType.Date,
"issuance_date",
"Date of Issue",
"Date (and possibly time) when the PID was issued.",
true,
NAMESPACE,
Icon.DATE_RANGE,
SampleData.issueDate.toDataItemFullDate()
)
.addAttribute(
DocumentAttributeType.Date,
"expiry_date",
"Date of Expiry",
"Date (and possibly time) when the PID will expire.",
true,
NAMESPACE,
Icon.CALENDAR_CLOCK,
SampleData.expiryDate.toDataItemFullDate()
)
.addAttribute(
DocumentAttributeType.String,
"issuing_authority",
"Issuing Authority",
"Name of the administrative authority that has issued this PID instance, or the " +
"ISO 3166 Alpha-2 country code of the respective Member State if there is" +
"no separate authority authorized to issue PIDs.",
true,
NAMESPACE,
Icon.ACCOUNT_BALANCE,
SampleData.ISSUING_AUTHORITY_EU_PID.toDataItem()
)
.addAttribute(
DocumentAttributeType.String,
"document_number",
"Document Number",
"A number for the PID, assigned by the PID Provider.",
false,
NAMESPACE,
Icon.NUMBERS,
SampleData.DOCUMENT_NUMBER.toDataItem()
)
.addAttribute(
DocumentAttributeType.String,
"administrative_number",
"Administrative Number",
"A number assigned by the PID Provider for audit control or other purposes.",
false,
NAMESPACE,
Icon.NUMBERS,
SampleData.ADMINISTRATIVE_NUMBER.toDataItem()
)
.addAttribute(
DocumentAttributeType.String,
"issuing_jurisdiction",
"Issuing Jurisdiction",
"Country subdivision code of the jurisdiction that issued the PID, as defined in " +
"ISO 3166-2:2020, Clause 8. The first part of the code SHALL be the same " +
"as the value for issuing_country.",
false,
NAMESPACE,
Icon.ACCOUNT_BALANCE,
SampleData.ISSUING_JURISDICTION.toDataItem()
)
.addAttribute(
DocumentAttributeType.StringOptions(Options.COUNTRY_ISO_3166_1_ALPHA_2),
"issuing_country",
"Issuing Country",
"Alpha-2 country code, as defined in ISO 3166-1, of the issuing authority’s " +
"country or territory",
true,
NAMESPACE,
Icon.ACCOUNT_BALANCE,
SampleData.ISSUING_COUNTRY.toDataItem()
)
.addSampleRequest(
id = "age_over_18",
displayName = "Age Over 18",
mdocDataElements = mapOf(
NAMESPACE to mapOf(
"age_over_18" to false,
)
),
vcClaims = listOf("age_over_18")
)
.addSampleRequest(
id = "mandatory",
displayName = "Mandatory Data Elements",
mdocDataElements = mapOf(
NAMESPACE to mapOf(
"family_name" to false,
"given_name" to false,
"birth_date" to false,
"age_over_18" to false,
"issuance_date" to false,
"expiry_date" to false,
"issuing_authority" to false,
"issuing_country" to false
)
),
vcClaims = listOf(
"family_name",
"given_name",
"birth_date",
"age_over_18",
"issuance_date",
"expiry_date",
"issuing_authority",
"issuing_country"
)
)
.addSampleRequest(
id = "full",
displayName = "All Data Elements",
mdocDataElements = mapOf(
NAMESPACE to mapOf()
),
vcClaims = listOf()
)
.build()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.android.identity.issuance.evidence

/**
* Request pre-authorized code from the client. Pre-authorized code is given to a wallet app
* as a part of an OpenId4VCI credential offer.
*/
class EvidenceRequestPreauthorizedCode : EvidenceRequest()
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.android.identity.issuance.evidence

/**
* Provides OpenId4VCI pre-authorized code to the issuer.
*/
data class EvidenceResponsePreauthorizedCode(
val code: String, // preauthorized code
val txCode: String? // transaction code entered by the user (may or may not be required)
) : EvidenceResponse()
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,13 @@ import kotlin.time.Duration.Companion.seconds
class FunkeAccess(
val accessToken: String,
val accessTokenExpiration: Instant,
var dpopNonce: String,
var dpopNonce: String?,
var cNonce: String?,
var refreshToken: String?,
) {
companion object {
suspend fun parseResponse(tokenResponse: HttpResponse): FunkeAccess {
val dpopNonce = tokenResponse.headers["DPoP-Nonce"]
?: throw IllegalArgumentException("No DPoP nonce in token response")
val tokenString = String(tokenResponse.readBytes())
val token = Json.parseToJsonElement(tokenString) as JsonObject
val accessToken = getField(token, "access_token").content
Expand Down
Loading

0 comments on commit 453c77b

Please sign in to comment.