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

Gemalto (Safenet) IDBridge K30 (Fina QSCD) support #2335

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

maxrd2
Copy link
Contributor

@maxrd2 maxrd2 commented May 10, 2021

This is first of series of patches to support my Gemalto USB eToken.
I'm not sure of exact model as it's distributed by croatian finance agency under the name Fina QCSD.

On google I found image of Gemalto (Safenet) IDBridge K30 that looks exactly like my token.

I have it working correctly under linux with opensc and official closed source binary driver (libeToken.so.10.7.77, libIDPrimePKCS11.so.10.7.77) - installed from safenetauthenticationclient_10.7.77_amd64.deb

I've managed to get wireshark captures with official driver. I have zero/minimal knowledge/experience of OpenSC and tokens so any help recommendations would be helpful.

I'm patching card-idprime.c code, I don't think I need to create completely separate driver for this?

Checklist
  • Documentation is added or updated
  • New files have a LGPL 2.1 license statement
  • PKCS#11 module is tested
  • Windows minidriver is tested
  • macOS tokend is tested
# output of: opensc-tool -n
Using reader with a card: Gemalto USB Shell Token V2 (xxxxxxxx) 00 00
Gemalto IDPrime (generic)

# output of: lsusb -d 08e6:3438 -v
Bus 003 Device 031: ID 08e6:3438 Gemalto (was Gemplus) GemPC Key SmartCard Reader
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0 
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0         8
  idVendor           0x08e6 Gemalto (was Gemplus)
  idProduct          0x3438 GemPC Key SmartCard Reader
  bcdDevice            2.00
  iManufacturer           1 Gemalto
  iProduct                2 USB SmartCard Reader
  iSerial                 3 XhiddenX
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength       0x005d
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0x80
      (Bus Powered)
    MaxPower               50mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           3
      bInterfaceClass        11 Chip/SmartCard
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              0 
      ChipCard Interface Descriptor:
        bLength                54
        bDescriptorType        33
        bcdCCID              1.01  (Warning: Only accurate for version 1.0)
        nMaxSlotIndex           0
        bVoltageSupport         7  5.0V 3.0V 1.8V 
        dwProtocols             3  T=0 T=1
        dwDefaultClock       4800
        dwMaxiumumClock      4800
        bNumClockSupported      0
        dwDataRate          12903 bps
        dwMaxDataRate      825806 bps
        bNumDataRatesSupp.     50
        dwMaxIFSD             254
        dwSyncProtocols  00000000 
        dwMechanical     00000000 
        dwFeatures       00010230
          Auto clock change
          Auto baud rate change
          NAD value other than 0x00 accepted
          TPDU level exchange
        dwMaxCCIDMsgLen       271
        bClassGetResponse      00
        bClassEnvelope         00
        wlcdLayout           none
        bPINSupport             0 
        bMaxCCIDBusySlots       1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x01  EP 1 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x83  EP 3 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0008  1x 8 bytes
        bInterval              16
can't get device qualifier: Resource temporarily unavailable
can't get debug descriptor: Resource temporarily unavailable
Device Status:     0x0000
  (Bus Powered)

@maxrd2
Copy link
Contributor Author

maxrd2 commented May 10, 2021

There was a problem with idprime_process_index() trying to read index file of 1700 or so bytes (only 500 or so bytes are needed for all entries) - it was failing with SC_ERROR_INVALID_DATA.
6c13d93 - made it reduce the number of entries so it logs warning - that didnt list all keys on card tho
ac290de - removed funky stuff from previous commit and made it read whole index file (properly I hope)

I will try to correct the label/IDs next. They are given numbered names with open idprime, whereas closed one gives better names (like key/certificate DN)

Also Profile object 36xxxxx76 entry is not shown with closed driver is that a problem?

# before patch: pkcs11-tool --module /usr/lib/pkcs11/opensc-pkcs11.so -O
error: PKCS11 function C_GetSlotInfo failed: rv = CKR_DATA_INVALID (0x20)
Aborting.

# after patch: pkcs11-tool --module /usr/lib/pkcs11/opensc-pkcs11.so -O
Using slot 0 with a present token (0x0)
...snip...
Certificate Object; type = X.509 cert
  label:      Certificate 3
  subject:    DN: C=HR, O=Financijska agencija, CN=Fina RDC 2015
  ID:         0003
...snip...
Profile object 36xxxxx76
  profile_id:          '4'

# official output: $ pkcs11-tool --module /opt/fina-gemalto/lib/libeToken.so -O
Using slot 0 with a present token (0x0)
...snip...
Certificate Object; type = X.509 cert
  label:      RDC CA 2015
  subject:    DN: C=HR, O=Financijska agencija, CN=Fina RDC 2015
  ID:         3632xxxxxxxx3331
...snip...

Also have noticed that list-slots command gives different flags and serial - is that important?

### pkcs11-tool --module /usr/lib/pkcs11/opensc-pkcs11.so --list-slots 
Available slots:
Slot 0 (0x0): Gemalto USB Shell Token V2 (95FE422C) 00 00
  token label        : FINA
  token manufacturer : Gemalto
  token model        : PKCS#15 emulated
  token flags        : login required, token initialized, PIN initialized
  hardware version   : 0.0
  firmware version   : 0.0
  serial num         : 40c0xxxxxxxx2a77
  pin min/max        : 4/16

### pkcs11-tool --module /opt/fina-gemalto/lib/libeToken.so --list-slots 
Available slots:
Slot 0 (0x0): Gemalto USB Shell Token V2 (95FE422C) 00 00
  token label        : FINA
  token manufacturer : Gemalto
  token model        : ID Prime MD
  token flags        : login required, rng, token initialized, PIN initialized, other flags=0x200
  hardware version   : 0.0
  firmware version   : 0.0
  serial num         : BEA9xxxxxxxx2AA4
  pin min/max        : 4/16

@maxrd2 maxrd2 marked this pull request as draft May 10, 2021 09:44
@maxrd2 maxrd2 force-pushed the gemalto-qscd-support branch 3 times, most recently from bb713a9 to 45d9e71 Compare May 10, 2021 09:58
@lgtm-com
Copy link

lgtm-com bot commented May 11, 2021

This pull request introduces 1 alert when merging baa00f5 into 35a8a1d - view on LGTM.com

new alerts:

  • 1 for FIXME comment

@maxrd2
Copy link
Contributor Author

maxrd2 commented May 11, 2021

Did another commit to show correct labels and key_id.

Had to figure file format in hexeditor (not sure how successful I was) there are few constant amount of bytes to skip, and then random list of repeating tags that follow the same pattern and seems to always end with 49. In case it fails to find key ID (or label) it will fallback to to use the counter - as it was before.

