Adapt HMAC to the EVP_MD_CTX changes
[openssl.git] / ssl / statem / statem_srvr.c
index 0689da0d3e94848e3ea3f10235acc8e8c8514d43..09718c5080b506194b1c3145356f1c357acb98da 100644 (file)
@@ -315,7 +315,7 @@ static int send_server_key_exchange(SSL *s)
     unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
 
     /*
-     * only send a ServerKeyExchange if DH, fortezza or RSA but we have a
+     * only send a ServerKeyExchange if DH or fortezza but we have a
      * sign only certificate PSK: may send PSK identity hints For
      * ECC ciphersuites, we send a serverKeyExchange message only if
      * the cipher suite is either ECDH-anon or ECDHE. In other cases,
@@ -324,15 +324,6 @@ static int send_server_key_exchange(SSL *s)
      */
     if (   (alg_k & SSL_kDHE)
         || (alg_k & SSL_kECDHE)
-        || ((alg_k & SSL_kRSA)
-            && (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL
-                || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher)
-                    && EVP_PKEY_size(s->cert->pkeys
-                                     [SSL_PKEY_RSA_ENC].privatekey) *
-                    8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)
-                   )
-               )
-           )
         /*
          * PSK: send ServerKeyExchange if PSK identity hint if
          * provided
@@ -868,10 +859,10 @@ WORK_STATE ossl_statem_server_post_process_message(SSL *s, WORK_STATE wst)
             s->rwstate = SSL_READING;
             BIO_clear_retry_flags(SSL_get_rbio(s));
             BIO_set_retry_read(SSL_get_rbio(s));
-            statem_set_sctp_read_sock(s, 1);
+            ossl_statem_set_sctp_read_sock(s, 1);
             return WORK_MORE_A;
         } else {
-            ossl_ossl_statem_set_sctp_read_sock(s, 0);
+            ossl_statem_set_sctp_read_sock(s, 0);
         }
 #endif
         return WORK_FINISHED_CONTINUE;
@@ -1550,7 +1541,7 @@ WORK_STATE tls_post_process_client_hello(SSL *s, WORK_STATE wst)
             s->s3->tmp.new_cipher = s->session->cipher;
         }
 
-        if (!SSL_USE_SIGALGS(s) || !(s->verify_mode & SSL_VERIFY_PEER)) {
+        if (!(s->verify_mode & SSL_VERIFY_PEER)) {
             if (!ssl3_digest_cached_records(s, 0)) {
                 al = SSL_AD_INTERNAL_ERROR;
                 goto f_err;
@@ -1723,18 +1714,10 @@ int tls_construct_server_done(SSL *s)
 
 int tls_construct_server_key_exchange(SSL *s)
 {
-#ifndef OPENSSL_NO_RSA
-    unsigned char *q;
-    int j, num;
-    RSA *rsa;
-    unsigned char md_buf[MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH];
-    unsigned int u;
-#endif
 #ifndef OPENSSL_NO_DH
     DH *dh = NULL, *dhp;
 #endif
 #ifndef OPENSSL_NO_EC
-    EC_KEY *ecdh = NULL, *ecdhp;
     unsigned char *encodedPoint = NULL;
     int encodedlen = 0;
     int curve_id = 0;
@@ -1774,35 +1757,6 @@ int tls_construct_server_key_exchange(SSL *s)
     if (type & (SSL_kPSK | SSL_kRSAPSK)) {
     } else
 #endif                          /* !OPENSSL_NO_PSK */
