From 7ffa19f93e308c7c57a178aeac1363a11702073d Mon Sep 17 00:00:00 2001 From: Will Childs-Klein Date: Fri, 14 Jun 2024 14:55:57 +0000 Subject: [PATCH] Add EVP_md_null and SSL_set_ciphersuites This commit adds two functions used by OpenLDAP 2.5.17+. Both functions are very straightforward. From OpenSSL's [docs][1] for `EVP_md_null`: >A "null" message digest that does nothing: i.e. the hash it returns is of zero length. From OpenSSL's [docs][2] for `SSL_set_ciphersuites`: > SSL_set_ciphersuites() is the same as SSL_CTX_set_ciphersuites() except it configures the ciphersuites for ssl. [1]: https://www.openssl.org/docs/man1.1.1/man3/EVP_md_null.html [2]: https://www.openssl.org/docs/man1.1.1/man3/SSL_set_ciphersuites.html --- crypto/digest_extra/digest_extra.c | 20 ++++++++++++++++++++ crypto/digest_extra/digest_test.cc | 5 +++++ include/openssl/digest.h | 4 ++++ include/openssl/ssl.h | 3 +++ ssl/ssl_lib.cc | 4 ++++ ssl/ssl_test.cc | 12 ++++++++++++ 6 files changed, 48 insertions(+) diff --git a/crypto/digest_extra/digest_extra.c b/crypto/digest_extra/digest_extra.c index 7f2a1b36daa..0a1286e73e2 100644 --- a/crypto/digest_extra/digest_extra.c +++ b/crypto/digest_extra/digest_extra.c @@ -274,3 +274,23 @@ static const EVP_MD evp_md_blake2b256 = { }; const EVP_MD *EVP_blake2b256(void) { return &evp_md_blake2b256; } + +static void null_init(EVP_MD_CTX *ctx) {} + +static void null_update(EVP_MD_CTX *ctx, const void *data, size_t count) {} + +static void null_final(EVP_MD_CTX *ctx, unsigned char *md) {} + +static const EVP_MD evp_md_null = { + NID_undef, + 0, + 0, + null_init, + null_update, + null_final, + 0, + 0, + NULL, +}; + +const EVP_MD *EVP_md_null(void) { return &evp_md_null; } diff --git a/crypto/digest_extra/digest_test.cc b/crypto/digest_extra/digest_test.cc index 784db1ff797..d836a94f167 100644 --- a/crypto/digest_extra/digest_test.cc +++ b/crypto/digest_extra/digest_test.cc @@ -70,6 +70,7 @@ static const MD shake128 = { "shake128", &EVP_shake128, nullptr, &SHAKE128}; static const MD shake256 = { "shake256", &EVP_shake256, nullptr, &SHAKE256}; static const MD md5_sha1 = { "MD5-SHA1", &EVP_md5_sha1, nullptr, nullptr }; static const MD blake2b256 = { "BLAKE2b-256", &EVP_blake2b256, nullptr, nullptr }; +static const MD md_null = { "NULL", &EVP_md_null, nullptr, nullptr }; struct DigestTestVector { // md is the digest to test. @@ -258,6 +259,10 @@ static const DigestTestVector kTestVectors[] = { // BLAKE2b-256 tests. {blake2b256, "abc", 1, "bddd813c634239723171ef3fee98579b94964e3bb1cb3e427262c8c068d52319"}, + + // NULL tests. Empty output for any input + {md_null, "abc", 1, ""}, + {md_null, "", 1, ""}, }; static void CompareDigest(const DigestTestVector *test, diff --git a/include/openssl/digest.h b/include/openssl/digest.h index 2dcd47b110f..15655b58cdd 100644 --- a/include/openssl/digest.h +++ b/include/openssl/digest.h @@ -369,6 +369,10 @@ OPENSSL_EXPORT OPENSSL_DEPRECATED void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, // when certain options are turned on. OPENSSL_EXPORT OPENSSL_DEPRECATED int EVP_add_digest(const EVP_MD *digest); +// EVP_md_null is a "null" message digest that does nothing: i.e. the hash it +// returns is of zero length. Included for OpenSSL compatibility +OPENSSL_EXPORT OPENSSL_DEPRECATED const EVP_MD *EVP_md_null(void); + #if defined(__cplusplus) } // extern C diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index 2a4b6587c2e..cc2c1f362fb 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -1721,6 +1721,9 @@ OPENSSL_EXPORT int SSL_set_strict_cipher_list(SSL *ssl, const char *str); // zero on failure. OPENSSL_EXPORT int SSL_CTX_set_ciphersuites(SSL_CTX *ctx, const char *str); +// SSL_set_ciphersuites simply wraps |SSL_CTX_set_ciphersuites|. +OPENSSL_EXPORT int SSL_set_ciphersuites(SSL *ssl, const char *str); + // SSL_set_cipher_list configures the cipher list for |ssl|, evaluating |str| as // a cipher string. It returns one on success and zero on failure. // diff --git a/ssl/ssl_lib.cc b/ssl/ssl_lib.cc index 13d0050ca98..667d34a0294 100644 --- a/ssl/ssl_lib.cc +++ b/ssl/ssl_lib.cc @@ -2221,6 +2221,10 @@ int SSL_CTX_set_ciphersuites(SSL_CTX *ctx, const char *str) { true /* only configure TLSv1.3 ciphers */); } +int SSL_set_ciphersuites(SSL *ssl, const char *str) { + return SSL_CTX_set_ciphersuites(ssl->ctx.get(), str); +} + int SSL_set_strict_cipher_list(SSL *ssl, const char *str) { if (!ssl->config) { return 0; diff --git a/ssl/ssl_test.cc b/ssl/ssl_test.cc index 754412ca8e7..b3762dfe951 100644 --- a/ssl/ssl_test.cc +++ b/ssl/ssl_test.cc @@ -1316,9 +1316,12 @@ TEST(SSLTest, TLSv13CipherRules) { SCOPED_TRACE(t.rule); bssl::UniquePtr ctx(SSL_CTX_new(TLS_method())); ASSERT_TRUE(ctx); + bssl::UniquePtr ssl(SSL_new(ctx.get())); + ASSERT_TRUE(ssl); // Test lax mode. ASSERT_TRUE(SSL_CTX_set_ciphersuites(ctx.get(), t.rule)); + ASSERT_TRUE(SSL_set_ciphersuites(ssl.get(), t.rule)); EXPECT_TRUE( CipherListsEqual(ctx.get(), t.expected, true /* TLSv1.3 only */)) << "Cipher rule evaluated to:\n" @@ -1331,8 +1334,11 @@ TEST(SSLTest, TLSv13CipherRules) { SCOPED_TRACE(rule); bssl::UniquePtr ctx(SSL_CTX_new(TLS_method())); ASSERT_TRUE(ctx); + bssl::UniquePtr ssl(SSL_new(ctx.get())); + ASSERT_TRUE(ssl); EXPECT_FALSE(SSL_CTX_set_ciphersuites(ctx.get(), rule)); + EXPECT_FALSE(SSL_set_ciphersuites(ssl.get(), rule)); ERR_clear_error(); } @@ -1340,8 +1346,11 @@ TEST(SSLTest, TLSv13CipherRules) { SCOPED_TRACE(rule); bssl::UniquePtr ctx(SSL_CTX_new(TLS_method())); ASSERT_TRUE(ctx); + bssl::UniquePtr ssl(SSL_new(ctx.get())); + ASSERT_TRUE(ssl); ASSERT_TRUE(SSL_CTX_set_ciphersuites(ctx.get(), rule)); + ASSERT_TRUE(SSL_set_ciphersuites(ssl.get(), rule)); // Currenly, only three TLSv1.3 ciphers are supported. EXPECT_EQ(3u, sk_SSL_CIPHER_num(tls13_ciphers(ctx.get()))); for (const SSL_CIPHER *cipher : tls13_ciphers(ctx.get())) { @@ -1359,8 +1368,11 @@ TEST(SSLTest, TLSv13CipherRules) { SCOPED_TRACE(t.rule); bssl::UniquePtr ctx(SSL_CTX_new(TLS_method())); ASSERT_TRUE(ctx); + bssl::UniquePtr ssl(SSL_new(ctx.get())); + ASSERT_TRUE(ssl); EXPECT_FALSE(SSL_CTX_set_ciphersuites(ctx.get(), t.rule)); + EXPECT_FALSE(SSL_set_ciphersuites(ssl.get(), t.rule)); ASSERT_EQ(ERR_GET_REASON(ERR_get_error()), SSL_R_NO_CIPHER_MATCH); ERR_clear_error(); }