OpenSC / OpenSC

Open source smart card tools and middleware. PKCS#11/MiniDriver/Tokend
https://github.com/OpenSC/OpenSC/wiki
GNU Lesser General Public License v2.1
2.59k stars 742 forks source link

D-Trust card 3.1 + Reiner SCT cyberJack Komfort + OpenSC + Mac => Pin only works if it has max length?? + Asking for PIN twice #2244

Open the-docta opened 3 years ago

the-docta commented 3 years ago

Problem Description

I have a brand new D-Trust Card 3.1 that is supposed to be usable for PDF signing (which is the ultimate goal)

I have access to the following two readers:

~ » opensc-tool --list-readers --verbose
# Detected readers (pcsc)
Nr.  Card  Features  Name
0    Yes   PIN pad   REINER SCT cyberJack RFID komfort
     3b:d2:18:00:81:31:fe:58:c9:01:14 Atos CardOS [IN USE]
1    No              Gemalto PC Twin Reader

the card is currently inserted into the cyberJack (also brand new) and I also have the Gemalto, which I have been using for almost two years now with opensc

The Card-PIN and the Signature-PIN are initialized and I initially had set them both to a length 6 digits (card requires 6 - 12) digits. Initial setting was done using the "D-Trust card assistant tool", which is a windows tool provided by the card issuer.

Changing pins is possible using both the PIN pad on cyberjack and also using Gemalto and "input fields" on app level.

now, Open SC refused the pins on both readers - even if the pin was entered on the Pin pad of the cyberJack, the display of the reader said the PIN is incorrect.

Here I was using the cyberJack and a 6-digit PIN, showing the second and third try:

~ » pkcs11-tool --test --login
Using slot 0 with a present token (0x0)
error: PKCS11 function C_Login failed: rv = CKR_GENERAL_ERROR (0x5)
Aborting.

~ » pkcs11-tool --test --login
Using slot 0 with a present token (0x0)
error: PKCS11 function C_Login failed: rv = CKR_PIN_LOCKED (0xa4)
Aborting.

(same for slot 1, which uses Signature-PIN, same for Gemalto and for cyberJack) The irritating thing is that the cyberJack showed "PIN inkorrekt" in the device display, though I had changed the PIN using the device display => I definitely entered the correct PIN.

After I changed the pin to a full allowed length of 12 digits, this started working - well, almost.

I think, the above is one issue, the below is a different one, I'll put them both in one ticket, please let me know if we should split that in two separate ones.

Now, if I run the following commands, I am asked for the PIN twice in each of the runs.

Same result with cyberJack and with Gemalto readers. The only difference: Pin is entered for cyberJack on Pin Pad of the device, with Gemalto on the command prompt. When I enter the PIN in the Pin Pad of cyberJack, the display of the device confirms "PIN korrekt" each time. so PIN is correct... BUT:

~ » pkcs11-tool --test --login --slot 0    
C_SeedRandom() and C_GenerateRandom():
  seeding (C_SeedRandom) not supported
  seems to be OK
Digests:
  all 4 digest functions seem to work
  MD5: OK
  SHA-1: OK
  RIPEMD160: OK
Signatures (currently only for RSA)
  testing key 0 (Authentisierungsschluessel) 
error: PKCS11 function C_SignFinal failed: rv = CKR_GENERAL_ERROR (0x5)
Aborting.

~ » pkcs11-tool --test --login --slot 1      
C_SeedRandom() and C_GenerateRandom():
  seeding (C_SeedRandom) not supported
  seems to be OK
Digests:
  all 4 digest functions seem to work
  MD5: OK
  SHA-1: OK
  RIPEMD160: OK
Signatures (currently only for RSA)
  testing key 0 (Signaturschluessel) 
error: PKCS11 function C_SignFinal failed: rv = CKR_USER_NOT_LOGGED_IN (0x101)
Aborting.

As to my ultimate goal, if I try to sign a PDF using Acrobat reader, I get same error: 0x101 when trying to sign the PDF.

Another thing I just noticed is when I use the card in the Gemalto (and PIN is entered on the terminal prompt), I can see it asks for the context specific pin hwn asking for the pin second time:

Logging in to "D-TRUST Card ... (Signature-PIN)".
Please enter User PIN: 
C_SeedRandom() and C_GenerateRandom():
  seeding (C_SeedRandom) not supported
  seems to be OK
Digests:
  all 4 digest functions seem to work
  MD5: OK
  SHA-1: OK
  RIPEMD160: OK
Signatures (currently only for RSA)
  testing key 0 (Signaturschluessel) 
Logging in to "D-TRUST Card ... (Signature-PIN)".
Please enter context specific PIN: 
error: PKCS11 function C_SignFinal failed: rv = CKR_USER_NOT_LOGGED_IN (0x101)
Aborting.

PS: opensc version:

OpenSC 0.21.0 [gcc  4.2.1 Compatible Apple LLVM 9.1.0 (clang-902.0.39.2)]
Enabled features: locking zlib readline openssl pcsc(/System/Library/Frameworks/PCSC.framework/PCSC)

