Skip to content

Conversation

@dengert
Copy link
Member

@dengert dengert commented Mar 13, 2022

Fix for arekinath/PivApplet#64

Minidriver fixes for ECC keys.

Cards with ECC keys need the KSP.

A minidriver is considered to support both CSP and KSP if registry has both:
"Crypto Provider"="Microsoft Base Smart Card Crypto Provider" and
"Smart Card Key Storage Provider"="Microsoft Smart Card Key Storage Provider"

Rather then change "Crypto Provider" a new registry key was added:
"InstalledBy"="OpenSC" which is used during uninstall to remove OpenSC registry.
Users and vendors are not expected to use this key so their entries are not deleted by OpenSC.

MD_MAX_KEY_CONTAINERS changed from 13 to 32 to support known cards that have more the 12 keys.

"CardGetProperty" "CP_CARD_KEYSIZES" passes key_type in dwFlags

SC_ALGORITHM_EXT_EC_NAMEDCURVE in not in the flags, but in ext_flags
so remove from the test. If any test is needed it should be to match
the curve name supported by Windows.

On branch minidriver-ECC
Changes to be committed:
modified: minidriver.c

Tested on Windows 10 using Idemia PIV card with 8 ECC keys.

Implementation of this PR will affect existing installations, as the Microsoft cert store saves "Provider = OpenSC CSP" This may require uses to cleanup the cert store so "Provider = Microsoft Base Smart Card Crypto Provider" for RSA. Some entries in cert store have "Provider = Microsoft Smart Card Key Storage Provider" for ECC keys if found on a card.

In other words we should never have tampered with the "Crypto Provider"="Microsoft Base Smart Card Crypto Provider" in the registry.

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

@dengert
Copy link
Member Author

dengert commented Mar 15, 2022

@vletoux Any idea when certutil -scinfo does not work with EC keys with OpenSC minidriver but venodor's version does?

I have a IDEMIA test card with all ECDSA keys. certutil -scinfo using their minidriver starts with this:

The Microsoft Smart Card Resource Manager is running.
Current reader/card status:
Readers: 1
  0: SCM Microsystems Inc. SCR35xx v2.0 USB SC Reader 0
--- Reader: SCM Microsystems Inc. SCR35xx v2.0 USB SC Reader 0
--- Status: SCARD_STATE_PRESENT | SCARD_STATE_UNPOWERED
--- Status: The card is available for use.
---   Card: IDEMIA ID-One PIV/CIV on V8 Device
---    ATR:
	3b d6 96 00 81 b1 fe 45  1f 87 80 31 c1 52 41 12   ;......E...1.RA.
	22                                                 "


=======================================================
Analyzing card in reader: SCM Microsystems Inc. SCR35xx v2.0 USB SC Reader 0
Microsoft Base Smart Card Crypto Provider: Missing stored keyset

--------------===========================--------------
================ Certificate 0 ================
--- Reader: SCM Microsystems Inc. SCR35xx v2.0 USB SC Reader 0
---   Card: IDEMIA ID-One PIV/CIV on V8 Device
Provider = Microsoft Smart Card Key Storage Provider
Key Container = PIV Authentication (fb5136538d)

Serial Number: b817e906
Issuer: CN=ICAM Test Card PIV P-384 Signing CA, OU=ICAM Test Cards, O=U.S. Government, C=US
 NotBefore: 10/17/2019 3:40 PM
 NotAfter: 10/16/2025 3:40 PM
Subject: CN=ID-One PIV TEST CARD 3 L, OU=Identity & Security N.A., O=IDEMIA, C=US
Non-root Certificate
Cert Hash(sha1): 6629fcec5fda7aad7d8a7b55bf9c72a9c53ac5e6

Performing  public key matching test...
Public key matching test succeeded
  Key Container = PIV Authentication (fb5136538d)
  Provider = Microsoft Smart Card Key Storage Provider
  ProviderType = 0
  Flags = 1
    0x1 (1)
  KeySpec = 0 -- XCN_AT_NONE