Does anyone know if there is format description of pubk[sx]cNNp11 files somewhere? Or what exactly are they.

# official closed driver - libeToken.so
Certificate Object; type = X.509 cert
  label:      CN=Fina Root CA, O=Financijska agencija, C=HR
  subject:    DN: C=HR, O=Financijska agencija, CN=Fina Root CA
  ID:         3730313832353431
Certificate Object; type = X.509 cert
  label:      RDC CA 2015
  subject:    DN: C=HR, O=Financijska agencija, CN=Fina RDC 2015
  ID:         3632313634373331

# opensc-pkcs11.so
Certificate Object; type = X.509 cert
  label:      RDC CA 2015
  subject:    DN: C=HR, O=Financijska agencija, CN=Fina RDC 2015
  ID:         3632313634373331
Public Key Object; RSA 4096 bits
  label:      RDC CA 2015
  ID:         3632313634373331
  Usage:      verify
  Access:     none
Certificate Object; type = X.509 cert
  label:      CN=Fina Root CA, O=Financijska agencija, C=HR
  subject:    DN: C=HR, O=Financijska agencija, CN=Fina Root CA
  ID:         3730313832353431
Public Key Object; RSA 4096 bits
  label:      CN=Fina Root CA, O=Financijska agencija, C=HR
  ID:         3730313832353431
  Usage:      verify
  Access:     none

@maxrd2 maxrd2 force-pushed the gemalto-qscd-support branch 2 times, most recently from 25f2659 to 359a359 Compare May 11, 2021 01:05
@maxrd2 maxrd2 marked this pull request as ready for review May 11, 2021 01:11
@maxrd2
Copy link
Contributor Author

maxrd2 commented May 11, 2021

Last commit implemented get_challenge and fixed this error:

C_SeedRandom() and C_GenerateRandom():
  seeding (C_SeedRandom) not supported
  ERR: C_GenerateRandom failed: CKR_DATA_LEN_RANGE (0x21)

now test works fine (although official one implements C_SeedRandom - will add that too):

# pkcs11-tool --module /usr/lib/pkcs11/opensc-pkcs11.so --test
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
  SHA-1: OK
  RIPEMD160: OK
Signatures (currently only for RSA)
Signatures: no private key found in this slot
Verify (currently only for RSA)
  No private key found for testing
Decryption (currently only for RSA)
No errors

there are still differences with official driver:

#### pkcs11-tool --module /usr/lib/pkcs11/opensc-pkcs11.so --list-mechanisms 
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

#### pkcs11-tool --module /opt/fina-gemalto/lib/libeToken.so --list-mechanisms 
Using slot 0 with a present token (0x0)
Supported mechanisms:
  DES3-MAC, keySize={24,24}, sign, verify
  DES3-MAC-GENERAL, keySize={24,24}, sign, verify
  AES-MAC, keySize={16,32}, sign, verify
  AES-MAC-GENERAL, keySize={16,32}, sign, verify
  DES3-CBC, keySize={24,24}, encrypt, decrypt, wrap, unwrap
  DES3-CBC-PAD, keySize={24,24}, encrypt, decrypt, wrap, unwrap
  AES-CBC, keySize={16,32}, encrypt, decrypt, wrap, unwrap
  AES-CBC-PAD, keySize={16,32}, encrypt, decrypt, wrap, unwrap
  AES-CTR, keySize={16,32}, encrypt, decrypt, wrap, unwrap
  mechtype-0x1088, keySize={16,32}, encrypt, decrypt, wrap, unwrap
  RSA-PKCS-KEY-PAIR-GEN, keySize={2048,2048}, hw, generate_key_pair
  RSA-PKCS, keySize={2048,2048}, hw, encrypt, decrypt, sign, sign_recover, verify, verify_recover, wrap, unwrap
  RSA-PKCS-OAEP, keySize={2048,2048}, hw, encrypt, decrypt, wrap, unwrap
  RSA-PKCS-PSS, keySize={2048,2048}, hw, sign, verify
  SHA1-RSA-PKCS-PSS, keySize={2048,2048}, verify
  SHA256-RSA-PKCS-PSS, keySize={2048,2048}, hw, sign, verify
  SHA384-RSA-PKCS-PSS, keySize={2048,2048}, hw, sign, verify
  SHA512-RSA-PKCS-PSS, keySize={2048,2048}, hw, sign, verify
  SHA1-RSA-PKCS, keySize={2048,2048}, verify
  SHA256-RSA-PKCS, keySize={2048,2048}, hw, sign, verify
  SHA384-RSA-PKCS, keySize={2048,2048}, hw, sign, verify
  SHA512-RSA-PKCS, keySize={2048,2048}, hw, sign, verify
  ECDSA-KEY-PAIR-GEN, keySize={256,256}, hw, generate_key_pair, EC F_P, EC OID, EC uncompressed
  ECDSA, keySize={256,256}, hw, sign, verify, EC F_P, EC OID, EC uncompressed
  ECDSA-SHA1, keySize={256,256}, verify, EC F_P, EC OID, EC uncompressed
  ECDSA-SHA256, keySize={256,256}, hw, sign, verify, EC F_P, EC OID, EC uncompressed
  ECDSA-SHA384, keySize={256,256}, hw, sign, verify, EC F_P, EC OID, EC uncompressed
  mechtype-0x80000045, keySize={256,256}, hw, sign, verify, EC F_P, EC OID, EC uncompressed
  ECDSA-SHA512, keySize={256,256}, hw, sign, verify, EC F_P, EC OID, EC uncompressed
  ECDH1-DERIVE, keySize={256,256}, hw, derive, EC F_P, EC OID, EC uncompressed
  DES3-KEY-GEN, keySize={24,24}, generate
  AES-KEY-GEN, keySize={16,32}, generate
  PBE-SHA1-DES3-EDE-CBC, keySize={24,24}, generate
  GENERIC-SECRET-KEY-GEN, keySize={112,2048}, generate
  PBA-SHA1-WITH-SHA1-HMAC, keySize={160,160}, generate
  PKCS5-PBKD2, generate
  SHA-1-HMAC-GENERAL, keySize={112,2048}, verify
  SHA-1-HMAC, keySize={112,2048}, verify
  mechtype-0x252, keySize={112,2048}, sign, verify
  SHA256-HMAC, keySize={112,2048}, sign, verify
  mechtype-0x262, keySize={112,2048}, sign, verify
  SHA384-HMAC, keySize={112,2048}, sign, verify
  mechtype-0x272, keySize={112,2048}, sign, verify
  SHA512-HMAC, keySize={112,2048}, sign, verify
  SHA-1, digest
  SHA256, digest
  SHA384, digest
  SHA512, digest
  mechtype-0x80006001, keySize={24,24}, generate

