summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ssl/s3_clnt.c17
-rw-r--r--ssl/s3_srvr.c32
-rw-r--r--ssl/ssl3.h1
3 files changed, 36 insertions, 14 deletions
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)