Commit 301fcb2843 for openssl.org

commit 301fcb284328902842ff363e6ad3a4144dae928c
Author: Matt Caswell <matt@openssl.org>
Date:   Wed Oct 14 10:45:21 2020 +0100

    Concentrate deprecated libssl API usage in one file

    We create a new file ssl/tls_depr.c to contain functions that need to call
    deprecated APIs in libssl. This enables us to remove
    OPENSSL_SUPPRESS_DEPRECATED from a number of other libssl files.

    The deprecated API usage is either related to ENGINEs and is needed to
    continue to support applications that use such ENGINEs. Or they are needed
    to support some deprecated public libssl APIs.

    One other file remains in libssl that still uses deprecated APIs: s3_cbc.c
    This is needed to support the deprecated SSLv3.

    Reviewed-by: Paul Dale <paul.dale@oracle.com>
    Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org>
    (Merged from https://github.com/openssl/openssl/pull/13135)

diff --git a/ssl/build.info b/ssl/build.info
index fd9a16784e..36755819dd 100644
--- a/ssl/build.info
+++ b/ssl/build.info
@@ -33,7 +33,7 @@ SOURCE[../libssl]=\
         bio_ssl.c ssl_err.c tls_srp.c t1_trce.c ssl_utst.c \
         record/ssl3_buffer.c record/ssl3_record.c record/dtls1_bitmap.c \
         statem/statem.c record/ssl3_record_tls13.c record/tls_pad.c \
-        $KTLSSRC
+        tls_depr.c $KTLSSRC
 IF[{- !$disabled{'deprecated-3.0'} -}]
   SOURCE[../libssl]=s3_cbc.c
 ENDIF
diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c
index b8d22a72ce..984578c05b 100644
--- a/ssl/ssl_ciph.c
+++ b/ssl/ssl_ciph.c
@@ -9,9 +9,6 @@
  * https://www.openssl.org/source/license.html
  */

-/* We need to use some engine deprecated APIs */
-#define OPENSSL_SUPPRESS_DEPRECATED
-
 #include <stdio.h>
 #include <ctype.h>
 #include <openssl/objects.h>
@@ -316,7 +313,7 @@ static int get_optional_pkey_id(const char *pkey_name)
                                     ameth) <= 0)
             pkey_id = 0;
     }
-    ENGINE_finish(tmpeng);
+    tls_engine_finish(tmpeng);
     return pkey_id;
 }

diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 219d30ff24..2c6b28aacf 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -9,9 +9,6 @@
  * https://www.openssl.org/source/license.html
  */

-/* We need to use some engine deprecated APIs */
-#define OPENSSL_SUPPRESS_DEPRECATED
-
 #include <stdio.h>
 #include "ssl_local.h"
 #include "e_os.h"
@@ -3396,7 +3393,7 @@ void SSL_CTX_free(SSL_CTX *a)
     SSL_CTX_SRP_CTX_free(a);
 #endif
 #ifndef OPENSSL_NO_ENGINE
-    ENGINE_finish(a->client_cert_engine);
+    tls_engine_finish(a->client_cert_engine);
 #endif

 #ifndef OPENSSL_NO_EC
