Topic: mutual authentication

Hello,
I just joined the community and have a question.

I understand that "mutual authentication" involves both sides of an SSL/TLS connection sending the certificate chain during the handshake and verifying the counterparty's chain.
So when does that happen?

Re: mutual authentication

Hi toni992,

My name is Anthony and I am a member of the wolfSSL team. The short answer is that it happens during the TLS  handshake.

The longer more nuanced answer follows.  From RFC 8466 (TLS 1.3)  https://datatracker.ietf.org/doc/html/rfc8446#section-2 you can see the following:

       Client                                           Server

Key  ^ ClientHello
Exch | + key_share*
     | + signature_algorithms*
     | + psk_key_exchange_modes*
     v + pre_shared_key*       -------->
                                                  ServerHello  ^ Key
                                                 + key_share*  | Exch
                                            + pre_shared_key*  v
                                        {EncryptedExtensions}  ^  Server
                                        {CertificateRequest*}  v  Params
                                               {Certificate*}  ^
                                         {CertificateVerify*}  | Auth
                                                   {Finished}  v
                               <--------  [Application Data*]
     ^ {Certificate*}
Auth | {CertificateVerify*}
     v {Finished}              -------->
       [Application Data]      <------->  [Application Data]

The certificate and certificate verify messages are where it happens.

The Certificate message is where the certificate chain is sent to the peer.  The CertificateVerify message is where the signature of the TLS handshake transcript is sent.  The peer verifies the chain and the signature of the TLS handshake transcript.

Please let me know if you would like further clarifications.

This is a great question and here at wolfSSL we love to know about the community member and what they are doing. 

Can you please let us know about your interest in wolfSSL and protocols?  Can you let us know about yourself and your projects?

For example, where are you located?  Can you let us know your goals.

Warm regards, Anthony

Share

Re: mutual authentication

Thanks for your help

Re: mutual authentication

Hi All,
       Newly joined the community and have question about mTLS.
We  are currently using the WolfSSL 5.6.4 in Linux and want to implement mTLS(Mutual Authentication ) using wolfSSL. I’m new to this so referred WolfSSL examples code from below link

https://github.com/wolfSSL/wolfssl-exam … er-tls13.c

WolfSSL Version: 5.6.4
My configuration:  ./configure --prefix=/home/firmware/wolfssl-5.6.4/usr --enable-fips=ready --enable-stunnel --disable-oldtls --enable-certreq --enable-certgen --enable-opensslall --enable-rsapss --enable-debug

Server code :

listenfd = socket(AF_INET, SOCK_STREAM, 0);

    /* setsockopt: Eliminates "ERROR on binding: Address already in
       use" error. */
    optval = 1;
    setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (const void *)&optval,
               sizeof(int));

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family      = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port        = htons(SERV_PORT);

    bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
    listen(listenfd, LISTENQ);
   

        wolfSSL_Init();
       
#if defined(DEBUG_WOLFSSL) && !defined(WOLFSSL_MDK_SHELL)
        wolfSSL_Debugging_ON();
#endif

    /* Create and initialize WOLFSSL_CTX structure */
    if ( (ctx = wolfSSL_CTX_new(wolfTLSv1_3_server_method())) == NULL) {
        fprintf(stderr, "wolfSSL_CTX_new error.\n");
        exit(EXIT_FAILURE);
    }
       
            /* Require mutual authentication */
      wolfSSL_CTX_set_verify(ctx,
        WOLFSSL_VERIFY_PEER | WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
       
       
         /* Load the trusted certificates */
         /* May be called multiple times to continue loading trusted certs into the
            wolfSSL Certificate Manager */
    if (wolfSSL_CTX_load_verify_locations(ctx,"certs/client-cert.pem", 0) !=
            SSL_SUCCESS) {
        fprintf(stderr, "Error loading certs/client-cert.pem, "
                "please check the file.\n");
        exit(EXIT_FAILURE);
    } 
             
        /* Load server certificate into WOLFSSL_CTX */
    if (wolfSSL_CTX_use_certificate_file(ctx,"certs/server-cert.pem",
                SSL_FILETYPE_PEM) != SSL_SUCCESS) {
       fprintf(stderr, "Error loading certs/server-cert.pem, "
               "please check the file.\n");
       exit(EXIT_FAILURE);
    }

    /* Load server key into WOLFSSL_CTX */
    if (wolfSSL_CTX_use_PrivateKey_file(ctx,"certs/server-key.pem",
                SSL_FILETYPE_PEM) != SSL_SUCCESS) {
       fprintf(stderr, "Error loading certs/server-key.pem, "
               "please check the file.\n");
       exit(EXIT_FAILURE);
    }
       
    while(1)
    {
        clilen = sizeof(cliaddr);
        WOLFSSL* ssl;

        if ( (connfd = accept(listenfd, (SA *) &cliaddr, &clilen)) < 0 )
        {
            if (errno == EINTR)
                continue;        /* back to while() */
            else
                err_sys("accept error\n");
        }

        printf("Connection from %s, port %d\n",
                inet_ntop(AF_INET, &cliaddr.sin_addr, buff, sizeof(buff)),
                ntohs(cliaddr.sin_port));

        /* Create WOLFSSL Object */
        if( (ssl = wolfSSL_new(ctx)) == NULL) {
           fprintf(stderr, "wolfSSL_new error.\n");
           exit(EXIT_FAILURE);
        }

        wolfSSL_set_fd(ssl, connfd);
       
               printf("/********************************** Client connected successfully\n");
        str_echo(ssl);                /* process the request */

        wolfSSL_free(ssl);            /* Free WOLFSSL object */

        close(connfd);                /* close connected socket */
    }   


With this server code I can see in logs “Verified Peer's cert” in server log file .  From my understanding, in server code we are loading client certificate as  trusted certificates and  server is asking client certificate as part of handshake (Because WOLFSSL_VERIFY_PEER is set) and verification is done against loaded certificates. But in Our use case  loading client certificate on the server side will not be possible.

1.    IS IT POSSIBLE MUTUAL AUTHENTICATION WITHOUT LOADING TRUSTED CERTIFICATES(client certificates) ON SERVER SIDE ?
2.    Is there any other way to do mTLS?

We have Certificate Authority(CA)  which provides certificates to server and client. So they both have certificates from same CA.

Server Certificates:
        ca.pem
server.pem   
        server.key

Client Certificates:
        ca.pem
client.pem   
client.key 

By default , client gets the server certificate and client verify server certificates to avoid MITM. we have to implement mTLS(Mutual Authentication ) between server and client communication.

So I started exploring other options and found information from below  link
https://www.wolfssl.com/forums/topic124 … ation.html

Modified Server Code:

listenfd = socket(AF_INET, SOCK_STREAM, 0);

    /* setsockopt: Eliminates "ERROR on binding: Address already in
       use" error. */
    optval = 1;
    setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (const void *)&optval,
               sizeof(int));

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family      = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port        = htons(SERV_PORT);

    bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
    listen(listenfd, LISTENQ);
   

        wolfSSL_Init();
       