Private key verifies
Microsoft Smart Card Key Storage Provider: KeySpec=0
AES256+RSAES_OAEP(ECC:CNG) test skipped

Using the same card and clearing out the cert store of any references to the certificates and using certutil and the OpenSC minidriver (just changing the registry 800001=to point at OpenSC minidriver) it shows:

The Microsoft Smart Card Resource Manager is running.
Current reader/card status:
Readers: 1
  0: SCM Microsystems Inc. SCR35xx v2.0 USB SC Reader 0
--- Reader: SCM Microsystems Inc. SCR35xx v2.0 USB SC Reader 0
--- Status: SCARD_STATE_PRESENT | SCARD_STATE_UNPOWERED
--- Status: The card is available for use.
---   Card: IDEMIA ID-One PIV/CIV on V8 Device
---    ATR:
	3b d6 96 00 81 b1 fe 45  1f 87 80 31 c1 52 41 12   ;......E...1.RA.
	22                                                 "


=======================================================
Analyzing card in reader: SCM Microsystems Inc. SCR35xx v2.0 USB SC Reader 0

--------------===========================--------------
================ Certificate 0 ================
--- Reader: SCM Microsystems Inc. SCR35xx v2.0 USB SC Reader 0
---   Card: IDEMIA ID-One PIV/CIV on V8 Device
Provider = Microsoft Base Smart Card Crypto Provider
Key Container = (null) [Default Container]

Cannot open the AT_SIGNATURE key for reader: SCM Microsystems Inc. SCR35xx v2.0 USB SC Reader 0
Cannot open the AT_KEYEXCHANGE key for reader: SCM Microsystems Inc. SCR35xx v2.0 USB SC Reader 0

--------------===========================--------------
================ Certificate 0 ================
--- Reader: SCM Microsystems Inc. SCR35xx v2.0 USB SC Reader 0
---   Card: IDEMIA ID-One PIV/CIV on V8 Device
Provider = Microsoft Smart Card Key Storage Provider
Key Container = (null) [Default Container]

Cannot open the  key for reader: SCM Microsystems Inc. SCR35xx v2.0 USB SC Reader 0

--------------===========================--------------

Done.
CertUtil: -SCInfo command completed successfully.

They spot that the the base CSP can not handle the card:

Microsoft Base Smart Card Crypto Provider: Missing stored keyset

OpenSC tries to returns this:

Key Container = (null) [Default Container]

Cannot open the AT_SIGNATURE key for reader: SCM Microsystems Inc. SCR35xx v2.0 USB SC Reader 0
Cannot open the AT_KEYEXCHANGE key for reader: SCM Microsystems Inc. SCR35xx v2.0 USB SC Reader 0

Then they have:

Provider = Microsoft Smart Card Key Storage Provider
Key Container = PIV Authentication (fb5136538d)

where OpenSC has:

Provider = Microsoft Smart Card Key Storage Provider
Key Container = (null) [Default Container]

Cannot open the  key for reader: SCM Microsystems Inc. SCR35xx v2.0 USB SC Reader 0

There is something wrong OpenSC minidriver when using ECDSA.
Default container is null, and confused with CSP vs KSP for EC keys.

md.log trace is available.

@vletoux
Copy link
Contributor

vletoux commented Mar 15, 2022

my first advice would be to test the minidriver with cmck.exe (can provide it to you)

@vletoux
Copy link
Contributor

vletoux commented Mar 15, 2022

@vletoux
Copy link
Contributor

vletoux commented Mar 15, 2022

I think that the empty container name can have an impact.
Indeed, you have special strings to query a container, including \.\reader\containername
If container name is empty, it may impact this logic.
Else it could be an incorrect property returned (typically the key length)

Seeing the md.log with the latest property call may help

@dengert
Copy link
Member Author

dengert commented Mar 15, 2022