@@ -5897,23 +5894,16 @@ const EVP_CIPHER *ssl_evp_cipher_fetch(OSSL_LIB_CTX *libctx,
                                        int nid,
                                        const char *properties)
 {
-    EVP_CIPHER *ciph;
+    const EVP_CIPHER *ciph;

-#ifndef OPENSSL_NO_ENGINE
-    ENGINE *eng;
+    ciph = tls_get_cipher_from_engine(nid);
+    if (ciph != NULL)
+        return ciph;

     /*
-     * If there is an Engine available for this cipher we use the "implicit"
-     * form to ensure we use that engine later.
+     * If there is no engine cipher then we do an explicit fetch. This may fail
+     * and that could be ok
      */
-    eng = ENGINE_get_cipher_engine(nid);
-    if (eng != NULL) {
-        ENGINE_finish(eng);
-        return EVP_get_cipherbynid(nid);
-    }
-#endif
-
-    /* Otherwise we do an explicit fetch. This may fail and that could be ok */
     ERR_set_mark();
     ciph = EVP_CIPHER_fetch(libctx, OBJ_nid2sn(nid), properties);
     ERR_pop_to_mark();
@@ -5952,21 +5942,11 @@ const EVP_MD *ssl_evp_md_fetch(OSSL_LIB_CTX *libctx,
                                int nid,
                                const char *properties)
 {
-    EVP_MD *md;
+    const EVP_MD *md;

-#ifndef OPENSSL_NO_ENGINE
-    ENGINE *eng;
-
-    /*
-     * If there is an Engine available for this digest we use the "implicit"
-     * form to ensure we use that engine later.
-     */
-    eng = ENGINE_get_digest_engine(nid);
-    if (eng != NULL) {
-        ENGINE_finish(eng);
-        return EVP_get_digestbynid(nid);
-    }
-#endif
+    md = tls_get_digest_from_engine(nid);
+    if (md != NULL)
+        return md;

     /* Otherwise we do an explicit fetch */
     ERR_set_mark();
diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h
index b83cf1e1ca..5e47320d62 100644
--- a/ssl/ssl_local.h
+++ b/ssl/ssl_local.h
@@ -2827,6 +2827,17 @@ int tls_provider_set_tls_params(SSL *s, EVP_CIPHER_CTX *ctx,
                                 const EVP_CIPHER *ciph,
                                 const EVP_MD *md);

+void tls_engine_finish(ENGINE *e);
+const EVP_CIPHER *tls_get_cipher_from_engine(int nid);
+const EVP_MD *tls_get_digest_from_engine(int nid);
+int tls_engine_load_ssl_client_cert(SSL *s, X509 **px509, EVP_PKEY **ppkey);
+int ssl_hmac_old_new(SSL_HMAC *ret);
+void ssl_hmac_old_free(SSL_HMAC *ctx);
+int ssl_hmac_old_init(SSL_HMAC *ctx, void *key, size_t len, char *md);
+int ssl_hmac_old_update(SSL_HMAC *ctx, const unsigned char *data, size_t len);
+int ssl_hmac_old_final(SSL_HMAC *ctx, unsigned char *md, size_t *len);
+size_t ssl_hmac_old_size(const SSL_HMAC *ctx);
+
 # else /* OPENSSL_UNIT_TEST */

 #  define ssl_init_wbio_buffer SSL_test_functions()->p_ssl_init_wbio_buffer
diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c
index 4c4fc80023..a10b1de071 100644
--- a/ssl/ssl_sess.c
+++ b/ssl/ssl_sess.c
@@ -8,9 +8,6 @@
  * https://www.openssl.org/source/license.html
  */

-/* We need to use some engine deprecated APIs */
-#define OPENSSL_SUPPRESS_DEPRECATED
-
 #include <stdio.h>
 #include <openssl/rand.h>
 #include <openssl/engine.h>
@@ -1205,24 +1202,6 @@ int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx)) (SSL *ssl, X509 **x509,
     return ctx->client_cert_cb;
 }

-#ifndef OPENSSL_NO_ENGINE
-int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e)
-{
-    if (!ENGINE_init(e)) {
-        SSLerr(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE, ERR_R_ENGINE_LIB);
-        return 0;
-    }
-    if (!ENGINE_get_ssl_client_cert_function(e)) {
-        SSLerr(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE,
-               SSL_R_NO_CLIENT_CERT_METHOD);
-        ENGINE_finish(e);
-        return 0;
-    }
-    ctx->client_cert_engine = e;
-    return 1;
-}
-#endif
-
 void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx,
                                     int (*cb) (SSL *ssl,
                                                unsigned char *cookie,
diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c
index cb5130c713..bda6f48f46 100644
--- a/ssl/statem/statem_clnt.c
+++ b/ssl/statem/statem_clnt.c
@@ -9,9 +9,6 @@
  * https://www.openssl.org/source/license.html
  */

-/* We need to use some engine deprecated APIs */
-#define OPENSSL_SUPPRESS_DEPRECATED
-
 #include <stdio.h>
 #include <time.h>
 #include <assert.h>
@@ -3866,9 +3863,7 @@ int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey)
     int i = 0;
 #ifndef OPENSSL_NO_ENGINE
     if (s->ctx->client_cert_engine) {
-        i = ENGINE_load_ssl_client_cert(s->ctx->client_cert_engine, s,
-                                        SSL_get_client_CA_list(s),
-                                        px509, ppkey, NULL, NULL, NULL);
+        i = tls_engine_load_ssl_client_cert(s, px509, ppkey);
         if (i != 0)
             return i;
     }
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index 8005f4ee32..1971a8e0bc 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -7,9 +7,6 @@
  * https://www.openssl.org/source/license.html
  */

