Commit 2daceb03 authored by Ben Laurie's avatar Ben Laurie
Browse files

Call OCSP Stapling callback after ciphersuite has been chosen, so the

right response is stapled. Also change SSL_get_certificate() so it
returns the certificate actually sent.  See
http://rt.openssl.org/Ticket/Display.html?id=2836.
parent 147d4c96
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -346,6 +346,12 @@

 Changes between 1.0.1 and 1.0.2 [xx XXX xxxx]

  *) Call OCSP Stapling callback after ciphersuite has been chosen, so
     the right response is stapled. Also change SSL_get_certificate()
     so it returns the certificate actually sent.
     See http://rt.openssl.org/Ticket/Display.html?id=2836.
     [Rob Stradling <rob.stradling@comodo.com>]

  *) Support for linux-x32, ILP32 environment in x86_64 framework.
     [Andy Polyakov]

+10 −0
Original line number Diff line number Diff line
@@ -1432,6 +1432,16 @@ int ssl3_get_client_hello(SSL *s)
	 * 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)
		{
+10 −2
Original line number Diff line number Diff line
@@ -2336,7 +2336,7 @@ int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s)

#endif

static int ssl_get_server_cert_index(SSL *s)
static int ssl_get_server_cert_index(const SSL *s)
	{
	int idx;
	idx = ssl_cipher_get_cert_index(s->s3->tmp.new_cipher);
@@ -2347,7 +2347,7 @@ static int ssl_get_server_cert_index(SSL *s)
	return idx;
	}

CERT_PKEY *ssl_get_server_send_pkey(SSL *s)
CERT_PKEY *ssl_get_server_send_pkey(const SSL *s)
	{
	CERT *c;
	int i;
@@ -2833,6 +2833,14 @@ void ssl_clear_cipher_ctx(SSL *s)
/* Fix this function so that it takes an optional type parameter */
X509 *SSL_get_certificate(const SSL *s)
	{
	if (s->server)
		{
		CERT_PKEY *certpkey;
		certpkey = ssl_get_server_send_pkey(s);
		if (certpkey && certpkey->x509)
			return certpkey->x509;
		}

	if (s->cert != NULL)
		return(s->cert->key->x509);
	else
+2 −1
Original line number Diff line number Diff line
@@ -934,7 +934,7 @@ int ssl_cert_set_cert_store(CERT *c, X509_STORE *store, int chain, int ref);
int ssl_undefined_function(SSL *s);
int ssl_undefined_void_function(void);
int ssl_undefined_const_function(const SSL *s);
CERT_PKEY *ssl_get_server_send_pkey(SSL *);
CERT_PKEY *ssl_get_server_send_pkey(const SSL *s);
unsigned char *ssl_get_authz_data(SSL *s, size_t *authz_length);
EVP_PKEY *ssl_get_sign_pkey(SSL *s,const SSL_CIPHER *c, const EVP_MD **pmd);
int ssl_cert_type(X509 *x,EVP_PKEY *pkey);
@@ -1201,6 +1201,7 @@ int tls1_shared_list(SSL *s,
unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned char *limit); 
unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned char *limit); 
int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **data, unsigned char *d, int n);
int ssl_check_clienthello_tlsext_late(SSL *s);
int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data, unsigned char *d, int n);
int ssl_prepare_clienthello_tlsext(SSL *s);
int ssl_prepare_serverhello_tlsext(SSL *s);
+59 −36
Original line number Diff line number Diff line
@@ -123,7 +123,7 @@ const char tls1_version_str[]="TLSv1" OPENSSL_VERSION_PTEXT;
static int tls_decrypt_ticket(SSL *s, const unsigned char *tick, int ticklen,
				const unsigned char *sess_id, int sesslen,
				SSL_SESSION **psess);
static int ssl_check_clienthello_tlsext(SSL *s);
static int ssl_check_clienthello_tlsext_early(SSL *s);
int ssl_check_serverhello_tlsext(SSL *s);
#endif

@@ -2246,7 +2246,7 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
		return 0;
		}

	if (ssl_check_clienthello_tlsext(s) <= 0) 
	if (ssl_check_clienthello_tlsext_early(s) <= 0) 
		{
		SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT,SSL_R_CLIENTHELLO_TLSEXT);
		return 0;
@@ -2647,7 +2647,7 @@ int ssl_prepare_serverhello_tlsext(SSL *s)
	return 1;
	}

static int ssl_check_clienthello_tlsext(SSL *s)
static int ssl_check_clienthello_tlsext_early(SSL *s)
	{
	int ret=SSL_TLSEXT_ERR_NOACK;
	int al = SSL_AD_UNRECOGNIZED_NAME;
@@ -2666,42 +2666,12 @@ static int ssl_check_clienthello_tlsext(SSL *s)
	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;
	
@@ -2753,8 +2723,8 @@ static int ssl_check_clienthello_tlsext(SSL *s)
			}
	}

#endif
 err:
#endif
	switch (ret)
		{
		case SSL_TLSEXT_ERR_ALERT_FATAL:
@@ -2772,6 +2742,59 @@ static int ssl_check_clienthello_tlsext(SSL *s)
		}
	}

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;