-#ifndef OPENSSL_NO_RSA
-    if (type & SSL_kRSA) {
-        rsa = cert->rsa_tmp;
-        if ((rsa == NULL) && (s->cert->rsa_tmp_cb != NULL)) {
-            rsa = s->cert->rsa_tmp_cb(s,
-                                      SSL_C_IS_EXPORT(s->s3->
-                                                      tmp.new_cipher),
-                                      SSL_C_EXPORT_PKEYLENGTH(s->s3->
-                                                              tmp.new_cipher));
-            if (rsa == NULL) {
-                al = SSL_AD_HANDSHAKE_FAILURE;
-                SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
-                       SSL_R_ERROR_GENERATING_TMP_RSA_KEY);
-                goto f_err;
-            }
-            RSA_up_ref(rsa);
-            cert->rsa_tmp = rsa;
-        }
-        if (rsa == NULL) {
-            al = SSL_AD_HANDSHAKE_FAILURE;
-            SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
-                   SSL_R_MISSING_TMP_RSA_KEY);
-            goto f_err;
-        }
-        r[0] = rsa->n;
-        r[1] = rsa->e;
-        s->s3->tmp.use_rsa_tmp = 1;
-    } else
-#endif
 #ifndef OPENSSL_NO_DH
     if (type & (SSL_kDHE | SSL_kDHEPSK)) {
         if (s->cert->dh_tmp_auto) {
@@ -1816,11 +1770,7 @@ int tls_construct_server_key_exchange(SSL *s)
         } else
             dhp = cert->dh_tmp;
         if ((dhp == NULL) && (s->cert->dh_tmp_cb != NULL))
-            dhp = s->cert->dh_tmp_cb(s,
-                                     SSL_C_IS_EXPORT(s->s3->
-                                                     tmp.new_cipher),
-                                     SSL_C_EXPORT_PKEYLENGTH(s->s3->
-                                                             tmp.new_cipher));
+            dhp = s->cert->dh_tmp_cb(s, 0, 1024);
         if (dhp == NULL) {
             al = SSL_AD_HANDSHAKE_FAILURE;
             SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
@@ -1871,21 +1821,13 @@ int tls_construct_server_key_exchange(SSL *s)
 #ifndef OPENSSL_NO_EC
     if (type & (SSL_kECDHE | SSL_kECDHEPSK)) {
         const EC_GROUP *group;
+        EC_KEY *ecdh = NULL;
 
-        ecdhp = cert->ecdh_tmp;
-        if (s->cert->ecdh_tmp_auto) {
-            /* Get NID of appropriate shared curve */
-            int nid = tls1_shared_curve(s, -2);
-            if (nid != NID_undef)
-                ecdhp = EC_KEY_new_by_curve_name(nid);
-        } else if ((ecdhp == NULL) && s->cert->ecdh_tmp_cb) {
-            ecdhp = s->cert->ecdh_tmp_cb(s,
-                                         SSL_C_IS_EXPORT(s->s3->
-                                                         tmp.new_cipher),
-                                         SSL_C_EXPORT_PKEYLENGTH(s->
-                                                                 s3->tmp.new_cipher));
-        }
-        if (ecdhp == NULL) {
+        /* Get NID of appropriate shared curve */
+        int nid = tls1_shared_curve(s, -2);
+        if (nid != NID_undef)
+            ecdh = EC_KEY_new_by_curve_name(nid);
+        if (ecdh == NULL) {
             al = SSL_AD_HANDSHAKE_FAILURE;
             SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
                    SSL_R_MISSING_TMP_ECDH_KEY);
@@ -1898,18 +1840,6 @@ int tls_construct_server_key_exchange(SSL *s)
             goto err;
         }
 
-        /* Duplicate the ECDH structure. */
-        if (ecdhp == NULL) {
-            SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB);
-            goto err;
-        }
-        if (s->cert->ecdh_tmp_auto)
-            ecdh = ecdhp;
-        else if ((ecdh = EC_KEY_dup(ecdhp)) == NULL) {
-            SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB);
-            goto err;
-        }
-
         s->s3->tmp.ecdh = ecdh;
         if ((EC_KEY_get0_public_key(ecdh) == NULL) ||
             (EC_KEY_get0_private_key(ecdh) == NULL) ||
@@ -1928,13 +1858,6 @@ int tls_construct_server_key_exchange(SSL *s)
             goto err;
         }
 
-        if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) &&
-            (EC_GROUP_get_degree(group) > 163)) {
-            SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
-                   SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER);
-            goto err;
-        }
-
         /*
          * XXX: For now, we only support ephemeral ECDH keys over named
          * (not generic) curves. For supported named curves, curve_id is
@@ -2102,33 +2025,6 @@ int tls_construct_server_key_exchange(SSL *s)
          * n is the length of the params, they start at &(d[4]) and p
          * points to the space at the end.
          */
