1 (edited by 0siris 2018-08-07 14:49:09)

Topic: [SOLVED] wolfSSL TLS Mutual Authentication

Hello,

I am working on a Mutual TLS Authentication application. I am using starter TLS code from your GitHub repo for both Client and Server located at https://github.com/wolfSSL/wolfssl-exam … ient-tls.c & https://github.com/wolfSSL/wolfssl-exam … rver-tls.c respectively.

I would like to verify that what I have interpreted from your documentation it's correct in my implementation as well as clarify a couple of things.


1) Is it the case that by doing the following for both Client and Server wolfSSL recognizes that Mutual Authentication is required and handles it on its own? or is this just part of the requirements?

Client Code

    if (wolfSSL_CTX_load_verify_locations(ctx, CACRT, NULL)
        != SSL_SUCCESS) {
        fprintf(stderr, "ERROR: failed to load %s, please check the file.\n",
                CACRT);
        return -1;
    }

    /* Load CLIENT certificates into WOLFSSL_CTX */ 
    if (wolfSSL_CTX_use_certificate_file(ctx, ClientCRT, SSL_FILETYPE_PEM)
        != SSL_SUCCESS) {
        fprintf(stderr, "ERROR: failed to load %s, please check the file.\n",
                ClientCRT);
        return -1;
    }

    /* Load CLIENT key into WOLFSSL_CTX */
    if (wolfSSL_CTX_use_PrivateKey_file(ctx, ClientKey, SSL_FILETYPE_PEM)
        != SSL_SUCCESS) {
        fprintf(stderr, "ERROR: failed to load %s, please check the file.\n",
                ClientKey);
        return -1;
    }

Server code

    if (wolfSSL_CTX_load_verify_locations(ctx, CACRT, NULL) != SSL_SUCCESS)
    {
        fprintf(stderr, "ERROR: failed to load %s, please check the file.\n",
                CACRT);
        return -1;
    }

    /* Load SERVER certificates into WOLFSSL_CTX */
    if (wolfSSL_CTX_use_certificate_file(ctx, ServerCRT, SSL_FILETYPE_PEM) != SSL_SUCCESS)
    {
        fprintf(stderr, "ERROR: failed to load %s, please check the file.\n",
                ServerCRT);
        return -1;
    }

    /* Load SERVER key into WOLFSSL_CTX */
    if (wolfSSL_CTX_use_PrivateKey_file(ctx, ServerKey, SSL_FILETYPE_PEM) != SSL_SUCCESS)
    {
        fprintf(stderr, "ERROR: failed to load %s, please check the file.\n",
                ServerKey);
        return -1;
    }

If this correct? Is there something else I have to do to enable mutual authentication?

2)Now following from the prior question. I think that wolfSSL_CTX_set_verify (on the server side) is what actually "Enables" mutual authentication. I really would like clarification on this and I would like to get a detailed explanation on what the below code does. My guess is that this code since is on the Server side, to my understanding it is verifying the certificate from the Client. Is that correct?

Server Code

    wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, 0);

3)What is the behavior if wolfSSL_CTX_set_verify fails? Does it disconnect automatically?

4) Is wolfSSL_CTX_set_verify required on the client side for mutual authentication? (My guess is no, since it is done automatically with the one way)

5)How can I use the VerifyCallback function from the wolfSSL_CTX_set_verify to see if it succeeds or fails?
I would like to do something along this lines below, I know it is not possible since wolfSSL_CTX_set_verify does not return anything, but I think the call back might be useful in this regard.

        verify = wolfSSL_CTX_set_verify(ctx, (verify = SSL_VERIFY_PEER), 0);
        if (verify != 1)
        {
            printf("TLS Client authentication Failed\n");
            shutdown = True;
        }
        else
        {
        printf("TLS: Client Authentication Succesful\n");
        printf("SECURED: Outbound/Inbound Connection to Server is TLS Secured\n");
        }

6) Is there a way to output/log where the TLS handshake might fail, for example if the client trying to connect has an unknown cert? Can the VerifyCallback be possibly used for that?

7) How can I verify that mutual TLS authentication took place? (I think that might be taken care of by wolfSSL_CTX_set_verify if it works the way I think I does)


I have also added a picture of my pcap with Wireshark. I have tried it 4 different ways: with calling wolfSSL_CTX_set_verify ONLY the client side, with calling wolfSSL_CTX_set_verify ONLY on the server side, calling wolfSSL_CTX_set_verify on both server and client, and without calling it. All four have the same structure. There is only one Certificate going from the Server to the Client.

8)Is there a certain place along the handshake where I should be calling wolfSSL_CTX_set_verify

Share

Re: [SOLVED] wolfSSL TLS Mutual Authentication

Osiris,

I can confirm that the call to wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, 0); is the correct solution for turning on mutual auth. The call to wolfSSL_CTX_load_verify_locations is what you use to load certs with which to authenticate but does not enable mutual auth by invocation.

See section "4.8 CLIENT AUTHENTICATION" of our manual here for more info: https://www.wolfssl.com/docs/wolfssl-manual/ch4/


What is the behavior if wolfSSL_CTX_set_verify fails? Does it disconnect automatically?

The connection will not proceed and whichever side failed to authenticate will send either a reset (RST) or close notify alert.

Is wolfSSL_CTX_set_verify required on the client side for mutual authentication? (My guess is no, since it is done automatically with the one way)

No it is not required on the client side.

5)How can I use the VerifyCallback function from the wolfSSL_CTX_set_verify to see if it succeeds or fails?

// just reports the error and returns 
static int myVerifyCheck(int preverify, WOLFSSL_X509_STORE_CTX* store)
{
    (void) preverify; // unused
    printf("In verification callback, error = %d, %s\n", store->error, wolfSSL_ERR_error_string(store->error, buffer));
    return WOLFSSL_SUCCESS; // or whatever you wish to return if error is valid
}

...

// then in your application call

wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, myVerifyCheck);

6) Is there a way to output/log where the TLS handshake might fail, for example if the client trying to connect has an unknown cert? Can the VerifyCallback be possibly used for that?

Yes you can use the verify callback for that or you can turn on wolfSSL debug messages by defining DEBUG_WOLFSSL in your settings and then calling wolfSSL_Debugging_ON(); in your application.

7) How can I verify that mutual TLS authentication took place? (I think that might be taken care of by wolfSSL_CTX_set_verify if it works the way I think I does)

Again see section 4.8 of our manual, that section details how to tell the server to fail if client does not present cert for mutual auth.

Warm Regards,

Kaleb

Re: [SOLVED] wolfSSL TLS Mutual Authentication

Hello Kaleb,

I really appreciate your response. I actually figured out how to get it working.

I do have some more following questions. I am needing to do some work with the peer's x509 cert, I need to be able to extract information from it.

How do I access the cert?

I have tried several things however my latest one seems like it should work.

WOLFSSL_X509 peerCert = wolfSSL_get_peer_certificate(ssl);

But I keep getting "undefined reference to `wolfSSL_get_peer_certificate".

What am I missing?

Share

Re: [SOLVED] wolfSSL TLS Mutual Authentication

Osiris,

Thanks for asking! To ensure this API is available please build with the setting "#define KEEP_PEER_CERT" or if using auto tools and configure:

./configure CFLAGS="-DKEEP_PEER_CERT"

Warm Regards,