@maxrd2 maxrd2 force-pushed the gemalto-qscd-support branch 2 times, most recently from 5467ef9 to 8607b8b Compare May 12, 2021 02:57
@Jakuje
Copy link
Member

Jakuje commented May 17, 2021

Thank you for the contributions. Looks like a good job for zero experince with smart cards/opensc and first pull request :)

I just checked with my IDPrime card and all looks good. But because of unrelated bug, the SHA*_RSA_PKCS signatures do not work with current master.

Also Profile object 36xxxxx76 entry is not shown with closed driver is that a problem?

This is part of PKCS #11 3.0 and the Profile object is provieded by the OpenSC, not the card so this is not a problem. The proprietary driver probably supports only PKCS #11 2.40 or something older.

Also have noticed that list-slots command gives different flags and serial - is that important?

The serial number of a card is collected from here with some comment. I think it was different also for me from the windows driver, but I did not find a better way to find the same value. If you will figure out how to get same value as the proprietary driver, it would be great.

The token flags do not look important.

Does anyone know if there is format description of pubk[sx]cNNp11 files somewhere? Or what exactly are they.

I used only my observations for parsing this as far as I remember. Did not find much useful documentation.

The CIFuzz already found a possible crash in your PR. Can you check its report:

READ of size 41 at 0x606000156475 thread T0
SCARINESS: 26 (multi-byte-read-heap-buffer-overflow)
    #0 0x523956 in __asan_memcpy /src/llvm-project/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp:22:3
    #1 0x9af5d4 in idprime_process_index /src/opensc/src/libopensc/card-idprime.c:411:4
    #2 0x9a61f6 in idprime_init /src/opensc/src/libopensc/card-idprime.c:482:6
    #3 0x567ee1 in sc_connect_card /src/opensc/src/libopensc/card.c:358:8
    #4 0x557467 in LLVMFuzzerTestOneInput /src/opensc/src/tests/fuzzing/fuzz_pkcs15_reader.c:209:5
    #5 0x45af73 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:599:15
    #6 0x45a47a in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool, bool*) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:505:3
    #7 0x45c7d4 in fuzzer::Fuzzer::ReadAndExecuteSeedCorpora(std::__Fuzzer::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:814:7
    #8 0x45c9e9 in fuzzer::Fuzzer::Loop(std::__Fuzzer::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:845:3
    #9 0x44c054 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:906:6
    #10 0x475b42 in main /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
    #11 0x7f157b2da83f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2083f)
    #12 0x421208 in _start (out/fuzz_pkcs15_reader+0x421208)

prkey_info->id.value[1] = (*entry)->fd & 0xff;
prkey_info->id.len = 2;
memcpy(prkey_info->id.value, (*entry)->key_id, 8);
prkey_info->id.len = 8;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My IDPrime does not have the key id property so it falls back to the counter, but causes 7 bytes zero padding, which does not look great. Can the fallback use the length of 2 again? Probably by storing the length of the key_id alongside it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be solved with 55f3c4d

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure the functions I have added for extracting the key info are good.

Could you toggle #if 0 here with your card and see if it logs correct fields?

They work in my case but I'm skipping some bytes here:

/* skip some bytes - buf[7] was seen with values 1 (skip 5 bytes) and 2 (skip 3 bytes) */

The if() in that line that decides how many bytes to skip and is likely wrong.
I had '1' there on CA certificates and '2' on personal certs.

If you don't have time for that would appreciate if you could dump the pubk[sx]cNNp11 files from the card and share them somehow (maybe just ones for CA keys so you don't share your personal info) and will try to improve parsing more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose you're getting correct key labels now?
Those seem to be at fixed position from pubk file start for me.
The key_id is immediately following certificate string tags (C/O/CN/L/...) - problem is those tags do not start at constant offset from file start :(

@maxrd2
Copy link
Contributor Author

maxrd2 commented May 17, 2021

Thank you for the contributions. Looks like a good job for zero experince with smart cards/opensc and first pull request :)

thanks... glad it does :)

I just checked with my IDPrime card and all looks good. But because of unrelated bug, the SHA*_RSA_PKCS signatures do not work with current master.

ooh.. i thought it was only with mine card.. was to address that next.
I can look into it if no one else is already looking into it.
EDIT: is there a bug report for this already?

Also have noticed that list-slots command gives different flags and serial - is that important?

The serial number of a card is collected from here with some comment. I think it was different also for me from the windows driver, but I did not find a better way to find the same value. If you will figure out how to get same value as the proprietary driver, it would be great.

I saw that, but my card's serial (at least what official driver is reporting) is completely different.
Have also dumped all the files on that card and searched for "official" serial number and it's nowhere to be found.

Does that function extract correct S/N in your case?

The token flags do not look important.

ok... I've added rng flag (CKF_RNG / SC_CARD_CAP_RNG) with commit d31a948 as support was implemented with 8607b8b.
Am not sure whether all ID prime cards support it.

My card also reports CKF_DUAL_CRYPTO_OPERATIONS (0x200) but this doesn't seem to be in use/supported by openSC.

Speaking of support I did a little ATR parser to figure what's in there and have noticed a comment here that I believe is wrong:

ATR says that EF.DIR and EF.ATR/INFO acc.svc. by the READ RECORD(s) command (record structure)

Here's what historical bytes in ATR header mean if I did it right:

+       // 3b 7f 96 00 00    80 31 80 65 b0 85 03 00 ef 12 0f fe 82 90 00
+       uint8_t *atr = card->atr;
+       // 80 31 80 65 b0 85 03 00 ef 12 0f fe 82 90 00
+       uint8_t *his = card->atr + 5;
+       // 80  A status indicator may be present in a COMPACT-TLV data object (one, two or three bytes, see 12.1.1.11)
+
+       // *** Any interindustry data element defined hereafter (see 12.1.1.3 to 12.1.1.10) may be present in EF.ATR/INFO
+       //     (see 12.2.2). If present in EF.ATR/INFO, it shall appear in a DO, i.e. a tag field set to '4X', a length field set to
+       //     '0Y' and a value field of Y bytes.
+
+       // 31  Card service data
+       // 80   '- table 116 - & 0x80 != 0x00    x Application selection by full DF name
+       //                   - & 0x40 != 0x00      Application selection by partial DF name
+       //                   - & 0x20 != 0x00      DOs available in EF.DIR (see 12.2.1)
+       //                   - & 0x10 != 0x00      DOs available in EF.ATR/INFO (see 12.2.2)
+       //                   - & 0x0E == 0x08      EF.DIR and EF.ATR/INFO acc.svc. by the READ BINARY command (transparent structure)
+       //                   - & 0x0E == 0x00    x EF.DIR and EF.ATR/INFO acc.svc. by the READ RECORD(s) command (record structure)
+       //                   - & 0x0E == 0x04      EF.DIR and EF.ATR/INFO acc.svc. by the GET DATA command (BER-TLV structure)
+       //                   - & 0x01 == 0x00    x Card with MF
+       //                   - & 0x01 == 0x01      Card without MF
+
+       // 65  Pre-issuing data - this interindustry data element is not defined in ISO/IEC 7816 [6].
+       //                 The card manufacturer defines a length, a structure and a coding for a card manufacturer, an integrated circuit
+       //                 name, an integrated circuit manufacturer, a ROM mask version, an operating system version, etc. This
+       //           --->  interindustry data element may contain an integrated circuit manufacturer identifier (see ISO/IEC 7816-6).
+       // b0
+       // 85
+       // 03
+       // 00
+       // ef
+
+       // 12  Country code (see ISO 3166-1 [3]) and optional national data
+       // 0f   '- should be 0x0ffe -- check with ISO 3166-1 [3]
+       // fe
+
+       // 82  Status indicator - value '0000' indicates that the status is not reported.
+       // 90  SW1 - interpreted according to 5.6, Table 5 :: 9000 - No further qualification
+       // 00  SW2 - interpreted according to 5.6, Table 6