Yes please provide cmck.exe. I will have a look at apimonitor.
@vletoux
Here is log from minidriver when card is first inserted followed by then when certutil -scinfo is run.
Note that the certificates are loaded into the cert store.

Using change msi file from this PR which don't appear to make any difference.

openssl-i3.md.log.txt

@dengert
Copy link
Member Author

dengert commented Mar 17, 2022

This experimental fix for arekinath/PivApplet#64 has some minor changes but it looks like the main problem is in how OpenSC minidriver is installed.

0b683472b07 "win32 setup: add basic minidriver card registration and unregistration via a custom action" replaces in the normal:

[HKEY_LOCAL_MACHINE\SOFTWARE\\Microsoft\Cryptography\Calais\SmartCards\<some name>]
"Crypto Provider"="Microsoft Base Smart Card Crypto Provider"

with

"Crypto Provider"="OpenSC CSP"

When a card has EC keys, the combination of: "Crypto Provider"="Microsoft Base Smart Card Crypto Provider" and "Smart Card Key Storage Provider"="Microsoft Smart Card Key Storage Provider" says the minidriver can do both. Without this only the CSP provider is used.

A temp solution, to use cards with EC keys is to use change registry entries:
[HKEY_LOCAL_MACHINE\SOFTWARE\\Microsoft\Cryptography\Calais\SmartCards\<some name>] and
[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Cryptography\Calais\SmartCards\<some name>] to use "Crypto Provider"="Microsoft Base Smart Card Crypto Provider".

These test were done on a Windows 10 PRO 64 bit system using the VS 2015 release versions built from this PR. Using am Idemia PIV test card with 8 EC keys and certs.

Since the use of the "Crypto Provider"="OpenSC CSP" has been in the code for 7 years now, there must not be much use of EC keys with the minidriver.

A long term fix would be to add some other" key" = "value" like "installedByOpenSC" = "VERSION".