-#ifndef OPENSSL_NO_RSA
-        if (pkey->type == EVP_PKEY_RSA && !SSL_USE_SIGALGS(s)) {
-            q = md_buf;
-            j = 0;
-            for (num = 2; num > 0; num--) {
-                EVP_MD_CTX_set_flags(&md_ctx,
-                                     EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
-                EVP_DigestInit_ex(&md_ctx, (num == 2)
-                                  ? s->ctx->md5 : s->ctx->sha1, NULL);
-                EVP_DigestUpdate(&md_ctx, &(s->s3->client_random[0]),
-                                 SSL3_RANDOM_SIZE);
-                EVP_DigestUpdate(&md_ctx, &(s->s3->server_random[0]),
-                                 SSL3_RANDOM_SIZE);
-                EVP_DigestUpdate(&md_ctx, d, n);
-                EVP_DigestFinal_ex(&md_ctx, q, (unsigned int *)&i);
-                q += i;
-                j += i;
-            }
-            if (RSA_sign(NID_md5_sha1, md_buf, j,
-                         &(p[2]), &u, pkey->pkey.rsa) <= 0) {
-                SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_LIB_RSA);
-                goto err;
-            }
-            s2n(u, p);
-            n += u + 2;
-        } else
-#endif
         if (md) {
             /* send signature algorithm */
             if (SSL_USE_SIGALGS(s)) {
@@ -2144,16 +2040,17 @@ int tls_construct_server_key_exchange(SSL *s)
 #ifdef SSL_DEBUG
             fprintf(stderr, "Using hash %s\n", EVP_MD_name(md));
 #endif
-            EVP_SignInit_ex(&md_ctx, md, NULL);
-            EVP_SignUpdate(&md_ctx, &(s->s3->client_random[0]),
-                           SSL3_RANDOM_SIZE);
-            EVP_SignUpdate(&md_ctx, &(s->s3->server_random[0]),
-                           SSL3_RANDOM_SIZE);
-            EVP_SignUpdate(&md_ctx, d, n);
-            if (!EVP_SignFinal(&md_ctx, &(p[2]),
-                               (unsigned int *)&i, pkey)) {
+            if (EVP_SignInit_ex(&md_ctx, md, NULL) <= 0
+                    || EVP_SignUpdate(&md_ctx, &(s->s3->client_random[0]),
+                                      SSL3_RANDOM_SIZE) <= 0
+                    || EVP_SignUpdate(&md_ctx, &(s->s3->server_random[0]),
+                                      SSL3_RANDOM_SIZE) <= 0
+                    || EVP_SignUpdate(&md_ctx, d, n) <= 0
+                    || EVP_SignFinal(&md_ctx, &(p[2]),
+                               (unsigned int *)&i, pkey) <= 0) {
                 SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_LIB_EVP);
-                goto err;
+                al = SSL_AD_INTERNAL_ERROR;
+                goto f_err;
             }
             s2n(i, p);
             n += i + 2;
@@ -2367,30 +2264,15 @@ MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt)
         size_t j;
 
         /* FIX THIS UP EAY EAY EAY EAY */
-        if (s->s3->tmp.use_rsa_tmp) {
-            if ((s->cert != NULL) && (s->cert->rsa_tmp != NULL))
-                rsa = s->cert->rsa_tmp;
-            /*
-             * Don't do a callback because rsa_tmp should be sent already
-             */
-            if (rsa == NULL) {
-                al = SSL_AD_HANDSHAKE_FAILURE;
-                SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
-                       SSL_R_MISSING_TMP_RSA_PKEY);
-                goto f_err;
-
-            }
-        } else {
-            pkey = s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey;
-            if ((pkey == NULL) ||
-                (pkey->type != EVP_PKEY_RSA) || (pkey->pkey.rsa == NULL)) {
-                al = SSL_AD_HANDSHAKE_FAILURE;
-                SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
-                       SSL_R_MISSING_RSA_CERTIFICATE);
-                goto f_err;
-            }
-            rsa = pkey->pkey.rsa;
+        pkey = s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey;
+        if ((pkey == NULL) ||
+            (pkey->type != EVP_PKEY_RSA) || (pkey->pkey.rsa == NULL)) {
+            al = SSL_AD_HANDSHAKE_FAILURE;
+            SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
+                   SSL_R_MISSING_RSA_CERTIFICATE);
+            goto f_err;
         }
