Topic: Retrieving the X509 structure of a peer certificate with WolfSSL
I have a couple of questions about WolfSSL and verifying peer certificates:
My applications calls
SSL_CTX_set_verify()
with
SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT
And it also wants to retrieve the X509 structure of each client's peer certificate in order to use information stored in it.
When I use OpenSSL my application does this by calling
SSL_get_peer_certificate()
right after the connection has been established.
But when I use this function with WolfSSL I run into difficulties.
With WolfSSL the SSL_get_peer_certificate() function allways returns a NULL pointer, unless it is called from within
int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx);
The problem I have with this is that from within verify_callback() I have no meaningfull place to store the information retrieved from any X509 structure.
Thus, I need to call SSL_get_peer_certificate() after the connection has been established and not from within verify_callback().
Is it possible to retrieve the peer certificate X509 structure after the connection has been established?
(Or is this information discarded by WolfSSL after verify_callback() completes, to save memory?)
My second question also relates to the process of verifiying a clients peer certificate.
Do I need to do extra verification when verify_callback() is called with preverify_ok=1 ?
With openSSL my application checks that SSL_get_verify_result() returns a value of X509_V_OK, but I have noticed that WolfSSL always returns X509_V_OK when you call this function (hardcoded into the C header files).
Just to be sure, my application uses a certificate manager to verify the peer certificate (again) like this:
int n = 1; // Assume the peer certificate is invalid or could not be authenticated
X509 * x509 = wolfSSL_get_peer_certificate(ssl);
if(x509){
WOLFSSL_CERT_MANAGER* cm = wolfSSL_CertManagerNew();
if(cm != nullptr){
if(wolfSSL_CertManagerLoadCA(cm, "ca.pem", nullptr) == SSL_SUCCESS){ // load the CA cert into the CM
if(wolfSSL_CertManagerSetCRL_Cb(cm, MissingCRL) == SSL_SUCCESS){ // cb to call when the CRL cert is missing
if(wolfSSL_CertManagerLoadCRL(cm, "/path/to/crl", SSL_FILETYPE_PEM, 0) == SSL_SUCCESS){ // load the CRL path into the CM
if(wolfSSL_CertManagerEnableCRL(cm, WOLFSSL_CRL_CHECKALL) == SSL_SUCCESS){ // enable CRL checking for this CM
const unsigned char *der;
int der_length, verify_ok;
der = wolfSSL_X509_get_der(x509, &der_length); // get peer X509 certificate in DER format
verify_ok = wolfSSL_CertManagerVerifyBuffer(cm, der, der_length, SSL_FILETYPE_ASN1); // verify it using the CM
if(verify_ok == SSL_SUCCESS){
n = 0; // Allow the connection to continue.
}
else {
n = 1; // Block the connection.
}
}
}
}
}
wolfSSL_CertManagerFree(cm);
}
}
Is this nessesary or can I trust the hardcoded X509_V_OK that SSL_get_verify_result() returns.