Main Content

Missing X.509 certificate

Server or client cannot be authenticated

Description

This defect occurs when you use a context to handle TLS/SSL connections with these functions, but you do not load an X.509 certificate into the context.

  • SSL_accept

  • SSL_connect

  • SSL_do_handshake

  • SSL_write

  • SSL_read

  • BIO_do_accept

  • BIO_do_connect

  • BIO_do_handshake

An X.509 certificate is a digital certificate that is issued to an entity. It contains information that identifies the entity. The certificate is used to authenticate connections to the entity identified in the certificate.

The checker raises a defect if:

  • For a server authentication, no certificate is loaded before handling a connection.

  • For a client authentication, the client attempts to connect to a server a second time after getting an SSL_ERROR_WANT_X509_LOOKUP error on the first connection attempt.

Risk

When you do not load an X.509 certificate into the context to handle TLS/SSL connections, the connection is not secure and is vulnerable to man-in-the-middle (MITM) attacks.

Fix

Load an X.509 certificate into the context you create to handle TLS/SSL connections.

Examples

expand all

#include <openssl/ssl.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <openssl/err.h>

unsigned char* buf;
int len;

SSL_CTX* InitServerCTX(void)
{
    SSL_CTX* ctx;
    OpenSSL_add_all_algorithms();
    ctx = SSL_CTX_new(SSLv23_server_method());
    SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1);
    if (ctx == NULL) {
        /*handle errors */
    }
    return ctx;
}

int OpenListener(int port)
{
    /* Create server socket */
}

void func()
{
    SSL_CTX* ctx;
    int server, port;
    int ret;
    SSL_library_init();

    ctx = InitServerCTX();
    server = OpenListener(port);
    while (1) {
        struct sockaddr_in addr;
        socklen_t len = sizeof(addr);
        SSL* ssl;

        int client = accept(server, (struct sockaddr*)&addr, &len);
        printf("Connection: %s:%d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
        ssl = SSL_new(ctx);
        SSL_set_fd(ssl, client);
        ret = SSL_accept(ssl);
        if (SSL_get_error(ssl, ret) <= 0)
            /* Serve connection */;
        else
            SSL_free(ssl);
    }
    close(server);
    SSL_CTX_free(ctx);
}

In this example, InitServerCTX() initializes context ctx for TLS/SSL connections, but no certificate is loaded into ctx. When SSL_accept checks the TLS/SLL handshake for the SSL structure created from ctx, there is no certificate available to authenticate the server.

Correction — Before Creating a SSL Structure, Load Certificate Into Context

One possible correction is to, before you create a SSL structure, load a certificate into the context you create for TLS/SSL connections, for instance with SSL_CTX_use_certificate_file.

#include <openssl/ssl.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <openssl/err.h>

unsigned char* buf;
int len;

SSL_CTX* InitServerCTX(void)
{
    SSL_CTX* ctx;
    OpenSSL_add_all_algorithms();
    ctx = SSL_CTX_new(SSLv23_server_method());
    SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1);
    if (ctx == NULL) {
        /*handle errors */
    }
    return ctx;
}

void LoadCertificates(SSL_CTX* ctx, char* CertFile, char* KeyFile)
{
    if (SSL_CTX_use_certificate_file(ctx, CertFile, SSL_FILETYPE_PEM) <= 0) {
        /* Handle errors */
    }
}

int OpenListener(int port)
{
    /* Create server socket */
}

void func()
{
    SSL_CTX* ctx;
    int server, port;
    int ret;
    SSL_library_init();

    ctx = InitServerCTX();
    LoadCertificates(ctx, "mycert.pem", "mycert.pem");
    server = OpenListener(port);
    while (1) {
        struct sockaddr_in addr;
        socklen_t len = sizeof(addr);
        SSL* ssl;

        int client = accept(server, (struct sockaddr*)&addr, &len);
        printf("Connection: %s:%d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
        ssl = SSL_new(ctx);
        SSL_set_fd(ssl, client);
        ret = SSL_accept(ssl);
        if (SSL_get_error(ssl, ret) <= 0)
            /* Serve connection */;
        else
            SSL_free(ssl);
    }
    close(server);
    SSL_CTX_free(ctx);
}

Result Information

Group: Cryptography
Language: C | C++
Default: Off
Command-Line Syntax: CRYPTO_SSL_NO_CERTIFICATE
Impact: Medium

Version History

Introduced in R2019b