#if defined(DEBUG_WOLFSSL) && !defined(WOLFSSL_MDK_SHELL)
        wolfSSL_Debugging_ON();
#endif

    /* Create and initialize WOLFSSL_CTX structure */
    if ( (ctx = wolfSSL_CTX_new(wolfTLSv1_3_server_method())) == NULL) {
        fprintf(stderr, "wolfSSL_CTX_new error.\n");
        exit(EXIT_FAILURE);
    }
       
            /* Require mutual authentication */
      wolfSSL_CTX_set_verify(ctx,
        WOLFSSL_VERIFY_PEER | WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT, myVerifyCheck);
       
       
         /* Load the trusted certificates */
         /* May be called multiple times to continue loading trusted certs into the
            wolfSSL Certificate Manager */
    if (wolfSSL_CTX_load_verify_locations(ctx,"certs/ca-cert.pem", 0) !=
            SSL_SUCCESS) {
        fprintf(stderr, "Error loading certs/ca-cert.pem, "
                "please check the file.\n");
        exit(EXIT_FAILURE);
    } 
             
        /* Load server certificate into WOLFSSL_CTX */
    if (wolfSSL_CTX_use_certificate_file(ctx,"certs/server-cert.pem",
                SSL_FILETYPE_PEM) != SSL_SUCCESS) {
       fprintf(stderr, "Error loading certs/server-cert.pem, "
               "please check the file.\n");
       exit(EXIT_FAILURE);
    }

    /* Load server key into WOLFSSL_CTX */
    if (wolfSSL_CTX_use_PrivateKey_file(ctx,"certs/server-key.pem",
                SSL_FILETYPE_PEM) != SSL_SUCCESS) {
       fprintf(stderr, "Error loading certs/server-key.pem, "
               "please check the file.\n");
       exit(EXIT_FAILURE);
    }
       
    while(1)
    {
        clilen = sizeof(cliaddr);
        WOLFSSL* ssl;

        if ( (connfd = accept(listenfd, (SA *) &cliaddr, &clilen)) < 0 )
        {
            if (errno == EINTR)
                continue;        /* back to while() */
            else
                err_sys("accept error\n");
        }

        printf("Connection from %s, port %d\n",
                inet_ntop(AF_INET, &cliaddr.sin_addr, buff, sizeof(buff)),
                ntohs(cliaddr.sin_port));

        /* Create WOLFSSL Object */
        if( (ssl = wolfSSL_new(ctx)) == NULL) {
           fprintf(stderr, "wolfSSL_new error.\n");
           exit(EXIT_FAILURE);
        }

        wolfSSL_set_fd(ssl, connfd);
       
       
        WOLFSSL_X509* peerCert = wolfSSL_get_peer_certificate(ssl);

        if(peerCert){
            // You have a pointer peerCert to the peer certification
                 printf("/********************************** You have a pointer peerCert to the peer certification\n");
        }
       
               printf("/********************************** Client connected successfully\n");
        str_echo(ssl);                /* process the request */

        wolfSSL_free(ssl);            /* Free WOLFSSL object */

        close(connfd);                /* close connected socket */
    }
       

For my testing I  used certificates from wolfssl-5.6.4/certs folder. But in server logs I see Failed to verify Peer's cert

wolfSSL Entering wolfSSL_X509_NAME_add_entry_by_NID
Found place for name entry
wolfSSL Entering wolfSSL_sk_push
wolfSSL Entering wolfSSL_sk_new_node
wolfSSL Entering wolfSSL_X509_NAME_ENTRY_free
wolfSSL Entering GetAlgoId
wolfSSL Entering DecodeCertExtensions
wolfSSL Entering DecodeSubjKeyId
wolfSSL Entering DecodeAuthKeyId
wolfSSL Entering DecodeBasicCaConstraints
wolfSSL Entering DecodeAltNames
wolfSSL Entering DecodeExtKeyUsage
No CA signer to verify with
try to load certificate if hash dir is set
wolfSSL Entering LoadCertByIssuer
Failed to verify Peer's cert

I’m I missing anything in code?  Why server is failed to verify client certificate ?


Regards
Ida Sreenivas

Share

Re: mutual authentication

Hello Ida Sreenivas,

My name is Anthony and I am a member of the wolfSSL team.  Please note that you have a support plan with wolfSSL.  As such it would be more appropriate if you opened a support ticket.  You can do  this by sending a message to support@wolfssl.com.  I look forward to helping you there.

Warm regards, Anthony

Share