Reputation: 98
I'm writing a server application that uses CryptoAPI and Schannel for setting up a secure SSL connection to clients. The server requires the clients to submit a certificate for verification (by setting the ASC_REQ_MUTUAL_AUTH
flag in AcceptSecurityContext
).
The problem I have is that some clients (namely clients using javax.net.ssl
) does not pass along their client certificate (even though it's been configured to do so). I suspect this is because the CA certificate used for signing the client certificates are not in the list of CA's passed to the client during the handshake.
I've tried to do variations of the following to add the CA certificate to this list:
PCERT_CONTEXT caCertContext = ...; /* Imported from a DER formatted file */
HCERTSTORE systemStore = CertOpenStore(
CERT_STORE_PROV_SYSTEM,
0,
0,
CERT_STORE_OPEN_EXISTING_FLAG |
CERT_SYSTEM_STORE_LOCAL_MACHINE,
L"ROOT");
bool ok = CertAddCertificateContextToStore(
systemStore,
caCertContext,
CERT_STORE_ADD_USE_EXISTING,
NULL);
if (!ok)
{
std::cerr << "Could not add certificate to system store!" << std::endl;
}
In the above example CertAddCertificateContextToStore
always fails. If I change CERT_SYSTEM_STORE_LOCAL_MACHINE
to CERT_SYSTEM_STORE_CURRENT_USER
I am presented with a popup asking me to confirm the certificate, but even if I accept the CA certificate will not appear in the list sent to the client.
I also tried extending the system store collection with a temporary memory store (something I picked up from here) but to no avail.
Anyone know of a way to solve this? Ideally programmatically without using any GUI or external tool?
Upvotes: 1
Views: 3284
Reputation: 342
If you don't want to add it systemwide (as you mentioned in the comment) you can open with the CERT_SYSTEM_STORE_CURRENT_USER
flag.
CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, CERT_STORE_OPEN_EXISTING_FLAG |
CERT_SYSTEM_STORE_CURRENT_USER, L"MY");
Upvotes: 0
Reputation: 625
You are getting that error because you don't have permission to access the store as read and write, you can only access it as read. So what you have to do is add CERT_STORE_READONLY_FLAG so it will be:
HCERTSTORE systemStore = CertOpenStore(
CERT_STORE_PROV_SYSTEM,
0,
0,
CERT_STORE_OPEN_EXISTING_FLAG |
CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_READONLY_FLAG ,
L"ROOT");
If you which to make changes to your store and not have it read only that means you will require administration elevation when you are running your C++ application.
Upvotes: 1