Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C_SignFinal failed: rv = CKR_GENERAL_ERROR with pkcs11-tool --test --login --pin XXXX #2953

Open
knecht opened this issue Dec 5, 2023 · 30 comments

Comments

@knecht
Copy link

knecht commented Dec 5, 2023

Problem Description

pkcs11-tool --test --login --pin XXXX
results in

Using slot 0 with a present token (0x0)
C_SeedRandom() and C_GenerateRandom():
  seeding (C_SeedRandom) not supported
  seems to be OK
Digests:
  all 4 digest functions seem to work
  MD5: OK
  RIPEMD160: OK
  SHA-1: OK
  SHA256: OK
Ciphers: not implemented
Signatures (currently only for RSA)
  testing key 0 (Private key 1) 
error: PKCS11 function C_SignFinal failed: rv = CKR_GENERAL_ERROR (0x5)
Aborting.

OpenSC-0.23.0-562-g258bfc8a, rev: 258bfc8a, commit-time: 2023-12-01 01:19:06 +0100
Using reader with a card: Gemalto PC Twin Reader (A7D1F9E2) 00 00
Gemalto IDPrime MD 830

Outgoing APDU (11 bytes):
00 22 41 B6 06 80 01 02 84 01 41 ."A.......A
Incoming APDU (2 bytes):
90 00 ..
P:17858; T:0x140064411954048 22:30:09.598 [opensc-pkcs11] card-idprime.c:1004:idprime_set_security_env: returning with: 0 (Success)

P:17858; T:0x140064411954048 22:30:09.598 [opensc-pkcs11] card-idprime.c:1020:idprime_compute_signature: called
P:17858; T:0x140064411954048 22:30:09.566 [opensc-pkcs11] apdu.c:367:sc_single_transmit: CLA:0, INS:2A, P1:90, P2:A0, data(37) 0x7ffe06e803f0
Outgoing APDU (42 bytes):
00 2A 90 A0 25 90 23 30 21 30 09 06 05 2B 0E 03 .*..%.#0!0...+..
02 1A 05 00 04 14 29 B0 E7 87 82 71 64 5F FF B7 ......)....qd_..
EE C7 DB 4A 74 73 A1 C0 0B C1                   ...Jts....

Incoming APDU (2 bytes):
6A 88 j.

P:17858; T:0x140064411954048 22:30:09.584 [opensc-pkcs11] apdu.c:382:sc_single_transmit: returning with: 0 (Success)
P:17858; T:0x140064411954048 22:30:09.584 [opensc-pkcs11] apdu.c:539:sc_transmit: returning with: 0 (Success)
P:17858; T:0x140064411954048 22:30:09.584 [opensc-pkcs11] card.c:523:sc_unlock: called
P:17858; T:0x140064411954048 22:30:09.584 [opensc-pkcs11] card-idprime.c:1057:idprime_compute_signature: The initial APDU did not return the same data
P:17858; T:0x140064411954048 22:30:09.584 [opensc-pkcs11] card-idprime.c:1058:idprime_compute_signature: returning with: -1400 (Internal error)

@dengert
Copy link
Member

dengert commented Dec 6, 2023

Can you try using 0.24.0-rc2? There are some changes in this area c182852

@knecht
Copy link
Author

knecht commented Dec 6, 2023

Same result, the only diff between 258bfc8 (the version I reported this issue against) and 0.24.0-rc2 is 258bfc8 itself anyway, which seems to introduce support for IDPrime 940C.

@dengert
Copy link
Member

dengert commented Dec 6, 2023

There is not a lot of information in the debug output.
What OS?
Do you have a different reader?
The failure at card-idprime.c:1057:idprime_compute_signature: The initial APDU did not return the same data
looks strange.
The data being sent is trying to use OID 06 05 2B 0E 03 02 1a SHA-1. Does your card support SHA-1?

the Ciphers: not implemented also looks strange.

The output of pkcs11-tool -O and pkcs11-tool -M might help.

Did you build with OpenSSL? (what version)

This could be pkcs11-tool --test is trying to test SHA-1 and the card does not support it.

