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.
This commit is contained in:
parent
bc78883017
commit
70d91d60bc
6
CHANGES
6
CHANGES
@ -4,6 +4,12 @@
|
|||||||
|
|
||||||
Changes between 1.0.1c and 1.0.1d [xx XXX xxxx]
|
Changes between 1.0.1c and 1.0.1d [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>]
|
||||||
|
|
||||||
*) Fix possible deadlock when decoding public keys.
|
*) Fix possible deadlock when decoding public keys.
|
||||||
[Steve Henson]
|
[Steve Henson]
|
||||||
|
|
||||||
|
@ -1183,7 +1183,7 @@ int ssl3_get_client_hello(SSL *s)
|
|||||||
goto f_err;
|
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);
|
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CLIENTHELLO_TLSEXT);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@ -1405,6 +1405,16 @@ int ssl3_get_client_hello(SSL *s)
|
|||||||
* s->tmp.new_cipher - the new cipher to use.
|
* 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 (ret < 0) ret=1;
|
||||||
if (0)
|
if (0)
|
||||||
{
|
{
|
||||||
|
@ -2287,7 +2287,7 @@ int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* THIS NEEDS CLEANING UP */
|
/* 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;
|
unsigned long alg_k,alg_a;
|
||||||
CERT *c;
|
CERT *c;
|
||||||
@ -2780,7 +2780,9 @@ void ssl_clear_cipher_ctx(SSL *s)
|
|||||||
/* Fix this function so that it takes an optional type parameter */
|
/* Fix this function so that it takes an optional type parameter */
|
||||||
X509 *SSL_get_certificate(const SSL *s)
|
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);
|
return(s->cert->key->x509);
|
||||||
else
|
else
|
||||||
return(NULL);
|
return(NULL);
|
||||||
|
@ -830,7 +830,7 @@ int ssl_verify_cert_chain(SSL *s,STACK_OF(X509) *sk);
|
|||||||
int ssl_undefined_function(SSL *s);
|
int ssl_undefined_function(SSL *s);
|
||||||
int ssl_undefined_void_function(void);
|
int ssl_undefined_void_function(void);
|
||||||
int ssl_undefined_const_function(const SSL *s);
|
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 *s,const SSL_CIPHER *c, const EVP_MD **pmd);
|
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);
|
int ssl_cert_type(X509 *x,EVP_PKEY *pkey);
|
||||||
void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher);
|
void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher);
|
||||||
@ -1088,7 +1088,8 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **data, unsigned char *d,
|
|||||||
int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data, unsigned char *d, int n, int *al);
|
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_clienthello_tlsext(SSL *s);
|
||||||
int ssl_prepare_serverhello_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);
|
int ssl_check_serverhello_tlsext(SSL *s);
|
||||||
|
|
||||||
#ifndef OPENSSL_NO_HEARTBEATS
|
#ifndef OPENSSL_NO_HEARTBEATS
|
||||||
|
91
ssl/t1_lib.c
91
ssl/t1_lib.c
@ -1763,7 +1763,7 @@ int ssl_prepare_serverhello_tlsext(SSL *s)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ssl_check_clienthello_tlsext(SSL *s)
|
int ssl_check_clienthello_tlsext_early(SSL *s)
|
||||||
{
|
{
|
||||||
int ret=SSL_TLSEXT_ERR_NOACK;
|
int ret=SSL_TLSEXT_ERR_NOACK;
|
||||||
int al = SSL_AD_UNRECOGNIZED_NAME;
|
int al = SSL_AD_UNRECOGNIZED_NAME;
|
||||||
@ -1782,42 +1782,12 @@ int ssl_check_clienthello_tlsext(SSL *s)
|
|||||||
else if (s->initial_ctx != NULL && s->initial_ctx->tlsext_servername_callback != 0)
|
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);
|
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
|
#ifdef TLSEXT_TYPE_opaque_prf_input
|
||||||
{
|
{
|
||||||
/* This sort of belongs into ssl_prepare_serverhello_tlsext(),
|
/* This sort of belongs into ssl_prepare_serverhello_tlsext(),
|
||||||
* but we might be sending an alert in response to the client hello,
|
* 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;
|
int r = 1;
|
||||||
|
|
||||||
@ -1869,8 +1839,8 @@ int ssl_check_clienthello_tlsext(SSL *s)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
err:
|
err:
|
||||||
|
#endif
|
||||||
switch (ret)
|
switch (ret)
|
||||||
{
|
{
|
||||||
case SSL_TLSEXT_ERR_ALERT_FATAL:
|
case SSL_TLSEXT_ERR_ALERT_FATAL:
|
||||||
@ -1888,6 +1858,59 @@ 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 ssl_check_serverhello_tlsext(SSL *s)
|
||||||
{
|
{
|
||||||
int ret=SSL_TLSEXT_ERR_NOACK;
|
int ret=SSL_TLSEXT_ERR_NOACK;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user