PIV smart cards and CERT_SET_KEY_PROV_HANDLE_PROP_ID
A PIV smart card (NIST SP 800-73) is a smart card with a PIV applet. Unlike other cards, a PIV card can't be identified by its ATR, while the Calais database registers cards by ATR.
CryptoAPI calls need a context from CryptAcquireContext, which takes a CSP (from the Calais database) and a container name. On most smart cards, the container name is stable: it comes from the ATR, the serial number, or the card position.
569f1c0b-0caa-44ea-a695-389f96408132) from certutil -scinfoWhen a smart card is inserted, the Certificate Propagation service enumerates the containers, finds the certificates, and adds them to the user store. Each certificate gets a CRYPT_KEY_PROV_INFO with the container and CSP names.
The fix: the container name changes at each insertion, but the service registers the certificate again each time, with the CERT_SET_KEY_PROV_HANDLE_PROP_ID flag (also CERT_SET_KEY_CONTEXT_PROP_ID) set.
CryptAcquireCertificatePrivateKey does more than call CertGetCertificateContextProperty(CERT_KEY_PROV_INFO_PROP_ID) and then CryptAcquireContext.
When CERT_SET_KEY_PROV_HANDLE_PROP_ID is set, the PCCERT_CONTEXT caches an HCRYPTPROV. CryptAcquireCertificatePrivateKey returns that handle when called with CRYPT_ACQUIRE_USE_PROV_INFO_FLAG.
The key stays reachable through its temporary container name, and the authentication cached on that handle can be reused. The caller can still change the SILENT_CONTEXT flag in CryptAcquireCertificatePrivateKey. The CryptoAPI context is released with the certificate context.
CryptGetProvParam with PP_UNIQUE_CONTAINER returns the same container name as PP_CONTAINER.