Attached are patches for 1.0.0 and 0.9.8.

-- 
Rob Stradling
Senior Research & Development Scientist
COMODO - Creating Trust Online
Office Tel: +44.(0)1274.730505
Office Fax: +44.(0)1274.730909
www.comodo.com

COMODO CA Limited, Registered in England No. 04058690
Registered Office:
   3rd Floor, 26 Office Village, Exchange Quay,
   Trafford Road, Salford, Manchester M5 3EQ

This e-mail and any files transmitted with it are confidential and 
intended solely for the use of the individual or entity to whom they are 
addressed.  If you have received this email in error please notify the 
sender by replying to the e-mail containing this attachment. Replies to 
this email may be monitored by COMODO for operational or business 
reasons. Whilst every endeavour is taken to ensure that e-mails are free 
from viruses, no liability can be accepted and the recipient is 
requested to use their own virus checking software.

Index: ssl/s3_srvr.c
===================================================================
RCS file: /v/openssl/cvs/openssl/ssl/s3_srvr.c,v
retrieving revision 1.126.2.42
diff -u -r1.126.2.42 s3_srvr.c
--- ssl/s3_srvr.c       16 Feb 2012 15:21:17 -0000      1.126.2.42
+++ ssl/s3_srvr.c       20 Sep 2012 14:40:41 -0000
@@ -1005,7 +1005,7 @@
                        goto f_err;
                        }
                }
