Main Content

Server certificate common name not checked

Attacker might use valid certificate to impersonate trusted host

Since R2020a

Description

The defect occurs when you do not check the common name provided in the server certificate against the domain name of the server.

Typically, when a client connects to a server, the server sends a digital certificate to the client that identifies the server as a trusted entity. The certificate contains information about the server, including the common name of the server. The common name matches the server domain name that the certificate identifies as a trusted entity.

The checker raises no defect if:

  • You pass the SSL context as an argument to the function that calls SSL_new.

  • You declare the SSL context outside the scope of the function handling the connection.

Risk

A malicious attacker might use a valid certificate to impersonate a trusted host, resulting in the client interacting with an untrusted server.

Fix

Use one of these functions to specify the server domain name that the program checks against the common name provided in the server certificate.

  • SSL_set_tlsext_host_name

  • SSL_set1_host

  • SSL_add1_host

Examples

expand all


#include <stdio.h>
#include <stdlib.h>
#include <openssl/ssl.h>

#define fatal_error() exit(-1)

void check_certificate(SSL_CTX* ctx, SSL* ssl)
{
    /* Check for Client authentication error */
    if (!SSL_get_peer_certificate(ssl)) {
        printf("SSL Client Authentication error\n");
        SSL_free(ssl);
        SSL_CTX_free(ctx);
        exit(0);
    }
    /* Check for Client authentication error */
    if (SSL_get_verify_result(ssl) != X509_V_OK) {
        printf("SSL Client Authentication error\n");
        SSL_free(ssl);
        SSL_CTX_free(ctx);
        exit(0);
    }
}

void func()
{
    int ret;
    SSL_CTX* ctx;
    SSL* ssl;

    /* creation context for the SSL protocol */
    ctx = SSL_CTX_new(SSLv23_client_method());
    if (ctx == NULL) fatal_error();

    /* Handle connection */
    ssl = SSL_new(ctx);
    SSL_set_connect_state(ssl);
    check_certificate(ctx, ssl);
    ret = SSL_connect(ssl);
    if (ret <= 0) fatal_error();

    SSL_free(ssl);
    SSL_CTX_free(ctx);
}

In this example, an SSL structure is initiated with a client connection method. The client validates the server certificate with check_certificate. However, the client does not check that the certificate common name matches the domain name of the server. An attacker might use the valid certificate to impersonate the trusted server.

Correction — Specify a Domain Name to Check Against the Certificate Common Name

One possible correction is to use SSL_set1_host to specify the expected domain name that the program checks against the server certificate common name.


#include <stdio.h>
#include <stdlib.h>
#include <openssl/ssl.h>

#define fatal_error() exit(-1)

void check_certificate(SSL_CTX* ctx, SSL* ssl)
{
    /* Check for Client authentication error */
    if (!SSL_get_peer_certificate(ssl)) {
        printf("SSL Client Authentication error\n");
        SSL_free(ssl);
        SSL_CTX_free(ctx);
        exit(0);
    }
    /* Check for Client authentication error */
    if (SSL_get_verify_result(ssl) != X509_V_OK) {
        printf("SSL Client Authentication error\n");
        SSL_free(ssl);
        SSL_CTX_free(ctx);
        exit(0);
    }
}

void func()
{
    int ret;
    SSL_CTX* ctx;
    SSL* ssl;

    /* creation context for the SSL protocol */
    ctx = SSL_CTX_new(SSLv23_client_method());
    if (ctx == NULL) fatal_error();

    /* Handle connection */
    ssl = SSL_new(ctx);
    SSL_set_connect_state(ssl);
    check_certificate(ctx, ssl);
    ret = SSL_set1_host(ssl, "www.mysite.com");
    if (ret <= 0) fatal_error();
    ret = SSL_connect(ssl);
    if (ret <= 0) fatal_error();

    SSL_free(ssl);
    SSL_CTX_free(ctx);
}
 

Result Information

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

Version History

Introduced in R2020a