+        rsa = pkey->pkey.rsa;
 
         /* SSLv3 and pre-standard DTLS omit the length bytes. */
         if (s->version == SSL3_VERSION || s->version == DTLS1_BAD_VER) {
@@ -2791,6 +2673,7 @@ MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt)
         }
     } else
 #endif                          /* OPENSSL_NO_SRP */
+#ifndef OPENSSL_NO_GOST
     if (alg_k & SSL_kGOST) {
         EVP_PKEY_CTX *pkey_ctx;
         EVP_PKEY *client_pub_pkey = NULL, *pk = NULL;
@@ -2803,11 +2686,32 @@ MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt)
 
         /* Get our certificate private key */
         alg_a = s->s3->tmp.new_cipher->algorithm_auth;
-        if (alg_a & SSL_aGOST01)
+        if (alg_a & SSL_aGOST12) {
+            /*
+             * New GOST ciphersuites have SSL_aGOST01 bit too
+             */
+            pk = s->cert->pkeys[SSL_PKEY_GOST12_512].privatekey;
+            if (pk == NULL) {
+                pk = s->cert->pkeys[SSL_PKEY_GOST12_256].privatekey;
+            }
+            if (pk == NULL) {
+                pk = s->cert->pkeys[SSL_PKEY_GOST01].privatekey;
+            }
+        } else if (alg_a & SSL_aGOST01) {
             pk = s->cert->pkeys[SSL_PKEY_GOST01].privatekey;
+        }
 
         pkey_ctx = EVP_PKEY_CTX_new(pk, NULL);