-/* We need access to the deprecated low level HMAC APIs */
-#define OPENSSL_SUPPRESS_DEPRECATED
-
 #include <stdio.h>
 #include <stdlib.h>
 #include <openssl/objects.h>
@@ -3387,8 +3384,7 @@ SSL_HMAC *ssl_hmac_new(const SSL_CTX *ctx)
 #ifndef OPENSSL_NO_DEPRECATED_3_0
     if (ctx->ext.ticket_key_evp_cb == NULL
             && ctx->ext.ticket_key_cb != NULL) {
-        ret->old_ctx = HMAC_CTX_new();
-        if (ret->old_ctx == NULL)
+        if (!ssl_hmac_old_new(ret))
             goto err;
         return ret;
     }
@@ -3410,19 +3406,12 @@ void ssl_hmac_free(SSL_HMAC *ctx)
     if (ctx != NULL) {
         EVP_MAC_CTX_free(ctx->ctx);
 #ifndef OPENSSL_NO_DEPRECATED_3_0
-        HMAC_CTX_free(ctx->old_ctx);
+        ssl_hmac_old_free(ctx);
 #endif
         OPENSSL_free(ctx);
     }
 }

-#ifndef OPENSSL_NO_DEPRECATED_3_0
-HMAC_CTX *ssl_hmac_get0_HMAC_CTX(SSL_HMAC *ctx)
-{
-    return ctx->old_ctx;
-}
-#endif
-
 EVP_MAC_CTX *ssl_hmac_get0_EVP_MAC_CTX(SSL_HMAC *ctx)
 {
     return ctx->ctx;
@@ -3441,8 +3430,7 @@ int ssl_hmac_init(SSL_HMAC *ctx, void *key, size_t len, char *md)
     }
 #ifndef OPENSSL_NO_DEPRECATED_3_0
     if (ctx->old_ctx != NULL)
-        return HMAC_Init_ex(ctx->old_ctx, key, len,
-                            EVP_get_digestbyname(md), NULL);
+        return ssl_hmac_old_init(ctx, key, len, md);
 #endif
     return 0;
 }
@@ -3453,7 +3441,7 @@ int ssl_hmac_update(SSL_HMAC *ctx, const unsigned char *data, size_t len)
         return EVP_MAC_update(ctx->ctx, data, len);
 #ifndef OPENSSL_NO_DEPRECATED_3_0
     if (ctx->old_ctx != NULL)
-        return HMAC_Update(ctx->old_ctx, data, len);
+        return ssl_hmac_old_update(ctx, data, len);
 #endif
     return 0;
 }
@@ -3464,15 +3452,8 @@ int ssl_hmac_final(SSL_HMAC *ctx, unsigned char *md, size_t *len,
     if (ctx->ctx != NULL)
         return EVP_MAC_final(ctx->ctx, md, len, max_size);
 #ifndef OPENSSL_NO_DEPRECATED_3_0
-    if (ctx->old_ctx != NULL) {
-        unsigned int l;
-
-        if (HMAC_Final(ctx->old_ctx, md, &l) > 0) {
-            if (len != NULL)
-                *len = l;
-            return 1;
-        }
-    }
+    if (ctx->old_ctx != NULL)
+        return ssl_hmac_old_final(ctx, md, len);
 #endif
     return 0;
 }
@@ -3483,7 +3464,7 @@ size_t ssl_hmac_size(const SSL_HMAC *ctx)
         return EVP_MAC_size(ctx->ctx);
 #ifndef OPENSSL_NO_DEPRECATED_3_0
     if (ctx->old_ctx != NULL)
-        return HMAC_size(ctx->old_ctx);
+        return ssl_hmac_old_size(ctx);
 #endif
     return 0;
 }