@knecht
Copy link
Author

knecht commented Dec 6, 2023

OS: Linux. Bult with openssl: 3.0.4 (computer 1,initial comment) and 3.1.4 (computer 2, this comment)
Results from same card, different computer, different reader, different distribution, same opensc version:

Using reader with a card: OMNIKEY CardMan (076B:3021) 3021 00 00
Gemalto IDPrime MD 830

pkcs11-tool --test --login --pin XXXX :

Using slot 0 with a present token (0x0)
C_SeedRandom() and C_GenerateRandom():
  seeding (C_SeedRandom) not supported
  seems to be OK
Digests:
  all 4 digest functions seem to work
  MD5: OK
  RIPEMD160: OK
  SHA-1: OK
  SHA256: OK
Ciphers: not implemented
Signatures (currently only for RSA)
  testing key 0 (Private key 1) 
error: PKCS11 function C_SignFinal failed: rv = CKR_GENERAL_ERROR (0x5)
Aborting.

pkcs11-tool -O

Using slot 0 with a present token (0x0)
Private Key Object; RSA 
  label:      Private key 1
  ID:         0001
  Usage:      decrypt, sign, signRecover
  Access:     sensitive, always sensitive, never extractable, local
Public Key Object; RSA 2048 bits
  label:      Public key 1
  ID:         0001
  Usage:      encrypt, verify, verifyRecover
  Access:     none
Certificate Object; type = X.509 cert
  label:      Certificate 1
  subject:    DN: <redacted>
  serial:     <redacted>
  ID:         0001
Profile object 2366500192
  profile_id:          CKP_PUBLIC_CERTIFICATES_TOKEN (4)

pkcs11-tool -M :

Using slot 0 with a present token (0x0)
Supported mechanisms:
  SHA-1, digest
  SHA224, digest
  SHA256, digest
  SHA384, digest
  SHA512, digest
  MD5, digest
  RIPEMD160, digest
  GOSTR3411, digest
  RSA-PKCS, keySize={1024,2048}, hw, decrypt, sign, verify
  SHA256-RSA-PKCS, keySize={1024,2048}, sign, verify
  SHA384-RSA-PKCS, keySize={1024,2048}, sign, verify
  SHA512-RSA-PKCS, keySize={1024,2048}, sign, verify
  RSA-PKCS-PSS, keySize={1024,2048}, hw, sign, verify
  SHA256-RSA-PKCS-PSS, keySize={1024,2048}, sign, verify
  SHA384-RSA-PKCS-PSS, keySize={1024,2048}, sign, verify
  SHA512-RSA-PKCS-PSS, keySize={1024,2048}, sign, verify
  RSA-PKCS-OAEP, keySize={1024,2048}, hw, decrypt

@knecht
Copy link
Author

knecht commented Dec 6, 2023

@dengert
Copy link
Member

dengert commented Dec 6, 2023

I do not have a way to test this, but you can try:

