PeculiarVentures / pvpkcs11

pvpkcs11 consists of a input validation library and a set of PKCS#11 implementations that wrap operating system and browser cryptographic implementations.
MIT License
32 stars 7 forks source link

Support using Windows mini drivers effectivly #34

Open microshine opened 6 years ago

microshine commented 6 years ago

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

  2. Rutoken

  3. 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

  4. 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

  5. SafeNET (CSP only)

  6. 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
  7. 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
microshine commented 6 years ago

@rmhrisk What do you think?

rmhrisk commented 6 years ago

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

supershippy commented 6 years ago
  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.
microshine commented 6 years ago

@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 commented 6 years ago

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.
supershippy commented 6 years ago

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.

microshine commented 6 years ago

@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

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 commented 6 years ago

I found example.

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

microshine commented 6 years ago

@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)

rmhrisk commented 6 years ago

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?

microshine commented 6 years ago

@rmhrisk Is it ok?

rmhrisk commented 6 years ago

Yes I think it’s the best we can do

supershippy commented 6 years ago

@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.

rmhrisk commented 6 years ago

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