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.

Share

Re: Retrieving the X509 structure of a peer certificate with WolfSSL

Hi alex_b,

If you would like wolfSSL to hang on to the peer certificate after the SSL/TLS handshake, you can define KEEP_PEER_CERT when compiling wolfSSL.

With wolfSSL, by default the verify callback is only called upon verification failure.  wolfSSL handles certificate verification internally, which is unlike OpenSSL that forces the user to do the verification.  This means that on all failure cases, the preverify parameter will be zero. 

Optionally, you can force wolfSSL to call the verify callback on every verification - regardless if it is successful or a failure - by defining WOLFSSL_ALWAYS_VERIFY_CB.  In this case, if preverify is equal to "1", wolfSSL has already successfully verified the peer certificate.  We provide this option for those users who wish to do custom inspection of certificate elements past normal certificate verification measures.

Does this help clear things up?

Best Regards,
Chris

Re: Retrieving the X509 structure of a peer certificate with WolfSSL

Hello chrisc,

As always, your reply is very much appreciated and very helpful indeed. I just knew the peer cert was discarded to optimize memory usage, I just didn't know how to hang on to it.  smile

FYI, My application creates it's own peer certificates and currently stores the name of the user as the subject CN. After a successful SSL/TLS handshake this information is extracted from the peer certificate using

char *peer = X509_NAME_oneline(X509_get_subject_name(x509), nullptr, 0);

My next challenge is to extract the other information I need from the certificate.

I want to store the seed key for a one-time-password generator in the certificate (encrypted using the public key generated from the private key used with that peer certificate).
A have already found a way to store that data in the certificate (as part of the 'X509v3 Subject Alternative Name') like this:

$ openssl x509 -noout -text -in peer.pem

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 109881812884 (0x1995776794)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: O=openGalaxy, OU=openGalaxy websocket interface, CN=openGalaxyCA/emailAddress=<empty>
        Validity
            Not Before: Dec  2 18:36:53 2015 GMT
            Not After : Dec  1 18:36:53 2016 GMT
        Subject: O=openGalaxy, OU=openGalaxy websocket interface, CN=NAME SURNAME/emailAddress=EMAIL-ADDRESS
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    ...
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                BA:33:4D:3C:60:14:B7:5F:9A:AA:A0:E6:8F:39:7F:10:23:9D:9C:C2
            X509v3 Authority Key Identifier: 
                keyid:CF:F9:12:EF:25:C4:D6:D7:68:E6:C1:4B:86:0F:C3:19:D8:9C:DC:66

            X509v3 Basic Constraints: 
                CA:FALSE
            X509v3 Key Usage: 
                Digital Signature, Non Repudiation, Key Encipherment, Data Encipherment
            X509v3 Extended Key Usage: 
                TLS Web Client Authentication
            X509v3 Subject Alternative Name: 
                DirName:/CN=ENCRYPTED OTP SEED
            X509v3 Issuer Alternative Name: 
                email:<empty>
    Signature Algorithm: sha256WithRSAEncryption
         ...

My goal is to get and decrypt the otp seed from the peer certificate and then use it to generate a one-time-password the user of the certificate would have to match (possibly using http basic authentication once the SSL/TLS connection has been established). I have however not looked into retrieving or decrypting the otp seed from the peer certificate using wolfSSL library functions yet...

Share

Re: Retrieving the X509 structure of a peer certificate with WolfSSL

I have tried to define KEEP_PEER_CERT as well as running the configure script with --enable-sep but I am still unable to retrieve the peer certificate sad

Every once in a while the application gets 'lucky' and can retrieve the cert (usually after a clean build) but most of the time SSL_get_peer_certificate() still returns a NULL pointer.

Share