Commit f695571e authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

Simplify tls_construct_server_key_exchange



Use negotiated signature algorithm and certificate index in
tls_construct_key_exchange instead of recalculating it.

Reviewed-by: default avatarRich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2623)
parent f365a3e2
Loading
Loading
Loading
Loading
+58 −72
Original line number Diff line number Diff line
@@ -1996,8 +1996,7 @@ int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt)
    size_t encodedlen = 0;
    int curve_id = 0;
#endif
    EVP_PKEY *pkey;
    const EVP_MD *md = NULL;
    const SIGALG_LOOKUP *lu = s->s3->tmp.sigalg;
    int al = SSL_AD_INTERNAL_ERROR, i;
    unsigned long type;
    const BIGNUM *r[4];
@@ -2154,17 +2153,13 @@ int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt)
        goto f_err;
    }

    if (!(s->s3->tmp.new_cipher->algorithm_auth & (SSL_aNULL | SSL_aSRP))
        && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_PSK)) {
        if (s->s3->tmp.cert_idx == -1 || s->s3->tmp.sigalg == NULL) {
    if (((s->s3->tmp.new_cipher->algorithm_auth & (SSL_aNULL | SSL_aSRP)) != 0)
        || ((s->s3->tmp.new_cipher->algorithm_mkey & SSL_PSK)) != 0) {
        lu = NULL;
    } else if (lu == NULL) {
        al = SSL_AD_DECODE_ERROR;
        goto f_err;
    }
        pkey = s->cert->pkeys[s->s3->tmp.cert_idx].privatekey;
        md = ssl_md(s->s3->tmp.sigalg->hash_idx);
    } else {
        pkey = NULL;
    }

#ifndef OPENSSL_NO_PSK
    if (type & SSL_PSK) {
@@ -2253,15 +2248,23 @@ int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt)
#endif

    /* not anonymous */
    if (pkey != NULL) {
    if (lu != NULL) {
        EVP_PKEY *pkey = s->cert->pkeys[s->s3->tmp.cert_idx].privatekey;
        const EVP_MD *md = ssl_md(lu->hash_idx);
        unsigned char *sigbytes1, *sigbytes2;
        size_t siglen;

        if (pkey == NULL || md == NULL) {
            /* Should never happen */
            al = SSL_AD_INTERNAL_ERROR;
            SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
                   ERR_R_INTERNAL_ERROR);
            goto f_err;
        }
        /*
         * n is the length of the params, they start at &(d[4]) and p
         * points to the space at the end.
         */
        if (md) {
            unsigned char *sigbytes1, *sigbytes2;
            size_t siglen;
            int ispss = 0;

        /* Get length of the parameters we have written above */
        if (!WPACKET_get_length(pkt, &paramlen)) {
@@ -2270,17 +2273,8 @@ int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt)
            goto f_err;
        }
        /* send signature algorithm */
            if (SSL_USE_SIGALGS(s)) {
                if (!tls12_get_sigandhash(s, pkt, pkey, md, &ispss)) {
                    /* Should never happen */
                    SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
                           ERR_R_INTERNAL_ERROR);
                    goto f_err;
                }
            }
#ifdef SSL_DEBUG
            fprintf(stderr, "Using hash %s\n", EVP_MD_name(md));
#endif
        if (SSL_USE_SIGALGS(s) && !WPACKET_put_bytes_u16(pkt, lu->sigalg))
                return 0;
        /*
         * Create the signature. We don't know the actual length of the sig
         * until after we've created it, so we reserve enough bytes for it
@@ -2294,9 +2288,8 @@ int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt)
                   ERR_R_INTERNAL_ERROR);
            goto f_err;
        }
            if (ispss) {
                if (EVP_PKEY_CTX_set_rsa_padding(pctx,
                                                 RSA_PKCS1_PSS_PADDING) <= 0
        if (lu->sig == EVP_PKEY_RSA_PSS) {
            if (EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) <= 0
                || EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, RSA_PSS_SALTLEN_DIGEST) <= 0) {
                SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
                       ERR_R_EVP_LIB);
@@ -2317,13 +2310,6 @@ int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt)
                   ERR_R_INTERNAL_ERROR);
            goto f_err;
        }
        } else {
            /* Is this error check actually needed? */
            al = SSL_AD_HANDSHAKE_FAILURE;
            SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
                   SSL_R_UNKNOWN_PKEY_TYPE);
            goto f_err;
        }
    }

    EVP_MD_CTX_free(md_ctx);