`certutil -v -scinfo" now works.

The Microsoft Smart Card Resource Manager is running.
Current reader/card status:
Readers: 1
  0: SCM Microsystems Inc. SCR35xx v2.0 USB SC Reader 0
--- Reader: SCM Microsystems Inc. SCR35xx v2.0 USB SC Reader 0
--- Status: SCARD_STATE_PRESENT | SCARD_STATE_UNPOWERED
--- Status: The card is available for use.
---   Card: OPENSC_PIV(2)
---    ATR:
	3b d6 96 00 81 b1 fe 45  1f 87 80 31 c1 52 41 12   ;......E...1.RA.
	22                                                 "


=======================================================
Analyzing card in reader: SCM Microsystems Inc. SCR35xx v2.0 USB SC Reader 0
Microsoft Base Smart Card Crypto Provider: Missing stored keyset

--------------===========================--------------
================ Certificate 0 ================
--- Reader: SCM Microsystems Inc. SCR35xx v2.0 USB SC Reader 0
---   Card: OPENSC_PIV(2)
Provider = Microsoft Smart Card Key Storage Provider
Key Container = 60470002580003013312345678901470

X509 Certificate:
...

@dengert dengert force-pushed the minidriver-ECC branch 4 times, most recently from e162712 to 29dcda4 Compare March 18, 2022 02:12
@dengert dengert changed the title minidriver fixes for key sizes for ECC Minidriver fixes for ECC keys Mar 18, 2022
@dengert
Copy link
Member Author

dengert commented Mar 18, 2022

@vletoux @metsma
Can you look at this PR, especially in the customactions.cpp and the comment in OpenSC.wxs.in:

<!-- install an alias for the Base smart card CSP. Using a different CSP in minidriver installation deactivate the plug and play feature
                  but not all other components like the pin change screen available after ctrl+alt+del.
                  It is because the "80000001" entry is still returning the minidriver dll.-->

@dengert
Copy link
Member Author

dengert commented Mar 23, 2022

Implementation of this PR will affect existing installations because the "Crypto Provider" is saved in the cert store as "Provider".
The certutil -Silent -store -user My can be used list the certificates in the windows store for a user. (-Silent cause the test of the private key to be skipped and the "Encryption test FAILED"
message.) #2517 which is affected by the use of "Crypto Provider=OpenSC CSP" in the registry.

If we want to use ECC keys will will eventually need make the changes.

For example from some tests to use a self signed cert on a card:

================ Certificate 118 ================
Serial Number: 1fef699450b7d8af4b3b0ac3364e0d32
Issuer: CN=Doug Engert-selfSignedTest-20200206-SHA256
 NotBefore: 2/7/2020 4:40 PM
 NotAfter: 2/7/2021 5:00 PM
Subject: CN=Doug Engert-selfSignedTest-20200206-SHA256
Signature matches Public Key
Root Certificate: Subject matches Issuer
Cert Hash(sha1): 57d1c02abfcd55767df5980d72c0c1290552e258
  Key Container = b3f65093-7384-1651-00ee-908132546647
  Provider = OpenSC CSP
Encryption test FAILED

IIRC I was trying to use an ECC key, but went back to test with RSA.

@annu0412
Copy link

Sorry for the late reply
When i execute powershell, i got...

Analyzing card in reader: OMNIKEY CardMan 5x21 0
Microsoft Base Smart Card Crypto Provider: Missing stored keyset

--------------===========================--------------
================ Certificate 0 ================
--- Reader: OMNIKEY CardMan 5x21 0
--- Card: Identity Device (NIST SP 800-73 [PIV])
Provider = Microsoft Smart Card Key Storage Provider
Key Container = 00000000000000010000000000000000

X509 Certificate:

Here you can see key container has strange value?
My windows login still not working on the other hand when i put same certificate on yubikey it worked.

@annu0412
Copy link

is there any way to enable on windows?

@dengert
Copy link
Member Author

dengert commented Apr 15, 2022

What powershell command did you use?

"Microsoft Base Smart Card Crypto Provider" only supports RSA See: https://docs.microsoft.com/en-us/windows-hardware/drivers/smartcard/smart-card-minidrivers "Microsoft Smart Card Key Storage Provider" is the KSP.

So it looks like it called both as expected.

The container ID should be unique on the machine so a cached certificate can identify a card so user can be told to insert the card. But it looks like container ID was derived from a card unique ID ie.e. the ID private, public and certs share. It could still work.

What type of card are you using?
If this was a Yubkey, did you create run the yubico-piv-tool with action "set-chuid"?

NIST does not define a serial number for a PIV card. The OpenSC PIV driver and minidriver uses either the FASC-N or GUID contained in the CHUID to derive a serial number for the card, which can then be used by minidriver to create the Container ID for each cert/key pair. (IIRC the default serial number is all zeros, and the one character ID is then inserted in the middle, thus "00000000000000010000000000000000"

The yubikey minidriver may use the Yubikey token serial number, and thus work.

If you use the same certificate on different cards windows can get confused as it can only cache one of them with the containerID it saw when first cached. . You will need to delete the cert(s) from the "my" cert store. Easy way is control panel->internet options->content->certificates->personal then find and remove the old certificates that also contain the container ID.

As I don't have access to AD, to test login, any additional testing would be helpful. See
https://github.com/OpenSC/OpenSC/wiki/Using-OpenSC on how to get OpenSC debug logs on Windows.

@dengert
Copy link
Member Author

dengert commented Jul 11, 2022

While reviewing this PR and #2575 the minidriver is called at:
https://github.com/OpenSC/OpenSC/pull/2523/files#diff-0472a0d91e9f422e4d90a09074f95d9edf67b14a2df432fcb3aacca29b9a3b39L4424

which calls md_query_key_sizes with the dwKeySpec

dwKeySpec is a combination of: ECC key, a specific usage (ECDSA or ECDHE), a specific keysize and a specific named curve.
as used starting here:

https://github.com/OpenSC/OpenSC/pull/2523/files#diff-0472a0d91e9f422e4d90a09074f95d9edf67b14a2df432fcb3aacca29b9a3b39L2786

But the OpenSC looks at vs->p15card->card->algorithms for just the keysize.
https://github.com/OpenSC/OpenSC/pull/2523/files#diff-0472a0d91e9f422e4d90a09074f95d9edf67b14a2df432fcb3aacca29b9a3b39L2782

struct sc_algorithm_info* algo_info; has parameters which for ECC is the namedCurve OID, which could be tested . But the OID for different supported curves are not filled in by most card drivers when they call sc_card_add_ec_alg

To see these, run in libopensc grep -A 1 _sc_card_add_ec_alg *

Microsoft has added additional curves and has defined the OIDs in CNG docs from April 2021 for example:
https://docs.microsoft.com/en-us/windows/win32/seccng/cng-portal
https://docs.microsoft.com/en-us/previous-versions/dn468735(v=vs.85)
https://docs.microsoft.com/en-us/windows/win32/seccng/cng-named-elliptic-curves

In the last reference above they do list multiple curves with the same size.

When and if these will be passed to a minidriver as dwKeySpec is not clear. Given that a certificate in the SPKI has the OID for the curve, they may never need to call the minidrive to get the size, assuming if the cert came from the card, it would support the curve.

@vletoux
Copy link
Contributor

vletoux commented Jul 11, 2022

dwKeySize is supposed to be zero for ECC keys
image

This is here only to deal with the RSA versability regarding key sizes (1024, 2048 etc)

@dengert
Copy link
Member Author

dengert commented Jul 12, 2022

I am not referring to CardCreateContainer but to CardQueryKeySizes:
CardQueryKeySizes

which says:
"Key size information is returned in the following structure. For ECC, minimum, default, and maximum are a specific value. Increment is 1."

the OpenSC minidriver implemantaion in master: https://github.com/OpenSC/OpenSC/blob/master/src/minidriver/minidriver.c#L4430-L4464
which calls https://github.com/OpenSC/OpenSC/blob/master/src/minidriver/minidriver.c#L2728-L2835
tries to return a specific values.

But this only works for some cards. Many do not fill in the vs->p15card->card->algorithms and card drivers do not fill in the OID when calling sc_card_add_ec_alg

@vletoux
Copy link
Contributor

vletoux commented Jul 12, 2022

my mistake, you are correct

dengert added a commit to dengert/OpenSC that referenced this pull request Aug 23, 2022
…lity

Add comment:
<!-- PR OpenSC#2523 no longer uses "Provider = OpenSC CSP", but existing certificates in cert store
    may have "Provider = OpenSC CSP" so we continue to add it for backward compatability.
    Run: "certutil -Silent -store -user My" and look for "Provider = OpenSC CSP". -->

 Date:      Tue Aug 23 14:38:24 2022 -0500

 On branch minidriver-ECC
 Changes to be committed:
	modified:   win32/OpenSC.wxs.in
@Jakuje
Copy link
Member

Jakuje commented Aug 30, 2022

I dont have a way to test this, but the only comment I would have here would be the typo marked by the codespell. The remaining codespell reports are fixed already in #2598.

"CardGetProperty" "CP_CARD_KEYSIZES" passes key_type in dwFlags

SC_ALGORITHM_EXT_EC_NAMEDCURVE in not in the flags, but in ext_flags
so remove from the test. If any test is needed it should be to match
the curve name to suported by Windows.

 Date:      Sun Mar 13 13:56:43 2022 -0500

 On branch minidriver-ECC
 Changes to be committed:
	modified:   minidriver.c
Newer cards can have more then 12 key on card. Minidriver
uses a fixed MD_MAX_KEY_CONTAINERS 12 change to 32

 Changes to be committed:
	modified:   minidriver.c
 Changes to be committed:
	modified:   minidriver.c
Cards with ECC keys need in registry both:
"Crypto Provider"="Microsoft Base Smart Card Crypto Provider"
"Smart Card Key Storage Provider"="Microsoft Smart Card Key Storage Provider"

So instead of replacing the crypto Provider,
add "InstalledBy"="OpenSC"
Then when uninstalling drivers, only uninstall drivers which have "OpenSC"

 On branch minidriver-ECC
 Changes to be committed:
	modified:   customactions.cpp
…lity

Add comment:
<!-- PR OpenSC#2523 no longer uses "Provider = OpenSC CSP", but existing certificates in cert store
    may have "Provider = OpenSC CSP" so we continue to add it for backward compatibility.
    Run: "certutil -Silent -store -user My" and look for "Provider = OpenSC CSP". -->

 Date:      Tue Aug 31 13:13:00 2022 -0500

 On branch minidriver-ECC
 Changes to be committed:
	modified:   win32/OpenSC.wxs.in
@dengert
Copy link
Member Author

dengert commented Aug 31, 2022

I don't have a way to test this, but the only comment I would have here would be the typo marked by the codespell. The remaining codespell reports are fixed already in #2598.

Cleaned up the compatibility spelling not covered by #2598
Dropped one commit and its revert commit and did force push.

Waiting for checks to run to test msi files on windows.

@Jakuje
Copy link
Member

Jakuje commented Sep 21, 2022

@dengert any update on this? Did you manage to test it? Ready to merge?

@dengert
Copy link
Member Author

dengert commented Sep 21, 2022

Yes I was able to test this with PIV card with EC keys. But on Windows OpenSC does not add PIV to the registry, because most, PIV card vendors provide plug-and-play windows drivers. I added the OpenSC registry entries manually for testing.

The main fix was to not mess with the "Provider = Microsoft Base Smart Card Crypto Provider". There may need to be additional fixes of OpenSC card drivers.

Windows CNG also talks about other curves in addition to the P256 and P384 changes may be needed in card drivers in the future.

@dengert
Copy link
Member Author

dengert commented Sep 21, 2022

In other words it is ready to commit. It does not break anything, only made improvements.

@Jakuje
Copy link
Member

Jakuje commented Sep 21, 2022

Thank you! Merging.

@Jakuje Jakuje merged commit f65746b into OpenSC:master Sep 21, 2022
@dengert
Copy link
Member Author

dengert commented Sep 22, 2022

If you use OpenSC on Windows, especially if you were having problems with EC keys, can you try installing OpenSC from https://github.com/OpenSC/Nightly

Uninstall any current OpenSC packages both 64 and 32 bit. Then install the nightly versions of the .msi files.

Please report if it works or does not work, along with the card type and ATR.
'opensc-tool -a` can be used to get the ATR.

It is not clear if certificates already registered in the Microsoft Certificate Store will have to be deleted or not. Previous versions of OpenSC set in registry "Provider = OpenSC" which caused EC keys to not work. #2523 fixes this to use "Provider = Microsoft Base Smart Card Crypto Provider" or "Provider = Microsoft Smart Card Key Storage Provider"

certutil.exe -v -SCInfo or a Microsoft browser to a site requeuing the use of the smart card can be used to verify if #2523 is working.

Thanks.

@dengert
Copy link
Member Author

dengert commented Oct 11, 2022 via email

AlexandreGonzalo pushed a commit to AlexandreGonzalo/OpenSC that referenced this pull request Nov 14, 2022
…lity

Add comment:
<!-- PR OpenSC#2523 no longer uses "Provider = OpenSC CSP", but existing certificates in cert store
    may have "Provider = OpenSC CSP" so we continue to add it for backward compatibility.
    Run: "certutil -Silent -store -user My" and look for "Provider = OpenSC CSP". -->

 Date:      Tue Aug 31 13:13:00 2022 -0500

 On branch minidriver-ECC
 Changes to be committed:
	modified:   win32/OpenSC.wxs.in
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants