Commit 38a73150 authored by Matt Caswell's avatar Matt Caswell
Browse files

Add a ciphersuite config sanity check for servers



Ensure that there are ciphersuites enabled for the maximum supported
version we will accept in a ClientHello.

Reviewed-by: default avatarRichard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/3316)
parent aafec89c
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -2194,8 +2194,7 @@ __owur int ssl_choose_server_version(SSL *s, CLIENTHELLO_MSG *hello,
                                     DOWNGRADE *dgrd);
__owur int ssl_choose_client_version(SSL *s, int version, int checkdgrd,
                                     int *al);
int ssl_get_client_min_max_version(const SSL *s, int *min_version,
                                   int *max_version);
int ssl_get_min_max_version(const SSL *s, int *min_version, int *max_version);

__owur long tls1_default_timeout(void);
__owur int dtls1_do_write(SSL *s, int type);
+1 −1
Original line number Diff line number Diff line
@@ -674,7 +674,7 @@ int tls_construct_extensions(SSL *s, WPACKET *pkt, unsigned int context,
    }

    if ((context & SSL_EXT_CLIENT_HELLO) != 0) {
        reason = ssl_get_client_min_max_version(s, &min_version, &max_version);
        reason = ssl_get_min_max_version(s, &min_version, &max_version);
        if (reason != 0) {
            SSLerr(SSL_F_TLS_CONSTRUCT_EXTENSIONS, reason);
            goto err;
+1 −1
Original line number Diff line number Diff line
@@ -464,7 +464,7 @@ int tls_construct_ctos_supported_versions(SSL *s, WPACKET *pkt,
        return 0;
    }

    reason = ssl_get_client_min_max_version(s, &min_version, &max_version);
    reason = ssl_get_min_max_version(s, &min_version, &max_version);
    if (reason != 0) {
        SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_SUPPORTED_VERSIONS, reason);
        return 0;
+36 −4
Original line number Diff line number Diff line
@@ -78,6 +78,39 @@ int tls_setup_handshake(SSL *s)
        return 0;

    if (s->server) {
        STACK_OF(SSL_CIPHER) *ciphers = SSL_get_ciphers(s);
        int i, ver_min, ver_max, ok = 0;

        /*
         * Sanity check that the maximum version we accept has ciphers
         * enabled. For clients we do this check during construction of the
         * ClientHello.
         */
        if (ssl_get_min_max_version(s, &ver_min, &ver_max) != 0) {
            SSLerr(SSL_F_TLS_SETUP_HANDSHAKE, ERR_R_INTERNAL_ERROR);
            ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
            return 0;
        }
        for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) {
            const SSL_CIPHER *c = sk_SSL_CIPHER_value(ciphers, i);

            if (SSL_IS_DTLS(s)) {
                if (DTLS_VERSION_GE(ver_max, c->min_dtls) &&
                        DTLS_VERSION_LE(ver_max, c->max_dtls))
                    ok = 1;
            } else if (ver_max >= c->min_tls && ver_max <= c->max_tls) {
                ok = 1;
            }
            if (ok)
                break;
        }
        if (!ok) {
            SSLerr(SSL_F_TLS_SETUP_HANDSHAKE, SSL_R_NO_CIPHERS_AVAILABLE);
            ERR_add_error_data(1, "No ciphers enabled for max supported "
                                  "SSL/TLS version");
            ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
            return 0;
        }
        if (SSL_IS_FIRST_HANDSHAKE(s)) {
            s->ctx->stats.sess_accept++;
        } else if (!s->s3->send_connection_binding &&
@@ -1781,7 +1814,7 @@ int ssl_choose_client_version(SSL *s, int version, int checkdgrd, int *al)
}

/*
 * ssl_get_client_min_max_version - get minimum and maximum client version
 * ssl_get_min_max_version - get minimum and maximum protocol version
 * @s: The SSL connection
 * @min_version: The minimum supported version
 * @max_version: The maximum supported version
@@ -1799,8 +1832,7 @@ int ssl_choose_client_version(SSL *s, int version, int checkdgrd, int *al)
 * Returns 0 on success or an SSL error reason number on failure.  On failure
 * min_version and max_version will also be set to 0.
 */
int ssl_get_client_min_max_version(const SSL *s, int *min_version,
                                   int *max_version)
int ssl_get_min_max_version(const SSL *s, int *min_version, int *max_version)
{
    int version;
    int hole;
@@ -1894,7 +1926,7 @@ int ssl_set_client_hello_version(SSL *s)
{
    int ver_min, ver_max, ret;

    ret = ssl_get_client_min_max_version(s, &ver_min, &ver_max);
    ret = ssl_get_min_max_version(s, &ver_min, &ver_max);

    if (ret != 0)
        return ret;
+1 −1
Original line number Diff line number Diff line
@@ -1013,7 +1013,7 @@ void ssl_set_client_disabled(SSL *s)
    s->s3->tmp.mask_a = 0;
    s->s3->tmp.mask_k = 0;
    ssl_set_sig_mask(&s->s3->tmp.mask_a, s, SSL_SECOP_SIGALG_MASK);
    ssl_get_client_min_max_version(s, &s->s3->tmp.min_ver, &s->s3->tmp.max_ver);
    ssl_get_min_max_version(s, &s->s3->tmp.min_ver, &s->s3->tmp.max_ver);
#ifndef OPENSSL_NO_PSK
    /* with PSK there must be client callback set */
    if (!s->psk_client_callback) {
Loading