Main Content

Missing certification authority list

Certificate for authentication cannot be trusted

Description

This defect occurs when you use a context to handle TLS/SSL connections with these functions, but you do not load a certification authority (CA) list into the context.

  • SSL_connect

  • SSL_accept

  • SSL_do_handshake

  • SSL_write

  • SSL_read

  • BIO_do_connect

  • BIO_do_accept

  • BIO_do_handshake

A CA is a trusted third party entity that issues digital certificates to other entities. The certificate contains information about its owner. Server or clients use this information to authenticate connections to the certificate owner.

The checker raises a defect if:

  • For server authentication, the client has no CA list to determine whether the server certificate is from a trusted source.

  • For client authentication, the server has no CA list to determine whether the client certificate is from a trusted source.

Risk

Without a CA list, you cannot determine if the certificate is issued by a trusted CA. The entity that presents the certificate for authentication might not be the entity described in the certificate. Your connection is vulnerable to man-in-the-middle (MITM) attacks.

Fix

Load a certification authority list into the context you create to handle TLS/SSL connections.

Examples

expand all

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

unsigned char* buf;

int OpenConnection(char* hostname, int port)
{
    /* Open the connection */
}

SSL_CTX* InitCTX(void)
{
    SSL_CTX* ctx;
    OpenSSL_add_all_algorithms();
    ctx = SSL_CTX_new(TLSv1_2_client_method());
    if (ctx == NULL) {
        /*handle errors */
    }
    return ctx;
}

void func()
{
    SSL_CTX* ctx;
    int server;
    SSL* ssl;
    char buf[1024];
    int bytes;
    char* hostname, *portnum;
    int ret;

    SSL_library_init();
    hostname = "localhost";
    portnum = "4433";

    ctx = InitCTX();
    server = OpenConnection(hostname, atoi(portnum));
    ssl = SSL_new(ctx);
    SSL_set_fd(ssl, server);
    ret = SSL_connect(ssl);
    if (SSL_get_error(ssl, ret) <= 0) {
        char* msg = "Hello???";
        printf("Connected with %s encryption\n", SSL_get_cipher(ssl));
        SSL_write(ssl, msg, strlen(msg));
        bytes = SSL_read(ssl, buf, sizeof(buf));
        buf[bytes] = 0;
        printf("Received: \"%s\"\n", buf);
        SSL_free(ssl);
    } else
        ERR_print_errors_fp(stderr);
    close(server);
    SSL_CTX_free(ctx);
}

In this example, a context ctx is initialized to handle TLS/SSL connections. When SSL_connect initializes the TLS/SSL handshake with the server by using the SSL structure ssl created from ctx, there is no CA list to check the validity of the server certificate.

Correction — Before Initiating the TLS/SSL Handshake, Load a CA List into the Context

One possible correction is to, before you initialize the SSL structure, specify a list of CA certificates for the context ctx, for instance with SSL_CTX_load_verify_locations.

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

unsigned char* buf;

int OpenConnection(char* hostname, int port)
{
    /* Open the connection */
}

SSL_CTX* InitCTX(void)
{
    SSL_CTX* ctx;
    OpenSSL_add_all_algorithms();
    ctx = SSL_CTX_new(TLSv1_2_client_method());
    if (ctx == NULL) {
        /*handle errors */
    }
    return ctx;
}

void LoadCA(SSL_CTX* ctx, char* CertFile, char* CertPath)
{
    if (SSL_CTX_load_verify_locations(ctx, CertFile, CertPath) <= 0) {
        /* handle errors */
    }
}

void func()
{
    SSL_CTX* ctx;
    int server;
    SSL* ssl;
    char buf[1024];
    int bytes;
    char* hostname, *portnum;
    int ret;

    SSL_library_init();
    hostname = "localhost";
    portnum = "4433";

    ctx = InitCTX();
    LoadCA(ctx, "cacert.pem", "ca/");
    server = OpenConnection(hostname, atoi(portnum));
    ssl = SSL_new(ctx);
    SSL_set_fd(ssl, server);
    ret = SSL_connect(ssl);
    if (SSL_get_error(ssl, ret) <= 0) {
        char* msg = "Hello???";
        printf("Connected with %s encryption\n", SSL_get_cipher(ssl));
        SSL_write(ssl, msg, strlen(msg));
        bytes = SSL_read(ssl, buf, sizeof(buf));
        buf[bytes] = 0;
        printf("Received: \"%s\"\n", buf);
        SSL_free(ssl);
    } else
        ERR_print_errors_fp(stderr);
    close(server);
    SSL_CTX_free(ctx);
}

Result Information

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

Version History

Introduced in R2019b