Main Content

Missing private key for X.509 certificate

Missing key might result in run-time error or non-secure encryption

Since R2020a

Description

The defect occurs when you load a X.509 certificate file into the SSL context but you do not load the corresponding private key, or the key that you load into the context is null.

Typically, in a TLS/SSL exchange, the server proves its identity during a TLS/SSL handshake by sending a X.509 certificate that contains information about the server and a public key. The client that receives the certificate uses the public key to encrypt and send a pre-master secret that can only be decrypted with the corresponding private key. The server uses the decrypted pre-master secret and other exchanged messages to generate session keys that are used to encrypt the communication session.

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

Not loading the private key for a X.509 certificate might result in a run-time error on non-secure encryption.

Fix

Load the private key of the X.509 certificate into the SSL context by calling SSL_CTX_use_PrivateKey_file or load the private key into the SSL structure by calling SSL_use_PrivateKey_file.

Examples

expand all

#include <stdio.h>
#include <stdlib.h>
#include <openssl/ssl.h>
#define SSL_SERVER_CRT "server.pem"

#define fatal_error() exit(-1)

void load_cert(SSL_CTX* ctx, const char* certfile)
{
    int ret = SSL_CTX_use_certificate_file(ctx, certfile, SSL_FILETYPE_PEM);
    if (ret <= 0) fatal_error();
}

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

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

    /* context configuration */
    load_cert(ctx, SSL_SERVER_CRT);

    /* Handle connection */
    ssl = SSL_new(ctx);
    ret = SSL_accept(ssl);
    if (ret <= 0) fatal_error();

    SSL_free(ssl);
    SSL_CTX_free(ctx);
}

In this example, SSL context ctx is initiated with server role and the function load_cert loads the server certificate into ctx. The server then waits for a client to initiate a handshake. However, since the private key is not loaded into the SSL structure, the server cannot decrypt the pre-master secret that a client sends, and the handshake fails.

Correction — Load Private Key into SSL Context

One possible correction is to load the private key into the SSL context after you load the server certificate file.

#include <stdio.h>
#include <stdlib.h>
#include <openssl/ssl.h>
#define SSL_SERVER_CRT "server.pem"
#define SSL_SERVER_KEY "server.key"

#define fatal_error() exit(-1)

void load_cert(SSL_CTX* ctx, const char* certfile)
{
    int ret = SSL_CTX_use_certificate_file(ctx, certfile, SSL_FILETYPE_PEM);
    if (ret <= 0) fatal_error();

    ret = SSL_CTX_use_PrivateKey_file(ctx, SSL_SERVER_KEY, SSL_FILETYPE_PEM);
    if (ret <= 0) fatal_error();
}

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

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

    /* context configuration */
    load_cert(ctx, SSL_SERVER_CRT);

    /* Handle connection */
    ssl = SSL_new(ctx);
    ret = SSL_accept(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_NO_PRIVATE_KEY
Impact: Medium

Version History

Introduced in R2020a