italia / cieid-android-sdk

BSD 3-Clause "New" or "Revised" License
17 stars 11 forks source link

Failure reading CIE with some SAMSUNG devices #13

Open pasqualedevita opened 3 years ago

pasqualedevita commented 3 years ago

While reading CIE (NFC reading) I got an error with the SAMSUNG SM-A300FU and authentication process fail.

I tested two different CIE cards on these apps:

  1. IO App -> fails
  2. INPS Mobile -> fails
  3. SampleApp cie-android-sdk -> fails
  4. CieID -> works

Here our IO App error log from cieid-android-sdk:

09-22 09:30:48.729  9546  9562 D CIE-DEBUG: onEvent
09-22 09:30:48.729  9546  9562 D CIE-DEBUG: ON_TAG_DISCOVERED
09-22 09:30:48.759  9546  9562 D CieIDSdkLogger: getIdServizi()
09-22 09:30:49.089  9546  9562 D CieIDSdkLogger: selectAidIas()
09-22 09:30:49.129  9546  9562 D CieIDSdkLogger: selectAidCie()
09-22 09:30:49.229  9546  9562 D CieIDSdkLogger: initDHParam()
09-22 09:30:49.849  9546  9562 D CieIDSdkLogger: readDappPubKey()
09-22 09:30:50.029  9546  9562 D CieIDSdkLogger: initExtAuthParam()
09-22 09:30:50.429  9546  9562 D CieIDSdkLogger: dhKeyExchange()
09-22 09:30:54.129  9546  9562 D CieIDSdkLogger: dApp()
09-22 09:30:54.319  9546  9562 D CieIDSdkLogger: java.lang.ArrayIndexOutOfBoundsException: length=0; index=0
09-22 09:30:54.319  9546  9562 D CIE-DEBUG: length=0; index=0
09-22 09:30:54.319  9546  9562 D CIE-DEBUG: onError
09-22 09:30:54.319  9546  9562 D CIE-DEBUG: length=0; index=0

Thank you for the help!

Device Manufacturer: SAMSUNG Model: SM-A300FU OS level: 23 Android version: 6.0.1

pasqualedevita commented 3 years ago

I also tested PosteID and Sample app in this repo with same SAMSUNG SM-A300FU and also authentication process fail. I don't kwon if PosteID uses cie-android-sdk.

pasqualedevita commented 3 years ago

From our customers tickets, we found that these devices also have problems:

Device Manufacturer: SAMSUNG Model: SM-J710F OS level: 27 Android version: 8.1

Device Manufacturer: SAMSUNG Model: SM-A510F OS level: 24 Android version: 7.0

Device Manufacturer: SAMSUNG Model: SM-A320FL OS level: 26 Android version: 8.0