-        EVP_PKEY_decrypt_init(pkey_ctx);
+        if (pkey_ctx == NULL) {
+            al = SSL_AD_INTERNAL_ERROR;
+            SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
+            goto f_err;
+        }
+        if (EVP_PKEY_decrypt_init(pkey_ctx) <= 0) {
+            al = SSL_AD_INTERNAL_ERROR;
+            SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
+            goto f_err;
+        }
         /*
          * If client certificate is present and is of the same type, maybe
          * use it for key exchange.  Don't mind errors from
@@ -2824,12 +2728,13 @@ MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt)
         if (!PACKET_get_bytes(pkt, &data, sess_key_len)) {
             al = SSL_AD_INTERNAL_ERROR;
             SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
-            goto f_err;
+            goto gerr;
         }
         if (ASN1_get_object ((const unsigned char **)&data, &Tlen, &Ttag,
                              &Tclass, sess_key_len) != V_ASN1_CONSTRUCTED
             || Ttag != V_ASN1_SEQUENCE
             || Tclass != V_ASN1_UNIVERSAL) {
+            al = SSL_AD_DECODE_ERROR;
             SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
                    SSL_R_DECRYPTION_FAILED);
             goto gerr;
@@ -2838,6 +2743,7 @@ MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt)
         inlen = Tlen;
         if (EVP_PKEY_decrypt
             (pkey_ctx, premaster_secret, &outlen, start, inlen) <= 0) {
+            al = SSL_AD_DECODE_ERROR;
             SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE,
                    SSL_R_DECRYPTION_FAILED);
             goto gerr;
@@ -2847,7 +2753,7 @@ MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt)
                                         sizeof(premaster_secret), 0)) {
             al = SSL_AD_INTERNAL_ERROR;
             SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
-            goto f_err;
+            goto gerr;
         }
         /* Check if pubkey from client certificate was used */
         if (EVP_PKEY_CTX_ctrl
@@ -2860,8 +2766,10 @@ MSG_PROCESS_RETURN tls_process_client_key_exchange(SSL *s, PACKET *pkt)
  gerr:
         EVP_PKEY_free(client_pub_pkey);
         EVP_PKEY_CTX_free(pkey_ctx);
-        goto err;
-    } else {
+        goto f_err;
+    } else
+#endif
+    {
         al = SSL_AD_HANDSHAKE_FAILURE;
         SSLerr(SSL_F_TLS_PROCESS_CLIENT_KEY_EXCHANGE, SSL_R_UNKNOWN_CIPHER_TYPE);
         goto f_err;
@@ -2927,7 +2835,7 @@ WORK_STATE tls_post_process_client_key_exchange(SSL *s, WORK_STATE wst)
         s->rwstate = SSL_READING;
         BIO_clear_retry_flags(SSL_get_rbio(s));
         BIO_set_retry_read(SSL_get_rbio(s));
-        statem_set_sctp_read_sock(s, 1);
+        ossl_statem_set_sctp_read_sock(s, 1);
         return WORK_MORE_B;
     } else {
         ossl_statem_set_sctp_read_sock(s, 0);
@@ -2937,8 +2845,9 @@ WORK_STATE tls_post_process_client_key_exchange(SSL *s, WORK_STATE wst)
     if (s->statem.no_cert_verify) {
         /* No certificate verify so we no longer need the handshake_buffer */
         BIO_free(s->s3->handshake_buffer);
+        s->s3->handshake_buffer = NULL;
         return WORK_FINISHED_CONTINUE;
-    } else if (SSL_USE_SIGALGS(s)) {
+    } else {
         if (!s->session->peer) {
             /* No peer certificate so we no longer need the handshake_buffer */
             BIO_free(s->s3->handshake_buffer);
@@ -2958,41 +2867,6 @@ WORK_STATE tls_post_process_client_key_exchange(SSL *s, WORK_STATE wst)
             ossl_statem_set_error(s);
             return WORK_ERROR;
         }
-    } else {
-        int offset = 0;
-        int dgst_num;
-
-        /*
-         * We need to get hashes here so if there is a client cert,
-         * it can be verified FIXME - digest processing for
-         * CertificateVerify should be generalized. But it is next
-         * step
-         */
-        if (!ssl3_digest_cached_records(s, 0)) {
-            ossl_statem_set_error(s);
-            return WORK_ERROR;
-        }
-        for (dgst_num = 0; dgst_num < SSL_MAX_DIGEST; dgst_num++) {
-            if (s->s3->handshake_dgst[dgst_num]) {
-                int dgst_size;
-
-                s->method->ssl3_enc->cert_verify_mac(s,
-                                                     EVP_MD_CTX_type
-                                                     (s->
-                                                      s3->handshake_dgst
-                                                      [dgst_num]),
-                                                     &(s->s3->
-                                                       tmp.cert_verify_md
-                                                       [offset]));
-                dgst_size =
-                    EVP_MD_CTX_size(s->s3->handshake_dgst[dgst_num]);
-                if (dgst_size < 0) {
-                    ossl_statem_set_error(s);
-                return WORK_ERROR;
-                }
-                offset += dgst_size;
-            }
-        }
     }
 
     return WORK_FINISHED_CONTINUE;
@@ -3003,10 +2877,13 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt)
     EVP_PKEY *pkey = NULL;
     unsigned char *sig, *data;
     int al, ret = MSG_PROCESS_ERROR;
