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

Use EVP_md5_sha1() to generate client verify



Reviewed-by: default avatarTim Hudson <tjh@openssl.org>
parent 396d5fd0
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -2069,6 +2069,7 @@ __owur unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
__owur unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
                                          unsigned char *limit, int *al);
__owur int ssl_parse_clienthello_tlsext(SSL *s, PACKET *pkt);
void ssl_set_default_md(SSL *s);
__owur int tls1_set_server_sigalgs(SSL *s);
__owur int ssl_check_clienthello_tlsext_late(SSL *s);
__owur int ssl_parse_serverhello_tlsext(SSL *s, PACKET *pkt);
+37 −140
Original line number Diff line number Diff line
@@ -1361,15 +1361,6 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL *s, PACKET *pkt)
        goto f_err;
    }
    s->s3->tmp.new_cipher = c;
    /*
     * Don't digest cached records if no sigalgs: we may need them for client
     * authentication.
     */
    if (!(SSL_USE_SIGALGS(s)
            || (s->s3->tmp.new_cipher->algorithm_auth
                & (SSL_aGOST12|SSL_aGOST01)))
            && !ssl3_digest_cached_records(s, 0))
        goto f_err;
    /* lets get the compression algorithm */
    /* COMPRESSION */
    if (!PACKET_get_1(pkt, &compression)) {
@@ -2075,6 +2066,8 @@ MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, PACKET *pkt)
            SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, ERR_R_MALLOC_FAILURE);
            goto err;
        }
    } else {
        ssl_set_default_md(s);
    }

    /* get the CA RDNs */
@@ -2967,70 +2960,40 @@ int tls_client_key_exchange_post_work(SSL *s)
int tls_construct_client_verify(SSL *s)
{
    unsigned char *p;
    unsigned char data[EVP_MAX_MD_SIZE]; /* GOST R 34.11-2012-256*/
    EVP_PKEY *pkey;
    EVP_PKEY_CTX *pctx = NULL;
    const EVP_MD *md = s->s3->tmp.md[s->cert->key - s->cert->pkeys];
    EVP_MD_CTX mctx;
    unsigned u = 0;
    unsigned long n;
    int j;
    long hdatalen = 0;
    void *hdata;

    EVP_MD_CTX_init(&mctx);

    p = ssl_handshake_start(s);
    pkey = s->cert->key->privatekey;
    /* Create context from key and test if sha1 is allowed as digest */
    pctx = EVP_PKEY_CTX_new(pkey, NULL);
    if (pctx == NULL) {
        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_MALLOC_FAILURE);
        goto err;
    }
    if (EVP_PKEY_sign_init(pctx) <= 0) {
        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR);
        goto err;
    }
    if (EVP_PKEY_CTX_set_signature_md(pctx, EVP_sha1()) > 0) {
        if (!SSL_USE_SIGALGS(s))
            s->method->ssl3_enc->cert_verify_mac(s,
                                                 NID_sha1,
                                                 &(data
                                                   [MD5_DIGEST_LENGTH]));
    } else {
        ERR_clear_error();
    }

    /*
     * For TLS v1.2 send signature algorithm and signature using agreed
     * digest and cached handshake records.
     */
    if (SSL_USE_SIGALGS(s) || pkey->type == NID_id_GostR3410_2001
                || pkey->type == NID_id_GostR3410_2012_256
                || pkey->type == NID_id_GostR3410_2012_512) {
        long hdatalen = 0;
        void *hdata;
        const EVP_MD *md = s->s3->tmp.md[s->cert->key - s->cert->pkeys];
    hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata);
        if (!SSL_USE_SIGALGS(s)) {
                int dgst_nid;
                if (EVP_PKEY_get_default_digest_nid(pkey, &dgst_nid) <= 0
                                || (md = EVP_get_digestbynid(dgst_nid)) == NULL) {
    if (hdatalen <= 0) {
        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR);
        goto err;
    }
        }
        if (hdatalen <= 0 || !tls12_get_sigandhash(p, pkey, md)) {
    if (SSL_USE_SIGALGS(s)) {
        if (!tls12_get_sigandhash(p, pkey, md)) {
            SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR);
            goto err;
        }
        if (SSL_USE_SIGALGS(s) ) {
        p += 2;
    }
#ifdef SSL_DEBUG
        fprintf(stderr, "Using TLS 1.2 with client alg %s\n",
                EVP_MD_name(md));
    fprintf(stderr, "Using client alg %s\n", EVP_MD_name(md));
#endif
    if (!EVP_SignInit_ex(&mctx, md, NULL)
        || !EVP_SignUpdate(&mctx, hdata, hdatalen)
        || (s->version == SSL3_VERSION
            && !EVP_MD_CTX_ctrl(&mctx, EVP_CTRL_SSL3_MASTER_SECRET,
                                s->session->master_key_length,
                                s->session->master_key))
        || !EVP_SignFinal(&mctx, p + 2, &u, pkey)) {
        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_EVP_LIB);
        goto err;
@@ -3045,6 +3008,7 @@ int tls_construct_client_verify(SSL *s)
            p[2 + i] = c;
        }
    }

    s2n(u, p);
    n = u + 2;
    if (SSL_USE_SIGALGS(s))