-               if (ssl_check_clienthello_tlsext(s) <= 0) {
+               if (ssl_check_clienthello_tlsext_early(s) <= 0) {
                        
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
                        goto err;
                }
@@ -1131,6 +1131,16 @@
         * s->tmp.new_cipher    - the new cipher to use.
         */
 
+       /* Handles TLS extensions that we couldn't check earlier */
+       if (s->version >= SSL3_VERSION)
+               {
+               if (ssl_check_clienthello_tlsext_late(s) <= 0)
+                       {
+                       
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
+                       goto err;
+                       }
+               }
+
        if (ret < 0) ret=1;
        if (0)
                {
Index: ssl/ssl_lib.c
===================================================================
RCS file: /v/openssl/cvs/openssl/ssl/ssl_lib.c,v
retrieving revision 1.133.2.31
diff -u -r1.133.2.31 ssl_lib.c
--- ssl/ssl_lib.c       5 Jan 2012 10:21:49 -0000       1.133.2.31
+++ ssl/ssl_lib.c       20 Sep 2012 14:40:41 -0000
@@ -1943,7 +1943,7 @@
        }
 
 /* THIS NEEDS CLEANING UP */
-X509 *ssl_get_server_send_cert(SSL *s)
+X509 *ssl_get_server_send_cert(const SSL *s)
        {
        unsigned long alg,kalg;
        CERT *c;
@@ -2420,7 +2420,9 @@
 /* Fix this function so that it takes an optional type parameter */
 X509 *SSL_get_certificate(const SSL *s)
        {
-       if (s->cert != NULL)
+       if (s->server)
+               return(ssl_get_server_send_cert(s));
+       else if (s->cert != NULL)
                return(s->cert->key->x509);
        else
                return(NULL);
Index: ssl/ssl_locl.h
===================================================================
RCS file: /v/openssl/cvs/openssl/ssl/ssl_locl.h,v
retrieving revision 1.63.2.22
diff -u -r1.63.2.22 ssl_locl.h
--- ssl/ssl_locl.h      9 Mar 2012 15:51:56 -0000       1.63.2.22
+++ ssl/ssl_locl.h      20 Sep 2012 14:40:41 -0000
@@ -740,7 +740,7 @@
 int ssl_undefined_function(SSL *s);
 int ssl_undefined_void_function(void);
 int ssl_undefined_const_function(const SSL *s);
-X509 *ssl_get_server_send_cert(SSL *);
+X509 *ssl_get_server_send_cert(const SSL *);
 EVP_PKEY *ssl_get_sign_pkey(SSL *,SSL_CIPHER *);
 int ssl_cert_type(X509 *x,EVP_PKEY *pkey);
 void ssl_set_cert_masks(CERT *c, SSL_CIPHER *cipher);
@@ -979,7 +979,8 @@
 int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data, unsigned char 
*d, int n, int *al);
 int ssl_prepare_clienthello_tlsext(SSL *s);
 int ssl_prepare_serverhello_tlsext(SSL *s);
-int ssl_check_clienthello_tlsext(SSL *s);
+int ssl_check_clienthello_tlsext_early(SSL *s);
+int ssl_check_clienthello_tlsext_late(SSL *s);
 int ssl_check_serverhello_tlsext(SSL *s);
 
 #ifdef OPENSSL_NO_SHA256
Index: ssl/t1_lib.c
===================================================================
RCS file: /v/openssl/cvs/openssl/ssl/t1_lib.c,v
retrieving revision 1.13.2.30
diff -u -r1.13.2.30 t1_lib.c
--- ssl/t1_lib.c        4 Jan 2012 14:25:10 -0000       1.13.2.30
+++ ssl/t1_lib.c        20 Sep 2012 14:40:41 -0000
@@ -745,7 +745,7 @@
        return 1;
        }
 
-int ssl_check_clienthello_tlsext(SSL *s)
+int ssl_check_clienthello_tlsext_early(SSL *s)
        {
        int ret=SSL_TLSEXT_ERR_NOACK;
        int al = SSL_AD_UNRECOGNIZED_NAME;
@@ -755,11 +755,34 @@
        else if (s->initial_ctx != NULL && 
s->initial_ctx->tlsext_servername_callback != 0)             
                ret = s->initial_ctx->tlsext_servername_callback(s, &al, 
s->initial_ctx->tlsext_servername_arg);
 
+       switch (ret)
+               {
+               case SSL_TLSEXT_ERR_ALERT_FATAL:
+                       ssl3_send_alert(s,SSL3_AL_FATAL,al); 
+                       return -1;
+
+               case SSL_TLSEXT_ERR_ALERT_WARNING:
+                       ssl3_send_alert(s,SSL3_AL_WARNING,al);
+                       return 1; 
+                                       
+               case SSL_TLSEXT_ERR_NOACK:
+                       s->servername_done=0;
+                       default:
+               return 1;
+               }
+       }
+
+int ssl_check_clienthello_tlsext_late(SSL *s)
+       {
+       int ret=SSL_TLSEXT_ERR_OK;
+       int al;
+
        /* If status request then ask callback what to do.
         * Note: this must be called after servername callbacks in case 
-        * the certificate has changed.
+        * the certificate has changed, and must be called after the cipher
+        * has been chosen because this may influence which certificate is sent
         */
-       if ((s->tlsext_status_type != -1) && s->ctx->tlsext_status_cb)
+       if ((s->tlsext_status_type != -1) && s->ctx && s->ctx->tlsext_status_cb)
                {
                int r;
                r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
@@ -785,7 +809,8 @@
                }
        else
                s->tlsext_status_expected = 0;
-       err:
+
+ err:
        switch (ret)
                {
                case SSL_TLSEXT_ERR_ALERT_FATAL:
@@ -795,11 +820,9 @@
                case SSL_TLSEXT_ERR_ALERT_WARNING:
                        ssl3_send_alert(s,SSL3_AL_WARNING,al);
                        return 1; 
-                                       
-               case SSL_TLSEXT_ERR_NOACK:
-                       s->servername_done=0;
-                       default:
-               return 1;
+
+               default:
+                       return 1;
                }
        }
 
Index: ssl/s3_srvr.c
===================================================================
RCS file: /v/openssl/cvs/openssl/ssl/s3_srvr.c,v
retrieving revision 1.171.2.29
diff -u -r1.171.2.29 s3_srvr.c
--- ssl/s3_srvr.c       15 Apr 2012 17:23:23 -0000      1.171.2.29
+++ ssl/s3_srvr.c       17 Sep 2012 19:37:45 -0000
@@ -1063,7 +1063,7 @@
                        goto f_err;
                        }
                }
