Commit 1c31fe7e authored by Sam Roberts's avatar Sam Roberts Committed by Matt Caswell
Browse files

Ignore cipher suites when setting cipher list



set_cipher_list() sets TLSv1.2 (and below) ciphers, and its success or
failure should not depend on whether set_ciphersuites() has been used to
setup TLSv1.3 ciphers.

Reviewed-by: default avatarPaul Dale <paul.dale@oracle.com>
Reviewed-by: default avatarBen Kaduk <kaduk@mit.edu>
Reviewed-by: default avatarMatt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/7759)

(cherry picked from commit 3c83c5ba4f6502c708b7a5f55c98a10e312668da)
parent cd272eee
Loading
Loading
Loading
Loading
+22 −2
Original line number Diff line number Diff line
@@ -2508,6 +2508,26 @@ STACK_OF(SSL_CIPHER) *SSL_CTX_get_ciphers(const SSL_CTX *ctx)
    return NULL;
}

/*
 * Distinguish between ciphers controlled by set_ciphersuite() and
 * set_cipher_list() when counting.
 */
static int cipher_list_tls12_num(STACK_OF(SSL_CIPHER) *sk)
{
    int i, num = 0;
    const SSL_CIPHER *c;

    if (sk == NULL)
        return 0;
    for (i = 0; i < sk_SSL_CIPHER_num(sk); ++i) {
        c = sk_SSL_CIPHER_value(sk, i);
        if (c->min_tls >= TLS1_3_VERSION)
            continue;
        num++;
    }
    return num;
}

/** specify the ciphers to be used by default by the SSL_CTX */
int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str)
{
@@ -2525,7 +2545,7 @@ int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str)
     */
    if (sk == NULL)
        return 0;
    else if (sk_SSL_CIPHER_num(sk) == 0) {
    else if (cipher_list_tls12_num(sk) == 0) {
        SSLerr(SSL_F_SSL_CTX_SET_CIPHER_LIST, SSL_R_NO_CIPHER_MATCH);
        return 0;
    }
@@ -2543,7 +2563,7 @@ int SSL_set_cipher_list(SSL *s, const char *str)
    /* see comment in SSL_CTX_set_cipher_list */
    if (sk == NULL)
        return 0;
    else if (sk_SSL_CIPHER_num(sk) == 0) {
    else if (cipher_list_tls12_num(sk) == 0) {
        SSLerr(SSL_F_SSL_SET_CIPHER_LIST, SSL_R_NO_CIPHER_MATCH);
        return 0;
    }
+35 −0
Original line number Diff line number Diff line
@@ -215,9 +215,44 @@ static int test_default_cipherlist_explicit(void)
    return result;
}

/* SSL_CTX_set_cipher_list() should fail if it clears all TLSv1.2 ciphers. */
static int test_default_cipherlist_clear(void)
{
    SETUP_CIPHERLIST_TEST_FIXTURE();
    SSL *s = NULL;

    if (fixture == NULL)
        return 0;

    if (!TEST_int_eq(SSL_CTX_set_cipher_list(fixture->server, "no-such"), 0))
        goto end;

    if (!TEST_int_eq(ERR_GET_REASON(ERR_get_error()), SSL_R_NO_CIPHER_MATCH))
        goto end;

    s = SSL_new(fixture->client);

    if (!TEST_ptr(s))
      goto end;

    if (!TEST_int_eq(SSL_set_cipher_list(s, "no-such"), 0))
        goto end;

    if (!TEST_int_eq(ERR_GET_REASON(ERR_get_error()),
                SSL_R_NO_CIPHER_MATCH))
        goto end;

    result = 1;
end:
    SSL_free(s);
    tear_down(fixture);
    return result;
}

int setup_tests(void)
{
    ADD_TEST(test_default_cipherlist_implicit);
    ADD_TEST(test_default_cipherlist_explicit);
    ADD_TEST(test_default_cipherlist_clear);
    return 1;
}
+2 −1
Original line number Diff line number Diff line
@@ -99,8 +99,9 @@ static int test_client_hello(int currtest)
         * ClientHello is already going to be quite long. To avoid getting one
         * that is too long for this test we use a restricted ciphersuite list
         */
        if (!TEST_true(SSL_CTX_set_cipher_list(ctx, "")))
        if (!TEST_false(SSL_CTX_set_cipher_list(ctx, "")))
            goto end;
        ERR_clear_error();
         /* Fall through */
    case TEST_ADD_PADDING:
    case TEST_PADDING_NOT_NEEDED:
+46 −5
Original line number Diff line number Diff line
@@ -1382,6 +1382,46 @@ int main(int argc, char *argv[])
        goto end;

    if (cipher != NULL) {
        if (strcmp(cipher, "") == 0) {
            if (!SSL_CTX_set_cipher_list(c_ctx, cipher)) {
                if (ERR_GET_REASON(ERR_peek_error()) == SSL_R_NO_CIPHER_MATCH) {
                    ERR_clear_error();
                } else {
                    ERR_print_errors(bio_err);
                    goto end;
                }
            } else {
                /* Should have failed when clearing all TLSv1.2 ciphers. */
                fprintf(stderr, "CLEARING ALL TLSv1.2 CIPHERS SHOULD FAIL\n");
                goto end;
            }

            if (!SSL_CTX_set_cipher_list(s_ctx, cipher)) {
                if (ERR_GET_REASON(ERR_peek_error()) == SSL_R_NO_CIPHER_MATCH) {
                    ERR_clear_error();
                } else {
                    ERR_print_errors(bio_err);
                    goto end;
                }
            } else {
                /* Should have failed when clearing all TLSv1.2 ciphers. */
                fprintf(stderr, "CLEARING ALL TLSv1.2 CIPHERS SHOULD FAIL\n");
                goto end;
            }

            if (!SSL_CTX_set_cipher_list(s_ctx2, cipher)) {
                if (ERR_GET_REASON(ERR_peek_error()) == SSL_R_NO_CIPHER_MATCH) {
                    ERR_clear_error();
                } else {
                    ERR_print_errors(bio_err);
                    goto end;
                }
            } else {
                /* Should have failed when clearing all TLSv1.2 ciphers. */
                fprintf(stderr, "CLEARING ALL TLSv1.2 CIPHERS SHOULD FAIL\n");
                goto end;
            }
        } else {
            if (!SSL_CTX_set_cipher_list(c_ctx, cipher)
                    || !SSL_CTX_set_cipher_list(s_ctx, cipher)
                    || !SSL_CTX_set_cipher_list(s_ctx2, cipher)) {
@@ -1389,6 +1429,7 @@ int main(int argc, char *argv[])
                goto end;
            }
        }
    }
    if (ciphersuites != NULL) {
        if (!SSL_CTX_set_ciphersuites(c_ctx, ciphersuites)
            || !SSL_CTX_set_ciphersuites(s_ctx, ciphersuites)