@@ -3052,82 +3016,15 @@ int tls_construct_client_verify(SSL *s)
    /* Digest cached records and discard handshake buffer */
    if (!ssl3_digest_cached_records(s, 0))
        goto err;
    } else
#ifndef OPENSSL_NO_RSA
    if (pkey->type == EVP_PKEY_RSA) {
        s->method->ssl3_enc->cert_verify_mac(s, NID_md5, &(data[0]));
        if (RSA_sign(NID_md5_sha1, data,
                     MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH,
                     &(p[2]), &u, pkey->pkey.rsa) <= 0) {
            SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_RSA_LIB);
            goto err;
        }
        s2n(u, p);
        n = u + 2;
    } else
#endif
#ifndef OPENSSL_NO_DSA
    if (pkey->type == EVP_PKEY_DSA) {
        if (!DSA_sign(pkey->save_type,
                      &(data[MD5_DIGEST_LENGTH]),
                      SHA_DIGEST_LENGTH, &(p[2]),
                      (unsigned int *)&j, pkey->pkey.dsa)) {
            SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_DSA_LIB);
            goto err;
        }
        s2n(j, p);
        n = j + 2;
    } else
#endif
#ifndef OPENSSL_NO_EC
    if (pkey->type == EVP_PKEY_EC) {
        if (!ECDSA_sign(pkey->save_type,
                        &(data[MD5_DIGEST_LENGTH]),
                        SHA_DIGEST_LENGTH, &(p[2]),
                        (unsigned int *)&j, pkey->pkey.ec)) {
            SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_ECDSA_LIB);
            goto err;
        }
        s2n(j, p);
        n = j + 2;
    } else
#endif
    if (pkey->type == NID_id_GostR3410_2001
            || pkey->type == NID_id_GostR3410_2012_256
            || pkey->type == NID_id_GostR3410_2012_512) {
        unsigned char signbuf[128];
        int i;
        size_t sigsize =
            (pkey->type == NID_id_GostR3410_2012_512) ? 128 : 64;
        int dgst_nid = NID_undef;

        EVP_PKEY_get_default_digest_nid(pkey, &dgst_nid);
        s->method->ssl3_enc->cert_verify_mac(s, dgst_nid, data);
        if (EVP_PKEY_sign(pctx, signbuf, &sigsize, data,
                          EVP_MD_size(EVP_get_digestbynid(dgst_nid))) <= 0) {
            SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR);
            goto err;
        }
        for (i = sigsize - 1, j = 0; i >= 0; j++, i--) {
            p[2 + j] = signbuf[i];
        }
        s2n(j, p);
        n = j + 2;
    } else {
        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR);
        goto err;
    }
    if (!ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE_VERIFY, n)) {
        SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR);
        goto err;
    }

    EVP_MD_CTX_cleanup(&mctx);
    EVP_PKEY_CTX_free(pctx);
    return 1;
 err:
    EVP_MD_CTX_cleanup(&mctx);
    EVP_PKEY_CTX_free(pctx);
    return 0;
}

+1 −1
Original line number Diff line number Diff line
@@ -2705,7 +2705,7 @@ static int ssl_check_clienthello_tlsext_early(SSL *s)
    }
}
/* Initialise digests to default values */
static void ssl_set_default_md(SSL *s)
void ssl_set_default_md(SSL *s)
{
    const EVP_MD **pmd = s->s3->tmp.md;
#ifndef OPENSSL_NO_DSA