From b57d93a5bf02a3d4f53413a7c2ee9fc939444b4e Mon Sep 17 00:00:00 2001 From: vkanellpoulos Date: Mon, 27 May 2024 12:49:51 +0300 Subject: [PATCH] refactor cbor parsing when adding document, in order to accept structure according to ISO 23220-4 --- README.md | 174 +++++++++--------- .../load-sample-data.md | 40 ++-- .../load-sample-data.md | 33 +++- .../-document-manager-impl/add-document.md | 7 - .../-document-manager/add-document.md | 7 - .../document/DocumentManagerImplTest.kt | 111 ++++++----- .../sample/SampleDocumentManagerImplTest.kt | 131 +++++++------ .../src/androidTest/res/raw/eu_pid.hex | 1 + .../eudi/wallet/document/DocumentManager.kt | 7 - .../wallet/document/DocumentManagerImpl.kt | 15 +- .../document/sample/SampleDocumentManager.kt | 29 ++- .../sample/SampleDocumentManagerImpl.kt | 52 +----- gradle.properties | 3 +- 13 files changed, 306 insertions(+), 304 deletions(-) create mode 100644 document-manager/src/androidTest/res/raw/eu_pid.hex diff --git a/README.md b/README.md index e25bed8..45bbc0b 100644 --- a/README.md +++ b/README.md @@ -18,16 +18,23 @@ The library is written in Kotlin and is available for Android. ## :heavy_exclamation_mark: Disclaimer -The released software is a initial development release version: -- The initial development release is an early endeavor reflecting the efforts of a short timeboxed period, and by no means can be considered as the final product. -- The initial development release may be changed substantially over time, might introduce new features but also may change or remove existing ones, potentially breaking compatibility with your existing code. -- The initial development release is limited in functional scope. -- The initial development release may contain errors or design flaws and other problems that could cause system or other failures and data loss. -- The initial development release has reduced security, privacy, availability, and reliability standards relative to future releases. This could make the software slower, less reliable, or more vulnerable to attacks than mature software. -- The initial development release is not yet comprehensively documented. -- Users of the software must perform sufficient engineering and additional testing in order to properly evaluate their application and determine whether any of the open-sourced components is suitable for use in that application. -- We strongly recommend not putting this version of the software into production use. -- Only the latest version of the software will be supported +The released software is a initial development release version: + +- The initial development release is an early endeavor reflecting the efforts of a short timeboxed period, and by no + means can be considered as the final product. +- The initial development release may be changed substantially over time, might introduce new features but also may + change or remove existing ones, potentially breaking compatibility with your existing code. +- The initial development release is limited in functional scope. +- The initial development release may contain errors or design flaws and other problems that could cause system or other + failures and data loss. +- The initial development release has reduced security, privacy, availability, and reliability standards relative to + future releases. This could make the software slower, less reliable, or more vulnerable to attacks than mature + software. +- The initial development release is not yet comprehensively documented. +- Users of the software must perform sufficient engineering and additional testing in order to properly evaluate their + application and determine whether any of the open-sourced components is suitable for use in that application. +- We strongly recommend not putting this version of the software into production use. +- Only the latest version of the software will be supported ## Requirements @@ -40,7 +47,7 @@ file. ```groovy dependencies { - implementation "eu.europa.ec.eudi:eudi-lib-android-wallet-document-manager:0.2.3-SNAPSHOT" + implementation "eu.europa.ec.eudi:eudi-lib-android-wallet-document-manager:0.3.0-SNAPSHOT" } ``` @@ -76,7 +83,7 @@ Document is an object that contains the following information: - `id` document's unique identifier - `docType` document's docType (example: "eu.europa.ec.eudiw.pid.1") -- `name` document's name. This is a human readable name. +- `name` document's name. This is a human-readable name. - `hardwareBacked` document's storage is hardware backed - `createdAt` document's creation date - `requiresUserAuth` flag that indicates if the document requires user authentication to be accessed @@ -127,16 +134,10 @@ In order to add a new document in `DocumentManager`, the following steps should 2. Send the issuance request to the issuer. 3. Add the document to the `DocumentManager` using the `addDocument` method. -In order to use with the `addDocument` method, document's data must be in CBOR bytes that has the following structure: +In order to use with the `addDocument` method, document's data must be in CBOR bytes that has the IssuerSigned structure +according to ISO 23220-4 : ```cddl -Data = { - "documents" : [+Document], ; Returned documents -} -Document = { - "docType" : DocType, ; Document type returned - "issuerSigned" : IssuerSigned, ; Returned data elements signed by the issuer -} IssuerSigned = { "nameSpaces" : IssuerNameSpaces, ; Returned data elements "issuerAuth" : IssuerAuth ; Contains the mobile security object (MSO) for issuer data authentication @@ -160,73 +161,82 @@ See the code below for an example of how to add a new document in `DocumentManag val docType = "eu.europa.ec.eudiw.pid.1" val hardwareBacked = false val attestationChallenge = byteArrayOf( - // attestation challenge bytes - // provided by the issuer + // attestation challenge bytes + // provided by the issuer ) val requestResult = - documentManager.createIssuanceRequest(docType, hardwareBacked, attestationChallenge) + documentManager.createIssuanceRequest(docType, hardwareBacked, attestationChallenge) when (requestResult) { - is CreateIssuanceRequestResult.Failure -> { - val error = requestResult.throwable - // handle error while creating issuance request - } - - is CreateIssuanceRequestResult.Success -> { - val request = requestResult.issuanceRequest - val docType = request.docType - // the device certificate that will be used in the signing of the document - // from the issuer while creating the MSO (Mobile Security Object) - val certificateNeedAuth = request.certificateNeedAuth - - // if the issuer requires the user to prove possession of the private key corresponding to the certificateNeedAuth - // then user can use the method below to sign issuer's data and send the signature to the issuer - val signingInputFromIssuer = byteArrayOf( - // signing input bytes from the issuer - // provided by the issuer - ) - val signatureResult = request.signWithAuthKey(signingInputFromIssuer) - when (signatureResult) { - is SignedWithAuthKeyResult.Success -> { - val signature = signatureResult.signature - // signature for the issuer - } - is SignedWithAuthKeyResult.Failure -> { - val error = signatureResult.throwable - // handle error while signing with auth key - } - is SignedWithAuthKeyResult.UserAuthRequired -> { - // user authentication is required to sign with auth key - val cryptoObject = signatureResult.cryptoObject - // use cryptoObject to authenticate the user - // after user authentication, the user can sign with auth key again - } - } - - // ... code that sends docType and certificates to issuer and signature if required - - // after receiving the MSO from the issuer, the user can start the issuance process - val issuerData: ByteArray = byteArrayOf( - // CBOR bytes of the document - ) - - val addResult = documentManager.addDocument(request, issuerData) - - when (addResult) { - is AddDocumentResult.Failure -> { - val error = addResult.throwable - // handle error while adding document - } - is AddDocumentResult.Success -> { - val documentId = addResult.documentId - // the documentId of the newly added document - // use the documentId to retrieve the document - documentManager.getDocumentById(documentId) - } - } - } + is CreateIssuanceRequestResult.Failure -> { + val error = requestResult.throwable + // handle error while creating issuance request + } + + is CreateIssuanceRequestResult.Success -> { + val request = requestResult.issuanceRequest + val docType = request.docType + // the device certificate that will be used in the signing of the document + // from the issuer while creating the MSO (Mobile Security Object) + val certificateNeedAuth = request.certificateNeedAuth + + // if the issuer requires the user to prove possession of the private key corresponding to the certificateNeedAuth + // then user can use the method below to sign issuer's data and send the signature to the issuer + val signingInputFromIssuer = byteArrayOf( + // signing input bytes from the issuer + // provided by the issuer + ) + val signatureResult = request.signWithAuthKey(signingInputFromIssuer) + when (signatureResult) { + is SignedWithAuthKeyResult.Success -> { + val signature = signatureResult.signature + // signature for the issuer + } + is SignedWithAuthKeyResult.Failure -> { + val error = signatureResult.throwable + // handle error while signing with auth key + } + is SignedWithAuthKeyResult.UserAuthRequired -> { + // user authentication is required to sign with auth key + val cryptoObject = signatureResult.cryptoObject + // use cryptoObject to authenticate the user + // after user authentication, the user can sign with auth key again + } + } + + // ... code that sends docType and certificates to issuer and signature if required + + // after receiving the MSO from the issuer, the user can start the issuance process + val issuerData: ByteArray = byteArrayOf( + // CBOR bytes of the document + ) + + val addResult = documentManager.addDocument(request, issuerData) + + when (addResult) { + is AddDocumentResult.Failure -> { + val error = addResult.throwable + // handle error while adding document + } + is AddDocumentResult.Success -> { + val documentId = addResult.documentId + // the documentId of the newly added document + // use the documentId to retrieve the document + documentManager.getDocumentById(documentId) + } + } + } } ``` +Library provides also an extension method on Document class to retrieve the document's data as JSONObject. + +```kotlin +import org.json.JSONObject + +val document = documentManager.getDocumentById("some_document_id") +val documentDataAsJson: JSONObject? = document?.nameSpacedDataJSONObject +``` + ### Working with sample documents The library, also provides a `SampleDocumentManager` class implementation that can be used to load @@ -262,7 +272,7 @@ documentManager.loadSampleData(sampleDocumentsByteArray) Sample documents must be in CBOR format with the following structure: ```cddl -Data = { +SampleData = { "documents" : [+Document], ; Returned documents } Document = { diff --git a/docs/document-manager/eu.europa.ec.eudi.wallet.document.sample/-sample-document-manager-impl/load-sample-data.md b/docs/document-manager/eu.europa.ec.eudi.wallet.document.sample/-sample-document-manager-impl/load-sample-data.md index 2a13842..d4ec08e 100644 --- a/docs/document-manager/eu.europa.ec.eudi.wallet.document.sample/-sample-document-manager-impl/load-sample-data.md +++ b/docs/document-manager/eu.europa.ec.eudi.wallet.document.sample/-sample-document-manager-impl/load-sample-data.md @@ -7,38 +7,42 @@ open override fun [loadSampleData](load-sample-data.md)(sampleData: [ByteArray]( Loads the sample data into the document manager. -The sample data is a CBOR bytearray that has the following structure: +#### Return + +[LoadSampleResult.Success](../-load-sample-result/-success/index.md) if the sample data has been loaded successfully. +Otherwise, returns [LoadSampleResult.Error](../-load-sample-result/-error/index.md), with the error message. + +Expected sampleData format is CBOR. The CBOR data must be in the following structure: ```cddl -Data = { - "documents" : [+Document], ; Returned documents +SampleData = { + "documents" : [+Document], ; Returned documents } Document = { - "docType" : DocType, ; Document type returned - "issuerSigned" : IssuerSigned, ; Returned data elements signed by the issuer + "docType" : DocType, ; Document type returned + "issuerSigned" : IssuerSigned, ; Returned data elements signed by the issuer } IssuerSigned = { - "nameSpaces" : IssuerNameSpaces, ; Returned data elements + "nameSpaces" : IssuerNameSpaces, ; Returned data elements + "issuerAuth" : IssuerAuth ; Contains the mobile security object (MSO) for issuer data authentication } IssuerNameSpaces = { ; Returned data elements for each namespace - + NameSpace => [ + IssuerSignedItemBytes ] + + NameSpace => [ + IssuerSignedItemBytes ] } +IssuerSignedItemBytes = #6.24(bstr .cbor IssuerSignedItem) IssuerSignedItem = { - "digestID" : uint, ; Digest ID for issuer data authentication - "random" : bstr, ; Random value for issuer data authentication - "elementIdentifier" : DataElementIdentifier, ; Data element identifier - "elementValue" : DataElementValue ; Data element value + "digestID" : uint, ; Digest ID for issuer data authentication + "random" : bstr, ; Random value for issuer data authentication + "elementIdentifier" : DataElementIdentifier, ; Data element identifier + "elementValue" : DataElementValue ; Data element value } +IssuerAuth = COSE_Sign1 ; The payload is MobileSecurityObjectBytes ``` -#### Return - -[LoadSampleResult.Success](../-load-sample-result/-success/index.md) if the sample data has been loaded successfully. Otherwise, returns [LoadSampleResult.Error](../-load-sample-result/-error/index.md), with the error message. - #### Parameters androidJvm -| | -|---| -| sampleData | +| | | +|------------|---------------------------------------------| +| sampleData | the sample data to be loaded in cbor format | diff --git a/docs/document-manager/eu.europa.ec.eudi.wallet.document.sample/-sample-document-manager/load-sample-data.md b/docs/document-manager/eu.europa.ec.eudi.wallet.document.sample/-sample-document-manager/load-sample-data.md index 133412d..c9d5792 100644 --- a/docs/document-manager/eu.europa.ec.eudi.wallet.document.sample/-sample-document-manager/load-sample-data.md +++ b/docs/document-manager/eu.europa.ec.eudi.wallet.document.sample/-sample-document-manager/load-sample-data.md @@ -11,10 +11,37 @@ Loads the sample data into the document manager. [LoadSampleResult.Success](../-load-sample-result/-success/index.md) if the sample data has been loaded successfully. Otherwise, returns [LoadSampleResult.Error](../-load-sample-result/-error/index.md), with the error message. +Expected sampleData format is CBOR. The CBOR data must be in the following structure: + +```cddl +SampleData = { + "documents" : [+Document], ; Returned documents +} +Document = { + "docType" : DocType, ; Document type returned + "issuerSigned" : IssuerSigned, ; Returned data elements signed by the issuer +} +IssuerSigned = { + "nameSpaces" : IssuerNameSpaces, ; Returned data elements + "issuerAuth" : IssuerAuth ; Contains the mobile security object (MSO) for issuer data authentication +} +IssuerNameSpaces = { ; Returned data elements for each namespace + + NameSpace => [ + IssuerSignedItemBytes ] +} +IssuerSignedItemBytes = #6.24(bstr .cbor IssuerSignedItem) +IssuerSignedItem = { + "digestID" : uint, ; Digest ID for issuer data authentication + "random" : bstr, ; Random value for issuer data authentication + "elementIdentifier" : DataElementIdentifier, ; Data element identifier + "elementValue" : DataElementValue ; Data element value +} +IssuerAuth = COSE_Sign1 ; The payload is MobileSecurityObjectBytes +``` + #### Parameters androidJvm -| | -|---| -| sampleData | +| | | +|------------|---------------------------------------------| +| sampleData | the sample data to be loaded in cbor format | diff --git a/docs/document-manager/eu.europa.ec.eudi.wallet.document/-document-manager-impl/add-document.md b/docs/document-manager/eu.europa.ec.eudi.wallet.document/-document-manager-impl/add-document.md index b559613..3a6ca21 100644 --- a/docs/document-manager/eu.europa.ec.eudi.wallet.document/-document-manager-impl/add-document.md +++ b/docs/document-manager/eu.europa.ec.eudi.wallet.document/-document-manager-impl/add-document.md @@ -10,13 +10,6 @@ Add document to the document manager. Expected data format is CBOR. The CBOR data must be in the following structure: ```cddl -Data = { - "documents" : [+Document], ; Returned documents -} -Document = { - "docType" : DocType, ; Document type returned - "issuerSigned" : IssuerSigned, ; Returned data elements signed by the issuer -} IssuerSigned = { "nameSpaces" : IssuerNameSpaces, ; Returned data elements "issuerAuth" : IssuerAuth ; Contains the mobile security object (MSO) for issuer data authentication diff --git a/docs/document-manager/eu.europa.ec.eudi.wallet.document/-document-manager/add-document.md b/docs/document-manager/eu.europa.ec.eudi.wallet.document/-document-manager/add-document.md index 079decc..234879f 100644 --- a/docs/document-manager/eu.europa.ec.eudi.wallet.document/-document-manager/add-document.md +++ b/docs/document-manager/eu.europa.ec.eudi.wallet.document/-document-manager/add-document.md @@ -10,13 +10,6 @@ Add document to the document manager. Expected data format is CBOR. The CBOR data must be in the following structure: ```cddl -Data = { - "documents" : [+Document], ; Returned documents -} -Document = { - "docType" : DocType, ; Document type returned - "issuerSigned" : IssuerSigned, ; Returned data elements signed by the issuer -} IssuerSigned = { "nameSpaces" : IssuerNameSpaces, ; Returned data elements "issuerAuth" : IssuerAuth ; Contains the mobile security object (MSO) for issuer data authentication diff --git a/document-manager/src/androidTest/java/eu/europa/ec/eudi/wallet/document/DocumentManagerImplTest.kt b/document-manager/src/androidTest/java/eu/europa/ec/eudi/wallet/document/DocumentManagerImplTest.kt index 61b3d22..013b66f 100644 --- a/document-manager/src/androidTest/java/eu/europa/ec/eudi/wallet/document/DocumentManagerImplTest.kt +++ b/document-manager/src/androidTest/java/eu/europa/ec/eudi/wallet/document/DocumentManagerImplTest.kt @@ -22,89 +22,85 @@ import androidx.test.platform.app.InstrumentationRegistry import com.android.identity.android.securearea.AndroidKeystoreSecureArea import com.android.identity.storage.EphemeralStorageEngine import com.android.identity.storage.StorageEngine +import eu.europa.ec.eudi.wallet.document.test.R import org.bouncycastle.util.encoders.Hex -import org.junit.AfterClass -import org.junit.Assert -import org.junit.BeforeClass -import org.junit.Test +import org.junit.* +import org.junit.Assert.* import org.junit.runner.RunWith import java.io.IOException import java.security.Signature -import java.util.UUID +import java.util.* import kotlin.random.Random @RunWith(AndroidJUnit4::class) class DocumentManagerImplTest { - companion object { - private lateinit var context: Context - private lateinit var secureArea: AndroidKeystoreSecureArea - private lateinit var storageEngine: StorageEngine - private lateinit var documentManager: DocumentManagerImpl - - @JvmStatic - @BeforeClass - @Throws(IOException::class) - fun setUp() { - context = InstrumentationRegistry.getInstrumentation().targetContext - storageEngine = EphemeralStorageEngine() - .apply { - deleteAll() - } - secureArea = AndroidKeystoreSecureArea(context, storageEngine) - documentManager = DocumentManagerImpl(context, storageEngine, secureArea) - .userAuth(false) - } + private val context: Context + get() = InstrumentationRegistry.getInstrumentation().targetContext + private lateinit var secureArea: AndroidKeystoreSecureArea + private lateinit var storageEngine: StorageEngine + private lateinit var documentManager: DocumentManagerImpl - @JvmStatic - @AfterClass - fun tearDown() { - storageEngine.deleteAll() - } + @Before + @Throws(IOException::class) + fun setUp() { + + storageEngine = EphemeralStorageEngine() + .apply { + deleteAll() + } + secureArea = AndroidKeystoreSecureArea(context, storageEngine) + documentManager = DocumentManagerImpl(context, storageEngine, secureArea) + .userAuth(false) + } + + @After + fun tearDown() { + storageEngine.deleteAll() } @Test fun test_getDocuments_returns_empty_list() { val documents = documentManager.getDocuments() - Assert.assertTrue(documents.isEmpty()) + assertTrue(documents.isEmpty()) } @Test fun test_getDocumentById_returns_null() { val documentId = "${UUID.randomUUID()}" val document = documentManager.getDocumentById(documentId) - Assert.assertNull(document) + assertNull(document) } @Test fun test_createIssuanceRequest() { val docType = "eu.europa.ec.eudiw.pid.1" val requestResult = documentManager.createIssuanceRequest(docType, false) - Assert.assertTrue(requestResult is CreateIssuanceRequestResult.Success) + assertTrue(requestResult is CreateIssuanceRequestResult.Success) val request = (requestResult as CreateIssuanceRequestResult.Success).issuanceRequest val documentId = request.documentId - Assert.assertEquals(docType, request.docType) - Assert.assertFalse(request.hardwareBacked) - Assert.assertTrue(documentId.isNotBlank()) - Assert.assertEquals(docType, request.name) + assertEquals(docType, request.docType) + assertFalse(request.hardwareBacked) + assertTrue(documentId.isNotBlank()) + assertEquals(docType, request.name) val stored = storageEngine.enumerate().toSet().filter { it.contains(request.documentId) } - Assert.assertEquals(3, stored.size) - Assert.assertNotNull(stored.firstOrNull { it.contains("AuthenticationKey_$documentId") }) - Assert.assertNotNull(stored.firstOrNull { it.contains("Credential_$documentId") }) - Assert.assertNotNull(stored.firstOrNull { it.contains("CredentialKey_$documentId") }) + assertEquals(3, stored.size) + assertNotNull(stored.firstOrNull { it.contains("AuthenticationKey_$documentId") }) + assertNotNull(stored.firstOrNull { it.contains("Credential_$documentId") }) + assertNotNull(stored.firstOrNull { it.contains("CredentialKey_$documentId") }) // assert that document manager never returns an incomplete document val document = documentManager.getDocumentById(documentId) - Assert.assertNull(document) + assertNull(document) val documents = documentManager.getDocuments() - Assert.assertTrue(documents.isEmpty()) + assertTrue(documents.isEmpty()) val data = Random.nextBytes(32) val proofResult = request.signWithAuthKey(data) - Assert.assertTrue(proofResult is SignedWithAuthKeyResult.Success) + assertTrue(proofResult is SignedWithAuthKeyResult.Success) proofResult as SignedWithAuthKeyResult.Success @@ -115,24 +111,39 @@ class DocumentManagerImplTest { initVerify(publicKey) update(data) } - Assert.assertTrue(sig.verify(proof)) + assertTrue(sig.verify(proof)) + } + + @Test + fun test_addDocument() { + val docType = "eu.europa.ec.eudiw.pid.1" + val data = context.resources.openRawResource(R.raw.eu_pid).use { raw -> + Hex.decode(raw.readBytes()) + } + + documentManager.checkPublicKeyBeforeAdding(false) + val issuanceRequest = documentManager.createIssuanceRequest(docType, false) + .getOrThrow() + val result = documentManager.addDocument(issuanceRequest, data) + assertTrue(result is AddDocumentResult.Success) + assertEquals(issuanceRequest.documentId, (result as AddDocumentResult.Success).documentId) } @Test fun test_checkPublicKeyInMso() { val docType = "eu.europa.ec.eudiw.pid.1" // some random data with mismatching public key - val data = Hex.decode( - "a169646f63756d656e747381a267646f6354797065781865752e6575726f70612e65632e65756469772e7069642e316c6973737565725369676e6564a26a697373756572417574688443a10126a118215902853082028130820226a0030201020209164ae59902dc051064300a06082a8648ce3d0403023058310b3009060355040613024245311c301a060355040a13134575726f7065616e20436f6d6d697373696f6e312b3029060355040313224555204469676974616c204964656e746974792057616c6c65742054657374204341301e170d3233303533303132333030305a170d3234303532393132333030305a3065310b3009060355040613024245311c301a060355040a13134575726f7065616e20436f6d6d697373696f6e313830360603550403132f4555204469676974616c204964656e746974792057616c6c6574205465737420446f63756d656e74205369676e65723059301306072a8648ce3d020106082a8648ce3d030107034200047c9313f4c1a4aa4eb0b3eb6811a4994e59de67996431c2f3ae088eb7a1061cb658bd8c39126c19597ac90df99d078d3ef3913ba34bdb2cbc6987d027e9af9dfca381cb3081c8301d0603551d0e04160414d1a4b1243932fb4572729948f2527d9558a74d2d301f0603551d230418301680143291eb0e1c011d140e764f6c4fea4c9638dafb04300e0603551d0f0101ff04040302078030120603551d25040b3009060728818c5d050102301f0603551d12041830168614687474703a2f2f7777772e65756469772e64657630410603551d1f043a30383036a034a032863068747470733a2f2f7374617469632e65756469772e6465762f706b692f63726c2f69736f31383031332d64732e63726c300a06082a8648ce3d0403020349003046022100de5f98e71ef65752126bf2c4b84fdedf81d243ca57b15bd318aab9f1ebeb3f7d022100fe22f7326b4b5758ff16fe86d33a8d8d29882169da049b5a5e2c806ab14708485905e1d8185905dca66776657273696f6e63312e306f646967657374416c676f726974686d675348412d32353667646f6354797065781865752e6575726f70612e65632e65756469772e7069642e316c76616c756544696765737473a1781865752e6575726f70612e65632e65756469772e7069642e31b821182c582057638d927c47c0de05a1574477c1a35cce07696e04db03edef7bd008b0a94c13183458205059852399c7406a7ebd905071366a49860b62d991d4518717a2b3edbd96efdd03582023fc15eb69f85039209b1ed5f3a21aa3b1502d00ec71d68643d0d43c7b7fc3c5182858202a443c0709654430b6e1282a3572f2f627369383637aa52e88a66dc665e47db7182058205f7cf3afabf5b18e37b7f0847de5ddbee911ffb63313915ad63dd5b7dcfdb28d1868582016df05d30b6d49367f5e254bbb56ec578add562bbb7f6a8d00efc371de2d0d9f182d5820e1b239c7b354dfdbfa5b2d88a9b7871c4635d4e105f7e26d2b3c6aae5570a69118675820ab9116b6af34db4d16bd9c64fefc2220b64c868b4798a36a8f8de882dbb7507918355820da5904c2c0a2f76e5e1052598d2767e1d453513c3b4558c641d91028995580740a58205ad8791e2810cdcd5d0a5a552cc1e6517c9ca786663671ee5a01167d6e944b8b1822582025046a6f760e17b99ed7f2cff8246a7f559df0a37f9b4fc6802a9dcee118c9a118325820932368ae52a906e902198be582d315489a753f2df736808bd036f78eae922727085820e17f1dfe052610d58506180d7a8a7d32e3ea10f9bed4764e57f087266034d3c8182f5820b0fccbee74ad3b8417b150406683c3d53dd7216c1cec302c14bc00308ebcbddb0558203ce9538b4911bb7d30431c3b876b72bd6ac1edf9ce64d2da093e7e5d0f4ff800182958204b687a5a91e7f0c3bef2e30167c16289fd5f4d894528062ac4390d199dda071e181f58201b4e4a0264eb7269bd9886005cad4d8db559165deeceba4038081fc1a17b6494182158208706ec4af33a2ac27c99630511acf241fe4bb8ba524a449170e1e43c212dbfb318235820217d449582502db48afd53e76a455472929bce8269becf6082de797c7cb8ec79182e5820014eb73a538d2abda14bf3364a7c15799c39b7dafd7087f124b5e65f0ea8b66e181e5820a0e494f171592ef30a4aefde6a3d47d5b1cf279892a5f1aa6d8d9c96e7c413310258207dca7cd2da2bdfe09b6b646ab55f2b615df545f47721f81f51287d764ffcd7b91824582092a91211a78959b178f7bbdbeec47b722608ab69c2401268b189afbdc32573a4183058206b61c567add567137ed7e02074f4ae1c2f966c698488a479cd803103b9ee349f18275820a06f425468bbd59a89364aef141b363a6d4593cb9b7c4c3e6ddcfaf51fe57c520958208d892a07f914e131776739b017b52bd82d5c6c81f22ac0a05996bbb41b2ef7ad181c5820b0c601c320f0231dbcd77a408ba5d8c50b2a112fce75175a1bddc344186977f00c5820f1531fd181a7bba46021ef03911d2fcc721a544fb6b0a464a8e5b9b127023fd30758202eac96ca881924f06815afef712d30d8d110433772dbd98837932033c4a7c9800658206bd09a938b1493e6d6da6179a7bca3bd8ea9e9f0d79cb55cf1af9dab2e4bbd52182b58200fa74fe3fcb963d6ea1d04bef14571e4e64dc1a80a9863bb59256dcc6e6a7db8182558208beb46bbddd84c621de9ed5ba384a4b6d171c8a0902327a80e16e7b4ca7eb81d181a5820cfb33358620b912fa3b25263229f1fb31370d913601cbcb1b8f12fd1a67056b26d6465766963654b6579496e666fa1696465766963654b6579a401022001215820f154dddb6933d3b3cda1dfc2619188b2ce8f7cce7b8ee666e155e1a1369ab8e9225820dd650230ed41dda9c70cc90d3ef0aca56ee278fb60728dcef33cee6909c34a5c6c76616c6964697479496e666fa3667369676e6564c074323032342d30312d32395431353a31323a31385a6976616c696446726f6dc074323032342d30312d32395431353a31323a31385a6a76616c6964556e74696cc074323032352d30312d32385431353a31323a31385a5840170fe1c5bf7467512eaa939703945086fb28b080715cd2ef8b2ede0901e0dbc5245bb934ba254d3ed592721f894df0e8135aac015270823fa64cd902ff22b0ba6a6e616d65537061636573a1781865752e6575726f70612e65632e65756469772e7069642e319821d818588aa46672616e646f6d584043ec8816b7c9f594b1301d8bbef75fb4d4a417a182b6eb1db7b3923f7d77752fdf9fc40f7b1dc267436f0c3575b6e855f3d1a3b39381e5e9a1918ef404c62874686469676573744944182c6c656c656d656e7456616c756569414e44455253534f4e71656c656d656e744964656e7469666965726b66616d696c795f6e616d65d8185883a46672616e646f6d5840596c14e573ad6311289d5aa14ba65a158a2411adaa17a04fbde20fa308385eb4bd935ba5aa91404a2d7a77c9e56a3100575b32336d720f837e1a39cd4f38218068646967657374494418346c656c656d656e7456616c7565634a414e71656c656d656e744964656e7469666965726a676976656e5f6e616d65d818588ca46672616e646f6d58409cfe6850c098fa07af2107ee225751ee44fc7312b8c17d335d5a31f859bda2b8703401543ccd1cb943dc61184db585f389a9898a31c7bbd632fce464608db596686469676573744944036c656c656d656e7456616c7565d903ec6a313938352d30332d333071656c656d656e744964656e7469666965726a62697274685f64617465d8185881a46672616e646f6d5840912e26d9e661cf8fb7d8a1ae06dba932a019f85c105783b658e1ce0224f61142e0d2e08250c841ee10c2f59336a7d13542fb026e00fa8c1877defe66e10525a768646967657374494418286c656c656d656e7456616c7565f571656c656d656e744964656e7469666965726b6167655f6f7665725f3138d8185881a46672616e646f6d5840eceda09c58a1351ade4449b1513768342fedd71e90c6ff659f29779788aeee67a7fbcd7bbc8e6d86cab8d596aa761757b78ea34366315a63d1bc95954fb7f43168646967657374494418206c656c656d656e7456616c7565f571656c656d656e744964656e7469666965726b6167655f6f7665725f3135d8185881a46672616e646f6d5840fdd84e9107aa326d918d78a0c01f5a02d6eb7e8b363d7f04af2e8b084d6f4c16ec967842d5ca9d833bbab1c8e6d6aa59cdd865f94418cb9c025c52ae0299dac268646967657374494418686c656c656d656e7456616c7565f571656c656d656e744964656e7469666965726b6167655f6f7665725f3231d8185881a46672616e646f6d58407bee4ed907205804f8261fa069660f28df0a728015e96eda0842489396e49772b050b4f8e200d2be0e9770ba9d208a48780ac091ca43cf6b3eb6c7bf0e987d5c686469676573744944182d6c656c656d656e7456616c7565f471656c656d656e744964656e7469666965726b6167655f6f7665725f3630d8185881a46672616e646f6d584012d8ab11fdf37cd79f55fb32eb89ac7b600624caf5dfa3021fd3ce6f3f630c30b8e09dcf727dcd6f7faa808cff3d8df689a15fddc5b81ab8107139f05564f4a068646967657374494418676c656c656d656e7456616c7565f471656c656d656e744964656e7469666965726b6167655f6f7665725f3635d8185881a46672616e646f6d58408ea40ad95621721f661d71a022613d0fe14d4e42afdc92aecaf06055b7e8079df16fa54f808f096d22b87d87ac08ee51a79be2c245d7485b132235edb2079b0368646967657374494418356c656c656d656e7456616c7565f471656c656d656e744964656e7469666965726b6167655f6f7665725f3638d8185882a46672616e646f6d58407cc60fcc1079a43377f1c01e3efeb6ecd70f2437447bbe2d5711d0e4e1c4f078a3c2e3702c943df0cc999243cc59852b33ee2a6980949bcb3984490225282f9e6864696765737449440a6c656c656d656e7456616c7565182671656c656d656e744964656e7469666965726c6167655f696e5f7965617273d8185886a46672616e646f6d5840d174d15e1dcf42ec1bb8d610c221aa6430d03bc7c8a42d367593e24bb3987fd48f9b5d5d5ee27ad511dd57df1bccc93a4bc9a21637fcc881f798ed4de2a6a87a68646967657374494418226c656c656d656e7456616c75651907c171656c656d656e744964656e7469666965726e6167655f62697274685f79656172d8185890a46672616e646f6d5840dcfc46c524c67dd0ddbe57dba4847b03373af83ce1063216fb380c44b0d6505aa13073081b5d7f118d802376f3c57931b825ee01d6c835fef3fc541c0200677d68646967657374494418326c656c656d656e7456616c756569414e44455253534f4e71656c656d656e744964656e7469666965727166616d696c795f6e616d655f6269727468d8185888a46672616e646f6d5840bf1e252d2b21bcd4551332635b8f2a2309a2786487cfbd30af370764cccfbc203a6c277846857bbd11f550461a38fccbc670eb0d5ef72e59a7cde45f983b6e28686469676573744944086c656c656d656e7456616c7565634a414e71656c656d656e744964656e74696669657270676976656e5f6e616d655f6269727468d8185887a46672616e646f6d58402c6272ed3cf208a37b5b685c39964ccde324e2809bd3231b85547e9038ecd305cabe023b6b6307d11e447f1537d0d12b34c2591dc683964b24d43f5807397e78686469676573744944182f6c656c656d656e7456616c75656653574544454e71656c656d656e744964656e7469666965726b62697274685f706c616365d8185884a46672616e646f6d5840befafc4e1055588febcef6785fa0b73cb1421a8b662a5573b3b094a0f864b5066f4f6bbfac23caa2a37505f73c260671d86e98e2f0fcf22c1f0c1181ec6f1e35686469676573744944056c656c656d656e7456616c756562534571656c656d656e744964656e7469666965726d62697274685f636f756e747279d8185883a46672616e646f6d5840b12493bd9b2318c61efadf4bc14cf5597019e0e373bde6ce1e9ca9c2bdb58ae2191f34f74df912c6b1111f3be5b30b41f9cb473ab188f79e3d3ff452aa88486568646967657374494418296c656c656d656e7456616c756562534571656c656d656e744964656e7469666965726b62697274685f7374617465d818588ba46672616e646f6d5840d81981b6b19c96219f160efa956a6c045fb5949c070726c014f79c9af916581c145f0fe868f2150a3944ba841dcfbfae752d9b13d5cb0ecbd594dd7de604857e686469676573744944181f6c656c656d656e7456616c75656b4b415452494e45484f4c4d71656c656d656e744964656e7469666965726a62697274685f63697479d8185895a46672616e646f6d58405d9625ee383e2d3711aa94f220b40a89baca8d27fb7f83e3c33238eb844820326301473a3fa5e8ece73cd6142e424c36c5abe4a0fe8cbd71fc28afa106c7fd9d68646967657374494418216c656c656d656e7456616c75656f464f5254554e41474154414e20313571656c656d656e744964656e746966696572707265736964656e745f61646472657373d8185888a46672616e646f6d5840f7c6518e429e51b48701087cbd9b064cfe022359bbd5e342897b60047b7e51557c9a9a3dc221cfa4830b082561338707608732dc1630538733e138208233f0ea68646967657374494418236c656c656d656e7456616c756562534571656c656d656e744964656e746966696572707265736964656e745f636f756e747279d8185886a46672616e646f6d5840c4d456592fde77d93fa67b6c2b0a4e1e3cf06b7de7f6da3f0267b69013af898b821ef7686a97500da0d329e63a7910dc21b2d1d1fcac917c3c7605bba293b287686469676573744944182e6c656c656d656e7456616c756562534571656c656d656e744964656e7469666965726e7265736964656e745f7374617465d818588ea46672616e646f6d5840fb1f4a2ab34be9385d5f4dc1b0fbeb9e228514bec11873f24ca042d93dffecf6a627b5864d60aec3096fcec1802aecdb947725acae6126619b3fea4f63ba51d2686469676573744944181e6c656c656d656e7456616c75656b4b415452494e45484f4c4d71656c656d656e744964656e7469666965726d7265736964656e745f63697479d818588ea46672616e646f6d58408ca7615aec5b08f079c2a5e59588f9b5a471764532845109744bbdd52a3878002c36b947e65c2a5f97725833bde32ba34f71205fc7e79c26bddfcb1a7b94b61c686469676573744944026c656c656d656e7456616c756565363431333371656c656d656e744964656e746966696572747265736964656e745f706f7374616c5f636f6465d8185891a46672616e646f6d5840d81981b6b19c96219f160efa956a6c045fb5949c070726c014f79c9af916581c145f0fe868f2150a3944ba841dcfbfae752d9b13d5cb0ecbd594dd7de604857e68646967657374494418246c656c656d656e7456616c75656c464f5254554e41474154414e71656c656d656e744964656e7469666965726f7265736964656e745f737472656574d818588da46672616e646f6d5840732165a96a0001a9ae2e5081f0453134d3f851da341bccee1fff5106180c0f3e4ce2893aaba78990ac43fffacc90d2bdd84183b0e070ba51cba8d0db5b3d4f1168646967657374494418306c656c656d656e7456616c756562313271656c656d656e744964656e746966696572757265736964656e745f686f7573655f6e756d626572d818587ca46672616e646f6d5840dbd09559cc5e22d4d64c6e7f4a8cd3d9d80c17b37f81dc88e60fe9a5b92febcb56a2a98feb5f47816a8a0fa036c8513545bebea2f3ce4c6f8f27646861830ab568646967657374494418276c656c656d656e7456616c75650171656c656d656e744964656e7469666965726667656e646572d8185882a46672616e646f6d584085b6e1e47aa35866afaffc94802e34ed02423caff52239db6f4f50f4d74142a14af3f4bad645d5dbb6ad1422421f53561cdabcb5fa99a7a1e9820f57dee0858c686469676573744944096c656c656d656e7456616c756562534571656c656d656e744964656e7469666965726b6e6174696f6e616c697479d8185898a46672616e646f6d5840827c15fe24327f6406484eae60e5b6a77c4bb562bf0cafa20c7c303c569b4794adc124a66bd257a8c580dc29d37bda94ef60d8eab7edb6becaa58d1623ac3cdf686469676573744944181c6c656c656d656e7456616c7565c074323030392d30312d30315430303a30303a30305a71656c656d656e744964656e7469666965726d69737375616e63655f64617465d8185895a46672616e646f6d58408a8c1cc86488832efd0e9a31d2f0c2d5eb1269bc3babbc992bd0c201ee60b589035fede85d3d1c72b2ed78970a8e1f1b344c3215022803b167eb62f28400c41e6864696765737449440c6c656c656d656e7456616c7565c074323035302d30332d33305430303a30303a30305a71656c656d656e744964656e7469666965726b6578706972795f64617465d8185889a46672616e646f6d5840732e962c389855cd544f3a4a1abef747ce59e3bb8ee256c5cee1f04b6b477333fd373bbe44b80c8c64fb41b2873d1c309c39c4d7da928cabe5ecf564633e9805686469676573744944076c656c656d656e7456616c75656355544f71656c656d656e744964656e7469666965727169737375696e675f617574686f72697479d818588da46672616e646f6d5840ff20478c01e6c57703e45e44eee1fad45bafbb7ad100cb053375e719ebf4aa263613af29b4f1793e27ffb7be141ec42007bd5074c5e58faaaafd51a2795094a0686469676573744944066c656c656d656e7456616c75656931313131313131313471656c656d656e744964656e7469666965726f646f63756d656e745f6e756d626572d8185895a46672616e646f6d584064751ef966e351dd32fab3f3aaf3d3eb6e31a51a1a6fe4ca316f4f9a7ad249f3fbe76ffa1b590bca54ba0a076a11332c869adbd15a8c40e9c6d6415d727b8ef3686469676573744944182b6c656c656d656e7456616c75656a3930313031363734363471656c656d656e744964656e7469666965727561646d696e6973747261746976655f6e756d626572d8185887a46672616e646f6d5840c8e8431de246dcf0ec024ac2ef8121db66d358af35fa9e8de93187da012791b05c0c072557c1f48a58a0bb7f260dfa84cc31c0a9ce6d05dce86b22ab4085bda968646967657374494418256c656c656d656e7456616c756562534571656c656d656e744964656e7469666965726f69737375696e675f636f756e747279d818588ea46672616e646f6d58407aa5210c2d76832452d8a7bcc8a92dae595f8c88df5ab42a520dee67b2f85bd6035939ad761168a1945244af9eeed21a80cb9a604ae13814b47e13123f585de5686469676573744944181a6c656c656d656e7456616c75656453452d4971656c656d656e744964656e7469666965727469737375696e675f6a7572697364696374696f6e" - ) + val data = context.resources.openRawResource(R.raw.eu_pid).use { raw -> + Hex.decode(raw.readBytes()) + } documentManager.checkPublicKeyBeforeAdding(true) val issuanceRequest = documentManager.createIssuanceRequest(docType, false) .getOrThrow() val result = documentManager.addDocument(issuanceRequest, data) - Assert.assertTrue(result is AddDocumentResult.Failure) + assertTrue(result is AddDocumentResult.Failure) result as AddDocumentResult.Failure - Assert.assertTrue(result.throwable is IllegalArgumentException) - Assert.assertEquals( + assertTrue(result.throwable is IllegalArgumentException) + assertEquals( "Public key in MSO does not match the one in the request", result.throwable.message ) diff --git a/document-manager/src/androidTest/java/eu/europa/ec/eudi/wallet/document/sample/SampleDocumentManagerImplTest.kt b/document-manager/src/androidTest/java/eu/europa/ec/eudi/wallet/document/sample/SampleDocumentManagerImplTest.kt index 01ff82c..80f3edf 100644 --- a/document-manager/src/androidTest/java/eu/europa/ec/eudi/wallet/document/sample/SampleDocumentManagerImplTest.kt +++ b/document-manager/src/androidTest/java/eu/europa/ec/eudi/wallet/document/sample/SampleDocumentManagerImplTest.kt @@ -15,7 +15,6 @@ */ package eu.europa.ec.eudi.wallet.document.sample -import android.content.Context import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.platform.app.InstrumentationRegistry import com.android.identity.android.securearea.AndroidKeystoreSecureArea @@ -33,35 +32,72 @@ import com.android.identity.mdoc.util.MdocUtil import com.android.identity.securearea.SecureArea import com.android.identity.securearea.SecureArea.KeyLockedException import com.android.identity.securearea.SecureAreaRepository -import com.android.identity.storage.StorageEngine import com.android.identity.util.Constants import com.upokecenter.cbor.CBORObject import eu.europa.ec.eudi.wallet.document.Document +import eu.europa.ec.eudi.wallet.document.DocumentManager import eu.europa.ec.eudi.wallet.document.DocumentManagerImpl import eu.europa.ec.eudi.wallet.document.test.R -import org.junit.AfterClass -import org.junit.Assert -import org.junit.BeforeClass -import org.junit.Test +import org.junit.* +import org.junit.Assert.* import org.junit.runner.RunWith -import java.io.IOException -import java.util.Base64 +import java.util.* @RunWith(AndroidJUnit4::class) class SampleDocumentManagerImplTest { + + val context + get() = InstrumentationRegistry.getInstrumentation().targetContext + + lateinit var storageEngine: AndroidStorageEngine + + lateinit var secureArea: AndroidKeystoreSecureArea + + lateinit var delegate: DocumentManager + + lateinit var documentManager: SampleDocumentManager + + val sampleData + get() = context.resources.openRawResource(R.raw.sample_data).use { raw -> + Base64.getDecoder().decode(raw.readBytes()) + } + + @Before + fun setup() { + storageEngine = AndroidStorageEngine.Builder(context, context.cacheDir) + .setUseEncryption(false) + .build() + .apply { + deleteAll() + } + secureArea = AndroidKeystoreSecureArea(context, storageEngine) + + delegate = DocumentManagerImpl(context, storageEngine, secureArea) + .userAuth(false) + + documentManager = SampleDocumentManagerImpl(context, delegate) + } + + @After + fun tearDown() { + storageEngine.deleteAll() + } + @Test fun test_loadSampleData() { + documentManager.loadSampleData(sampleData) val documents = documentManager.getDocuments() - Assert.assertEquals(2, documents.size) - Assert.assertEquals("eu.europa.ec.eudiw.pid.1", documents[0].docType) - Assert.assertEquals("org.iso.18013.5.1.mDL", documents[1].docType) + assertEquals(2, documents.size) + assertEquals("eu.europa.ec.eudiw.pid.1", documents[0].docType) + assertEquals("org.iso.18013.5.1.mDL", documents[1].docType) } @Test @Throws(KeyLockedException::class) fun test_sampleDocuments() { + documentManager.loadSampleData(sampleData) val documents = documentManager.getDocuments() - Assert.assertEquals(2, documents.size) + assertEquals(2, documents.size) for (document in documents) { val dataElements = document.nameSpaces.flatMap { (nameSpace, elementIdentifiers) -> elementIdentifiers.map { elementIdentifier -> @@ -94,16 +130,16 @@ class SampleDocumentManagerImplTest { .setSessionTranscript(transcript) .setDeviceResponse(response) .parse() - Assert.assertEquals("Documents in response", 1, responseObj.documents.size) - Assert.assertTrue( + assertEquals("Documents in response", 1, responseObj.documents.size) + assertTrue( "IssuerSigned authentication", responseObj.documents[0].issuerSignedAuthenticated, ) - Assert.assertTrue( + assertTrue( "DeviceSigned authentication", responseObj.documents[0].deviceSignedAuthenticated, ) - Assert.assertEquals( + assertEquals( "Digest Matching", 0, responseObj.documents[0].numIssuerEntryDigestMatchFailures, @@ -116,57 +152,18 @@ class SampleDocumentManagerImplTest { var staticAuthData: StaticAuthData, ) - companion object { - private lateinit var context: Context - private lateinit var secureArea: AndroidKeystoreSecureArea - private lateinit var storageEngine: StorageEngine - private lateinit var documentManager: SampleDocumentManagerImpl - private lateinit var sampleData: ByteArray - - @JvmStatic - @BeforeClass - @Throws(IOException::class) - fun setUp() { - context = InstrumentationRegistry.getInstrumentation().targetContext - storageEngine = AndroidStorageEngine.Builder(context, context.cacheDir) - .setUseEncryption(false) - .build() - .apply { - deleteAll() - } - secureArea = AndroidKeystoreSecureArea(context, storageEngine) - val delegate = DocumentManagerImpl(context, storageEngine, secureArea) - .userAuth(false) - documentManager = SampleDocumentManagerImpl(context, delegate) - try { - context.resources.openRawResource(R.raw.sample_data).use { raw -> - sampleData = Base64.getDecoder().decode(raw.readBytes()) - } - } catch (e: Exception) { - throw IOException(e) - } - val result = documentManager.loadSampleData(sampleData) - Assert.assertTrue(result is LoadSampleResult.Success) - } - - @JvmStatic - @AfterClass - fun tearDown() { - storageEngine.deleteAll() - } - private fun getStaticAuthDataFromDocument(document: Document): DocumentIssuerData { - val secureAreaRepository = SecureAreaRepository() - secureAreaRepository.addImplementation(secureArea) - val credentialStore = CredentialStore(storageEngine, secureAreaRepository) - val credential = credentialStore.lookupCredential(document.id) - Assert.assertNotNull(credential) - val authKey = credential!!.authenticationKeys[0] - Assert.assertNotNull(authKey) - return DocumentIssuerData( - staticAuthData = StaticAuthDataParser(authKey.issuerProvidedData).parse(), - keyAlias = authKey.alias, - ) - } + private fun getStaticAuthDataFromDocument(document: Document): DocumentIssuerData { + val secureAreaRepository = SecureAreaRepository() + secureAreaRepository.addImplementation(secureArea) + val credentialStore = CredentialStore(storageEngine, secureAreaRepository) + val credential = credentialStore.lookupCredential(document.id) + assertNotNull(credential) + val authKey = credential!!.authenticationKeys[0] + assertNotNull(authKey) + return DocumentIssuerData( + staticAuthData = StaticAuthDataParser(authKey.issuerProvidedData).parse(), + keyAlias = authKey.alias, + ) } } diff --git a/document-manager/src/androidTest/res/raw/eu_pid.hex b/document-manager/src/androidTest/res/raw/eu_pid.hex new file mode 100644 index 0000000..029793e --- /dev/null +++ b/document-manager/src/androidTest/res/raw/eu_pid.hex @@ -0,0 +1 @@ +a26a697373756572417574688443a10126a118215902853082028130820226a0030201020209164ae59902dc051064300a06082a8648ce3d0403023058310b3009060355040613024245311c301a060355040a13134575726f7065616e20436f6d6d697373696f6e312b3029060355040313224555204469676974616c204964656e746974792057616c6c65742054657374204341301e170d3233303533303132333030305a170d3234303532393132333030305a3065310b3009060355040613024245311c301a060355040a13134575726f7065616e20436f6d6d697373696f6e313830360603550403132f4555204469676974616c204964656e746974792057616c6c6574205465737420446f63756d656e74205369676e65723059301306072a8648ce3d020106082a8648ce3d030107034200047c9313f4c1a4aa4eb0b3eb6811a4994e59de67996431c2f3ae088eb7a1061cb658bd8c39126c19597ac90df99d078d3ef3913ba34bdb2cbc6987d027e9af9dfca381cb3081c8301d0603551d0e04160414d1a4b1243932fb4572729948f2527d9558a74d2d301f0603551d230418301680143291eb0e1c011d140e764f6c4fea4c9638dafb04300e0603551d0f0101ff04040302078030120603551d25040b3009060728818c5d050102301f0603551d12041830168614687474703a2f2f7777772e65756469772e64657630410603551d1f043a30383036a034a032863068747470733a2f2f7374617469632e65756469772e6465762f706b692f63726c2f69736f31383031332d64732e63726c300a06082a8648ce3d0403020349003046022100de5f98e71ef65752126bf2c4b84fdedf81d243ca57b15bd318aab9f1ebeb3f7d022100fe22f7326b4b5758ff16fe86d33a8d8d29882169da049b5a5e2c806ab14708485905e1d8185905dca66776657273696f6e63312e306f646967657374416c676f726974686d675348412d32353667646f6354797065781865752e6575726f70612e65632e65756469772e7069642e316c76616c756544696765737473a1781865752e6575726f70612e65632e65756469772e7069642e31b821182c582057638d927c47c0de05a1574477c1a35cce07696e04db03edef7bd008b0a94c13183458205059852399c7406a7ebd905071366a49860b62d991d4518717a2b3edbd96efdd03582023fc15eb69f85039209b1ed5f3a21aa3b1502d00ec71d68643d0d43c7b7fc3c5182858202a443c0709654430b6e1282a3572f2f627369383637aa52e88a66dc665e47db7182058205f7cf3afabf5b18e37b7f0847de5ddbee911ffb63313915ad63dd5b7dcfdb28d1868582016df05d30b6d49367f5e254bbb56ec578add562bbb7f6a8d00efc371de2d0d9f182d5820e1b239c7b354dfdbfa5b2d88a9b7871c4635d4e105f7e26d2b3c6aae5570a69118675820ab9116b6af34db4d16bd9c64fefc2220b64c868b4798a36a8f8de882dbb7507918355820da5904c2c0a2f76e5e1052598d2767e1d453513c3b4558c641d91028995580740a58205ad8791e2810cdcd5d0a5a552cc1e6517c9ca786663671ee5a01167d6e944b8b1822582025046a6f760e17b99ed7f2cff8246a7f559df0a37f9b4fc6802a9dcee118c9a118325820932368ae52a906e902198be582d315489a753f2df736808bd036f78eae922727085820e17f1dfe052610d58506180d7a8a7d32e3ea10f9bed4764e57f087266034d3c8182f5820b0fccbee74ad3b8417b150406683c3d53dd7216c1cec302c14bc00308ebcbddb0558203ce9538b4911bb7d30431c3b876b72bd6ac1edf9ce64d2da093e7e5d0f4ff800182958204b687a5a91e7f0c3bef2e30167c16289fd5f4d894528062ac4390d199dda071e181f58201b4e4a0264eb7269bd9886005cad4d8db559165deeceba4038081fc1a17b6494182158208706ec4af33a2ac27c99630511acf241fe4bb8ba524a449170e1e43c212dbfb318235820217d449582502db48afd53e76a455472929bce8269becf6082de797c7cb8ec79182e5820014eb73a538d2abda14bf3364a7c15799c39b7dafd7087f124b5e65f0ea8b66e181e5820a0e494f171592ef30a4aefde6a3d47d5b1cf279892a5f1aa6d8d9c96e7c413310258207dca7cd2da2bdfe09b6b646ab55f2b615df545f47721f81f51287d764ffcd7b91824582092a91211a78959b178f7bbdbeec47b722608ab69c2401268b189afbdc32573a4183058206b61c567add567137ed7e02074f4ae1c2f966c698488a479cd803103b9ee349f18275820a06f425468bbd59a89364aef141b363a6d4593cb9b7c4c3e6ddcfaf51fe57c520958208d892a07f914e131776739b017b52bd82d5c6c81f22ac0a05996bbb41b2ef7ad181c5820b0c601c320f0231dbcd77a408ba5d8c50b2a112fce75175a1bddc344186977f00c5820f1531fd181a7bba46021ef03911d2fcc721a544fb6b0a464a8e5b9b127023fd30758202eac96ca881924f06815afef712d30d8d110433772dbd98837932033c4a7c9800658206bd09a938b1493e6d6da6179a7bca3bd8ea9e9f0d79cb55cf1af9dab2e4bbd52182b58200fa74fe3fcb963d6ea1d04bef14571e4e64dc1a80a9863bb59256dcc6e6a7db8182558208beb46bbddd84c621de9ed5ba384a4b6d171c8a0902327a80e16e7b4ca7eb81d181a5820cfb33358620b912fa3b25263229f1fb31370d913601cbcb1b8f12fd1a67056b26d6465766963654b6579496e666fa1696465766963654b6579a4010220012158202dfdfd68953d26ae0c2eaa6182e9e68bb018415b4fa7baeed2846bd48e878bf82258204c788291ca635ece0f18813e73fa80bbcb648b58317a5f9e08cfae17c1b656366c76616c6964697479496e666fa3667369676e6564c074323032342d30352d32375430373a34333a35345a6976616c696446726f6dc074323032342d30352d32375430373a34333a35345a6a76616c6964556e74696cc074323032352d30352d32375430373a34333a35345a5840d9dae87651d4e6e193d5386469f680ee5a3dfd1f94766df3e6b20ebe557db3ca4fc3c0333fde709b4f9c032ef392b32afde5c1c3a4dd34d6e5ea543a8e19b8a86a6e616d65537061636573a1781865752e6575726f70612e65632e65756469772e7069642e319821d818588aa46672616e646f6d584043ec8816b7c9f594b1301d8bbef75fb4d4a417a182b6eb1db7b3923f7d77752fdf9fc40f7b1dc267436f0c3575b6e855f3d1a3b39381e5e9a1918ef404c62874686469676573744944182c6c656c656d656e7456616c756569414e44455253534f4e71656c656d656e744964656e7469666965726b66616d696c795f6e616d65d8185883a46672616e646f6d5840596c14e573ad6311289d5aa14ba65a158a2411adaa17a04fbde20fa308385eb4bd935ba5aa91404a2d7a77c9e56a3100575b32336d720f837e1a39cd4f38218068646967657374494418346c656c656d656e7456616c7565634a414e71656c656d656e744964656e7469666965726a676976656e5f6e616d65d818588ca46672616e646f6d58409cfe6850c098fa07af2107ee225751ee44fc7312b8c17d335d5a31f859bda2b8703401543ccd1cb943dc61184db585f389a9898a31c7bbd632fce464608db596686469676573744944036c656c656d656e7456616c7565d903ec6a313938352d30332d333071656c656d656e744964656e7469666965726a62697274685f64617465d8185881a46672616e646f6d5840912e26d9e661cf8fb7d8a1ae06dba932a019f85c105783b658e1ce0224f61142e0d2e08250c841ee10c2f59336a7d13542fb026e00fa8c1877defe66e10525a768646967657374494418286c656c656d656e7456616c7565f571656c656d656e744964656e7469666965726b6167655f6f7665725f3138d8185881a46672616e646f6d5840eceda09c58a1351ade4449b1513768342fedd71e90c6ff659f29779788aeee67a7fbcd7bbc8e6d86cab8d596aa761757b78ea34366315a63d1bc95954fb7f43168646967657374494418206c656c656d656e7456616c7565f571656c656d656e744964656e7469666965726b6167655f6f7665725f3135d8185881a46672616e646f6d5840fdd84e9107aa326d918d78a0c01f5a02d6eb7e8b363d7f04af2e8b084d6f4c16ec967842d5ca9d833bbab1c8e6d6aa59cdd865f94418cb9c025c52ae0299dac268646967657374494418686c656c656d656e7456616c7565f571656c656d656e744964656e7469666965726b6167655f6f7665725f3231d8185881a46672616e646f6d58407bee4ed907205804f8261fa069660f28df0a728015e96eda0842489396e49772b050b4f8e200d2be0e9770ba9d208a48780ac091ca43cf6b3eb6c7bf0e987d5c686469676573744944182d6c656c656d656e7456616c7565f471656c656d656e744964656e7469666965726b6167655f6f7665725f3630d8185881a46672616e646f6d584012d8ab11fdf37cd79f55fb32eb89ac7b600624caf5dfa3021fd3ce6f3f630c30b8e09dcf727dcd6f7faa808cff3d8df689a15fddc5b81ab8107139f05564f4a068646967657374494418676c656c656d656e7456616c7565f471656c656d656e744964656e7469666965726b6167655f6f7665725f3635d8185881a46672616e646f6d58408ea40ad95621721f661d71a022613d0fe14d4e42afdc92aecaf06055b7e8079df16fa54f808f096d22b87d87ac08ee51a79be2c245d7485b132235edb2079b0368646967657374494418356c656c656d656e7456616c7565f471656c656d656e744964656e7469666965726b6167655f6f7665725f3638d8185882a46672616e646f6d58407cc60fcc1079a43377f1c01e3efeb6ecd70f2437447bbe2d5711d0e4e1c4f078a3c2e3702c943df0cc999243cc59852b33ee2a6980949bcb3984490225282f9e6864696765737449440a6c656c656d656e7456616c7565182671656c656d656e744964656e7469666965726c6167655f696e5f7965617273d8185886a46672616e646f6d5840d174d15e1dcf42ec1bb8d610c221aa6430d03bc7c8a42d367593e24bb3987fd48f9b5d5d5ee27ad511dd57df1bccc93a4bc9a21637fcc881f798ed4de2a6a87a68646967657374494418226c656c656d656e7456616c75651907c171656c656d656e744964656e7469666965726e6167655f62697274685f79656172d8185890a46672616e646f6d5840dcfc46c524c67dd0ddbe57dba4847b03373af83ce1063216fb380c44b0d6505aa13073081b5d7f118d802376f3c57931b825ee01d6c835fef3fc541c0200677d68646967657374494418326c656c656d656e7456616c756569414e44455253534f4e71656c656d656e744964656e7469666965727166616d696c795f6e616d655f6269727468d8185888a46672616e646f6d5840bf1e252d2b21bcd4551332635b8f2a2309a2786487cfbd30af370764cccfbc203a6c277846857bbd11f550461a38fccbc670eb0d5ef72e59a7cde45f983b6e28686469676573744944086c656c656d656e7456616c7565634a414e71656c656d656e744964656e74696669657270676976656e5f6e616d655f6269727468d8185887a46672616e646f6d58402c6272ed3cf208a37b5b685c39964ccde324e2809bd3231b85547e9038ecd305cabe023b6b6307d11e447f1537d0d12b34c2591dc683964b24d43f5807397e78686469676573744944182f6c656c656d656e7456616c75656653574544454e71656c656d656e744964656e7469666965726b62697274685f706c616365d8185884a46672616e646f6d5840befafc4e1055588febcef6785fa0b73cb1421a8b662a5573b3b094a0f864b5066f4f6bbfac23caa2a37505f73c260671d86e98e2f0fcf22c1f0c1181ec6f1e35686469676573744944056c656c656d656e7456616c756562534571656c656d656e744964656e7469666965726d62697274685f636f756e747279d8185883a46672616e646f6d5840b12493bd9b2318c61efadf4bc14cf5597019e0e373bde6ce1e9ca9c2bdb58ae2191f34f74df912c6b1111f3be5b30b41f9cb473ab188f79e3d3ff452aa88486568646967657374494418296c656c656d656e7456616c756562534571656c656d656e744964656e7469666965726b62697274685f7374617465d818588ba46672616e646f6d5840d81981b6b19c96219f160efa956a6c045fb5949c070726c014f79c9af916581c145f0fe868f2150a3944ba841dcfbfae752d9b13d5cb0ecbd594dd7de604857e686469676573744944181f6c656c656d656e7456616c75656b4b415452494e45484f4c4d71656c656d656e744964656e7469666965726a62697274685f63697479d8185895a46672616e646f6d58405d9625ee383e2d3711aa94f220b40a89baca8d27fb7f83e3c33238eb844820326301473a3fa5e8ece73cd6142e424c36c5abe4a0fe8cbd71fc28afa106c7fd9d68646967657374494418216c656c656d656e7456616c75656f464f5254554e41474154414e20313571656c656d656e744964656e746966696572707265736964656e745f61646472657373d8185888a46672616e646f6d5840f7c6518e429e51b48701087cbd9b064cfe022359bbd5e342897b60047b7e51557c9a9a3dc221cfa4830b082561338707608732dc1630538733e138208233f0ea68646967657374494418236c656c656d656e7456616c756562534571656c656d656e744964656e746966696572707265736964656e745f636f756e747279d8185886a46672616e646f6d5840c4d456592fde77d93fa67b6c2b0a4e1e3cf06b7de7f6da3f0267b69013af898b821ef7686a97500da0d329e63a7910dc21b2d1d1fcac917c3c7605bba293b287686469676573744944182e6c656c656d656e7456616c756562534571656c656d656e744964656e7469666965726e7265736964656e745f7374617465d818588ea46672616e646f6d5840fb1f4a2ab34be9385d5f4dc1b0fbeb9e228514bec11873f24ca042d93dffecf6a627b5864d60aec3096fcec1802aecdb947725acae6126619b3fea4f63ba51d2686469676573744944181e6c656c656d656e7456616c75656b4b415452494e45484f4c4d71656c656d656e744964656e7469666965726d7265736964656e745f63697479d818588ea46672616e646f6d58408ca7615aec5b08f079c2a5e59588f9b5a471764532845109744bbdd52a3878002c36b947e65c2a5f97725833bde32ba34f71205fc7e79c26bddfcb1a7b94b61c686469676573744944026c656c656d656e7456616c756565363431333371656c656d656e744964656e746966696572747265736964656e745f706f7374616c5f636f6465d8185891a46672616e646f6d5840d81981b6b19c96219f160efa956a6c045fb5949c070726c014f79c9af916581c145f0fe868f2150a3944ba841dcfbfae752d9b13d5cb0ecbd594dd7de604857e68646967657374494418246c656c656d656e7456616c75656c464f5254554e41474154414e71656c656d656e744964656e7469666965726f7265736964656e745f737472656574d818588da46672616e646f6d5840732165a96a0001a9ae2e5081f0453134d3f851da341bccee1fff5106180c0f3e4ce2893aaba78990ac43fffacc90d2bdd84183b0e070ba51cba8d0db5b3d4f1168646967657374494418306c656c656d656e7456616c756562313271656c656d656e744964656e746966696572757265736964656e745f686f7573655f6e756d626572d818587ca46672616e646f6d5840dbd09559cc5e22d4d64c6e7f4a8cd3d9d80c17b37f81dc88e60fe9a5b92febcb56a2a98feb5f47816a8a0fa036c8513545bebea2f3ce4c6f8f27646861830ab568646967657374494418276c656c656d656e7456616c75650171656c656d656e744964656e7469666965726667656e646572d8185882a46672616e646f6d584085b6e1e47aa35866afaffc94802e34ed02423caff52239db6f4f50f4d74142a14af3f4bad645d5dbb6ad1422421f53561cdabcb5fa99a7a1e9820f57dee0858c686469676573744944096c656c656d656e7456616c756562534571656c656d656e744964656e7469666965726b6e6174696f6e616c697479d8185898a46672616e646f6d5840827c15fe24327f6406484eae60e5b6a77c4bb562bf0cafa20c7c303c569b4794adc124a66bd257a8c580dc29d37bda94ef60d8eab7edb6becaa58d1623ac3cdf686469676573744944181c6c656c656d656e7456616c7565c074323030392d30312d30315430303a30303a30305a71656c656d656e744964656e7469666965726d69737375616e63655f64617465d8185895a46672616e646f6d58408a8c1cc86488832efd0e9a31d2f0c2d5eb1269bc3babbc992bd0c201ee60b589035fede85d3d1c72b2ed78970a8e1f1b344c3215022803b167eb62f28400c41e6864696765737449440c6c656c656d656e7456616c7565c074323035302d30332d33305430303a30303a30305a71656c656d656e744964656e7469666965726b6578706972795f64617465d8185889a46672616e646f6d5840732e962c389855cd544f3a4a1abef747ce59e3bb8ee256c5cee1f04b6b477333fd373bbe44b80c8c64fb41b2873d1c309c39c4d7da928cabe5ecf564633e9805686469676573744944076c656c656d656e7456616c75656355544f71656c656d656e744964656e7469666965727169737375696e675f617574686f72697479d818588da46672616e646f6d5840ff20478c01e6c57703e45e44eee1fad45bafbb7ad100cb053375e719ebf4aa263613af29b4f1793e27ffb7be141ec42007bd5074c5e58faaaafd51a2795094a0686469676573744944066c656c656d656e7456616c75656931313131313131313471656c656d656e744964656e7469666965726f646f63756d656e745f6e756d626572d8185895a46672616e646f6d584064751ef966e351dd32fab3f3aaf3d3eb6e31a51a1a6fe4ca316f4f9a7ad249f3fbe76ffa1b590bca54ba0a076a11332c869adbd15a8c40e9c6d6415d727b8ef3686469676573744944182b6c656c656d656e7456616c75656a3930313031363734363471656c656d656e744964656e7469666965727561646d696e6973747261746976655f6e756d626572d8185887a46672616e646f6d5840c8e8431de246dcf0ec024ac2ef8121db66d358af35fa9e8de93187da012791b05c0c072557c1f48a58a0bb7f260dfa84cc31c0a9ce6d05dce86b22ab4085bda968646967657374494418256c656c656d656e7456616c756562534571656c656d656e744964656e7469666965726f69737375696e675f636f756e747279d818588ea46672616e646f6d58407aa5210c2d76832452d8a7bcc8a92dae595f8c88df5ab42a520dee67b2f85bd6035939ad761168a1945244af9eeed21a80cb9a604ae13814b47e13123f585de5686469676573744944181a6c656c656d656e7456616c75656453452d4971656c656d656e744964656e7469666965727469737375696e675f6a7572697364696374696f6e \ No newline at end of file diff --git a/document-manager/src/main/java/eu/europa/ec/eudi/wallet/document/DocumentManager.kt b/document-manager/src/main/java/eu/europa/ec/eudi/wallet/document/DocumentManager.kt index 34f1b24..75fbc2a 100644 --- a/document-manager/src/main/java/eu/europa/ec/eudi/wallet/document/DocumentManager.kt +++ b/document-manager/src/main/java/eu/europa/ec/eudi/wallet/document/DocumentManager.kt @@ -82,13 +82,6 @@ interface DocumentManager { * Expected data format is CBOR. The CBOR data must be in the following structure: * * ```cddl - * Data = { - * "documents" : [+Document], ; Returned documents - * } - * Document = { - * "docType" : DocType, ; Document type returned - * "issuerSigned" : IssuerSigned, ; Returned data elements signed by the issuer - * } * IssuerSigned = { * "nameSpaces" : IssuerNameSpaces, ; Returned data elements * "issuerAuth" : IssuerAuth ; Contains the mobile security object (MSO) for issuer data authentication diff --git a/document-manager/src/main/java/eu/europa/ec/eudi/wallet/document/DocumentManagerImpl.kt b/document-manager/src/main/java/eu/europa/ec/eudi/wallet/document/DocumentManagerImpl.kt index 014112f..2e23f48 100644 --- a/document-manager/src/main/java/eu/europa/ec/eudi/wallet/document/DocumentManagerImpl.kt +++ b/document-manager/src/main/java/eu/europa/ec/eudi/wallet/document/DocumentManagerImpl.kt @@ -21,9 +21,7 @@ import COSE.Sign1Message import android.content.Context import android.util.Log import com.android.identity.android.securearea.AndroidKeystoreSecureArea -import com.android.identity.android.securearea.AndroidKeystoreSecureArea.KEY_PURPOSE_SIGN -import com.android.identity.android.securearea.AndroidKeystoreSecureArea.USER_AUTHENTICATION_TYPE_BIOMETRIC -import com.android.identity.android.securearea.AndroidKeystoreSecureArea.USER_AUTHENTICATION_TYPE_LSKF +import com.android.identity.android.securearea.AndroidKeystoreSecureArea.* import com.android.identity.credential.Credential import com.android.identity.credential.CredentialStore import com.android.identity.credential.NameSpacedData @@ -39,7 +37,7 @@ import eu.europa.ec.eudi.wallet.document.internal.supportsStrongBox import eu.europa.ec.eudi.wallet.document.internal.withTag24 import java.security.SecureRandom import java.time.Instant -import java.util.UUID +import java.util.* /** @@ -162,16 +160,9 @@ class DocumentManagerImpl( try { val credential = credentialStore.lookupCredential(request.documentId) ?: return AddDocumentResult.Failure(IllegalArgumentException("No credential found for ${request.documentId}")) - val cbor = CBORObject.DecodeFromBytes(data) - - val documentCbor = - cbor["documents"].values.firstOrNull { it["docType"].AsString() == request.docType } - ?: return AddDocumentResult.Failure( - IllegalArgumentException("No document found for ${request.docType}"), - ) + val issuerSigned = CBORObject.DecodeFromBytes(data) credential.apply { - val issuerSigned = documentCbor["issuerSigned"] val issuerAuthBytes = issuerSigned["issuerAuth"].EncodeToBytes() val issuerAuth = Message .DecodeFromBytes(issuerAuthBytes, MessageTag.Sign1) as Sign1Message diff --git a/document-manager/src/main/java/eu/europa/ec/eudi/wallet/document/sample/SampleDocumentManager.kt b/document-manager/src/main/java/eu/europa/ec/eudi/wallet/document/sample/SampleDocumentManager.kt index 93d3760..363ee79 100644 --- a/document-manager/src/main/java/eu/europa/ec/eudi/wallet/document/sample/SampleDocumentManager.kt +++ b/document-manager/src/main/java/eu/europa/ec/eudi/wallet/document/sample/SampleDocumentManager.kt @@ -53,9 +53,36 @@ interface SampleDocumentManager : DocumentManager { /** * Loads the sample data into the document manager. * - * @param sampleData + * @param sampleData the sample data to be loaded in cbor format * @return [LoadSampleResult.Success] if the sample data has been loaded successfully. * Otherwise, returns [LoadSampleResult.Error], with the error message. + * + * Expected sampleData format is CBOR. The CBOR data must be in the following structure: + * + * ```cddl + * SampleData = { + * "documents" : [+Document], ; Returned documents + * } + * Document = { + * "docType" : DocType, ; Document type returned + * "issuerSigned" : IssuerSigned, ; Returned data elements signed by the issuer + * } + * IssuerSigned = { + * "nameSpaces" : IssuerNameSpaces, ; Returned data elements + * "issuerAuth" : IssuerAuth ; Contains the mobile security object (MSO) for issuer data authentication + * } + * IssuerNameSpaces = { ; Returned data elements for each namespace + * + NameSpace => [ + IssuerSignedItemBytes ] + * } + * IssuerSignedItemBytes = #6.24(bstr .cbor IssuerSignedItem) + * IssuerSignedItem = { + * "digestID" : uint, ; Digest ID for issuer data authentication + * "random" : bstr, ; Random value for issuer data authentication + * "elementIdentifier" : DataElementIdentifier, ; Data element identifier + * "elementValue" : DataElementValue ; Data element value + * } + * IssuerAuth = COSE_Sign1 ; The payload is MobileSecurityObjectBytes + * ``` */ fun loadSampleData(sampleData: ByteArray): LoadSampleResult diff --git a/document-manager/src/main/java/eu/europa/ec/eudi/wallet/document/sample/SampleDocumentManagerImpl.kt b/document-manager/src/main/java/eu/europa/ec/eudi/wallet/document/sample/SampleDocumentManagerImpl.kt index f677a7a..7531a4c 100644 --- a/document-manager/src/main/java/eu/europa/ec/eudi/wallet/document/sample/SampleDocumentManagerImpl.kt +++ b/document-manager/src/main/java/eu/europa/ec/eudi/wallet/document/sample/SampleDocumentManagerImpl.kt @@ -25,13 +25,7 @@ import com.upokecenter.cbor.CBORObject import eu.europa.ec.eudi.wallet.document.AddDocumentResult import eu.europa.ec.eudi.wallet.document.CreateIssuanceRequestResult import eu.europa.ec.eudi.wallet.document.DocumentManager -import eu.europa.ec.eudi.wallet.document.internal.docTypeName -import eu.europa.ec.eudi.wallet.document.internal.getEmbeddedCBORObject -import eu.europa.ec.eudi.wallet.document.internal.issuerCertificate -import eu.europa.ec.eudi.wallet.document.internal.issuerPrivateKey -import eu.europa.ec.eudi.wallet.document.internal.oneKey -import eu.europa.ec.eudi.wallet.document.internal.supportsStrongBox -import eu.europa.ec.eudi.wallet.document.internal.withTag24 +import eu.europa.ec.eudi.wallet.document.internal.* import java.security.MessageDigest import java.security.PublicKey @@ -58,36 +52,6 @@ class SampleDocumentManagerImpl( */ fun hardwareBacked(flag: Boolean) = apply { hardwareBacked = flag } - /** - * Loads the sample data into the document manager. - * - * The sample data is a CBOR bytearray that has the following structure: - * - * ```cddl - * Data = { - * "documents" : [+Document], ; Returned documents - * } - * Document = { - * "docType" : DocType, ; Document type returned - * "issuerSigned" : IssuerSigned, ; Returned data elements signed by the issuer - * } - * IssuerSigned = { - * "nameSpaces" : IssuerNameSpaces, ; Returned data elements - * } - * IssuerNameSpaces = { ; Returned data elements for each namespace - * + NameSpace => [ + IssuerSignedItemBytes ] - * } - * IssuerSignedItem = { - * "digestID" : uint, ; Digest ID for issuer data authentication - * "random" : bstr, ; Random value for issuer data authentication - * "elementIdentifier" : DataElementIdentifier, ; Data element identifier - * "elementValue" : DataElementValue ; Data element value - * } - * ``` - * - * @param sampleData - * @return [LoadSampleResult.Success] if the sample data has been loaded successfully. Otherwise, returns [LoadSampleResult.Error], with the error message. - */ override fun loadSampleData(sampleData: ByteArray): LoadSampleResult { try { val cbor = CBORObject.DecodeFromBytes(sampleData) @@ -110,7 +74,7 @@ class SampleDocumentManagerImpl( val mso = generateMso(docType, authKey, nameSpaces) val issuerAuth = signMso(mso) - val data = generateData(docType, nameSpaces, issuerAuth) + val data = generateData(nameSpaces, issuerAuth) when (val addResult = addDocument(request, data)) { is AddDocumentResult.Failure -> return LoadSampleResult.Error(addResult.throwable) @@ -168,20 +132,12 @@ class SampleDocumentManagerImpl( }.EncodeToCBORObject() private fun generateData( - docType: String, issuerNameSpaces: CBORObject, issuerAuth: CBORObject, ): ByteArray { return mapOf( - "documents" to arrayOf( - mapOf( - "docType" to docType, - "issuerSigned" to mapOf( - "nameSpaces" to issuerNameSpaces, - "issuerAuth" to issuerAuth, - ), - ), - ), + "nameSpaces" to issuerNameSpaces, + "issuerAuth" to issuerAuth, ).let { CBORObject.FromObject(it).EncodeToBytes() } } } diff --git a/gradle.properties b/gradle.properties index 865f9c9..4d46a7e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -26,8 +26,7 @@ systemProp.sonar.host.url=https://sonarcloud.io systemProp.sonar.gradle.skipCompile=true systemProp.sonar.coverage.jacoco.xmlReportPaths=build/reports/jacoco/testDebugUnitTestCoverage/testDebugUnitTestCoverage.xml,build/reports/jacoco/testReleaseUnitTestCoverage/testReleaseUnitTestCoverage.xml systemProp.sonar.projectName=eudi-lib-android-wallet-document-manager - -VERSION_NAME=0.2.3-SNAPSHOT +VERSION_NAME=0.3.0-SNAPSHOT SONATYPE_HOST=S01 SONATYPE_AUTOMATIC_RELEASE=false