-    int type = 0, i, j;
+    int type = 0, j;
     unsigned int len;
     X509 *peer;
     const EVP_MD *md = NULL;
+    long hdatalen = 0;
+    void *hdata;
+
     EVP_MD_CTX mctx;
     EVP_MD_CTX_init(&mctx);
 
@@ -3024,11 +2901,14 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt)
     /* Check for broken implementations of GOST ciphersuites */
     /*
      * If key is GOST and n is exactly 64, it is bare signature without
-     * length field
+     * length field (CryptoPro implementations at least till CSP 4.0)
      */
+#ifndef OPENSSL_NO_GOST
     if (PACKET_remaining(pkt) == 64 && pkey->type == NID_id_GostR3410_2001) {
         len = 64;
-    } else {
+    } else
+#endif
+    {
         if (SSL_USE_SIGALGS(s)) {
             int rv;
 
@@ -3047,7 +2927,17 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt)
 #ifdef SSL_DEBUG
             fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
 #endif
+        } else {
+            /* Use default digest for this key type */
+            int idx = ssl_cert_type(NULL, pkey);
+            if (idx >= 0)
+                md = s->s3->tmp.md[idx];
+            if (md == NULL) {
+                al = SSL_AD_INTERNAL_ERROR;
+                goto f_err;
+            }
         }
+
         if (!PACKET_get_net_2(pkt, &len)) {
             SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_LENGTH_MISMATCH);
             al = SSL_AD_DECODE_ERROR;
@@ -3067,97 +2957,42 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt)
         goto f_err;
     }
 
-    if (SSL_USE_SIGALGS(s)) {
-        long hdatalen = 0;
-        void *hdata;
-        hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata);
-        if (hdatalen <= 0) {
-            SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_INTERNAL_ERROR);
-            al = SSL_AD_INTERNAL_ERROR;
-            goto f_err;
-        }
+    hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata);
+    if (hdatalen <= 0) {
+        SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_INTERNAL_ERROR);
+        al = SSL_AD_INTERNAL_ERROR;
+        goto f_err;
+    }
 #ifdef SSL_DEBUG
-        fprintf(stderr, "Using TLS 1.2 with client verify alg %s\n",
-                EVP_MD_name(md));
+    fprintf(stderr, "Using client verify alg %s\n", EVP_MD_name(md));
 #endif
-        if (!EVP_VerifyInit_ex(&mctx, md, NULL)
-            || !EVP_VerifyUpdate(&mctx, hdata, hdatalen)) {
-            SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_EVP_LIB);
-            al = SSL_AD_INTERNAL_ERROR;
-            goto f_err;
-        }
+    if (!EVP_VerifyInit_ex(&mctx, md, NULL)
+        || !EVP_VerifyUpdate(&mctx, hdata, hdatalen)) {
+        SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_EVP_LIB);
+        al = SSL_AD_INTERNAL_ERROR;
+        goto f_err;
+    }
 
