From: Dr. Stephen Henson Date: Sat, 25 Jan 2014 13:31:07 +0000 (+0000) Subject: Support retries in certificate callback X-Git-Tag: OpenSSL_1_0_2-beta1~92 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=ede90b1121b448395c8742166e19b2b475f14975;p=oweals%2Fopenssl.git Support retries in certificate callback (cherry picked from commit 0ebc965b9ca4352e407bb7cfa65ac235942117f6) Conflicts: ssl/s3_srvr.c ssl/ssl3.h --- diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c index 6aeab442e1..9e3c847de9 100644 --- a/ssl/s3_clnt.c +++ b/ssl/s3_clnt.c @@ -3301,11 +3301,20 @@ int ssl3_send_client_certificate(SSL *s) if (s->state == SSL3_ST_CW_CERT_A) { /* Let cert callback update client certificates if required */ - if (s->cert->cert_cb - && s->cert->cert_cb(s, s->cert->cert_cb_arg) <= 0) + if (s->cert->cert_cb) { - ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_INTERNAL_ERROR); - return 0; + i = s->cert->cert_cb(s, s->cert->cert_cb_arg); + if (i < 0) + { + s->rwstate=SSL_X509_LOOKUP; + return -1; + } + if (i == 0) + { + ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_INTERNAL_ERROR); + return 0; + } + s->rwstate=SSL_NOTHING; } if (ssl3_check_client_certificate(s)) s->state=SSL3_ST_CW_CERT_C; diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c index 619c710ca4..8e8daf2997 100644 --- a/ssl/s3_srvr.c +++ b/ssl/s3_srvr.c @@ -353,12 +353,11 @@ int ssl3_accept(SSL *s) case SSL3_ST_SR_CLNT_HELLO_C: s->shutdown=0; - if (s->rwstate != SSL_X509_LOOKUP) - { - ret=ssl3_get_client_hello(s); - if (ret <= 0) goto end; - } + ret=ssl3_get_client_hello(s); + if (ret <= 0) goto end; #ifndef OPENSSL_NO_SRP + s->state = SSL3_ST_SR_CLNT_HELLO_D; + case SSL3_ST_SR_CLNT_HELLO_D: { int al; if ((ret = ssl_check_srp_ext_ClientHello(s,&al)) < 0) @@ -940,6 +939,9 @@ int ssl3_get_client_hello(SSL *s) #endif STACK_OF(SSL_CIPHER) *ciphers=NULL; + if (s->state == SSL3_ST_SR_CLNT_HELLO_C) + goto retry_cert; + /* We do this so that we will respond with our native type. * If we are TLSv1 and we get SSLv3, we will respond with TLSv1, * This down switching should be handled by a different method. @@ -1384,12 +1386,22 @@ int ssl3_get_client_hello(SSL *s) } ciphers=NULL; /* Let cert callback update server certificates if required */ - if (s->cert->cert_cb - && s->cert->cert_cb(s, s->cert->cert_cb_arg) <= 0) + retry_cert: + if (s->cert->cert_cb) { - al=SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CERT_CB_ERROR); - goto f_err; + int rv = s->cert->cert_cb(s, s->cert->cert_cb_arg); + if (rv == 0) + { + al=SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CERT_CB_ERROR); + goto f_err; + } + if (rv < 0) + { + s->rwstate=SSL_X509_LOOKUP; + return -1; + } + s->rwstate = SSL_NOTHING; } c=ssl3_choose_cipher(s,s->session->ciphers, SSL_get_ciphers(s)); diff --git a/ssl/ssl3.h b/ssl/ssl3.h index 57b568a477..e2a58c30cc 100644 --- a/ssl/ssl3.h +++ b/ssl/ssl3.h @@ -669,6 +669,7 @@ typedef struct ssl3_state_st #define SSL3_ST_SR_CLNT_HELLO_A (0x110|SSL_ST_ACCEPT) #define SSL3_ST_SR_CLNT_HELLO_B (0x111|SSL_ST_ACCEPT) #define SSL3_ST_SR_CLNT_HELLO_C (0x112|SSL_ST_ACCEPT) +#define SSL3_ST_SR_CLNT_HELLO_D (0x115|SSL_ST_ACCEPT) /* write to client */ #define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A (0x113|SSL_ST_ACCEPT) #define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B (0x114|SSL_ST_ACCEPT)