diff --git a/ssl/tls_depr.c b/ssl/tls_depr.c
new file mode 100644
index 0000000000..df630915d0
--- /dev/null
+++ b/ssl/tls_depr.c
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/* We need to use some engine and HMAC deprecated APIs */
+#define OPENSSL_SUPPRESS_DEPRECATED
+
+#include <openssl/engine.h>
+#include "ssl_local.h"
+
+/*
+ * Engine APIs are only used to support applications that still use ENGINEs.
+ * Once ENGINE is removed completely, all of this code can also be removed.
+ */
+
+#ifndef OPENSSL_NO_ENGINE
+void tls_engine_finish(ENGINE *e)
+{
+    ENGINE_finish(e);
+}
+#endif
+
+const EVP_CIPHER *tls_get_cipher_from_engine(int nid)
+{
+#ifndef OPENSSL_NO_ENGINE
+    ENGINE *eng;
+
+    /*
+     * If there is an Engine available for this cipher we use the "implicit"
+     * form to ensure we use that engine later.
+     */
+    eng = ENGINE_get_cipher_engine(nid);
+    if (eng != NULL) {
+        ENGINE_finish(eng);
+        return EVP_get_cipherbynid(nid);
+    }
+#endif
+    return NULL;
+}
+
+const EVP_MD *tls_get_digest_from_engine(int nid)
+{
+#ifndef OPENSSL_NO_ENGINE
+    ENGINE *eng;
+
+    /*
+     * If there is an Engine available for this digest we use the "implicit"
+     * form to ensure we use that engine later.
+     */
+    eng = ENGINE_get_digest_engine(nid);
+    if (eng != NULL) {
+        ENGINE_finish(eng);
+        return EVP_get_digestbynid(nid);
+    }
+#endif
+    return NULL;
+}
+
+#ifndef OPENSSL_NO_ENGINE
+int tls_engine_load_ssl_client_cert(SSL *s, X509 **px509, EVP_PKEY **ppkey)
+{
+    return ENGINE_load_ssl_client_cert(s->ctx->client_cert_engine, s,
+                                       SSL_get_client_CA_list(s),
+                                       px509, ppkey, NULL, NULL, NULL);
+}
+#endif
+
+#ifndef OPENSSL_NO_ENGINE
+int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e)
+{
+    if (!ENGINE_init(e)) {
+        SSLerr(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE, ERR_R_ENGINE_LIB);
+        return 0;
+    }
+    if (!ENGINE_get_ssl_client_cert_function(e)) {
+        SSLerr(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE,
+               SSL_R_NO_CLIENT_CERT_METHOD);
+        ENGINE_finish(e);
+        return 0;
+    }
+    ctx->client_cert_engine = e;
+    return 1;
+}
+#endif
+
+/*
+ * The HMAC APIs below are only used to support the deprecated public API
+ * macro SSL_CTX_set_tlsext_ticket_key_cb(). The application supplied callback
+ * takes an HMAC_CTX in its argument list. The preferred alternative is
+ * SSL_CTX_set_tlsext_ticket_key_evp_cb(). Once
+ * SSL_CTX_set_tlsext_ticket_key_cb() is removed, then all of this code can also
+ * be removed.
+ */
+#ifndef OPENSSL_NO_DEPRECATED_3_0
+int ssl_hmac_old_new(SSL_HMAC *ret)
+{
+    ret->old_ctx = HMAC_CTX_new();
+    if (ret->old_ctx == NULL)
+        return 0;
+
+    return 1;
+}
+
+void ssl_hmac_old_free(SSL_HMAC *ctx)
+{
+    HMAC_CTX_free(ctx->old_ctx);
+}
+
+int ssl_hmac_old_init(SSL_HMAC *ctx, void *key, size_t len, char *md)
+{
+    return HMAC_Init_ex(ctx->old_ctx, key, len, EVP_get_digestbyname(md), NULL);
+}
+
+int ssl_hmac_old_update(SSL_HMAC *ctx, const unsigned char *data, size_t len)
+{
+    return HMAC_Update(ctx->old_ctx, data, len);
+}
+
+int ssl_hmac_old_final(SSL_HMAC *ctx, unsigned char *md, size_t *len)
+{
+    unsigned int l;
+
+    if (HMAC_Final(ctx->old_ctx, md, &l) > 0) {
+        if (len != NULL)
+            *len = l;
+        return 1;
+    }
+
+    return 0;
+}
+
+size_t ssl_hmac_old_size(const SSL_HMAC *ctx)
+{
+    return HMAC_size(ctx->old_ctx);
+}
+
+HMAC_CTX *ssl_hmac_get0_HMAC_CTX(SSL_HMAC *ctx)
+{
+    return ctx->old_ctx;
+}
+#endif
+