diff --git a/src/libopensc/card-idprime.c b/src/libopensc/card-idprime.c
index a3aedd98e..95e9e7c20 100644
--- a/src/libopensc/card-idprime.c
+++ b/src/libopensc/card-idprime.c
@@ -1055,7 +1055,7 @@ idprime_compute_signature(struct sc_card *card,
        /* This just returns the passed data (hash code) (for verification?) */
        if (apdu.resplen != datalen || memcmp(rbuf + pad, data, datalen - pad) != 0) {
                sc_log(card->ctx, "The initial APDU did not return the same data");
-               LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
+               LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
        }
        /* INS: 0x2A  PERFORM SECURITY OPERATION
         * P1:  0x9E  Resp: Digital Signature

I suspect the card does not support doing SHA-1 based on comment:
`/* SHA-1 mechanisms are not allowed in the card I have available */

If it works please submit a PR.

@knecht
Copy link
Author

knecht commented Dec 6, 2023

well, this changed the error message

Using slot 0 with a present token (0x0)
C_SeedRandom() and C_GenerateRandom():
  seeding (C_SeedRandom) not supported
  seems to be OK
Digests:
  all 4 digest functions seem to work
  MD5: OK
  RIPEMD160: OK
  SHA-1: OK
  SHA256: OK
Ciphers: not implemented
Signatures (currently only for RSA)
  testing key 0 (Private key 1) 
error: PKCS11 function C_SignFinal failed: rv = CKR_FUNCTION_NOT_SUPPORTED (0x54)
Aborting.

doesn't the " SHA-1: OK " line mean, sha1 works as expected?

@Jakuje
Copy link
Member

Jakuje commented Dec 6, 2023

This part is regarding digests and they are not implemented on the card. The IDPrime cards I was working with did not allow signatures with SHA-1:

/* SHA-1 mechanisms are not allowed in the card I have available */

I would propose to give it a try with SHA2. Unfortunately, the pkcs11-tool test still insist on trying SHA1 ... I think we should change this (or use sha-1 only after trying other more reasonable digests and not treat it as an error).

@knecht
Copy link
Author

knecht commented Dec 6, 2023

pkcs11-tool -s --pin XXXX -m SHA256-RSA-PKCS --input-file blob --output-file blob.sig
Using slot 0 with a present token (0x0)
Using signature algorithm SHA256-RSA-PKCS
error: PKCS11 function C_SignFinal failed: rv = CKR_FUNCTION_NOT_SUPPORTED (0x54)
Aborting.

same for each of the "sign" mechanisms listed by pkcs11-tool -M

@Jakuje
Copy link
Member

Jakuje commented Dec 6, 2023

Do you have some more information about the idprime card you have? I assume this will be a wrong object reference in the security environment (error is 6A 88, which is DATA NOT FOUND). The debug log does not show the card detection phase and driver intialization, which might show up some more useful information, but given how the key IDs are guessed now, I am not sure if we will be able to figure them our for your card without seeing what the official driver does.

@knecht
Copy link
Author

knecht commented Dec 7, 2023

It is an employee access card. I know that it can be used for windows logins. I do not have any more technical information.
Since I am still unable to find a complete protocol specification, it's a bit difficult for me to understand the APDU data. Thus, I am not entirely sure which parts are sensitive data and which not, that's why I am a bit hesitant to simply attach the complete log. I will try to assemble a more complete log soon. Do you have a link to card or APDU specifications you could share with me?
I was able to successfully use the certificate on the card for TLS authentication using:
https://www.globalsign.com/en/safenet-drivers/USB/10.8/GlobalSign-SAC-Ubuntu-2204.zip
(firefox, library=/usr/lib/pkcs11/libIDPrimePKCS11.so in pkcs11.txt)

How can I find out what's the difference? wireshark? or do you know an easier way?

@knecht
Copy link
Author

knecht commented Dec 7, 2023

when using the closed source safenet driver with opensc's pkcs11-tool, it looks like that

$ pkcs11-tool --module usr/lib/pkcs11/libIDPrimePKCS11.so  --test --login --pin XXXX
Using slot 0 with a present token (0x0)
C_SeedRandom() and C_GenerateRandom():
  seems to be OK
Digests:
  all 4 digest functions seem to work
  SHA-1: OK
  SHA256: OK
Ciphers: not implemented
Signatures (currently only for RSA)
  testing key 0 (<redacted uuid>) 
  ERR: C_SignUpdate failed: CKR_KEY_FUNCTION_NOT_PERMITTED (0x68)
  testing signature mechanisms:
    RSA-PKCS: OK
    SHA256-RSA-PKCS: OK
Verify (currently only for RSA)
  testing key 0 (<redacted uuid>)
    RSA-PKCS: OK
Decryption (currently only for RSA)
  testing key 0 (<redacted uuid>)
    RSA-PKCS: OK
    RSA-PKCS-OAEP: mgf not set, defaulting to MGF1-SHA256
OAEP parameters: hashAlg=SHA256, mgf=MGF1-SHA256, encoding parameter (Label) present, length 3
error: PKCS11 function C_Decrypt failed: rv = CKR_MECHANISM_PARAM_INVALID (0x71)
Aborting.

@Jakuje
Copy link
Member

Jakuje commented Dec 7, 2023

Yes, the safenet driver is the one that I meant by the "official one". I see that with this driver, it looks like the only SHA256-RSA-PKCS and RSA-PKCS.

If you would be getting the PSCS trace from the safenet driver, I would be interested in APDU with instruction 0x22 (set security environment -- second byte of the APDU):

sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0);