-        if (EVP_VerifyFinal(&mctx, data, len, pkey) <= 0) {
-            al = SSL_AD_DECRYPT_ERROR;
-            SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_BAD_SIGNATURE);
-            goto f_err;
-        }
-    } else
-#ifndef OPENSSL_NO_RSA
-    if (pkey->type == EVP_PKEY_RSA) {
-        i = RSA_verify(NID_md5_sha1, s->s3->tmp.cert_verify_md,
-                       MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, data, len,
-                       pkey->pkey.rsa);
-        if (i < 0) {
-            al = SSL_AD_DECRYPT_ERROR;
-            SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_BAD_RSA_DECRYPT);
-            goto f_err;
-        }
-        if (i == 0) {
-            al = SSL_AD_DECRYPT_ERROR;
-            SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_BAD_RSA_SIGNATURE);
-            goto f_err;
-        }
-    } else
-#endif
-#ifndef OPENSSL_NO_DSA
-    if (pkey->type == EVP_PKEY_DSA) {
-        j = DSA_verify(pkey->save_type,
-                       &(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]),
-                       SHA_DIGEST_LENGTH, data, len, pkey->pkey.dsa);
-        if (j <= 0) {
-            /* bad signature */
-            al = SSL_AD_DECRYPT_ERROR;
-            SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_BAD_DSA_SIGNATURE);
-            goto f_err;
-        }
-    } else
-#endif
-#ifndef OPENSSL_NO_EC
-    if (pkey->type == EVP_PKEY_EC) {
-        j = ECDSA_verify(pkey->save_type,
-                         &(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]),
-                         SHA_DIGEST_LENGTH, data, len, pkey->pkey.ec);
-        if (j <= 0) {
-            /* bad signature */
-            al = SSL_AD_DECRYPT_ERROR;
-            SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_BAD_ECDSA_SIGNATURE);
-            goto f_err;
-        }
-    } else
+#ifndef OPENSSL_NO_GOST
+    if (pkey->type == NID_id_GostR3410_2001
+            || pkey->type == NID_id_GostR3410_2012_256
+            || pkey->type == NID_id_GostR3410_2012_512) {
+        BUF_reverse(data, NULL, len);
+    }
 #endif
-    if (pkey->type == NID_id_GostR3410_2001) {
-        unsigned char signature[64];
-        int idx;
-        EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new(pkey, NULL);
-        EVP_PKEY_verify_init(pctx);
-        if (len != 64) {
-            fprintf(stderr, "GOST signature length is %d", len);
-        }
-        for (idx = 0; idx < 64; idx++) {
-            signature[63 - idx] = data[idx];
-        }
-        j = EVP_PKEY_verify(pctx, signature, 64, s->s3->tmp.cert_verify_md,
-                            32);
-        EVP_PKEY_CTX_free(pctx);
-        if (j <= 0) {
-            al = SSL_AD_DECRYPT_ERROR;
-            SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_BAD_ECDSA_SIGNATURE);
-            goto f_err;
-        }
-    } else {
-        SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_INTERNAL_ERROR);
-        al = SSL_AD_UNSUPPORTED_CERTIFICATE;
+
+    if (s->version == SSL3_VERSION
+        && !EVP_MD_CTX_ctrl(&mctx, EVP_CTRL_SSL3_MASTER_SECRET,
+                            s->session->master_key_length,
+                            s->session->master_key)) {
+        SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, ERR_R_EVP_LIB);
+        al = SSL_AD_INTERNAL_ERROR;
+        goto f_err;
+    }
+
+    if (EVP_VerifyFinal(&mctx, data, len, pkey) <= 0) {
+        al = SSL_AD_DECRYPT_ERROR;
+        SSLerr(SSL_F_TLS_PROCESS_CERT_VERIFY, SSL_R_BAD_SIGNATURE);
         goto f_err;
     }
 
@@ -3316,7 +3151,7 @@ int tls_construct_new_session_ticket(SSL *s)
 {
     unsigned char *senc = NULL;
     EVP_CIPHER_CTX ctx;
-    HMAC_CTX hctx;
+    HMAC_CTX hctx = HMAC_CTX_EMPTY;
     unsigned char *p, *macstart;
     const unsigned char *const_p;
     int len, slen_full, slen;
@@ -3337,7 +3172,7 @@ int tls_construct_new_session_ticket(SSL *s)
         return 0;
     }
     senc = OPENSSL_malloc(slen_full);
-    if (!senc) {
+    if (senc == NULL) {
         ossl_statem_set_error(s);
         return 0;
     }