05-10 22:09:31.560  V/InputMethodManager(28861): Starting input: tba=android.view.inputmethod.EditorInfo@53576a7 nm : it.pagopa.io.app ic=com.android.internal.widget.EditableInputConnection@e149754
05-10 22:09:23.777  W/System.err(28861):    at java.lang.Thread.run(Thread.java:764)
05-10 22:09:23.777  W/System.err(28861):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
05-10 22:09:23.777  W/System.err(28861):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
05-10 22:09:23.777  W/System.err(28861):    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
05-10 22:09:23.777  W/System.err(28861):    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
05-10 22:09:23.777  W/System.err(28861):    at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:57)
05-10 22:09:23.777  W/System.err(28861):    at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:66)
05-10 22:09:23.777  W/System.err(28861):    at io.reactivex.Scheduler$DisposeTask.run(Scheduler.java:578)
05-10 22:09:23.777  W/System.err(28861):    at io.reactivex.internal.operators.single.SingleSubscribeOn$SubscribeOnObserver.run(SingleSubscribeOn.java:89)
05-10 22:09:23.777  W/System.err(28861):    at io.reactivex.Single.subscribe(Single.java:3666)
05-10 22:09:23.777  W/System.err(28861):    at io.reactivex.internal.operators.observable.ObservableSingleSingle.subscribeActual(ObservableSingleSingle.java:35)
05-10 22:09:23.777  W/System.err(28861):    at io.reactivex.Observable.subscribe(Observable.java:12284)
05-10 22:09:23.777  W/System.err(28861):    at retrofit2.adapter.rxjava2.CallExecuteObservable.subscribeActual(CallExecuteObservable.java:45)
05-10 22:09:23.777  W/System.err(28861):    at retrofit2.OkHttpCall.execute(OkHttpCall.java:188)
05-10 22:09:23.777  W/System.err(28861):    at okhttp3.RealCall.execute(RealCall.java:93)
05-10 22:09:23.777  W/System.err(28861):    at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:257)
05-10 22:09:23.777  W/System.err(28861):    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
05-10 22:09:23.777  W/System.err(28861):    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
05-10 22:09:23.777  W/System.err(28861):    at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.kt:150)
05-10 22:09:23.777  W/System.err(28861):    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
05-10 22:09:23.777  W/System.err(28861):    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
05-10 22:09:23.777  W/System.err(28861):    at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:127)
05-10 22:09:23.777  W/System.err(28861):    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
05-10 22:09:23.776  W/System.err(28861):    at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
05-10 22:09:23.776  W/System.err(28861):    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
05-10 22:09:23.776  W/System.err(28861):    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
05-10 22:09:23.776  W/System.err(28861):    at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
05-10 22:09:23.776  W/System.err(28861):    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
05-10 22:09:23.776  W/System.err(28861):    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
05-10 22:09:23.776  W/System.err(28861):    at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:45)
05-10 22:09:23.776  W/System.err(28861):    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
05-10 22:09:23.776  W/System.err(28861):    at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.java:88)
05-10 22:09:23.776  W/System.err(28861):    at okhttp3.internal.http1.Http1Codec.readResponseHeaders(Http1Codec.java:189)
05-10 22:09:23.776  W/System.err(28861):    at okhttp3.internal.http1.Http1Codec.readHeaderLine(Http1Codec.java:215)
05-10 22:09:23.776  W/System.err(28861):    at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.kt:333)
05-10 22:09:23.776  W/System.err(28861):    at okio.RealBufferedSource.indexOf(RealBufferedSource.kt:449)
05-10 22:09:23.776  W/System.err(28861):    at okio.AsyncTimeout$source$1.read(AsyncTimeout.kt:129)
05-10 22:09:23.776  W/System.err(28861):    at okio.InputStreamSource.read(Okio.kt:93)
05-10 22:09:23.776  W/System.err(28861):    at com.android.org.conscrypt.ConscryptFileDescriptorSocket$SSLInputStream.read(ConscryptFileDescriptorSocket.java:567)
05-10 22:09:23.776  W/System.err(28861):    at com.android.org.conscrypt.SslWrapper.read(SslWrapper.java:391)
05-10 22:09:23.776  W/System.err(28861):    at com.android.org.conscrypt.NativeCrypto.SSL_read(Native Method)
05-10 22:09:23.776  W/System.err(28861):    at com.android.org.conscrypt.CryptoUpcalls.rawSignDigestWithPrivateKey(CryptoUpcalls.java:123)
05-10 22:09:23.776  W/System.err(28861):    at java.security.Signature.sign(Signature.java:735)
05-10 22:09:23.776  W/System.err(28861):    at java.security.Signature$Delegate.engineSign(Signature.java:1414)
05-10 22:09:23.776  W/System.err(28861):    at it.ipzs.cieidsdk.ciekeystore.CieSignatureImpl.engineSign(CieSignatureImpl.kt:36)
05-10 22:09:23.776  W/System.err(28861):    at it.ipzs.cieidsdk.nfc.Ias.sign(Ias.kt:638)
05-10 22:09:23.776  W/System.err(28861):    at it.ipzs.cieidsdk.nfc.Ias.sendApduSM(Ias.kt:1364)
05-10 22:09:23.776  W/System.err(28861):    at it.ipzs.cieidsdk.nfc.Ias.getRespSM(Ias.kt:1630)
05-10 22:09:23.775  W/System.err(28861):    at it.ipzs.cieidsdk.nfc.Ias.respSM(Ias.kt:1523)
05-10 22:09:23.775  W/System.err(28861): java.lang.ArrayIndexOutOfBoundsException: length=0; index=0
05-10 22:09:23.775  W/System.err(28861): Exception while signing message with RSA private key:
pasqualedevita commented 3 years ago

I tried to login with CIE into INPS website and CieID app fails to read the CIE card. I also tried to login into AIFA website without success.

I repeated same tests with another device and I logged in successfully with CIE on both websites.

So it seems that I can register the CIE in CieID app on SAMSUNG SM-A300FU but I can't login in websites with CIE.

I hope that will be useful to continue to investigate the issue.

fventola-ipzs commented 3 years ago

The registration process in the CieID app has different procedures from the authentication process. The CieID app authentication is based on the same code of this sdk and we think the same issue at this point. The issue depends on low level NFC communication of this specific device with the CIE. We will try to solve this issue when we will have the device available.

ghost commented 3 years ago

@fventola89 I think this issue is related to #15, where I found a wordaround and a possible solution

fventola-ipzs commented 3 years ago

@etmatrix we found a partial solution of the problem increasing nfc delay in startNfcListening with this code:

options.putInt(NfcAdapter.EXTRA_READER_PRESENCE_CHECK_DELAY, 6000)

But the problem on server TLS communication still continue. We solve the problem of private key adding this check on CieProvider:

 if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.Q) {
            put("Signature.NONEwithRSA", CieSignatureImpl.None::class.java.name)
        } else {
            put("Cipher.RSA/ECB/PKCS1Padding", Cipher::class.java.name)
        }

We are working on a new TLS communication between server and app to solve completely the issue. We hope to release the fix in the next months.