Which takes me to "Pre-issuing data" byte 0x65 with value 0xb0850300ef.
This is supposed to hold card/IC/ROM model/version? Any idea if those can be used reliably to detect various devices and what they support?

The CIFuzz already found a possible crash in your PR. Can you check its report:

Think I've fixed that with c43c83a - have added logging of filenames on card it might help with supporting some new devices.
Does CIFuzz check need manual start?

@Jakuje
Copy link
Member

Jakuje commented May 18, 2021

The SHA2 variants with RSA should be fixed with #2342 and #2341 (already in master).

@Jakuje
Copy link
Member

Jakuje commented May 18, 2021

Does that function extract correct S/N in your case?

no. I think I searched everywhere without success too. I assume it will be some checksum of some data, made in the proprietary driver, but its a lot of trial-and-errors or de-compiling ...

My card also reports CKF_DUAL_CRYPTO_OPERATIONS (0x200) but this doesn't seem to be in use/supported by openSC.

Right. I think we do not support this in OpenSC PKCS#11 module

Speaking of support I did a little ATR parser to figure what's in there and have noticed a comment here that I believe is wrong:

Yeah. Your historical bytes are bit different from mine:

80 31 80 65 B0 85 03 00 EF 12 0F FE 82 90 00
80 31 80 65 B0 84 41 3D F6 12 0F FE 82 90 00

I copied the comment from the ATR parser, but clearly with the mask applied, it does not have to apply to all configurations so feel free to remove it.

https://smartcard-atr.apdu.fr/parse?ATR=3b%3A7f%3A96%3A00%3A00%3A80%3A31%3A80%3A65%3Ab0%3A84%3A41%3A3d%3Af6%3A12%3A0f%3Afe%3A82%3A90%3A00

Which takes me to "Pre-issuing data" byte 0x65 with value 0xb0850300ef.
This is supposed to hold card/IC/ROM model/version? Any idea if those can be used reliably to detect various devices and what they support?

Probably not. I think this is mostly for the issuing party to mark some data for the card. I think it will be same for all different cards issues by one party/in one batch/by one TPS and so on. But it can be used as part of the hash to generate the unique SN

More unique information can be collected from the card ID (as it is now used for SN), from the CPLC you can get also some unique serial numbers and dates:

https://stackoverflow.com/questions/39238382/how-do-i-get-cplc-data-from-a-smart-card

Does CIFuzz check need manual start?

After some idiots started to use the github CI for bitcoin mining, for new contributors we need to approve the code before the CI is started.

@maxrd2
Copy link
Contributor Author

maxrd2 commented May 18, 2021

So I went a bit further with debugging signature during test. It was like this:

#### pkcs11-tool --module /usr/lib/pkcs11/opensc-pkcs11.so --test --pin xxx
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
  SHA-1: OK
  RIPEMD160: OK
Signatures (currently only for RSA)
  testing key 0 (MLADEN MILINKOVIĆ) 
error: PKCS11 function C_SignFinal failed: rv = CKR_FUNCTION_FAILED (0x6)
Aborting.

In commit 5f6ab8d have changed reference for SC_CARD_TYPE_IDPRIME_V3 from 0xF7 + key_id to 0xF5 + key_id
I did that because proprietary drived was sending apdu with F5 while opensc sent F7.
So now it goes like this:

#### pkcs11-tool --module /usr/lib/pkcs11/opensc-pkcs11.so --test --pin xxx
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
  SHA-1: OK
  RIPEMD160: OK
Signatures (currently only for RSA)
  testing key 0 (MLADEN MILINKOVIĆ) 
  all 4 signature functions seem to work
  testing signature mechanisms:
    RSA-PKCS: OK
    SHA256-RSA-PKCS: ERR: verification failed
  testing key 1 (CN=Fina Root CA, O=Financijska agencija, C=HR) with 1 mechanism
error: PKCS11 function C_Sign failed: rv = CKR_FUNCTION_NOT_SUPPORTED (0x54)
Aborting.
    RSA-PKCS: 

Now... key 1 is root CA... i don't think they placed root CA private key on my card... am i wrong?
Anyhow it probably needs different pin so it's failing or something like that.. what do you think?

I have noticed that 3rd byte in index entry contains some nice value which I have used to calculate key_reference: 0xF0 + start[2]
Before it was 0xF7 + key_id - for me 0xF5 + key_id works -- key_id is taken from filename as you did it before.

Support for V3 key references 0xF7 was added with commit edaf921 - relative PR #2205. (that PR also fixed C_Login on my card btw)
Then was touched in commit 072c64a when V4 was added (maybe it could use same pattern).

Have pushed commit a0d6c5d which dumps whole entry and extra details when parsing card index file.
That way we could maybe figure what's going on with other V3 cards if 0xF0 + start[2] is not working in that case.
Maybe there is some simpler/cleaner way to do it?

Have started looking to do READ RECORD in order to get EF.DIR and EF.ATR/INFO - think that might provide some more info on key_reference or am I just wasting time?

thanks

@Jakuje
Copy link
Member

Jakuje commented May 18, 2021

Now... key 1 is root CA... i don't think they placed root CA private key on my card... am i wrong?

They usually don't do that :) It is probably only the certificate (and maybe public key) on the card, which can allow the applications to verify your user certificate on the card (or at least copy the cert from the card to local store). Some vendors do that and these might require some different handling in the driver (not adding private key to the pkcs15 structs). My IDPrime has only the certs with keys so I did not try to handle this case. Is there any difference in the index file between the certs with keys and without?

