Enclosed two patches for head and stable to finish cleanup
for this ticket.
- leaving a trace in CHANGES
- removing some unncessary SSL_err and permitting
an srp user callback to allow a worker to obtain
a user verifier.
- cleanup and comments in s_server and demonstration
for asynchronous srp user lookup
diff -r -c openssl-1.0.1-stable-SNAP-20111219/apps/s_server.c openssl-1.0.1-stable-SNAP-20111219PS/apps/s_server.c
*** openssl-1.0.1-stable-SNAP-20111219/apps/s_server.c 2011-11-16 01:00:33.000000000 +0100
--- openssl-1.0.1-stable-SNAP-20111219PS/apps/s_server.c 2011-12-19 15:42:07.777319434 +0100
***************
*** 380,410 ****
/* This is a context that we pass to callbacks */
typedef struct srpsrvparm_st
{
- int verbose;
char *login;
SRP_VBASE *vb;
} srpsrvparm;
static int MS_CALLBACK ssl_srp_server_param_cb(SSL *s, int *ad, void *arg)
{
! srpsrvparm *p = (srpsrvparm *) arg;
! SRP_user_pwd *user;
!
! p->login = BUF_strdup(SSL_get_srp_username(s));
! BIO_printf(bio_err, "SRP username = \"%s\"\n", p->login);
! user = SRP_VBASE_get_by_user(p->vb, p->login);
! if (user == NULL)
{
BIO_printf(bio_err, "User %s doesn't exist\n", p->login);
return SSL3_AL_FATAL;
}
! if (SSL_set_srp_server_param(s, user->N, user->g, user->s, user->v,
! user->info) < 0)
{
*ad = SSL_AD_INTERNAL_ERROR;
return SSL3_AL_FATAL;
}
return SSL_ERROR_NONE;
}
--- 380,422 ----
/* This is a context that we pass to callbacks */
typedef struct srpsrvparm_st
{
char *login;
SRP_VBASE *vb;
+ SRP_user_pwd *user;
} srpsrvparm;
+ /* This callback pretends to require some asynchronous logic in order to obtain
+ a verifier. When the callback is called for a new connection we return
+ with a negative value. This will provoke the accept etc to return with
+ an LOOKUP_X509. The main logic of the reinvokes the suspended call
+ (which would normally occur after a worker has finished) and we
+ set the user parameters.
+ */
static int MS_CALLBACK ssl_srp_server_param_cb(SSL *s, int *ad, void *arg)
{
! srpsrvparm *p = (srpsrvparm *)arg;
! if (p->login == NULL && p->user == NULL )
! {
! p->login = SSL_get_srp_username(s);
! BIO_printf(bio_err, "SRP username = \"%s\"\n", p->login);
! return (-1) ;
! }
! if (p->user == NULL)
{
BIO_printf(bio_err, "User %s doesn't exist\n", p->login);
return SSL3_AL_FATAL;
}
! if (SSL_set_srp_server_param(s, p->user->N, p->user->g, p->user->s, p->user->v,
! p->user->info) < 0)
{
*ad = SSL_AD_INTERNAL_ERROR;
return SSL3_AL_FATAL;
}
+ BIO_printf(bio_err, "SRP parameters set: username = \"%s\" info=\"%s\" \n", p->login,p->user->info);
+ /* need to check whether there are memory leaks */
+ p->user = NULL;
+ p->login = NULL;
return SSL_ERROR_NONE;
}
***************
*** 908,913 ****
--- 920,928 ----
#ifndef OPENSSL_NO_JPAKE
static char *jpake_secret = NULL;
#endif
+ #ifndef OPENSSL_NO_SRP
+ static srpsrvparm srp_callback_parm;
+ #endif
static char *srtp_profiles = NULL;
int MAIN(int argc, char *argv[])
***************
*** 953,959 ****
#ifndef OPENSSL_NO_SRP
char *srpuserseed = NULL;
char *srp_verifier_file = NULL;
- srpsrvparm p;
#endif
#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
meth=SSLv23_server_method();
--- 968,973 ----
***************
*** 1842,1849 ****
#ifndef OPENSSL_NO_SRP
if (srp_verifier_file != NULL)
{
! p.vb = SRP_VBASE_new(srpuserseed);
! if ((ret = SRP_VBASE_init(p.vb, srp_verifier_file)) != SRP_NO_ERROR)
{
BIO_printf(bio_err,
"Cannot initialize SRP verifier file \"%s\":ret=%d\n",
--- 1856,1865 ----
#ifndef OPENSSL_NO_SRP
if (srp_verifier_file != NULL)
{
! srp_callback_parm.vb = SRP_VBASE_new(srpuserseed);
! srp_callback_parm.user = NULL;
! srp_callback_parm.login = NULL;
! if ((ret = SRP_VBASE_init(srp_callback_parm.vb, srp_verifier_file)) != SRP_NO_ERROR)
{
BIO_printf(bio_err,
"Cannot initialize SRP verifier file \"%s\":ret=%d\n",
***************
*** 1851,1857 ****
goto end;
}
SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE,verify_callback);
! SSL_CTX_set_srp_cb_arg(ctx, &p);
SSL_CTX_set_srp_username_callback(ctx, ssl_srp_server_param_cb);
}
else
--- 1867,1873 ----
goto end;
}
SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE,verify_callback);
! SSL_CTX_set_srp_cb_arg(ctx, &srp_callback_parm);
SSL_CTX_set_srp_username_callback(ctx, ssl_srp_server_param_cb);
}
else
***************
*** 2219,2224 ****
--- 2235,2250 ----
{ static count=0; if (++count == 100) { count=0; SSL_renegotiate(con); } }
#endif
k=SSL_write(con,&(buf[l]),(unsigned int)i);
+ while (SSL_get_error(con,k) == SSL_ERROR_WANT_X509_LOOKUP)
+ {
+ BIO_printf(bio_s_out,"LOOKUP renego during write\n");
+ srp_callback_parm.user = SRP_VBASE_get_by_user(srp_callback_parm.vb, srp_callback_parm.login);
+ if (srp_callback_parm.user)
+ BIO_printf(bio_s_out,"LOOKUP done %s\n",srp_callback_parm.user->info);
+ else
+ BIO_printf(bio_s_out,"LOOKUP not successful\n");
+ k=SSL_write(con,&(buf[l]),(unsigned int)i);
+ }
switch (SSL_get_error(con,k))
{
case SSL_ERROR_NONE:
***************
*** 2266,2271 ****
--- 2292,2307 ----
{
again:
i=SSL_read(con,(char *)buf,bufsize);
+ while (SSL_get_error(con,i) == SSL_ERROR_WANT_X509_LOOKUP)
+ {
+ BIO_printf(bio_s_out,"LOOKUP renego during read\n");
+ srp_callback_parm.user = SRP_VBASE_get_by_user(srp_callback_parm.vb, srp_callback_parm.login);
+ if (srp_callback_parm.user)
+ BIO_printf(bio_s_out,"LOOKUP done %s\n",srp_callback_parm.user->info);
+ else
+ BIO_printf(bio_s_out,"LOOKUP not successful\n");
+ i=SSL_read(con,(char *)buf,bufsize);
+ }
switch (SSL_get_error(con,i))
{
case SSL_ERROR_NONE:
***************
*** 2278,2284 ****
break;
case SSL_ERROR_WANT_WRITE:
case SSL_ERROR_WANT_READ:
- case SSL_ERROR_WANT_X509_LOOKUP:
BIO_printf(bio_s_out,"Read BLOCK\n");
break;
case SSL_ERROR_SYSCALL:
--- 2314,2319 ----
***************
*** 2343,2349 ****
unsigned char *exportedkeymat;
! if ((i=SSL_accept(con)) <= 0)
{
if (BIO_sock_should_retry(i))
{
--- 2378,2395 ----
unsigned char *exportedkeymat;
! i=SSL_accept(con);
! while (i <= 0 && SSL_get_error(con,i) == SSL_ERROR_WANT_X509_LOOKUP)
! {
! BIO_printf(bio_s_out,"LOOKUP during accept %s\n",srp_callback_parm.login);
! srp_callback_parm.user = SRP_VBASE_get_by_user(srp_callback_parm.vb, srp_callback_parm.login);
! if (srp_callback_parm.user)
! BIO_printf(bio_s_out,"LOOKUP done %s\n",srp_callback_parm.user->info);
! else
! BIO_printf(bio_s_out,"LOOKUP not successful\n");
! i=SSL_accept(con);
! }
! if (i <= 0)
{
if (BIO_sock_should_retry(i))
{
***************
*** 2567,2572 ****
--- 2613,2628 ----
if (hack)
{
i=SSL_accept(con);
+ while (i <= 0 && SSL_get_error(con,i) == SSL_ERROR_WANT_X509_LOOKUP)
+ {
+ BIO_printf(bio_s_out,"LOOKUP during accept %s\n",srp_callback_parm.login);
+ srp_callback_parm.user = SRP_VBASE_get_by_user(srp_callback_parm.vb, srp_callback_parm.login);
+ if (srp_callback_parm.user)
+ BIO_printf(bio_s_out,"LOOKUP done %s\n",srp_callback_parm.user->info);
+ else
+ BIO_printf(bio_s_out,"LOOKUP not successful\n");
+ i=SSL_accept(con);
+ }
switch (SSL_get_error(con,i))
{
diff -r -c openssl-1.0.1-stable-SNAP-20111219/CHANGES openssl-1.0.1-stable-SNAP-20111219PS/CHANGES
*** openssl-1.0.1-stable-SNAP-20111219/CHANGES 2011-12-10 02:00:19.000000000 +0100
--- openssl-1.0.1-stable-SNAP-20111219PS/CHANGES 2011-12-19 15:43:45.509319433 +0100
***************
*** 4,9 ****
--- 4,13 ----
Changes between 1.0.0f and 1.0.1 [xx XXX xxxx]
+ *) Make TLS-SRP code conformant with RFC 5054
+ API cleanup (removal of unnecessary code)
+ [Peter Sylvester <[email protected]>]
+
*) Add TLS key material exporter from RFC 5705.
[Eric Rescorla]
diff -r -c openssl-1.0.1-stable-SNAP-20111219/ssl/s3_srvr.c openssl-1.0.1-stable-SNAP-20111219PS/ssl/s3_srvr.c
*** openssl-1.0.1-stable-SNAP-20111219/ssl/s3_srvr.c 2011-11-25 02:00:22.000000000 +0100
--- openssl-1.0.1-stable-SNAP-20111219PS/ssl/s3_srvr.c 2011-12-19 15:42:14.677319434 +0100
***************
*** 338,353 ****
case SSL3_ST_SR_CLNT_HELLO_C:
s->shutdown=0;
!
! ret=ssl3_get_client_hello(s);
! if (ret <= 0) goto end;
#ifndef OPENSSL_NO_SRP
{
int al;
! if ((ret = ssl_check_srp_ext_ClientHello(s,&al)) != SSL_ERROR_NONE)
{
! ssl3_send_alert(s,SSL3_AL_FATAL,al);
! SSLerr(SSL_F_SSL3_ACCEPT,SSL_R_CLIENTHELLO_TLSEXT);
ret = SSL_TLSEXT_ERR_ALERT_FATAL;
ret= -1;
goto end;
--- 338,364 ----
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;
! }
#ifndef OPENSSL_NO_SRP
{
int al;
! if ((ret = ssl_check_srp_ext_ClientHello(s,&al)) < 0)
! {
! /* callback indicates firther work to be done */
! s->rwstate=SSL_X509_LOOKUP;
! goto end;
! }
! if (ret != SSL_ERROR_NONE)
{
! ssl3_send_alert(s,SSL3_AL_FATAL,al);
! /* This is not really an error but the only means to
! for a client to detect whether srp is supported. */
! if (al != TLS1_AD_UNKNOWN_PSK_IDENTITY)
! SSLerr(SSL_F_SSL3_ACCEPT,SSL_R_CLIENTHELLO_TLSEXT);
ret = SSL_TLSEXT_ERR_ALERT_FATAL;
ret= -1;
goto end;
diff -r -c openssl-SNAP-20111219/apps/s_server.c openssl-SNAP-20111219PS/apps/s_server.c
*** openssl-SNAP-20111219/apps/s_server.c 2011-11-16 01:00:04.000000000 +0100
--- openssl-SNAP-20111219PS/apps/s_server.c 2011-12-19 15:53:28.745319433 +0100
***************
*** 384,414 ****
/* This is a context that we pass to callbacks */
typedef struct srpsrvparm_st
{
- int verbose;
char *login;
SRP_VBASE *vb;
} srpsrvparm;
static int MS_CALLBACK ssl_srp_server_param_cb(SSL *s, int *ad, void *arg)
{
! srpsrvparm *p = arg;
! SRP_user_pwd *user;
!
! p->login = BUF_strdup(SSL_get_srp_username(s));
! BIO_printf(bio_err, "SRP username = \"%s\"\n", p->login);
! user = SRP_VBASE_get_by_user(p->vb, p->login);
! if (user == NULL)
{
BIO_printf(bio_err, "User %s doesn't exist\n", p->login);
return SSL3_AL_FATAL;
}
! if (SSL_set_srp_server_param(s, user->N, user->g, user->s, user->v,
! user->info) < 0)
{
*ad = SSL_AD_INTERNAL_ERROR;
return SSL3_AL_FATAL;
}
return SSL_ERROR_NONE;
}
--- 384,426 ----
/* This is a context that we pass to callbacks */
typedef struct srpsrvparm_st
{
char *login;
SRP_VBASE *vb;
+ SRP_user_pwd *user;
} srpsrvparm;
+ /* This callback pretends to require some asynchronous logic in order to obtain
+ a verifier. When the callback is called for a new connection we return
+ with a negative value. This will provoke the accept etc to return with
+ an LOOKUP_X509. The main logic of the reinvokes the suspended call
+ (which would normally occur after a worker has finished) and we
+ set the user parameters.
+ */
static int MS_CALLBACK ssl_srp_server_param_cb(SSL *s, int *ad, void *arg)
{
! srpsrvparm *p = (srpsrvparm *)arg;
! if (p->login == NULL && p->user == NULL )
! {
! p->login = SSL_get_srp_username(s);
! BIO_printf(bio_err, "SRP username = \"%s\"\n", p->login);
! return (-1) ;
! }
! if (p->user == NULL)
{
BIO_printf(bio_err, "User %s doesn't exist\n", p->login);
return SSL3_AL_FATAL;
}
! if (SSL_set_srp_server_param(s, p->user->N, p->user->g, p->user->s, p->user->v,
! p->user->info) < 0)
{
*ad = SSL_AD_INTERNAL_ERROR;
return SSL3_AL_FATAL;
}
+ BIO_printf(bio_err, "SRP parameters set: username = \"%s\" info=\"%s\" \n", p->login,p->user->info);
+ /* need to check whether there are memory leaks */
+ p->user = NULL;
+ p->login = NULL;
return SSL_ERROR_NONE;
}
***************
*** 917,922 ****
--- 929,937 ----
#ifndef OPENSSL_NO_JPAKE
static char *jpake_secret = NULL;
#endif
+ #ifndef OPENSSL_NO_SRP
+ static srpsrvparm srp_callback_parm;
+ #endif
static char *srtp_profiles = NULL;
int MAIN(int argc, char *argv[])
***************
*** 964,970 ****
#ifndef OPENSSL_NO_SRP
char *srpuserseed = NULL;
char *srp_verifier_file = NULL;
- srpsrvparm p;
#endif
#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
meth=SSLv23_server_method();
--- 979,984 ----
***************
*** 1871,1878 ****
#ifndef OPENSSL_NO_SRP
if (srp_verifier_file != NULL)
{
! p.vb = SRP_VBASE_new(srpuserseed);
! if ((ret = SRP_VBASE_init(p.vb, srp_verifier_file)) != SRP_NO_ERROR)
{
BIO_printf(bio_err,
"Cannot initialize SRP verifier file \"%s\":ret=%d\n",
--- 1885,1894 ----
#ifndef OPENSSL_NO_SRP
if (srp_verifier_file != NULL)
{
! srp_callback_parm.vb = SRP_VBASE_new(srpuserseed);
! srp_callback_parm.user = NULL;
! srp_callback_parm.login = NULL;
! if ((ret = SRP_VBASE_init(srp_callback_parm.vb, srp_verifier_file)) != SRP_NO_ERROR)
{
BIO_printf(bio_err,
"Cannot initialize SRP verifier file \"%s\":ret=%d\n",
***************
*** 1880,1886 ****
goto end;
}
SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE,verify_callback);
! SSL_CTX_set_srp_cb_arg(ctx, &p);
SSL_CTX_set_srp_username_callback(ctx, ssl_srp_server_param_cb);
}
else
--- 1896,1902 ----
goto end;
}
SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE,verify_callback);
! SSL_CTX_set_srp_cb_arg(ctx, &srp_callback_parm);
SSL_CTX_set_srp_username_callback(ctx, ssl_srp_server_param_cb);
}
else
***************
*** 2249,2254 ****
--- 2265,2280 ----
{ static count=0; if (++count == 100) { count=0; SSL_renegotiate(con); } }
#endif
k=SSL_write(con,&(buf[l]),(unsigned int)i);
+ while (SSL_get_error(con,k) == SSL_ERROR_WANT_X509_LOOKUP)
+ {
+ BIO_printf(bio_s_out,"LOOKUP renego during write\n");
+ srp_callback_parm.user = SRP_VBASE_get_by_user(srp_callback_parm.vb, srp_callback_parm.login);
+ if (srp_callback_parm.user)
+ BIO_printf(bio_s_out,"LOOKUP done %s\n",srp_callback_parm.user->info);
+ else
+ BIO_printf(bio_s_out,"LOOKUP not successful\n");
+ k=SSL_write(con,&(buf[l]),(unsigned int)i);
+ }
switch (SSL_get_error(con,k))
{
case SSL_ERROR_NONE:
***************
*** 2296,2301 ****
--- 2322,2337 ----
{
again:
i=SSL_read(con,(char *)buf,bufsize);
+ while (SSL_get_error(con,i) == SSL_ERROR_WANT_X509_LOOKUP)
+ {
+ BIO_printf(bio_s_out,"LOOKUP renego during read\n");
+ srp_callback_parm.user = SRP_VBASE_get_by_user(srp_callback_parm.vb, srp_callback_parm.login);
+ if (srp_callback_parm.user)
+ BIO_printf(bio_s_out,"LOOKUP done %s\n",srp_callback_parm.user->info);
+ else
+ BIO_printf(bio_s_out,"LOOKUP not successful\n");
+ i=SSL_read(con,(char *)buf,bufsize);
+ }
switch (SSL_get_error(con,i))
{
case SSL_ERROR_NONE:
***************
*** 2308,2314 ****
break;
case SSL_ERROR_WANT_WRITE:
case SSL_ERROR_WANT_READ:
- case SSL_ERROR_WANT_X509_LOOKUP:
BIO_printf(bio_s_out,"Read BLOCK\n");
break;
case SSL_ERROR_SYSCALL:
--- 2344,2349 ----
***************
*** 2373,2379 ****
unsigned char *exportedkeymat;
! if ((i=SSL_accept(con)) <= 0)
{
if (BIO_sock_should_retry(i))
{
--- 2408,2425 ----
unsigned char *exportedkeymat;
! i=SSL_accept(con);
! while (i <= 0 && SSL_get_error(con,i) == SSL_ERROR_WANT_X509_LOOKUP)
! {
! BIO_printf(bio_s_out,"LOOKUP during accept %s\n",srp_callback_parm.login);
! srp_callback_parm.user = SRP_VBASE_get_by_user(srp_callback_parm.vb, srp_callback_parm.login);
! if (srp_callback_parm.user)
! BIO_printf(bio_s_out,"LOOKUP done %s\n",srp_callback_parm.user->info);
! else
! BIO_printf(bio_s_out,"LOOKUP not successful\n");
! i=SSL_accept(con);
! }
! if (i <= 0)
{
if (BIO_sock_should_retry(i))
{
***************
*** 2593,2598 ****
--- 2639,2654 ----
if (hack)
{
i=SSL_accept(con);
+ while (i <= 0 && SSL_get_error(con,i) == SSL_ERROR_WANT_X509_LOOKUP)
+ {
+ BIO_printf(bio_s_out,"LOOKUP during accept %s\n",srp_callback_parm.login);
+ srp_callback_parm.user = SRP_VBASE_get_by_user(srp_callback_parm.vb, srp_callback_parm.login);
+ if (srp_callback_parm.user)
+ BIO_printf(bio_s_out,"LOOKUP done %s\n",srp_callback_parm.user->info);
+ else
+ BIO_printf(bio_s_out,"LOOKUP not successful\n");
+ i=SSL_accept(con);
+ }
switch (SSL_get_error(con,i))
{
diff -r -c openssl-SNAP-20111219/CHANGES openssl-SNAP-20111219PS/CHANGES
*** openssl-SNAP-20111219/CHANGES 2011-12-13 17:00:02.000000000 +0100
--- openssl-SNAP-20111219PS/CHANGES 2011-12-19 15:48:19.645319434 +0100
***************
*** 258,263 ****
--- 258,267 ----
*) Add -attime option to openssl utilities.
[Peter Eckersley <[email protected]>, Ben Laurie and Steve Henson]
+ *) Make TLS-SRP code conformant with RFC 5054
+ API cleanup (removal of unnecessary code)
+ [Peter Sylvester <[email protected]>]
+
*) Add TLS key material exporter from RFC 5705.
[Eric Rescorla]
Only in openssl-SNAP-20111219PS: CHANGES.orig
diff -r -c openssl-SNAP-20111219/ssl/s3_srvr.c openssl-SNAP-20111219PS/ssl/s3_srvr.c
*** openssl-SNAP-20111219/ssl/s3_srvr.c 2011-11-25 02:00:10.000000000 +0100
--- openssl-SNAP-20111219PS/ssl/s3_srvr.c 2011-12-19 15:54:41.525319433 +0100
***************
*** 339,361 ****
case SSL3_ST_SR_CLNT_HELLO_B:
case SSL3_ST_SR_CLNT_HELLO_C:
! s->shutdown=0;
! ret=ssl3_get_client_hello(s);
! if (ret <= 0) goto end;
#ifndef OPENSSL_NO_SRP
{
int al;
!
! if ((ret = ssl_check_srp_ext_ClientHello(s,&al)) != SSL_ERROR_NONE)
! {
! ssl3_send_alert(s,SSL3_AL_FATAL,al);
! SSLerr(SSL_F_SSL3_ACCEPT,SSL_R_CLIENTHELLO_TLSEXT);
ret = SSL_TLSEXT_ERR_ALERT_FATAL;
ret= -1;
goto end;
! }
}
! #endif
s->renegotiate = 2;
s->state=SSL3_ST_SW_SRVR_HELLO_A;
--- 339,371 ----
case SSL3_ST_SR_CLNT_HELLO_B:
case SSL3_ST_SR_CLNT_HELLO_C:
! if (s->rwstate != SSL_X509_LOOKUP)
! {
! ret=ssl3_get_client_hello(s);
! if (ret <= 0) goto end;
! }
#ifndef OPENSSL_NO_SRP
{
int al;
! if ((ret = ssl_check_srp_ext_ClientHello(s,&al)) < 0)
! {
! /* callback indicates firther work to be done */
! s->rwstate=SSL_X509_LOOKUP;
! goto end;
! }
! if (ret != SSL_ERROR_NONE)
! {
! ssl3_send_alert(s,SSL3_AL_FATAL,al);
! /* This is not really an error but the only means to
! for a client to detect whether srp is supported. */
! if (al != TLS1_AD_UNKNOWN_PSK_IDENTITY)
! SSLerr(SSL_F_SSL3_ACCEPT,SSL_R_CLIENTHELLO_TLSEXT);
ret = SSL_TLSEXT_ERR_ALERT_FATAL;
ret= -1;
goto end;
! }
}
! #endif
s->renegotiate = 2;
s->state=SSL3_ST_SW_SRVR_HELLO_A;