!a && !a->b is clearly wrong! Changed to !a || !a->b (Coverity ID 145).
[openssl.git] / ssl / s3_clnt.c
index 23875f00e0e082b55548c03d151eba3e47ffb6f2..5cea73ca1abcbedaf7c06d5482d1e7dd66af734c 100644 (file)
 #include <openssl/dh.h>
 #endif
 #include <openssl/bn.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
 
 static const SSL_METHOD *ssl3_get_client_method(int ver);
 static int ca_dn_cmp(const X509_NAME * const *a,const X509_NAME * const *b);
@@ -716,7 +719,7 @@ err:
 int ssl3_get_server_hello(SSL *s)
        {
        STACK_OF(SSL_CIPHER) *sk;
-       SSL_CIPHER *c;
+       const SSL_CIPHER *c;
        unsigned char *p,*d;
        int i,al,ok;
        unsigned int j;
@@ -785,6 +788,23 @@ int ssl3_get_server_hello(SSL *s)
                goto f_err;
                }
 
+#ifndef OPENSSL_NO_TLSEXT
+       /* check if we want to resume the session based on external pre-shared secret */
+       if (s->version >= TLS1_VERSION && s->tls_session_secret_cb)
+               {
+               SSL_CIPHER *pref_cipher=NULL;
+               s->session->master_key_length=sizeof(s->session->master_key);
+               if (s->tls_session_secret_cb(s, s->session->master_key,
+                                            &s->session->master_key_length,
+                                            NULL, &pref_cipher,
+                                            s->tls_session_secret_cb_arg))
+                       {
+                       s->session->cipher = pref_cipher ?
+                               pref_cipher : ssl_get_cipher_by_char(s, p+j);
+                       }
+               }
+#endif /* OPENSSL_NO_TLSEXT */
+
        if (j != 0 && j == s->session->session_id_length
            && memcmp(p,s->session->session_id,j) == 0)
            {
@@ -2723,8 +2743,7 @@ int ssl3_send_client_certificate(SSL *s)
                 * ssl->rwstate=SSL_X509_LOOKUP; return(-1);
                 * We then get retied later */
                i=0;
-               if (s->ctx->client_cert_cb != NULL)
-                       i=s->ctx->client_cert_cb(s,&(x509),&(pkey));
+               i = ssl_do_client_cert_cb(s, &x509, &pkey);
                if (i < 0)
                        {
                        s->rwstate=SSL_X509_LOOKUP;
@@ -2925,11 +2944,8 @@ static int ssl3_check_finished(SSL *s)
        {
        int ok;
        long n;
-       /* If we have no ticket or session ID is non-zero length (a match of
-        * a non-zero session length would never reach here) it cannot be a
-        * resumed session.
-        */
-       if (!s->session->tlsext_tick || s->session->session_id_length)
+       /* If we have no ticket it cannot be a resumed session. */
+       if (!s->session->tlsext_tick)
                return 1;
        /* this function is called when we really expect a Certificate
         * message, so permit appropriate message length */
@@ -2948,3 +2964,21 @@ static int ssl3_check_finished(SSL *s)
        return 1;
        }
 #endif
+
+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);
+               if (i != 0)
+                       return i;
+               }
+#endif
+       if (s->ctx->client_cert_cb)
+               i = s->ctx->client_cert_cb(s,px509,ppkey);
+       return i;
+       }