Then I would be interested in the initialization and what makes it different from the cards supporting also other digests.

The APDUs with PIN will always have the instruction 0x20 (again, second byte of APDU) so you might be certainly interested to exclude these:

ins = 0x20;

I am not aware of any public specification for the idprime cards. What is in opensc is implemented based on the observation of safenet driver does to various cards. But most of the APDU specification is described in the ISO 7816 standard, which is neither generally available, but the most important snippets are usually possible to find through google.

@knecht
Copy link
Author

knecht commented Dec 7, 2023

safenet 002241b606800142840131
opensc  002241b606800142840141

when I change

case SC_CARD_TYPE_IDPRIME_830:
new_object.key_reference = 0x41 + cert_id;

from 0x41 to 0x31, pkcs11-tool can succesfully sign using this card and opensc and firefox can use the certificate as client certificate.

@Jakuje
Copy link
Member

Jakuje commented Dec 18, 2023

I am sorry for a delay, but the reply got lost in dozens of other mails I was handling last weeks.

Thank you for having a look into this. Can you post a ATR of your card (opensc-tool --atr or from debug log)? I will get to see my card what key reference it is using and try to compare the ATRs if there is something we can differentiate from the. Ideally I would also like to see a whole debug log from the idprime_init to see what OS version is there:

static int idprime_init(sc_card_t *card)

Could it be that your card is IDPrime 3810, which is using the offset 0x31 and your is just mismatched for 830 by ATR?

case SC_CARD_TYPE_IDPRIME_3810:

@knecht
Copy link
Author

knecht commented Dec 23, 2023

$ opensc-tool --atr
Using reader with a card: Generic CCID Reader (A7D1F9E2) 00 00
3b:7f:96:00:00:80:31:80:65:b0:84:56:51:10:12:0f:fe:82:90:00

the SACTool from the safenet driver package identifies it as

Product name: IDPrime MD 830nc
Card type: IDPrime
Applet Version: IDPrime Java Applet 4.3.5.D
Mask version: G259

idprime_init.log

@Jakuje
Copy link
Member

Jakuje commented Dec 23, 2023

Thank you for the ATR, logs and information from the SACTool. Indeed, the ATR matches the 830 version exactly. I will try to go through the log to see if I will see something different from the 380 card I have, but I will have access to it only after a new year. Hopefully we will be able to figure out something from the SACTool output too.

@frankmorgner
Copy link
Member

What's the status of this topic, is there anything to do?

@Jakuje
Copy link
Member

Jakuje commented Jan 30, 2024

I am looking into this now. I did not have the cards at me.

When comparing the output with the card I have, I see different CPCL data (unsurprisingly), but same OS version which I use for detection of some stuff in the driver.

Containermap is redacted in the log but I am not sure if it can have something useful.

While looking through the index file, there are some so far unknown objects for me.

07: 7 entries follow, each 21 B long
02 02: DF
  00 06: object length
  63 61 72 64 63 66 00 00 00 00 00 00 00 00 00 00 01
  cardcf
02 01: DF
  00 10: object length
  63 61 72 64 69 64 00 00 00 00 00 00 00 00 00 00 03
  cardid
02 05: DF
  00 00: object length
  6D 73 69 74 67 66 00 00 00 00 00 00 00 00 00 00 01
  msitgf ???
02 03: DF
  00 08: object length
  63 61 72 64 61 70 70 73 00 00 00 00 00 00 00 00 01
  cardapps
02 04: DF
  05 0A: object length
  63 6D 61 70 66 69 6C 65 6D 73 63 70 00 00 00 00 01
  cmapfilemscp