-               if (ssl_check_clienthello_tlsext(s) <= 0) {
+               if (ssl_check_clienthello_tlsext_early(s) <= 0) {
                        
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
                        goto err;
                }
@@ -1282,6 +1282,16 @@
         * s->tmp.new_cipher    - the new cipher to use.
         */
 
+       /* Handles TLS extensions that we couldn't check earlier */
+       if (s->version >= SSL3_VERSION)
+               {
+               if (ssl_check_clienthello_tlsext_late(s) <= 0)
+                       {
+                       
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
+                       goto err;
+                       }
+               }
+
        if (ret < 0) ret=1;
        if (0)
                {
Index: ssl/ssl_lib.c
===================================================================
RCS file: /v/openssl/cvs/openssl/ssl/ssl_lib.c,v
retrieving revision 1.176.2.23
diff -u -r1.176.2.23 ssl_lib.c
--- ssl/ssl_lib.c       5 Jan 2012 10:22:23 -0000       1.176.2.23
+++ ssl/ssl_lib.c       17 Sep 2012 19:37:45 -0000
@@ -2107,7 +2107,7 @@
 #endif
 
 /* THIS NEEDS CLEANING UP */
-X509 *ssl_get_server_send_cert(SSL *s)
+X509 *ssl_get_server_send_cert(const SSL *s)
        {
        unsigned long alg_k,alg_a;
        CERT *c;
@@ -2593,7 +2593,9 @@
 /* Fix this function so that it takes an optional type parameter */
 X509 *SSL_get_certificate(const SSL *s)
        {
-       if (s->cert != NULL)
+       if (s->server)
+               return(ssl_get_server_send_cert(s));
+       else if (s->cert != NULL)
                return(s->cert->key->x509);
        else
                return(NULL);
Index: ssl/ssl_locl.h
===================================================================
RCS file: /v/openssl/cvs/openssl/ssl/ssl_locl.h,v
retrieving revision 1.100.2.12
diff -u -r1.100.2.12 ssl_locl.h
--- ssl/ssl_locl.h      9 Mar 2012 15:52:09 -0000       1.100.2.12
+++ ssl/ssl_locl.h      17 Sep 2012 19:37:45 -0000
@@ -808,7 +808,7 @@
 int ssl_undefined_function(SSL *s);
 int ssl_undefined_void_function(void);
 int ssl_undefined_const_function(const SSL *s);
-X509 *ssl_get_server_send_cert(SSL *);
+X509 *ssl_get_server_send_cert(const SSL *);
 EVP_PKEY *ssl_get_sign_pkey(SSL *,const SSL_CIPHER *);
 int ssl_cert_type(X509 *x,EVP_PKEY *pkey);
 void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher);
@@ -1056,7 +1056,8 @@
 int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data, unsigned char 
*d, int n, int *al);
 int ssl_prepare_clienthello_tlsext(SSL *s);
 int ssl_prepare_serverhello_tlsext(SSL *s);
-int ssl_check_clienthello_tlsext(SSL *s);
+int ssl_check_clienthello_tlsext_early(SSL *s);
+int ssl_check_clienthello_tlsext_late(SSL *s);
 int ssl_check_serverhello_tlsext(SSL *s);
 
 #ifdef OPENSSL_NO_SHA256
Index: ssl/t1_lib.c
===================================================================
RCS file: /v/openssl/cvs/openssl/ssl/t1_lib.c,v
retrieving revision 1.64.2.19
diff -u -r1.64.2.19 t1_lib.c
--- ssl/t1_lib.c        4 Jan 2012 14:24:48 -0000       1.64.2.19
+++ ssl/t1_lib.c        17 Sep 2012 19:37:45 -0000
@@ -1333,7 +1333,7 @@
        return 1;
        }
 
-int ssl_check_clienthello_tlsext(SSL *s)
+int ssl_check_clienthello_tlsext_early(SSL *s)
        {
        int ret=SSL_TLSEXT_ERR_NOACK;
        int al = SSL_AD_UNRECOGNIZED_NAME;
@@ -1352,42 +1352,12 @@
        else if (s->initial_ctx != NULL && 
s->initial_ctx->tlsext_servername_callback != 0)             
                ret = s->initial_ctx->tlsext_servername_callback(s, &al, 
s->initial_ctx->tlsext_servername_arg);
 
-       /* If status request then ask callback what to do.
-        * Note: this must be called after servername callbacks in case 
-        * the certificate has changed.
-        */
-       if ((s->tlsext_status_type != -1) && s->ctx && s->ctx->tlsext_status_cb)
-               {
-               int r;
-               r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
-               switch (r)
-                       {
-                       /* We don't want to send a status request response */
-                       case SSL_TLSEXT_ERR_NOACK:
-                               s->tlsext_status_expected = 0;
-                               break;
-                       /* status request response should be sent */
-                       case SSL_TLSEXT_ERR_OK:
-                               if (s->tlsext_ocsp_resp)
-                                       s->tlsext_status_expected = 1;
-                               else
-                                       s->tlsext_status_expected = 0;
-                               break;
-                       /* something bad happened */
-                       case SSL_TLSEXT_ERR_ALERT_FATAL:
-                               ret = SSL_TLSEXT_ERR_ALERT_FATAL;
-                               al = SSL_AD_INTERNAL_ERROR;
-                               goto err;
-                       }
-               }
-       else
-               s->tlsext_status_expected = 0;
-
 #ifdef TLSEXT_TYPE_opaque_prf_input
        {
                /* This sort of belongs into ssl_prepare_serverhello_tlsext(),
                 * but we might be sending an alert in response to the client 
hello,
-                * so this has to happen here in 
ssl_check_clienthello_tlsext(). */
+                * so this has to happen here in
+                * ssl_check_clienthello_tlsext_early(). */
 
                int r = 1;
        
@@ -1439,8 +1409,8 @@
                        }
        }
 
-#endif
  err:
+#endif
        switch (ret)
                {
                case SSL_TLSEXT_ERR_ALERT_FATAL:
@@ -1458,6 +1428,59 @@
                }
        }
 
