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