Steps to reproduce

see above

Logs

let me know if anything form the output and which OPENSC_DEBUG level is needed to understand, what is wrong

hamarituc commented 5 days ago

For 5.1/5.4, the PIN is flagged as user PIN instead of signature PIN in the minidriver, which causes the flag not to be set. You may try the following patch to be a little more relaxed:

diff --git a/src/minidriver/minidriver.c b/src/minidriver/minidriver.c
index 92dcceac3..8b27ac565 100644
--- a/src/minidriver/minidriver.c
+++ b/src/minidriver/minidriver.c
@@ -6014,7 +6014,7 @@ DWORD WINAPI CardAuthenticateEx(__in PCARD_DATA pCardData,
                 * conflicts with framework-pkcs15.c use of auth_method  SC_AC_CONTEXT_SPECIFIC
                 * for a different purpose. But needs to be reviewed 
                 */
-               if (PinId == MD_ROLE_USER_SIGN && vs->need_pin_always) {
+               if (vs->need_pin_always) {
                        logprintf(pCardData, 7, "Setting SC_AC_CONTEXT_SPECIFIC cbPinData: %lu old auth_method: %0x auth_id:%x \n",
                                        (unsigned long) cbPinData, (unsigned int) auth_info->auth_method, (unsigned char) auth_info->auth_id.value[0]);
                        auth_info->auth_method = SC_AC_CONTEXT_SPECIFIC;

This will basically always set auth_info->auth_method = SC_AC_CONTEXT_SPECIFIC; if at least one of the PINs does require user consent, which may have side effects (unlikely, I think). For more finegrained control, the the linked suggestion above needs to be implemented.

I tried this patch and it didn't solve the issues. This is consistent to my observations in https://github.com/OpenSC/OpenSC/issues/2244#issuecomment-2503562168. The logs of the run with the patch applied are attached here for completeness:

The only notable difference is:

-[cardmod] CardSetProperty
-[cardmod] CardSetProperty wszProperty=Parent Window, pbData=009FDB38, cbDataLen=4, dwFlags=0
-[cardmod] Saved parent window (00020374)
-[cardmod] MD_Function:CardSetProperty:6677 returning with: 0x00000000
-[cardmod] MD_Function:CardSetProperty:6611 called
-[cardmod] 
-P:8768 T:5256 pCardData:10859E40 
-[cardmod] CardSetProperty
-[cardmod] CardSetProperty wszProperty=PIN Context String, pbData=00000000, cbDataLen=2, dwFlags=0
-[cardmod] Saved PIN context string: (null)
-[cardmod] MD_Function:CardSetProperty:6683 returning with: 0x00000000
+[cardmod] CardReadFile
+[cardmod] pszDirectoryName = <NULL>, pszFileName = cardcf, dwFlags = 0, pcbData=009FD764, ppbData=009FD768
+[cardmod] check_reader_status for CardReadFile
+[cardmod] MD_Function:check_card_status:404 called
+[cardmod] MD_Function:check_card_status:414 returning with: 0x00000000
+[cardmod] sizeof(size_t):4 sizeof(ULONG_PTR):4 sizeof(__int3264):4 sizeof pCardData->hSCardCtx:4
+[cardmod] pCardData->hSCardCtx:0xCD020002 hScard:0xEA040000
+[cardmod] HANDLES CHANGED from  vs->hSCardCtx:0xCD020002 vs->hScard:0xEA030000
+[cardmod] ctx.c:1032:sc_ctx_use_reader: called
+[cardmod] reader-pcsc.c:2575:pcsc_use_reader: called
+[cardmod] Reusing the reader
+[cardmod] reader-pcsc.c:2629:pcsc_use_reader: returning with: 0 (Success)
+[cardmod] sc_ctx_use_reader returned 0
+[cardmod] sc.c:340:sc_detect_card_presence: called
+[cardmod] reader-pcsc.c:494:pcsc_detect_card_presence: called
+[cardmod] REINER SCT cyberJack RFID komfort (2011541641) 00 00 check
+[cardmod] reader-pcsc.c:403:refresh_attributes: returning with: 0 (Success)
+[cardmod] reader-pcsc.c:502:pcsc_detect_card_presence: returning with: 5
+[cardmod] sc.c:351:sc_detect_card_presence: returning with: 5
+[cardmod] check_reader_status r=5 flags 0x00000005
+[cardmod] MD_Function:check_card_reader_status:489 returning with: 0x00000000
+[cardmod] MD virtual file system: found '(null)' directory
+[cardmod] MD virtual file system: found 'cardcf' file
+[cardmod] returns 'cardcf' content:
+[cardmod] --- 137D25B0:6
+[cardmod]  0000  00000000 0000
+[cardmod] MD_Function:CardReadFile:4254 returning with: 0x00000000

It seems the application calls CardSetProperty twice in the first run and skip these calls in the second run and calls CardReadFile instead. I have no idea why this happens and I would like to declare it as an application specific behavior so we cannot do much here.

I will remove the patch from #3137 later.