Use EVP_md5_sha1() to generate client verify
[openssl.git] / ssl / statem / statem_clnt.c
index dea29d5b8f99a5cec9c95482644ee6a34f7ef875..c6bc86f0fe4593145a69eddda9d6b3c2aaa91536 100644 (file)
@@ -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,167 +2960,71 @@ 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) {
+
+    hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata);
+    if (hdatalen <= 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) {
-                        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;
-        }
+        p += 2;
+    }
 #ifdef SSL_DEBUG
-        fprintf(stderr, "Using TLS 1.2 with client alg %s\n",
-                EVP_MD_name(md));
-#endif
-        if (!EVP_SignInit_ex(&mctx, md, NULL)
-            || !EVP_SignUpdate(&mctx, hdata, hdatalen)
-            || !EVP_SignFinal(&mctx, p + 2, &u, pkey)) {
-            SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_VERIFY, ERR_R_EVP_LIB);
-            goto err;
-        }
-        if (pkey->type == NID_id_GostR3410_2001
-                || pkey->type == NID_id_GostR3410_2012_256
-                || pkey->type == NID_id_GostR3410_2012_512) {
-            unsigned int i, k;
-            for (i = u - 1, k = 0; k < u/2; k++, i--) {
-                char c = p[2 + k];
-                p[2 + k] = p[2 + i];
-                p[2 + i] = c;
-            }
-        }
-        s2n(u, p);
-        n = u + 2;
-        if (SSL_USE_SIGALGS(s))
-            n += 2;
-        /* 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
+    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;
+    }
     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;
+        unsigned int i, k;
+        for (i = u - 1, k = 0; k < u/2; k++, i--) {
+            char c = p[2 + k];
+            p[2 + k] = p[2 + i];
+            p[2 + i] = c;
         }
-        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;
     }
+
+    s2n(u, p);
+    n = u + 2;
+    if (SSL_USE_SIGALGS(s))
+        n += 2;
+    /* Digest cached records and discard handshake buffer */
+    if (!ssl3_digest_cached_records(s, 0))
+        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;
 }