Then was touched in commit 072c64a when V4 was added (maybe it could use same pattern).

What OS version does your card have? It should be visible in the debug log with OPENSC_DEBUG=9.

Before it was 0xF7 + key_id - for me 0xF5 + key_id works -- key_id is taken from filename as you did it before.

It might be that the key_id here is not just the counter of know objects but also unknown or anything else. This was also mostly guesswork and approximation from my card and debug logs provided by couple of people here (finding already four different versions that work and 1 that does not at all).

Have started looking to do READ RECORD in order to get EF.DIR and EF.ATR/INFO - think that might provide some more info on key_reference or am I just wasting time?

No idea here.

@maxrd2
Copy link
Contributor Author

maxrd2 commented May 18, 2021

Now... key 1 is root CA... i don't think they placed root CA private key on my card... am i wrong?

They usually don't do that :) It is probably only the certificate (and maybe public key) on the card, which can allow the applications to verify your user certificate on the card (or at least copy the cert from the card to local store). Some vendors do that and these might require some different handling in the driver (not adding private key to the pkcs15 structs). My IDPrime has only the certs with keys so I did not try to handle this case. Is there any difference in the index file between the certs with keys and without?

ok.. will try to figure a way to differentiate those.. it would be really helpful to get index file and maybe some pubkey files from other token models.

Then was touched in commit 072c64a when V4 was added (maybe it could use same pattern).

What OS version does your card have? It should be visible in the debug log with OPENSC_DEBUG=9.

0x03 - card->type = SC_CARD_TYPE_IDPRIME_V3
think this is CPLC (or do you prefer something else?):

