openwallet-foundation-labs / identity-credential Goto Github PK
View Code? Open in Web Editor NEWLicense: Apache License 2.0
License: Apache License 2.0
Termination session bytes send AFTER
draining the queue and transmitting all the deviceResponse
bytes.
The termination message was sent while draining the queue and caused the reader to receive only partial deviceResponse
Currently we only support P-256.
When calculating the ECDSA value for SECP521R1, the "keySize" should be "66":
https://github.com/google/identity-credential/blob/b3388ede2f2541b3dc33d5417d5268ed19801b4d/identity/src/main/java/com/android/identity/Util.java#L576
Any leading zeros are trimmed but not replaced: causing a signature value of less than 132 bytes in such cases
Note: you may get a signature with no leading zeros (for neither R nor S) - in which case the value returned by coseSign1Sign will be correct
After scanning the deviceengagement qr-code with the verifier, the two devices connect to each other.
verifier shows spinner next to "Connection Setup", but nothing else happens.
The app notifies the user the screen lock is not set and letting users know the screenlock has to be set in order to use the application.
The app crashes without notifying
(TBD)
Press "Show QR Code" to get to the "Sharing Document" screen. Lock and unlock the device and the app crashes because it tried to start a new transfer even though one is already underway.
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.android.mdl.app, PID: 10791
java.lang.RuntimeException: Unable to resume activity {com.android.mdl.app/com.android.mdl.app.MainActivity}: java.lang.IllegalStateException: Transfer has already started.
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4894)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4927)
at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:57)
at android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:45)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:179)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2380)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:205)
at android.os.Looper.loop(Looper.java:294)
at android.app.ActivityThread.main(ActivityThread.java:8098)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:578)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:946)
Caused by: java.lang.IllegalStateException: Transfer has already started.
at com.android.mdl.app.transfer.TransferManager.startQrEngagement(TransferManager.kt:102)
at com.android.mdl.app.viewmodel.ShareDocumentViewModel.triggerQrEngagement(ShareDocumentViewModel.kt:45)
at com.android.mdl.app.fragment.ShareDocumentFragment.onResume(ShareDocumentFragment.kt:77)
at androidx.fragment.app.Fragment.performResume(Fragment.java:3180)
at androidx.fragment.app.FragmentStateManager.resume(FragmentStateManager.java:606)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:285)
at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:113)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1433)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2977)
at androidx.fragment.app.FragmentManager.dispatchResume(FragmentManager.java:2909)
at androidx.fragment.app.Fragment.performResume(Fragment.java:3189)
at androidx.fragment.app.FragmentStateManager.resume(FragmentStateManager.java:606)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:285)
at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:113)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1433)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2977)
at androidx.fragment.app.FragmentManager.dispatchResume(FragmentManager.java:2909)
at androidx.fragment.app.FragmentController.dispatchResume(FragmentController.java:285)
at androidx.fragment.app.FragmentActivity.onResumeFragments(FragmentActivity.java:334)
at androidx.fragment.app.FragmentActivity.onPostResume(FragmentActivity.java:323)
at androidx.appcompat.app.AppCompatActivity.onPostResume(AppCompatActivity.java:242)
at android.app.Activity.performResume(Activity.java:8626)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4884)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4927)
at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:57)
at android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:45)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:179)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2380)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:205)
at android.os.Looper.loop(Looper.java:294)
at android.app.ActivityThread.main(ActivityThread.java:8098)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:578)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:946)
Depends on issue #186
1)If the device retrieval mdoc request from the verifier contains an incorrect version number i.e 1.1
2) The mdoc should communicates the correct status code which is 10 or 12 without document key pair in the DeviceResponse by validating against the major version number as per ISO 18013-5 (8.1 Encoding of data structures and data elements)
1)The validation of version number doesn't takes place properly
2) successful engagement takes place with status code as 0 and document key pair is present with empty array
If the BLE connection is lost after the 'State' characteristic is set to value '0x01' then the mdoc should stop scanning for UUID and opens a new session if required as per ISO-18013-5
The mDoc is still in central client mode scanning for the UUID.
A response with appropriate error code should be send to verifier when an exception occurs while decrypting request.
According to document ISO 18013-5, section 9.1.1.4 Table 20(attached): An error code should be send when there is an exception while processing the request before terminating the session. But in the IC API when an exception occurred while decrypting a request(PresentationHelper->onMessageReceived()) there is no response with error codes send to the verifier. The DataTransport session is closed and an error message is send to the reportError method which gets communicated to the onError callback. When the implementing app tries to send the response with error code the below 2 issues blocks it.
No response with appropriate error code has been send to verifier during exception while decrypting request
There are more than 5 exception handling in PresentationHelper->onMessageReceived() method and all the cases should be covered. One such case is listed below
While sending an encrypted device retrieval mdoc request to the mdoc in a SessionEstablishment message make sure the mdoc reader ephemeral public point is not on the curve
Hi
Building an app from this base. I noticed that WebAPI and OIDC has not been implemented. Do you happen to have the spec for this protocols so I can build it myself?
App starts
App (app holder) crashes immediately
app holder
on Pixel 3aBtw, I also tried on an OnePlus 8, and it's running.
Find the Logcat of the crash below:
2021-09-15 08:07:14.441 19198-19198/com.ul.ims.gmdl.appholder E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.ul.ims.gmdl.appholder, PID: 19198
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.ul.ims.gmdl.appholder/com.android.mdl.app.MainActivity}: android.view.InflateException: Binary XML file line #26 in com.ul.ims.gmdl.appholder:layout/activity_main: Binary XML file line #26 in com.ul.ims.gmdl.appholder:layout/activity_main: Error inflating class fragment
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3431)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3595)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7660)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Caused by: android.view.InflateException: Binary XML file line #26 in com.ul.ims.gmdl.appholder:layout/activity_main: Binary XML file line #26 in com.ul.ims.gmdl.appholder:layout/activity_main: Error inflating class fragment
Caused by: android.view.InflateException: Binary XML file line #26 in com.ul.ims.gmdl.appholder:layout/activity_main: Error inflating class fragment
Caused by: java.lang.UnsupportedOperationException
at androidx.security.identity.IdentityCredential.storeStaticAuthenticationData(IdentityCredential.java:405)
at androidx.security.identity.Helpers.provisionSelfSignedCredential(Helpers.java:358)
at com.android.mdl.app.document.DocumentManager.createDummyCredential(DocumentManager.kt:103)
at com.android.mdl.app.document.DocumentManager.access$createDummyCredential(DocumentManager.kt:40)
at com.android.mdl.app.document.DocumentManager$1.invokeSuspend(DocumentManager.kt:71)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:274)
at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:84)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:59)
at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source:1)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:38)
at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source:1)
at com.android.mdl.app.document.DocumentManager.<init>(DocumentManager.kt:65)
at com.android.mdl.app.document.DocumentManager.<init>(DocumentManager.kt:40)
at com.android.mdl.app.document.DocumentManager$Companion.getInstance(DocumentManager.kt:53)
at com.android.mdl.app.fragment.SelectDocumentFragment.onCreateView(SelectDocumentFragment.kt:59)
at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2963)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:518)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:282)
at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:112)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1647)
at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3126)
at androidx.fragment.app.FragmentManager.dispatchViewCreated(FragmentManager.java:3063)
at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:2988)
at androidx.fragment.app.FragmentStateManager.ensureInflatedView(FragmentStateManager.java:392)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:281)
2021-09-15 08:07:14.441 19198-19198/com.ul.ims.gmdl.appholder E/AndroidRuntime: at androidx.fragment.app.FragmentLayoutInflaterFactory.onCreateView(FragmentLayoutInflaterFactory.java:140)
at androidx.fragment.app.FragmentController.onCreateView(FragmentController.java:135)
at androidx.fragment.app.FragmentActivity.dispatchFragmentsOnCreateView(FragmentActivity.java:319)
at androidx.fragment.app.FragmentActivity.onCreateView(FragmentActivity.java:298)
at android.view.LayoutInflater.tryCreateView(LayoutInflater.java:1067)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:995)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:959)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:1121)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1082)
at android.view.LayoutInflater.inflate(LayoutInflater.java:680)
at android.view.LayoutInflater.inflate(LayoutInflater.java:532)
at android.view.LayoutInflater.inflate(LayoutInflater.java:479)
at androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:696)
at androidx.appcompat.app.AppCompatActivity.setContentView(AppCompatActivity.java:170)
at com.android.mdl.app.MainActivity.onCreate(MainActivity.kt:22)
at android.app.Activity.performCreate(Activity.java:8000)
at android.app.Activity.performCreate(Activity.java:7984)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3404)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3595)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7660)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Among other things this makes it easy to validate the behavior of a particular mdoc app if the reader sends this.
In some cases our reader crashes if the holder closes the connection right after sending the response. This has been observed when using Wifi Aware but I believe it also applies to other transports.
java.lang.IllegalArgumentException: Navigation action/destination com.android.mdl.appreader:id/action_Transfer_to_RequestOptions cannot be found from the current destination Destination(com.android.mdl.appreader:id/ShowDocument) label=Show Document class=com.android.mdl.appreader.fragment.ShowDocumentFragment
As per ISO 18013-5(8.3.3.1.1.3) Standard
Device retrieval mdoc response should contain an error code 0 for the missed item that are requested from the verifier.
A response without any error code for the missed items(requested items that are not present in Holder) is returned
This has been added in the TODO bucket list
An exception has occurred in the compiler (1.8.0_202). Please file a bug against the Java compiler via the Java bug reporting page (http://bugreport.java.com) after checking the Bug Database (http://bugs.java.com) for duplicates. Include your program and the following diagnostic in your report. Thank you.
java.lang.AssertionError: annotationType(): unrecognized Attribute name MODULE (class com.sun.tools.javac.util.UnsharedNameTable$NameImpl)
at com.sun.tools.javac.util.Assert.error(Assert.java:133)
at com.sun.tools.javac.code.TypeAnnotations.annotationType(TypeAnnotations.java:231)
at com.sun.tools.javac.code.TypeAnnotations$TypeAnnotationPositions.separateAnnotationsKinds(TypeAnnotations.java:294)
at com.sun.tools.javac.code.TypeAnnotations$TypeAnnotationPositions.visitMethodDef(TypeAnnotations.java:1066)
at com.sun.tools.javac.tree.JCTree$JCMethodDecl.accept(JCTree.java:778)
at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49)
at com.sun.tools.javac.code.TypeAnnotations$TypeAnnotationPositions.scan(TypeAnnotations.java:275)
at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:57)
at com.sun.tools.javac.code.TypeAnnotations$TypeAnnotationPositions.visitClassDef(TypeAnnotations.java:1042)
at com.sun.tools.javac.tree.JCTree$JCClassDecl.accept(JCTree.java:693)
at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49)
at com.sun.tools.javac.code.TypeAnnotations$TypeAnnotationPositions.scan(TypeAnnotations.java:275)
at com.sun.tools.javac.code.TypeAnnotations$1.run(TypeAnnotations.java:127)
at com.sun.tools.javac.comp.Annotate.flush(Annotate.java:152)
at com.sun.tools.javac.comp.Annotate.enterDone(Annotate.java:129)
at com.sun.tools.javac.comp.Enter.complete(Enter.java:512)
at com.sun.tools.javac.comp.Enter.main(Enter.java:471)
at com.sun.tools.javac.main.JavaCompiler.enterTrees(JavaCompiler.java:982)
at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:857)
at com.sun.tools.javac.main.Main.compile(Main.java:523)
at com.sun.tools.javac.api.JavacTaskImpl.doCall(JavacTaskImpl.java:129)
at com.sun.tools.javac.api.JavacTaskImpl.call(JavacTaskImpl.java:138)
at org.gradle.internal.compiler.java.IncrementalCompileTask.call(IncrementalCompileTask.java:74)
at org.gradle.api.internal.tasks.compile.AnnotationProcessingCompileTask.call(AnnotationProcessingCompileTask.java:93)
at org.gradle.api.internal.tasks.compile.ResourceCleaningCompilationTask.call(ResourceCleaningCompilationTask.java:57)
at org.gradle.api.internal.tasks.compile.JdkJavaCompiler.execute(JdkJavaCompiler.java:55)
at org.gradle.api.internal.tasks.compile.JdkJavaCompiler.execute(JdkJavaCompiler.java:40)
at org.gradle.api.internal.tasks.compile.NormalizingJavaCompiler.delegateAndHandleErrors(NormalizingJavaCompiler.java:97)
at org.gradle.api.internal.tasks.compile.NormalizingJavaCompiler.execute(NormalizingJavaCompiler.java:51)
at org.gradle.api.internal.tasks.compile.NormalizingJavaCompiler.execute(NormalizingJavaCompiler.java:37)
at org.gradle.api.internal.tasks.compile.AnnotationProcessorDiscoveringCompiler.execute(AnnotationProcessorDiscoveringCompiler.java:51)
at org.gradle.api.internal.tasks.compile.AnnotationProcessorDiscoveringCompiler.execute(AnnotationProcessorDiscoveringCompiler.java:37)
at org.gradle.api.internal.tasks.compile.ModuleApplicationNameWritingCompiler.execute(ModuleApplicationNameWritingCompiler.java:46)
at org.gradle.api.internal.tasks.compile.ModuleApplicationNameWritingCompiler.execute(ModuleApplicationNameWritingCompiler.java:36)
at org.gradle.api.internal.tasks.compile.CleaningJavaCompiler.execute(CleaningJavaCompiler.java:53)
at org.gradle.api.internal.tasks.compile.incremental.IncrementalCompilerFactory.lambda$createRebuildAllCompiler$0(IncrementalCompilerFactory.java:98)
at org.gradle.api.internal.tasks.compile.incremental.IncrementalResultStoringCompiler.execute(IncrementalResultStoringCompiler.java:60)
at org.gradle.api.internal.tasks.compile.incremental.IncrementalResultStoringCompiler.execute(IncrementalResultStoringCompiler.java:44)
at org.gradle.api.internal.tasks.compile.CompileJavaBuildOperationReportingCompiler$2.call(CompileJavaBuildOperationReportingCompiler.java:59)
at org.gradle.api.internal.tasks.compile.CompileJavaBuildOperationReportingCompiler$2.call(CompileJavaBuildOperationReportingCompiler.java:51)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:409)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:399)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:157)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:242)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:150)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:94)
at org.gradle.internal.operations.DelegatingBuildOperationExecutor.call(DelegatingBuildOperationExecutor.java:36)
at org.gradle.api.internal.tasks.compile.CompileJavaBuildOperationReportingCompiler.execute(CompileJavaBuildOperationReportingCompiler.java:51)
at org.gradle.api.tasks.compile.JavaCompile.performCompilation(JavaCompile.java:293)
at org.gradle.api.tasks.compile.JavaCompile.performIncrementalCompilation(JavaCompile.java:203)
at org.gradle.api.tasks.compile.JavaCompile.compile(JavaCompile.java:183)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:104)
at org.gradle.api.internal.project.taskfactory.IncrementalInputsTaskAction.doExecute(IncrementalInputsTaskAction.java:32)
at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:42)
at org.gradle.api.internal.project.taskfactory.AbstractIncrementalTaskAction.execute(AbstractIncrementalTaskAction.java:25)
at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:28)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$3.run(ExecuteActionsTaskExecuter.java:569)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:395)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:387)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:157)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:242)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:150)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:84)
at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:554)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:537)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.access$300(ExecuteActionsTaskExecuter.java:108)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$TaskExecution.executeWithPreviousOutputFiles(ExecuteActionsTaskExecuter.java:278)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$TaskExecution.execute(ExecuteActionsTaskExecuter.java:267)
at org.gradle.internal.execution.steps.ExecuteStep.lambda$execute$0(ExecuteStep.java:32)
at java.util.Optional.map(Optional.java:215)
at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:32)
at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:26)
at org.gradle.internal.execution.steps.CleanupOutputsStep.execute(CleanupOutputsStep.java:67)
at org.gradle.internal.execution.steps.CleanupOutputsStep.execute(CleanupOutputsStep.java:36)
at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:49)
at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:34)
at org.gradle.internal.execution.steps.CancelExecutionStep.execute(CancelExecutionStep.java:43)
at org.gradle.internal.execution.steps.TimeoutStep.executeWithoutTimeout(TimeoutStep.java:73)
at org.gradle.internal.execution.steps.TimeoutStep.execute(TimeoutStep.java:54)
at org.gradle.internal.execution.steps.CatchExceptionStep.execute(CatchExceptionStep.java:34)
at org.gradle.internal.execution.steps.CreateOutputsStep.execute(CreateOutputsStep.java:44)
at org.gradle.internal.execution.steps.SnapshotOutputsStep.execute(SnapshotOutputsStep.java:54)
at org.gradle.internal.execution.steps.SnapshotOutputsStep.execute(SnapshotOutputsStep.java:38)
at org.gradle.internal.execution.steps.BroadcastChangingOutputsStep.execute(BroadcastChangingOutputsStep.java:49)
at org.gradle.internal.execution.steps.CacheStep.executeWithoutCache(CacheStep.java:159)
at org.gradle.internal.execution.steps.CacheStep.execute(CacheStep.java:72)
at org.gradle.internal.execution.steps.CacheStep.execute(CacheStep.java:43)
at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:44)
at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:33)
at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:38)
at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:24)
at org.gradle.internal.execution.steps.SkipUpToDateStep.executeBecause(SkipUpToDateStep.java:92)
at org.gradle.internal.execution.steps.SkipUpToDateStep.lambda$execute$0(SkipUpToDateStep.java:85)
at java.util.Optional.map(Optional.java:215)
at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:55)
at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:39)
at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:76)
at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:37)
at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:36)
at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:26)
at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:94)
at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:49)
at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:79)
at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:53)
at org.gradle.internal.execution.steps.ValidateStep.execute(ValidateStep.java:74)
at org.gradle.internal.execution.steps.SkipEmptyWorkStep.lambda$execute$2(SkipEmptyWorkStep.java:78)
at java.util.Optional.orElseGet(Optional.java:267)
at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:78)
at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:34)
at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsStartedStep.execute(MarkSnapshottingInputsStartedStep.java:39)
at org.gradle.internal.execution.steps.LoadExecutionStateStep.execute(LoadExecutionStateStep.java:40)
at org.gradle.internal.execution.steps.LoadExecutionStateStep.execute(LoadExecutionStateStep.java:28)
at org.gradle.internal.execution.impl.DefaultWorkExecutor.execute(DefaultWorkExecutor.java:33)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:194)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:186)
at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:114)
at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)
at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:62)
at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57)
at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:56)
at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:409)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:399)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:157)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:242)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:150)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:94)
at org.gradle.internal.operations.DelegatingBuildOperationExecutor.call(DelegatingBuildOperationExecutor.java:36)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52)
at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:41)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:356)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:343)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:336)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:322)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.lambda$run$0(DefaultPlanExecutor.java:127)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:191)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.executeNextNode(DefaultPlanExecutor.java:182)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:124)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
at java.lang.Thread.run(Thread.java:748)
Task :identity:bundleLibResDebug NO-SOURCE
Task :appholder:mergeDebugNativeLibs UP-TO-DATE
Task :appholder:stripDebugDebugSymbols NO-SOURCE
Task :appverifier:processDebugResources
Task :appverifier:mergeDebugNativeLibs UP-TO-DATE
Task :appverifier:stripDebugDebugSymbols NO-SOURCE
Task :appverifier:mergeExtDexDebug
If there is incorrect session establishment data then the holder should send status code as 20 for termination
Instead Holder disconnect from the verifier without sending session termination
1.Establish a successful device engagement between holder and reader using QR (BLE mode)
2.Send an invalid session establishment message from the reader to the holder
3.Expect the above failure i.e the holder disconnected without sending status code as 20 for termination
While it would not make much sense to send a second request before the previous has been answered and the ISO standard implicitly states that the request should be followed by a response (and then further back and forth communication may resume), I think the library still shouldn't crash if that happens.
If the verifier application sends multiple requests in sequence, before the response has been sent, the identity-credential library crashes with:
java.lang.IllegalStateException: SessionTranscript already set
at com.android.identity.SoftwarePresentationSession.setSessionTranscript(SoftwarePresentationSession.java:98)
at com.android.identity.PresentationHelper$1.onMessageReceived(PresentationHelper.java:451)
at com.android.identity.DataTransport.lambda$reportMessageReceived$6(DataTransport.java:343)
at com.android.identity.DataTransport$$ExternalSyntheticLambda8.run(Unknown Source:4)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:233)
at android.app.ActivityThread.main(ActivityThread.java:8030)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:631)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:978)
Right now we just show a QR code scanner window and you just have to know you can also NFC tap.
Util.fromHex("XX") throws IllegalArgumentException
Util.fromHex("XX") returns -17 (= 0xEF)
This is because Util.fromHex() is built on top of Character.digit(), and Character.digit('X', 16) returns -1.
I already have a commit to fix this, I'm just filing this issue first so I can reference it from my fix commit.
I install app holder on Samsung Galaxy S7 which runs on Android 8.0 and create a mDoc.
I install app verifier on Samsung Galaxy S10 which runs on Android 12.0.
I use NFC option for Data retrieval method.
I tap two devices to read mDoc. But nothing happens.
(TBD)
Depends on issue #186
Pressing "Show QR Code" with bluetooth disabled results in an ungraceful crash and doesn't explain that you need to turn BT on in order to make it work. There's an example stack trace below and there are TODOs in the code for this same issue.
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.android.mdl.app, PID: 10229
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.bluetooth.le.BluetoothLeScanner.startScan(java.util.List, android.bluetooth.le.ScanSettings, android.bluetooth.le.ScanCallback)' on a null object reference
at com.android.identity.DataTransportBleCentralClientMode.connectAsMdoc(DataTransportBleCentralClientMode.java:195)
at com.android.identity.DataTransportBleCentralClientMode.connect(DataTransportBleCentralClientMode.java:292)
at com.android.identity.QrEngagementHelper.startListening(QrEngagementHelper.java:144)
at com.android.identity.QrEngagementHelper.<init>(QrEngagementHelper.java:46)
at com.android.mdl.app.transfer.QrCommunicationSetup.configure(QrCommunicationSetup.kt:91)
at com.android.mdl.app.transfer.TransferManager.startQrEngagement(TransferManager.kt:125)
at com.android.mdl.app.viewmodel.ShareDocumentViewModel.triggerQrEngagement(ShareDocumentViewModel.kt:45)
at com.android.mdl.app.fragment.ShareDocumentFragment.onResume(ShareDocumentFragment.kt:77)
at androidx.fragment.app.Fragment.performResume(Fragment.java:3180)
at androidx.fragment.app.FragmentStateManager.resume(FragmentStateManager.java:606)
at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:285)
at androidx.fragment.app.SpecialEffectsController$FragmentStateManagerOperation.complete(SpecialEffectsController.java:771)
at androidx.fragment.app.SpecialEffectsController$Operation.completeSpecialEffect(SpecialEffectsController.java:690)
at androidx.fragment.app.DefaultSpecialEffectsController$SpecialEffectsInfo.completeSpecialEffect(DefaultSpecialEffectsController.java:877)
at androidx.fragment.app.DefaultSpecialEffectsController.startAnimations(DefaultSpecialEffectsController.java:176)
at androidx.fragment.app.DefaultSpecialEffectsController.executeOperations(DefaultSpecialEffectsController.java:126)
at androidx.fragment.app.SpecialEffectsController.executePendingOperations(SpecialEffectsController.java:306)
at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1912)
at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1823)
at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1760)
at androidx.fragment.app.FragmentManager$5.run(FragmentManager.java:547)
at android.os.Handler.handleCallback(Handler.java:958)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:205)
at android.os.Looper.loop(Looper.java:294)
at android.app.ActivityThread.main(ActivityThread.java:8098)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:578)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:946)
See https://github.com/android/cose-lib for a library we could use.
There are currently a set of duplicate files copied over from the identity/ library that are located at wwwverifier/src/main/java/com/google/sps/identity, as there were some difficulties in importing classes from identity/ to wwwverifier/. In the future, these extra files should be removed, and the file RequestServlet.java should be modified accordingly.
App run successfully.
Execution failed for task ':appreader:generateSafeArgsDebug'.
Could not read '\mdl-ref-apps\app\build\intermediates\metadata_application_id\debug\application-id.txt' as it does not exist.
Fails to install and run app.
Android Studio 4.1.1
Windows 10 Enterprise
Others:
Same issue when running 'appreader' app.
For example, a CN to reproduce this would be "CN=Company, Ltd".
If the mdoc is acting as the GATT client during device retrieval using BLE and does not support the L2CAP transmission profile, the mdoc follows the correct close procedure which is mdoc should write the value 0x0000 to descriptor of 'Server2Client'.
The mDL did not write value 0x0000 to descriptor of 'Server2Client and it closes the BLE connection
1.if the mdoc is acting as the GATT client during device retrieval using BLE and does not support the L2CAP transmission profile,
2.Set the value of the 'State' characteristic of the mdoc reader service to 0x02 (End) to signal the end of data transmission
An option to send status: 20
along with the data in a MdocResponse in order to initiate "early" session termination.
According to https://developer.android.com/guide/topics/data/autobackup this database ends up being backed up and restored. We should probably opt out of doing that since all of these documents will reference HW-backed keys that are not backed up and restored.
The 'Android Identity Credential Authentication Key' certificate contains a custom extension 1.3.6.1.4.1.11129.2.1.26 with the ProofOfBinding.
Example:
A3 44 (68)
30 42 (66)
30 40 (64)
06 0A (10): 2B06010401D67902011A
04 32 (50): 826E50726F6F664F6642696E64696E675820F6098091A6CCA59DA9512B262515440750B757C2E1EB30C7B5FA93E59127FAFB
Is this valid format according to X.509? I think the content should also be ASN.1 encoded, but currently it is just raw bytes of ProofOfContent.
The certificate is generated in CredentialData.java, generateAuthenticatoinKeyCert method.
As per ISO 18013-5(8.3.3.1.1.3) Standard
If BLE connection is lost before the 'State' characteristic is set to value '0x01', the mdoc should try to reconnect.
No reconnection is taking place
The personalize
method of the WritableIdentityCredential
creates a COSE_Sign1 structure including the Credential data and its AccessControlProfile
s.
The output of wc.personalize(personalizationBuilderAuth.build())
contains the CBOR COSE_Sign1 data and some information about the AccessControlProfile
s. This seems to be correct. However, when loading this data in a Kotlin COSE_Sign1 object (package com.ul.ims.gmdl.cbordata.security.CoseSign1
) the AccessControlProfile
are missing.
I have added a small test settings below. Please compare the output of debug1
and debug2
. I honestly don't know if I am missing something or if it is a bug.
package com.google.x
import android.util.Log
import androidx.security.identity.*
import androidx.test.platform.app.InstrumentationRegistry
import com.ul.ims.gmdl.cbordata.security.CoseSign1
import org.junit.Test
class PopTest {
@Test
fun testProofOfProvisioning() {
val context = InstrumentationRegistry.getInstrumentation().context
val store = IdentityCredentialStore.getInstance(context)
val wc: WritableIdentityCredential?
try {
store.deleteCredentialByName("test_credential")
} catch(npe: NullPointerException) {
// Ignore, document not created yet. Only for recurring tests
}
wc = store.createCredential(
"test_credential",
"testDoc"
)
val personalizationBuilderAuth = PersonalizationData.Builder()
val namespace = "namespace.test"
val acpid = AccessControlProfileId(1)
val acp = AccessControlProfile.Builder(acpid)
.setUserAuthenticationRequired(false)
.setUserAuthenticationTimeout(0)
.build()
personalizationBuilderAuth.addAccessControlProfile(
acp
)
personalizationBuilderAuth.putEntryString(
namespace,
"id1",
arrayListOf(acpid),
"test1"
)
personalizationBuilderAuth.putEntryString(
namespace,
"id2",
arrayListOf(acpid),
"test2"
)
personalizationBuilderAuth.putEntryString(
namespace,
"id3",
arrayListOf(acpid),
"test3"
)
personalizationBuilderAuth.putEntryString(
namespace,
"id4",
arrayListOf(acpid),
"test4"
)
personalizationBuilderAuth.putEntryString(
namespace,
"id5",
arrayListOf(acpid),
"test5"
)
val data = personalizationBuilderAuth.build()
val proofOfProvisioningCbor = wc.personalize(data)
val coseSign1 = CoseSign1.Builder().decode(proofOfProvisioningCbor).build()
val debug1 = String(proofOfProvisioningCbor)
val debug2 = String(coseSign1.payloadData!!)
}
}
Expected Behavior
The app shouldn’t be crashing while trying to writing the credential with hardware backed storage with all devices
Actual Behavior
The app is crashing on some of the devices while trying to write the credential with hardware backed
Steps to Reproduce the Problem
Device: Google pixel 6
Android OS : 13.0
E/AndroidRuntime: FATAL EXCEPTION: DefaultDispatcher-worker-1
Process: com.android.mdl.app, PID: 15986
java.lang.RuntimeException: Unexpected ServiceSpecificException with code 1
at android.security.identity.CredstoreIdentityCredentialStore.createCredential(CredstoreIdentityCredentialStore.java:129)
at com.android.identity.HardwareIdentityCredentialStore.createCredential(HardwareIdentityCredentialStore.java:109)
at com.android.identity.Utility.provisionSelfSignedCredential(Utility.java:273)
at com.android.mdl.app.document.DocumentManager.provisionSelfSigned(DocumentManager.kt:694)
at com.android.mdl.app.document.DocumentManager.provisionSelfSignedMdl(DocumentManager.kt:356)
at com.android.mdl.app.document.DocumentManager.access$provisionSelfSignedMdl(DocumentManager.kt:24)
at com.android.mdl.app.document.DocumentManager$createSelfSignedCredential$1.invokeSuspend(DocumentManager.kt:188)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:284)
at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:85)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:59)
at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source:1)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:38)
at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source:1)
at com.android.mdl.app.document.DocumentManager.createSelfSignedCredential(DocumentManager.kt:181)
at com.android.mdl.app.viewmodel.SelfSignedViewModel$createSelfSigned$1.invokeSuspend(SelfSignedViewModel.kt:206)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at kotlinx.coroutines.internal.LimitedDispatcher.run(LimitedDispatcher.kt:42)
at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:95)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664)
Suppressed: kotlinx.coroutines.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@7420abd, Dispatchers.IO]
Caused by: android.os.ServiceSpecificException: HAL failed with exception code -8 (EX_SERVICE_SPECIFIC), service-specific error code 1, message 'Error initializing WritableIdentityCredential' (code 1)
at android.os.Parcel.createExceptionOrNull(Parcel.java:3025)
at android.os.Parcel.createException(Parcel.java:2995)
at android.os.Parcel.readException(Parcel.java:2978)
at android.os.Parcel.readException(Parcel.java:2920)
at android.security.identity.ICredentialStore$Stub$Proxy.createCredential(ICredentialStore.java:197)
at android.security.identity.CredstoreIdentityCredentialStore.createCredential(CredstoreIdentityCredentialStore.java:109)
... 24 more
D/OpenGLRenderer: endAllActiveAnimators on 0xb40000711a06b560 (RippleDrawable) with handle 0xb40000702a36b8c0
Recommended upgrade version:
2.4.21
Are there any public specification regarding the provisioning? I don't think ISO 18013 talks about provisioning, and the ISO/IEC 23220 isn't available to public yet.
I am looking mainly at the ProvisioningSession and CertifyAuthKeysSession. For example
The only 'specification' I found is in the mdl-ref-server/README.md file. Where can I find more info about it?
When I tap with another device which installs App Holder apk, I meet this exception. Galaxy S7 run Android 8.0:
java.lang.IllegalArgumentException: Navigation action/destination com.android.mdl.appreader:id/action_Transfer_to_RequestOptions cannot be found from the current destination Destination(com.android.mdl.appreader:id/RequestOptions) label=Mdoc Verifier class=com.android.mdl.appreader.fragment.RequestOptionsFragment
at androidx.navigation.NavController.navigate(NavController.kt:1540)
at com.android.mdl.appreader.fragment.TransferFragment.onViewCreated$lambda-0(TransferFragment.kt:114)
18013-5 8.2.1.1 Device engagement structure" says DeviceEngagement should not contain DeviceRetrievalMethods map at all for NFC, however our implementation inserts this with an empty list of methods.
Currently, there is no signal when the mdoc has completed transferring the device response. In our implementations, a callback would be useful for performing an activity like terminating the session.
IdentityCredentialStore.getHardwareInstance()
Should return null if hardware backed is not supported (it's marked @nullable and javadoc states unsupported will return null).
Throws a runtime exception with message "HW-backed IdentityCredential not supported"
NFC static handover should be working fine with NFC +BLE mode
on Doing NFC static handover , the device engagement data create twice and holder app tries to decrypt the data with keys from first created Device engagemet data result in request decryption failure at holder end . Have attached the logs for the google holder app
Google Holder app logs.txt
verifier app-logs-2023-01-17232107_NFC _Static with google.txt
You should be able to verify and present between iOS and Android
Nothing happens unless you add some calls to super
So, I have implemented all of this stuff in Swift for iOS including all the unit tests etc. It all works fine but interop between Android and iOS versions does not. I looked at some other BLE examples and saw that usually you need to invoke the super class f.i here:
super.onCharacteristicReadRequest(device, requestId, offset, characteristic)
When I do this it works (although a bit intermittently, I get timeouts) but when running Android as reader/verifier I get the request over the iOS holder, can decrypt the session and reply but the reader never gets the notification on the server2client characteristic. I wonder why it works Android-Android without this though.
So, I wonder if there is some other difference between iOS/Android. Setting up for notification is simpler on IOS and does not involve the CLIENT_CHARACTERISTIC_CONFIG descriptor. Why else should I look for here? Think I already tried invoking super. on the Central.
(TBD)
See 18013-5 clause 9.1.5.2 for example.
subject/issuer mismatch was reported at the Brisbane test event.
The portrait in the self-signed document details can be replaced from the camera.
After taking a picture, the app crashes.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.