pvpkcs11 icon indicating copy to clipboard operation
pvpkcs11 copied to clipboard

Support using Windows mini drivers effectivly

Open microshine opened this issue 7 years ago • 14 comments

I've got some questions about SmartCard Provider using.

  1. Is there any way to open MS_SMART_CARD_KEY_STORAGE_PROVIDER provider (NCryptOpenStorageProvider) for specific card? It looks that Windows opens only first SmartCard and doesn't enum certificates and keys for multi SmartCard using

two tokens in slot

  1. Rutoken
  2. Yubikey NEO
Start SmartCard application
SmartCard GUID: 98364C541F19BC0E25D0B8CD4A7159F5
Provider name: Microsoft Smart Card Key Storage Provider
Certificate: RU, "RSA rutoken #1"
Key enum:
  81d4edc5-8696-4170-b42b-4d5ae9453a50
  New key
Done

first token was removed

  1. Yubikey NEO
Start SmartCard application
SmartCard GUID: F8CD87C7503693F2612A81C4BA57AFBB
Provider name: Microsoft Smart Card Key Storage Provider
Certificate: micro
Key enum:
  c787cdf8-3650-f293-612a-81c4ba5fc10b
Done

fist token supports CSP interface only

  1. SafeNET (CSP only)
  2. Yubikey NEO
Start SmartCard application
SmartCard GUID: F8CD87C7503693F2612A81C4BA57AFBB
Provider name: Microsoft Smart Card Key Storage Provider
Certificate: micro
Key enum:
  c787cdf8-3650-f293-612a-81c4ba5fc10b
Done
  1. Which implementation do we have to use?

Current version

  1. Use SCard API to catch insert/remove tokens. This API allows to determine which Storage Provider SmartCard uses (CSP, KSP or custom)
  2. Create slot for each Reader name. (Certificates from user store have property with linked Reader name)
  3. Use SmartCards for signing only. Cannot generate key.

New version

  1. Create slot for KSP and CSP providers
  2. Generate keys and adding certificates
  3. Remove keys and certificates
  4. Use crypto operations
  • Doesn't support multi smart cards
  • We don't know reader name from provider

microshine avatar Jan 14 '18 13:01 microshine

@rmhrisk What do you think?

microshine avatar Jan 14 '18 13:01 microshine

I have asked a friend who is expert on windows smart card support hopefully he has time to look.

rmhrisk avatar Jan 14 '18 16:01 rmhrisk

  1. Once you obtain a list of readers using SCardListReaders, you can pass the format string \\.\<ReaderName>\ as the pszScope for NCryptEnumKeys to specify the enumeration should be from the card in that reader. It's not possible to do all readers from the a single NCryptEnumKeys call.
  2. If a token only supports the CSP interface, you'll need to use the CAPI CSP functions. The in-box smart card CSP is called MS_SCARD_PROV.

supershippy avatar Jan 16 '18 19:01 supershippy

@supershippy Thank you
I'm using SCard API https://github.com/PeculiarVentures/pvpkcs11/blob/ms_smart_card/src/mscapi/scard.cpp

Can I use \\.\<ReaderName>\ for key generation? How can I check if reader supports readonly mode?

microshine avatar Jan 16 '18 19:01 microshine

This is why I didn't use pszScope

https://msdn.microsoft.com/ru-ru/library/windows/desktop/aa376259(v=vs.85).aspx

pszScope [in, optional]
  This parameter is not currently used and must be NULL.

microshine avatar Jan 16 '18 19:01 microshine

Yeah, unfortunately MSDN doesn't do a great job of splitting between different KSPs and the unique behavior among them. For key generation, you'll also need to specify the name of the new key. You can do that with \\.\<ReaderName>\<KeyName>. Being read only is a property of the card rather than reader and you will need to load the minidriver in order to get that. If you call SCardGetCardTypeProviderName and query the SCARD_PROVIDER_CARD_MODULE, you'll get the name of the minidriver. You'll need to LoadLibrary it and then call CardGetProperty and retrieve the CP_CARD_READ_ONLY property. Or you can try generating a key and see if it fails with SCARD_E_READ_ONLY_CARD since loading up the minidriver is a bit heavyweight.

BTW, all of this only applies for cards that have a minidriver and use the in-box KSP/CSP. If a card uses its own KSP/CSP, then it may have a completely different naming format and support other properties.

supershippy avatar Jan 16 '18 19:01 supershippy

@supershippy I need your help I've got two Rutoken tokens.

{"level":"info","message":"PCSCWatcher: New reader detected `Aktiv Rutoken ECP 0`","timestamp":"2018-01-16T20:06:18.499Z"}
{"level":"info","message":"PCSCWatcher: New reader detected `Aktiv Rutoken ECP 1`","timestamp":"2018-01-16T20:06:18.500Z"}

I'm using NCryptEnumKeys but I can not get keys I tried

  • NCryptEnumKeys(hProv, L"//./Aktiv Rutoken ECP 1", &keyName, &pos, NCRYPT_SILENT_FLAG)
  • NCryptEnumKeys(hProv, L"\\.\Aktiv Rutoken ECP 1", &keyName, &pos, NCRYPT_SILENT_FLAG)
  • NCryptEnumKeys(hProv, L"\\\\.\\Aktiv Rutoken ECP 1", &keyName, &pos, NCRYPT_SILENT_FLAG) No result. The same for Aktiv Rutoken ECP 0

But if I use NULL for pszScope I've got (reader: Aktiv Rutoken ECP 0)

Start SmartCard application
SmartCard GUID: 98364C541F19BC0E25D0B8CD4A7159F5
Provider name: Microsoft Smart Card Key Storage Provider
Certificate: RU, "RSA rutoken #1"
Key enum:
  81d4edc5-8696-4170-b42b-4d5ae9453a50
  New key
Done

microshine avatar Jan 16 '18 20:01 microshine

I found example.

pszScope must be \\\\.\\Aktiv Rutoken ECP 1\\

microshine avatar Jan 16 '18 20:01 microshine

@supershippy I've got one more question about Windows CAPI Is there any way to use CertOpenStore for Smart Card?

I need it for Certificate management (read/import/remove)

microshine avatar Jan 18 '18 13:01 microshine

There is not, at least not reliably only a very few smartcards provide implementations of the certstream APIs.

You can filter to those certificates that use a given CSP/KSP by looking at the KEY_PROV_INFO on a certificate.

You don’t know what minidriver is used though as it gets selected at insertion based on the ATR match done at another layer in the stack.

Shippy is there a hanky way to infer this I do not remember?

rmhrisk avatar Jan 18 '18 15:01 rmhrisk

@rmhrisk Is it ok?

  • show certs which has private key only
  • import certificate which can be linked with private key (I hope NCRYPT_CEERTIFICATE_PROPERTY must do it)
  • show all RSA, EC keys from key

microshine avatar Jan 18 '18 15:01 microshine

Yes I think it’s the best we can do

rmhrisk avatar Jan 18 '18 15:01 rmhrisk

@rmhrisk Is your question on how to query the minidriver being used? You can use SCardGetCardTypeProviderName to find the minidriver. You can use SCardListCards to get the card name from ATR.

supershippy avatar Jan 18 '18 19:01 supershippy

@supershippy the question is can I get a list of certificates on a given smart card.

rmhrisk avatar Jan 18 '18 20:01 rmhrisk