P:492896; T:0x139909762131776 19:46:18.456 [opensc-pkcs11] reader-pcsc.c:324:pcsc_transmit: 
Outgoing APDU (5 bytes):
00 CA 9F 7F 2D ....-
P:492896; T:0x139909762131776 19:46:18.456 [opensc-pkcs11] reader-pcsc.c:242:pcsc_internal_transmit: called
P:492896; T:0x139909762131776 19:46:18.465 [opensc-pkcs11] reader-pcsc.c:333:pcsc_transmit: 
Incoming APDU (47 bytes):
9F 7F 2A 40 90 71 64 12 91 21 72 03 00 91 15 B4 ..*@.qd..!r.....
06 37 0D 28 52 12 92 91 15 50 03 91 15 50 04 91 .7.(R....P...P..
15 00 00 00 14 00 00 00 00 00 00 00 00 90 00    ...............

Before it was 0xF7 + key_id - for me 0xF5 + key_id works -- key_id is taken from filename as you did it before.

It might be that the key_id here is not just the counter of know objects but also unknown or anything else. This was also mostly guesswork and approximation from my card and debug logs provided by couple of people here (finding already four different versions that work and 1 that does not at all).

yeah.. mine says it's V3 but has different key_reference offset I wonder if there are V3 cards that would have third offset.

In my case 4 keys are named in index file: ksc01, kxc00, kxc10, kxc11 - key_id was taken from last ASCII number before mine patch.
I would be pleasantly surprised if my patch works on original V3 card this was tested on aswell.

Will keep diging and try to figure more stuff... maybe I'll find some nice disassembler and try that way :-/

@Jakuje
Copy link
Member

Jakuje commented May 19, 2021

I have OS version 1:

P:2058118; T:0x140233656369600 10:47:53.604 [opensc-pkcs11] card-idprime.c:502:idprime_init: Detected IDPrime applet version 1

My index parsing (on your branch) looks like this:

0B 02 01 00 10 63 61 72 64 69 64 00 00 00 00 00 .....cardid.....
00 00 00 00 00 03 02 02 00 0E 63 61 72 64 63 66 ..........cardcf
00 00 00 00 00 00 00 00 00 00 01 02 03 00 18 63 ...............c
61 72 64 61 70 70 73 00 00 00 00 00 00 00 00 01 ardapps.........
02 04 05 0A 63 6D 61 70 66 69 6C 65 6D 73 63 70 ....cmapfilemscp
00 00 00 00 01 02 05 00 22 74 69 6E 66 6F 00 00 ........"tinfo..
00 70 31 31 00 00 00 00 00 01 02 06 05 12 6B 78 .p11..........kx
63 30 31 00 00 00 6D 73 63 70 00 00 00 00 01 02 c01...mscp......
07 05 45 6B 78 63 30 30 00 00 00 6D 73 63 70 00 ..Ekxc00...mscp.
00 00 00 01 02 08 05 11 6B 78 63 30 33 00 00 00 ........kxc03...
6D 73 63 70 00 00 00 00 01 02 09 05 51 6B 78 63 mscp........Qkxc
30 32 00 00 00 6D 73 63 70 00 00 00 00 01 02 0A 02...mscp.......
05 19 6B 78 63 30 34 00 00 00 6D 73 63 70 00 00 ..kxc04...mscp..
00 00 01 02 0B 05 6B 6B 78 63 30 35 00 00 00 6D ......kkxc05...m
73 63 70 00 00 00 00 01 00 00 00 00 00 00 00 00 scp.............
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
90 00                                           ..
P:2058118; T:0x140233656369600 10:47:53.697 [opensc-pkcs11] apdu.c:382:sc_single_transmit: returning with: 0 (Success)
P:2058118; T:0x140233656369600 10:47:53.697 [opensc-pkcs11] apdu.c:537:sc_transmit: returning with: 0 (Success)
P:2058118; T:0x140233656369600 10:47:53.697 [opensc-pkcs11] card.c:523:sc_unlock: called
P:2058118; T:0x140233656369600 10:47:53.697 [opensc-pkcs11] reader-pcsc.c:737:pcsc_unlock: called
P:2058118; T:0x140233656369600 10:47:53.697 [opensc-pkcs11] iso7816.c:164:iso7816_read_binary: returning with: 256
P:2058118; T:0x140233656369600 10:47:53.697 [opensc-pkcs11] card-idprime.c:408:idprime_process_index: df=0201, len=16
P:2058118; T:0x140233656369600 10:47:53.697 [opensc-pkcs11] card-idprime.c:469:idprime_process_index: Skipping object with type=10|0, name=cardid, data=02010010636172646964000000000000 0000000003
P:2058118; T:0x140233656369600 10:47:53.697 [opensc-pkcs11] card-idprime.c:408:idprime_process_index: df=0202, len=14
P:2058118; T:0x140233656369600 10:47:53.697 [opensc-pkcs11] card-idprime.c:469:idprime_process_index: Skipping object with type=0|e, name=cardcf, data=0202000E636172646366000000000000 0000000001
P:2058118; T:0x140233656369600 10:47:53.698 [opensc-pkcs11] card-idprime.c:408:idprime_process_index: df=0203, len=24
P:2058118; T:0x140233656369600 10:47:53.698 [opensc-pkcs11] card-idprime.c:469:idprime_process_index: Skipping object with type=10|8, name=cardapps, data=02030018636172646170707300000000 0000000001
P:2058118; T:0x140233656369600 10:47:53.698 [opensc-pkcs11] card-idprime.c:408:idprime_process_index: df=0204, len=1290
P:2058118; T:0x140233656369600 10:47:53.698 [opensc-pkcs11] card-idprime.c:469:idprime_process_index: Skipping object with type=0|a, name=cmapfilemscp, data=0204050A636D617066696C656D736370 0000000001
P:2058118; T:0x140233656369600 10:47:53.698 [opensc-pkcs11] card-idprime.c:408:idprime_process_index: df=0205, len=34
P:2058118; T:0x140233656369600 10:47:53.698 [opensc-pkcs11] card-idprime.c:465:idprime_process_index: Found p11/tinfo object with type=20|2, name=tinfo, data=0205002274696E666F00000070313100 0000000001
P:2058118; T:0x140233656369600 10:47:53.698 [opensc-pkcs11] card-idprime.c:408:idprime_process_index: df=0206, len=1298
P:2058118; T:0x140233656369600 10:47:53.698 [opensc-pkcs11] card-idprime.c:456:idprime_process_index: Found certificate with fd=1, key_ref=50(32), type=10|2, name=kxc01, data=020605126B786330310000006D736370 0000000001
	label=��
P:2058118; T:0x140233656369600 10:47:53.698 [opensc-pkcs11] card-idprime.c:408:idprime_process_index: df=0207, len=1349
P:2058118; T:0x140233656369600 10:47:53.698 [opensc-pkcs11] card-idprime.c:456:idprime_process_index: Found certificate with fd=2, key_ref=49(31), type=40|5, name=kxc00, data=020705456B786330300000006D736370 0000000001
	label=��
P:2058118; T:0x140233656369600 10:47:53.698 [opensc-pkcs11] card-idprime.c:408:idprime_process_index: df=0208, len=1297
P:2058118; T:0x140233656369600 10:47:53.699 [opensc-pkcs11] card-idprime.c:456:idprime_process_index: Found certificate with fd=3, key_ref=52(34), type=10|1, name=kxc03, data=020805116B786330330000006D736370 0000000001
	label=��
P:2058118; T:0x140233656369600 10:47:53.699 [opensc-pkcs11] card-idprime.c:408:idprime_process_index: df=0209, len=1361
P:2058118; T:0x140233656369600 10:47:53.699 [opensc-pkcs11] card-idprime.c:456:idprime_process_index: Found certificate with fd=4, key_ref=51(33), type=50|1, name=kxc02, data=020905516B786330320000006D736370 0000000001
	label=��
P:2058118; T:0x140233656369600 10:47:53.699 [opensc-pkcs11] card-idprime.c:408:idprime_process_index: df=020A, len=1305
P:2058118; T:0x140233656369600 10:47:53.699 [opensc-pkcs11] card-idprime.c:456:idprime_process_index: Found certificate with fd=5, key_ref=53(35), type=10|9, name=kxc04, data=020A05196B786330340000006D736370 0000000001
	label=��
P:2058118; T:0x140233656369600 10:47:53.699 [opensc-pkcs11] card-idprime.c:408:idprime_process_index: df=020B, len=1387
P:2058118; T:0x140233656369600 10:47:53.699 [opensc-pkcs11] card-idprime.c:456:idprime_process_index: Found certificate with fd=6, key_ref=54(36), type=60|b, name=kxc05, data=020B056B6B786330350000006D736370 0000000001
	label=��
P:2058118; T:0x140233656369600 10:47:53.699 [opensc-pkcs11] card-idprime.c:476:idprime_process_index: returning with: 0 (Success)
P:2058118; T:0x140233656369600 10:47:53.699 [opensc-pkcs11] card-idprime.c:583:idprime_init: returning with: 0 (Success)

@kirichkov originally reported the issue #2202 based on which I added the offsets. You can try to get in touch with him if you will be able to figure out differences between your cards.

@kirichkov
Copy link
Contributor

kirichkov commented May 19, 2021

How can I help? I have access to both v3 and v4 idprimes. They both function the same save for the offsets.

P.S. I have two pair of keys on my card and the second slot is the one that currently has the pair with valid certificate. The first slot has a pair with an expired certificate. Maybe that's what's causing the mismatch? Is it possible that keys are enumerated rather than slots this would explain the difference of 2 (F5 being the first key, F6 the second?).

@maxrd2
Copy link
Contributor Author

maxrd2 commented May 19, 2021

I have OS version 1:
My index parsing (on your branch) looks like this:

@Jakuje Your start[2] == 5 on all files.. so that's completely different from my index

How can I help? I have access to both v3 and v4 idprimes. They both function the same save for the offsets.

I'm wondering if code change I did to calculate key_reference works correctly on your V3, so it would be great if you could try that.
Instead of using 0xF7 + key_id have changed it to 0xF0 + start[2]

P.S. I have two pair of keys on my card and the second slot is the one that currently has the pair with valid certificate. The first slot has a pair with an expired certificate. Maybe that's what's causing the mismatch? Is it possible that keys are enumerated rather than slots this would explain the difference of 2 (F5 being the first key, F6 the second?).

Are keys from both slots listed in your index file? Would be great if you could also paste the debug output of OPENSC_DEBUG=2 pkcs11-tool --list-slots - lines containing idprime_process_index should be enough.

EDIT: oh... you need to compile my branch for that output

@kirichkov
Copy link
Contributor

kirichkov commented May 19, 2021

Is it possible for you to upload a patch, because I want to apply it on top of #2342 which isn't merged just yet. Alternatively you can create a second branch rebased on top of #2342 and I can compile that second branch.

I think I can handle safely transplanting #2342 on top of your branch, it's just a few lines.

Also, some info from the minidriver:
from what I can see the difference between v3 and v4 is the Applet version. My v3 card has applet version 4.0.2.K while v4 has 4.4.2.A.

@Jakuje
Copy link
Member

Jakuje commented May 19, 2021

Also, some info from the minidriver:
from what I can see the difference between v3 and v4 is the Applet version. My v3 card has applet version 4.0.2.K while v4 has 4.4.2.A.

How did you get the applet version? I was able to find only the OS version in the CPLC.

@kirichkov
Copy link
Contributor

Unfortunately your branch, together with #2342 is not working - Firefox gives me SEC_ERROR_TOKEN_NOT_LOGGED_IN

doing pkcs11-tool --login --test also gives me an error CKR_USER_NOT_LOGGED_IN

Here's the list-slots - https://gist.github.com/kirichkov/9b804c3462c05307087f0f4889c1b80c.

@kirichkov
Copy link
Contributor

How did you get the applet version? I was able to find only the OS version in the CPLC.

Gemalto provides a software on their website - Windows only, and there you can get that information, so they must have some way of extracting this data from the card. The Linux software they ship - SafeNet Authentication Client Tools - also shows the Applet version - @maxrd2 also mentions it.

I did a APDU capture and it must be somewhere in this log.

@maxrd2
Copy link
Contributor Author

maxrd2 commented May 19, 2021

Unfortunately your branch, together with #2342 is not working - Firefox gives me SEC_ERROR_TOKEN_NOT_LOGGED_IN

doing pkcs11-tool --login --test also gives me an error CKR_USER_NOT_LOGGED_IN

Here's the list-slots - https://gist.github.com/kirichkov/9b804c3462c05307087f0f4889c1b80c.

Thank you.. login error is probably due to wrong key_references... they are calculated as F5/F6 instead of F7/F8.
And key label/id extraction isn't working for you either... will have to keep digging.

@maxrd2
Copy link
Contributor Author

maxrd2 commented May 19, 2021

I have noticed that proprietary driver before selecting the IDPrime app sends the adpu with INS:A6 - not sure what that is.

here is mine:

**** STANDARD STUFF - does A6 <- error - select IDPrime App - does A6 <- OK ****
// send CLA:0 INS:A6 P1:0 P2:0 Lc:- CD:- Le:15 - [unknown command] some kind of select???
00019019 [139781925238336] APDU: 00 A6 00 00 15 
// recv SW1:6D SW2:00 - aborted - checking error - Instruction code not supported or invalid
00005355 [139781925238336] SW: 6D 00 

// send CLA:0 INS:A4 P1:04 P2:04 Lc:0B CD:A0 00 00 00 18 80 00 00 00 06 62 Le:- - [select] application: IDPrimeApp
00000188 [139781925238336] APDU: 00 A4 04 00 0B A0 00 00 00 18 80 00 00 00 06 62 
// recv SW1:90 SW2:00 - completed - normal processing
00025439 [139781925238336] SW: 90 00 

// send CLA:0 INS:A6 P1:0 P2:0 Lc:- CD:- Le:15 - [unknown command] some kind of select???
00000207 [139781925238336] APDU: 00 A6 00 00 15 
// recv SW1:90 SW2:00 - completed - normal processing w/ 21 bytes ,,,,,, IDPrimeApp identifier is in the middle of response
00008440 [139781925238336] SW: 73 CC 42 A2 6E 30 5C 51 A0 00 00 00 18 80 00 00 00 06 62 40 51 90 00 

here is one from kirichkov capture:

**** STANDARD STUFF - does A6 <- error - select IDPrime App - does A6 <- OK ****
// send CLA:0 INS:A6 P1:0 P2:0 Lc:- CD:- Le:15 - [unknown command] some kind of select???
43580412 [140402338293504] APDU: 00 A6 00 00 15 
// recv SW1:6D SW2:00 - aborted - checking error - Instruction code not supported or invalid
00013572 [140402338293504] SW: 6D 00 

// send CLA:0 INS:A4 P1:04 P2:04 Lc:0B CD:A0 00 00 00 18 80 00 00 00 06 62 Le:- - [select] application: IDPrimeApp
00000234 [140402338293504] APDU: 00 A4 04 00 0B A0 00 00 00 18 80 00 00 00 06 62 
// recv SW1:90 SW2:00 - completed - normal processing
00026205 [140402338293504] SW: 90 00 

// send CLA:0 INS:A6 P1:0 P2:0 Lc:- CD:- Le:15 - [unknown command] some kind of select???
00000184 [140402338293504] APDU: 00 A6 00 00 15 
// recv SW1:90 SW2:00 - completed - normal processing w/ 21 bytes ,,,,,, IDPrimeApp identifier is in the middle of response
00008992 [140402338293504] SW: DA 45 E4 ED 95 63 B7 8C A0 00 00 00 18 80 00 00 00 06 62 40 51 90 00 

his successful response to A6 contains different bytes before IDPrimeApp - wonder if that is something important

IDPrime App ID                    A0 00 00 00 18 80 00 00 00 06 62
Mine: SW: 73 CC 42 A2 6E 30 5C 51 A0 00 00 00 18 80 00 00 00 06 62 40 51 90 00 
His:  SW: DA 45 E4 ED 95 63 B7 8C A0 00 00 00 18 80 00 00 00 06 62 40 51 90 00 

@dengert
Copy link
Member

dengert commented May 19, 2021

APDU: 00 A4 04 00 0B A0 00 00 00 18 80 00 00 00 06 62
is a SELECT FILE with an AID. This selects the applet. It look like in the second trace above, it is required.
i.e. the initial active applet may be different so the APDU: 00 A6 00 00 15 fails.

Note that OpenSC has many drivers, and during the card match phase, some drivers send a SELECT FLE with AID.

A well behave card will return file not found, and not reset its internal state. We have seen drivers that did not handle
SELECT FILE with AID, and would either return 90 00 even if it did not handle the applet, or could reset the active applet.

@dengert
Copy link
Member

dengert commented May 19, 2021

P.S. Also note if you have more then one application running (or starting a second application) may also
send APDUs to the card and cause the card to change selected applets.

@kirichkov
Copy link
Contributor

P.S. Also note if you have more then one application running (or starting a second application) may also
send APDUs to the card and cause the card to change selected applets.

In my dump I was running only the proprietary software which retrieves the applet version.

@maxrd2
Copy link
Contributor Author

maxrd2 commented May 19, 2021

APDU: 00 A4 04 00 0B A0 00 00 00 18 80 00 00 00 06 62
is a SELECT FILE with an AID. This selects the applet. It look like in the second trace above, it is required.
i.e. the initial active applet may be different so the APDU: 00 A6 00 00 15 fails.

Yes... I understand that - it's already used in card-idprime.c.
I'm not sure what following is though. it requires app [A0 00 00 00 18 80 00 00 00 06 62] to be selected. INS:A6 isn't documented in ISO/IEC 7816-4 (I have 3rd edition from 2013-04-15). INS:A4 is SELECT; A5 is SELECT DATA. what is A6?

// send CLA:0 INS:A6 P1:0 P2:0 Lc:- CD:- Le:15 - [unknown command] some kind of select???
00000207 [139781925238336] APDU: 00 A6 00 00 15 
// recv SW1:90 SW2:00 - completed - normal processing w/ 21 bytes ,,,,,, IDPrimeApp identifier is in the middle of response
00008440 [139781925238336] SW: 73 CC 42 A2 6E 30 5C 51 A0 00 00 00 18 80 00 00 00 06 62 40 51 90 00 

@dengert
Copy link
Member

dengert commented May 19, 2021

I don't see 'A6' as a command either. My copy is older then yours. But reading #2335 (comment) 'A6' fails, then SELECT FILE AID is sent, then 'A6' works. So it looks like the applet knows how to support it.
"In the interindustry class, any valid INS code not defined in ISO/IEC 7816 [6] is RFU." there is a 7816-4 version from 2020.

Many cards handle the SELECT FILE AID in the Card OS to switch select the applet and send all other commands to the active applet. Looks like the applet with AID A0 00 00 00 18 80 00 00 00 06 62 knows how to handle A6.

@Jakuje
Copy link
Member

Jakuje commented Aug 24, 2021

Was there any progress on this PR? I would be happy to merge the general improvements for idprime, but not sure about the key references rearrangements, as they seem to work for one card, but not for others.

@maxrd2
Copy link
Contributor Author

maxrd2 commented Aug 24, 2021

Was there any progress on this PR? I would be happy to merge the general improvements for idprime, but not sure about the key references rearrangements, as they seem to work for one card, but not for others.

I didn't manage to correctly find key references yet (was busy with other things)

I think 59bf32b and 32f3851 are safe for merging. Still have to do more work on rest.

Would you like me to make separate PR for those two?

EDIT: in meantime I've also had to renew keys.. I wonder what ids will those end up having

@Jakuje
Copy link
Member

Jakuje commented Aug 24, 2021

Thank you for the update. It would be probably best to take these two into separate PR, if you still plan to have a look into the rest of the stuff separately.

@dengert
Copy link
Member

dengert commented Aug 24, 2021

The "index" as shown in #2335 (comment) is the used for Microsoft minidriver. The vendor may have done this so they do not need to supply a minidriver for Windows.

So another approach is to treat this card as a GID card. OpenSC has a card-gids.c which can run on any system.

try this to see if has the applet:
opensc-tool --card-driver default -s"00A40400 09 A00000039742544659 00"
This tries to select the GIDS applet on the card.
line 119 in gids.c has: struct sc_aid gids_aid = { { 0xA0,0x00,0x00,0x03,0x97,0x42,0x54,0x46,0x59 }, 9 };

Try running some tests by forcing the driver. This can be done in the opensc.conf file by giving ATR and driver, or with environment variable "OPENSC_DRIVER=gids"

Try something like: OPENSC_DRIVER=gids pkcs11-tool -O
Edited to corrected above to "pkcs11-tool"

If this works, and meets your needs, this may be a better way to use the new card which is an easy change.

@Jakuje
Copy link
Member

Jakuje commented Aug 24, 2021

This does not work for me with my Gemalto IDPrime card:

$ ./src/tools/opensc-tool --card-driver default -s"00A40400 09 A00000039742544659 00"
Using reader with a card: OMNIKEY AG CardMan 3121 00 00
Sending: 00 A4 04 00 09 A0 00 00 03 97 42 54 46 59 00 
Received (SW1=0x6A, SW2=0x82)
$ OPENSC_DRIVER=gids ./src/tools/pkcs11-tool -L --module=src/pkcs11/.libs/opensc-pkcs11.so
Available slots:
Slot 0 (0x0): OMNIKEY AG CardMan 3121 00 00
  (token not recognized)

@dengert
Copy link
Member

dengert commented Aug 24, 2021

OK, so your card does not have a GIDS applet. But does it have the "index" that look like it is for the minidriver?

@maxrd2 can you try the opensc-tool --card-driver default -s"00A40400 09 A00000039742544659 00"

In any case knowing the "index" is a Microsoft object, could help in understanding what is going on.

@maxrd2
Copy link
Contributor Author

maxrd2 commented Aug 24, 2021

I get this:

$ opensc-tool --card-driver default -s"00A40400 09 A00000039742544659 00"
Using reader with a card: Gemalto USB Shell Token V2 (95FE422C) 00 00
Sending: 00 A4 04 00 09 A0 00 00 03 97 42 54 46 59 00 
Received (SW1=0x6A, SW2=0x82)
$ OPENSC_DRIVER=gids pkcs11-tool -L --module=/home/max/projects/opensc-git/src/pkcs11/.libs/opensc-pkcs11.so
Available slots:
Slot 0 (0x0): Gemalto USB Shell Token V2 (95FE422C) 00 00
  (token not recognized)

I've "downloaded" all files from the card, and there mscp/cmapfile that contains 2 GUIDS one for each key I believe and whole structure seems to follow the microsoft minidriver standards.

I've been looking into this and reading the docs, but didn't get to doing any tests yet.

@dengert
Copy link
Member

dengert commented Aug 24, 2021

OK, thanks for testing if it has a Microsoft GIDS applet.

@frankmorgner
Copy link
Member

What's the status of this PR? Initially it looks like a success story, but the later comments seem to indicate some problems with other versions of Gemalto's applet...

@maxrd2
Copy link
Contributor Author

maxrd2 commented Feb 24, 2023

What's the status of this PR? Initially it looks like a success story, but the later comments seem to indicate some problems with other versions of Gemalto's applet...

The commits 59bf32b and 32f3851 seems good as they fix reading index on my device and don't break other devices. Rest of the commits fix my device, but break other two - haven't figured a way yet to reliably read the key information on all devices.

Having access only to my device makes this especially hard :(

Should I rebase and cherry-pick two good commits into separate PR?

@Jakuje
Copy link
Member

Jakuje commented Mar 3, 2023

We have some work in progress for supporting more IDPrime smart cards in #2666 -- can you have a look if these changes make any difference for your cards?

We also have now couple of cards we can try your changes on. It looks like the content of the IDPrime cards is very dependent on the way how the card/token were enrolled/provisioned but the #2666 already moved quite a bit from the current version.

@bostjanpisler
Copy link

@maxrd2 Slovenia issues the same certificate USB (IDBridge K30), and we're trying to read it to sign a file in p7m, would this PR work for that? Thanks

@maxrd2
Copy link
Contributor Author

maxrd2 commented Apr 21, 2023

@maxrd2 Slovenia issues the same certificate USB (IDBridge K30), and we're trying to read it to sign a file in p7m, would this PR work for that? Thanks

@bostjanpisler I'm really not sure. Last time I've tried i was able to use all keys that were on my card.
I'm not sure if changes I did have fixed only my USB dongle, or all IDBridge K30 - since it broke some dongles that others have tested.

@Jakuje Will test and let you know ASAP - I haven't used the card and played with it for >1yr, so have to start from scratch

@frankmorgner
Copy link
Member

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

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

Successfully merging this pull request may close these issues.

None yet

6 participants