02 06: DF
  00 0C: object length
  70 69 6E 68 00 00 00 00 6D 73 63 6C 6D 00 00 00 01
  pinh ... msclm
02 07: DF
  05 B4: object length
  6B 78 63 30 30 00 00 00 6D 73 63 70 00 00 00 00 01
  kxc00 ... mscp

I (and opensc now) understand only the last object (kxc00), which is the key object. My card has also the cardcf, cardid, but I do not think these files had anything useful. The cmapfile (container map) is already parsed, but I do not think it contains anything super-useful for now.

So from here we are left with the pinh file (this could contain some pin label or something, but I would need to see the content of the file. This could be collected by sending the APDU through opensc-tool:

$ opensc-tool -s "00 A4 08 00 02 02 06" -s "00 B0 00 00 56"

Can you try to run this command and post the output?

Other than that, my card with the same ATR reports all the other details very similar, including having a key in 02 07 DF, but the key reference is 0x41 for me.

If you are ok to run the patched version of OpenSC until we will be able to figure out where does this magic number come from, thats probably the best bet for now.

There still might be some APDUs that the official safenet driver sends to get information about key references, but more probably it will be just some magic number derived from some other bits where I did not find the connection yet.

@knecht
Copy link
Author

knecht commented Feb 1, 2024

Sending: 00 A4 08 00 02 02 06 
Received (SW1=0x90, SW2=0x00)
Sending: 00 B0 00 00 56 
Received (SW1=0x62, SW2=0x82)

@knecht
Copy link
Author

knecht commented Feb 1, 2024

This is what the safenet driver is doing. Perhaps the FILE_NOT_FOUND responses influence its key reference choice.

00 INS_CHECK_RESET_AND_APPLET_SELECTION 0000 15  
SW1_INSTRUCTION_CODE_NOT_SUPPORTED_OR_INVALID 00 
00 INS_SELECT_FILE 0400 0b a000000018800000000662
90 00 
00 INS_CHECK_RESET_AND_APPLET_SELECTION 0000 15  
<redacted>90 00
00 INS_SELECT_FILE 0000 02 0029
SW1_WRONG_PARAM SW2_FILE_NOT_FOUND 
00 INS_SELECT_FILE 0000 02 0201
SW1_USE_GET_DATA 1c 
00 INS_GET_RESP 0000 1c  
<redacted> 90 00
00 INS_SELECT_FILE 0000 02 0201
SW1_USE_GET_DATA 1c 
00 INS_GET_RESP 0000 1c  
<redacted> 90 00
00 INS_READ_BIN 0000 10  
<redacted> 90 00
00 INS_SELECT_FILE 0000 02 0202
SW1_USE_GET_DATA 1c 
00 INS_GET_RESP 0000 1c  
<redacted> 90 00
00 INS_READ_BIN 0000 06  
000403000b0090 00
00 INS_GET_DATA GET_APPLET_VERSION 00  
SW1_TOO_SHORT_MUST_REISSUE 0a 
00 INS_GET_DATA GET_APPLET_VERSION 0a  
df3007342e332e352e4490 00
00 INS_CHECK_RESET_AND_APPLET_SELECTION 0000 15  
<redacted>90 00
00 INS_SELECT_FILE 0000 02 0028
SW1_WRONG_PARAM SW2_FILE_NOT_FOUND 
00 INS_VRFY_0x21 0011 <1 byte length of pin> <pin>
90 00 
00 INS_MANAGE_SECURITY_ENVIRONMENT 41b6 06 800142840131
90 00 
00 INS_PERFORM_SECURITY_OPERATION 90a0 22 <redacted>
SW1_USE_GET_DATA 20 
00 INS_GET_RESP 0000 20  
<redacted> 90 00

btw, it seems to use instruction 0x21 instead of 0x20 for transmitting the pin

@Jakuje
Copy link
Member

Jakuje commented Feb 2, 2024

Received (SW1=0x62, SW2=0x82)

This is WARNING_BUF_END_BEFORE_LE. Can you try with longer LE 0 like this?

$ opensc-tool -s "00 A4 08 00 02 02 06" -s "00 B0 00 00 00"

btw, it seems to use instruction 0x21 instead of 0x20 for transmitting the pin

Interesting. I think I never saw a card to use the 0x21 for verify.

According to the iso 7816-4:

If INS = '21', the command data field shall convey a verification data object (e.g., tag '5F2E', see ISO/IEC 7816-11), normally not empty. The presence of an empty verification data object with an extended header list (tag '4D', see 8.5.1) expresses that the verification data come from a sensor on the card.

Is the data field of the APDU just the PIN (potentially padded) or some more complicated structure?

00 INS_GET_DATA GET_APPLET_VERSION 0a

Can you clarify what is the P1 value for this APDU? The iso specs do not mention any P1 value related to GET_APPLET_VERSION so I assume this would be some proprietary encoding.

@knecht
Copy link
Author

knecht commented Feb 2, 2024

Sending: 00 A4 08 00 02 02 06 
Received (SW1=0x90, SW2=0x00)
Sending: 00 B0 00 00 00 
Received (SW1=0x90, SW2=0x00):
04 80 00 00 8B 14 8F 82 6F 33 0E CC ........o3..

the bytes following 00 INS_VRFY_0x21 0011 are one byte indicating the length of the pin and then the pin itself.

GET_APPLET_VERSION in this output means ins == 0xca && p1 == 0xdf && p2 == 0x30.
I called it GET_APPLET_VERSION because SACTool shows the response to this command as "applet version"

Jakuje added a commit to Jakuje/OpenSC that referenced this issue Feb 2, 2024
@Jakuje
Copy link
Member

Jakuje commented Feb 2, 2024

Thanks! This sounds like working also on my card:

$ opensc-tool -s "00 A4 0000 02 0202" -s "00 CA DF 30 00"
Using reader with a card: Gemalto PC Twin Reader (84090C9A) 00 00
Sending: 00 A4 00 00 02 02 02 
Received (SW1=0x90, SW2=0x00)
Sending: 00 CA DF 30 00 
Received (SW1=0x90, SW2=0x00):
DF 30 07 34 2E 33 2E 35 2E 44 .0.4.3.5.D

And matches the applet version:

Applet Version: IDPrime Java Applet 4.3.5.D

I am getting completely same output, so that does not sound like a difference that we could use, but certainly helpful to get some more information about applets in there.

But it looks like it works also without selecting the particular file so I will add it to the driver too. So I am not sure if there would be something else I could do now.

If it might help, I can provide you with a debug logs or traces from our card (as there is really nothing private on the test cards) so you can compare it to your traces, if you are interested.

@knecht
Copy link
Author

knecht commented Feb 2, 2024

Yes, that would be great. If I had a dump of the apdu traffic between your card and the safenet driver while signing something, I could at least find out which part is relevant for the key reference selection.

@arrowd

This comment was marked as off-topic.

@Jakuje
Copy link
Member

Jakuje commented Feb 6, 2024

I noticed that if I do another C_Sign call after the first one failed with CKR_GENERAL_ERROR, the operation succeeds. I'll happily test the patch for this issue when it becomes available.

You have also IDPrime 380 card? Can you provide debug logs?

@arrowd
Copy link

arrowd commented Feb 6, 2024

No. It is Nitrokey 3C NFC. The bug is easily reproducing for me, so if you tell me how to enable debug logging, I will provide it.

@Jakuje
Copy link
Member

Jakuje commented Feb 6, 2024

No. It is Nitrokey 3C NFC. The bug is easily reproducing for me, so if you tell me how to enable debug logging, I will provide it.

So please, in a new issue. This is about IDPrime cards. The CKR_GENERAL_ERROR is general error that can happen in many different cases.

@xhanulik
Copy link
Contributor

xhanulik commented Feb 6, 2024

@knecht Here are the APDU traces from pkcs11-tool --test using the safenet driver.
idprime830_pkcs11.txt
idprime830_pkcs11_apdu.txt

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants