Reputation: 119
I have SSL connection to server. I had root CA and it was also the server certificate. I don't have a client certificate, when connection starts client verifies the server certificate and if it's valid connects. Now I've created Intermediate CA from my root CA, and replace it as server certificate, now I want the client to verify if the server certificate is trusted by root CA, I do it in C++ with openSSL API. how can I do it? here is what i've tried but it needs something more.
const Char *caCert = "/home/omar/CA/host/host_rsa_key.crt";
X509_LOOKUP *lookup = X509_STORE_add_lookup(ctx_ -> cert_store,X509_LOOKUP_file());
result=X509_LOOKUP_load_file(lookup,caCert,X509_FILETYPE_PEM);
if(result != 1)
{
log()<<ERROR! Cannot load file to lookup structure\n";
return;
}
SSL_CTX_sess_set_new_cb(ctx_, handshakeCallback);
SSL_CTX_set_verify(ctx_, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
verifyCallback);
SSL_CTX_set_verify_depth(ctx_, 8);
this is where I load all certificate into ssl_ctx.
I have verifyCallback function which calls verifyCertificate() method here it is
Int verifyCertificate(Int preverify, X509_STORE_CTX *store)
{
X509 *cert = NULL;
// X509_NAME *name = NULL;
SSL *ssl = NULL;
Int certDepth = -1;
Int certErr = 0;
Char *certHost = NULL;
Char *certHash = NULL;
Char *certData = NULL;
cert = X509_STORE_CTX_get_current_cert(store);
if (cert == NULL)
log() << " ERROR! Failed to get certificate.\n";
goto VerifyCertificateError;
}
certDepth = X509_STORE_CTX_get_error_depth(store);
certErr = X509_STORE_CTX_get_error(store);
ssl = (SSL *) X509_STORE_CTX_get_ex_data(store, SSL_get_ex_data_X509_STORE_CTX_idx());
if (ssl == NULL)
{
log() << ERROR! Failed to get SSL context from store context.\n";
goto VerifyCertificateError;
}
if (preverify == 0)
{
//
// Self signed certificate allowed, SSH host auth style.
//
if (certErr == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT)
{
log() << " Certificate preverify failed on self";
return 1;
}
else if (certErr == X509_V_ERR_CERT_NOT_YET_VALID)
{
log() << Allowing not yet valid certificate.\n";
return 1;
}
else if (certErr == X509_V_ERR_CERT_HAS_EXPIRED)
{
log() << " Allowing expired certificate.\n";
return 1;
}
else if(certErr == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT)
{
log()<<" Unable to get issuer cert.\n"
return 1;
}
if (certDepth == 0)
{
if (parseCertificate(store, certHost, certHash, certData) == 0)
{
log() << "Encryptable: ERROR! Failed to parse certificate.\n";
goto VerifyCertificateError;
}
goto VerifyCertificateError;
}
if (authCallback_(certHost, certHash, certData, certCallback_,
callbackParameter_) == 0)
{
log() << " ERROR! Failed to authorize "
<< "the server certificate.\n";
goto VerifyCertificateError;
if (certData != NULL)
{
delete [] certData;
}
return 0;
}
Upvotes: 1
Views: 1576
Reputation: 123561
Intermediate certificates are checked by OpenSSL and there is nothing special you need to do. Of course
You don't need a verify_callback because the default callback does the verification already, that is it checks the whole trust chain, including the intermediate certificates. If you still use one, preverify
contains the result of the checks OpenSSL is doing already and your verification callback should just return this value unless you have specific cases where you need the verification to behave differently.
Upvotes: 1