+int ssl_check_clienthello_tlsext_late(SSL *s)
+       {
+       int ret=SSL_TLSEXT_ERR_OK;
+       int al;
+
+       /* If status request then ask callback what to do.
+        * Note: this must be called after servername callbacks in case 
+        * the certificate has changed, and must be called after the cipher
+        * has been chosen because this may influence which certificate is sent
+        */
+       if ((s->tlsext_status_type != -1) && s->ctx && s->ctx->tlsext_status_cb)
+               {
+               int r;
+               r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
+               switch (r)
+                       {
+                       /* We don't want to send a status request response */
+                       case SSL_TLSEXT_ERR_NOACK:
+                               s->tlsext_status_expected = 0;
+                               break;
+                       /* status request response should be sent */
+                       case SSL_TLSEXT_ERR_OK:
+                               if (s->tlsext_ocsp_resp)
+                                       s->tlsext_status_expected = 1;
+                               else
+                                       s->tlsext_status_expected = 0;
+                               break;
+                       /* something bad happened */
+                       case SSL_TLSEXT_ERR_ALERT_FATAL:
+                               ret = SSL_TLSEXT_ERR_ALERT_FATAL;
+                               al = SSL_AD_INTERNAL_ERROR;
+                               goto err;
+                       }
+               }
+       else
+               s->tlsext_status_expected = 0;
+
+ err:
+       switch (ret)
+               {
+               case SSL_TLSEXT_ERR_ALERT_FATAL:
+                       ssl3_send_alert(s,SSL3_AL_FATAL,al); 
+                       return -1;
+
+               case SSL_TLSEXT_ERR_ALERT_WARNING:
+                       ssl3_send_alert(s,SSL3_AL_WARNING,al);
+                       return 1; 
+
+               default:
+                       return 1;
+               }
+       }
+
 int ssl_check_serverhello_tlsext(SSL *s)
        {
        int ret=SSL_TLSEXT_ERR_NOACK;

Reply via email to