16 พฤษภาคม 2552 0:01In a program I write, I iterate over the certificates installed on the local machine and end up with a CERT_CONTEXT. But in order to implement a smart card removal policy for an application that I am writing, I need to use the SCardGetStatusChange API. However, I am having a hard time going from a CERT_CONTEXT (or the HCRYPTPROV you can get from it) to a smart card reader name or ATR string, which is necessary to determine which smart card reader from SCardListReaders I actually want to pay attention to. Is this possible or am I just destined to have to subscribe to changes on all smart card readers, even if it isn't the one that houses the private key of the certificate I'm using? I understand that some certificates may not have their private key stored on a smart card, but if it is, I am wondering if I can get any info about the smart card reader.
18 พฤษภาคม 2552 23:07It looks like CryptGetProvParam(PP_SMARTCARD_READER) is exactly what I am looking for. It is documented as only be available on Vista and later, but at least with the ActivIdentity CSP it works on XP. Unless there is another flag documented as being supported for Win2k and XP, this may be as close as I get to a solution.
17 มีนาคม 2555 22:35
The only information you can retrieve is using:
CertGetCertificateContextProperty(pCertContext, CERT_KEY_PROV_INFO_PROP_ID, pProvInfo, &dwSize)
You will then find the CSP and the container name. As you explained, only the CSP knows how to find the smart card. Most of the time, it is the Microsoft Base Smart Card provider, which provides some information like PP_SMARTCARD_READER. But I think the smart card have to be inserted for that.
For unknown CSP, you could check the Calais Database (in the registry) to find the smart card name and ATR. But you may have more than one entry.