static int s_msg=0;
static int s_quiet=0;
+static char *keymatexportlabel=NULL;
+static int keymatexportlen=20;
+
static int hack=0;
#ifndef OPENSSL_NO_ENGINE
static char *engine_id=NULL;
static int cert_chain = 0;
#endif
+
#ifndef OPENSSL_NO_PSK
static char *psk_identity="Client_identity";
char *psk_key=NULL; /* by default PSK is not used */
/* This is a context that we pass to callbacks */
typedef struct srpsrvparm_st
{
- int verbose;
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;
- SRP_user_pwd *user;
-
- p->login = BUF_strdup(SSL_get_srp_username(s));
- BIO_printf(bio_err, "SRP username = \"%s\"\n", p->login);
+ 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) ;
+ }
- user = SRP_VBASE_get_by_user(p->vb, p->login);
- if (user == NULL)
+ 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, user->N, user->g, user->s, user->v,
- user->info) < 0)
+ 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;
}
# ifndef OPENSSL_NO_NEXTPROTONEG
BIO_printf(bio_err," -nextprotoneg arg - set the advertised protocols for the NPN extension (comma-separated list)\n");
# endif
+ BIO_printf(bio_err," -use_srtp profiles - Offer SRTP key management with a colon-separated profile list");
#endif
+ BIO_printf(bio_err," -keymatexport label - Export keying material using label\n");
+ BIO_printf(bio_err," -keymatexportlen len - Export len bytes of keying material (default 20)\n");
}
static int local_argc=0;
#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[])
{
#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();
psk_key=*(++argv);
for (i=0; i<strlen(psk_key); i++)
{
- if (isxdigit((int)psk_key[i]))
+ if (isxdigit((unsigned char)psk_key[i]))
continue;
BIO_printf(bio_err,"Not a hex number '%s'\n",*argv);
goto bad;
jpake_secret = *(++argv);
}
#endif
+ else if (strcmp(*argv,"-use_srtp") == 0)
+ {
+ if (--argc < 1) goto bad;
+ srtp_profiles = *(++argv);
+ }
+ else if (strcmp(*argv,"-keymatexport") == 0)
+ {
+ if (--argc < 1) goto bad;
+ keymatexportlabel= *(++argv);
+ }
+ else if (strcmp(*argv,"-keymatexportlen") == 0)
+ {
+ if (--argc < 1) goto bad;
+ keymatexportlen=atoi(*(++argv));
+ if (keymatexportlen == 0) goto bad;
+ }
else
{
BIO_printf(bio_err,"unknown option %s\n",*argv);
else
SSL_CTX_sess_set_cache_size(ctx,128);
+ if (srtp_profiles != NULL)
+ SSL_CTX_set_tlsext_use_srtp(ctx, srtp_profiles);
+
#if 0
if (cipher == NULL) cipher=getenv("SSL_CIPHER");
#endif
#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)
+ 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",
goto end;
}
SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE,verify_callback);
- SSL_CTX_set_srp_cb_arg(ctx, &p);
+ SSL_CTX_set_srp_cb_arg(ctx, &srp_callback_parm);
SSL_CTX_set_srp_username_callback(ctx, ssl_srp_server_param_cb);
}
else
goto err;
}
+#ifndef OPENSSL_NO_HEARTBEATS
+ if ((buf[0] == 'B') &&
+ ((buf[1] == '\n') || (buf[1] == '\r')))
+ {
+ BIO_printf(bio_err,"HEARTBEATING\n");
+ SSL_heartbeat(con);
+ i=0;
+ continue;
+ }
+#endif
if ((buf[0] == 'r') &&
((buf[1] == '\n') || (buf[1] == '\r')))
{
{ static count=0; if (++count == 100) { count=0; SSL_renegotiate(con); } }
#endif
k=SSL_write(con,&(buf[l]),(unsigned int)i);
+#ifndef OPENSSL_NO_SRP
+ 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);
+ }
+#endif
switch (SSL_get_error(con,k))
{
case SSL_ERROR_NONE:
{
again:
i=SSL_read(con,(char *)buf,bufsize);
+#ifndef OPENSSL_NO_SRP
+ 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);
+ }
+#endif
switch (SSL_get_error(con,i))
{
case SSL_ERROR_NONE:
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:
const unsigned char *next_proto_neg;
unsigned next_proto_neg_len;
#endif
+ unsigned char *exportedkeymat;
- if ((i=SSL_accept(con)) <= 0)
+
+ i=SSL_accept(con);
+#ifndef OPENSSL_NO_SRP
+ 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);
+ }
+#endif
+ if (i <= 0)
{
if (BIO_sock_should_retry(i))
{
BIO_printf(bio_s_out, "\n");
}
#endif
+ {
+ SRTP_PROTECTION_PROFILE *srtp_profile
+ = SSL_get_selected_srtp_profile(con);
+
+ if(srtp_profile)
+ BIO_printf(bio_s_out,"SRTP Extension negotiated, profile=%s\n",
+ srtp_profile->name);
+ }
if (SSL_cache_hit(con)) BIO_printf(bio_s_out,"Reused session-id\n");
if (SSL_ctrl(con,SSL_CTRL_GET_FLAGS,0,NULL) &
TLS1_FLAGS_TLS_PADDING_BUG)
- BIO_printf(bio_s_out,"Peer has incorrect TLSv1 block padding\n");
+ BIO_printf(bio_s_out,
+ "Peer has incorrect TLSv1 block padding\n");
#ifndef OPENSSL_NO_KRB5
client_princ = kssl_ctx_get0_client_princ(SSL_get0_kssl_ctx(con));
if (client_princ != NULL)
#endif /* OPENSSL_NO_KRB5 */
BIO_printf(bio_s_out, "Secure Renegotiation IS%s supported\n",
SSL_get_secure_renegotiation_support(con) ? "" : " NOT");
+ if (keymatexportlabel != NULL) {
+ BIO_printf(bio_s_out, "Keying material exporter:\n");
+ BIO_printf(bio_s_out, " Label: '%s'\n", keymatexportlabel);
+ BIO_printf(bio_s_out, " Length: %i bytes\n",
+ keymatexportlen);
+ exportedkeymat = OPENSSL_malloc(keymatexportlen);
+ if (exportedkeymat != NULL) {
+ i = SSL_export_keying_material(con, exportedkeymat,
+ keymatexportlen,
+ keymatexportlabel,
+ strlen(keymatexportlabel),
+ NULL, 0, 0);
+ if (i != keymatexportlen) {
+ BIO_printf(bio_s_out,
+ " Error: return value %i\n", i);
+ } else {
+ BIO_printf(bio_s_out, " Keying material: ");
+ for (i=0; i<keymatexportlen; i++)
+ BIO_printf(bio_s_out, "%02X",
+ exportedkeymat[i]);
+ BIO_printf(bio_s_out, "\n");
+ }
+ OPENSSL_free(exportedkeymat);
+ }
+ }
+
return(1);
}
if (hack)
{
i=SSL_accept(con);
-
+#ifndef OPENSSL_NO_SRP
+ 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);
+ }
+#endif
switch (SSL_get_error(con,i))
{
case SSL_ERROR_NONE: