X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fssltest.c;h=db87b1a35ea1af9f76ae6f6d4cea17c293ac113b;hp=abf214ad7f9b4d2a7f324c4e68f3d1ec8c9cc711;hb=c6913eeb762edffddecaaba5c84909d7a7962927;hpb=bc120a54c9268ac37ede72aa88ed49ac6dbd4403 diff --git a/ssl/ssltest.c b/ssl/ssltest.c index abf214ad7f..db87b1a35e 100644 --- a/ssl/ssltest.c +++ b/ssl/ssltest.c @@ -181,6 +181,9 @@ #ifndef OPENSSL_NO_DH #include #endif +#ifndef OPENSSL_NO_SRP +#include +#endif #include #define _XOPEN_SOURCE_EXTENDED 1 /* Or gethostname won't be declared properly @@ -246,9 +249,127 @@ static unsigned int psk_server_callback(SSL *ssl, const char *identity, unsigned unsigned int max_psk_len); #endif +#ifndef OPENSSL_NO_SRP +/* SRP client */ +/* This is a context that we pass to all callbacks */ +typedef struct srp_client_arg_st + { + char *srppassin; + char *srplogin; + } SRP_CLIENT_ARG; + +#define PWD_STRLEN 1024 + +static char * MS_CALLBACK ssl_give_srp_client_pwd_cb(SSL *s, void *arg) + { + SRP_CLIENT_ARG *srp_client_arg = (SRP_CLIENT_ARG *)arg; + return BUF_strdup((char *)srp_client_arg->srppassin); + } + +/* SRP server */ +/* This is a context that we pass to SRP server callbacks */ +typedef struct srp_server_arg_st + { + char *expected_user; + char *pass; + } SRP_SERVER_ARG; + +static int MS_CALLBACK ssl_srp_server_param_cb(SSL *s, int *ad, void *arg) + { + SRP_SERVER_ARG * p = (SRP_SERVER_ARG *) arg; + + if (strcmp(p->expected_user, SSL_get_srp_username(s)) != 0) + { + fprintf(stderr, "User %s doesn't exist\n", SSL_get_srp_username(s)); + return SSL3_AL_FATAL; + } + if (SSL_set_srp_server_param_pw(s,p->expected_user,p->pass,"1024")<0) + { + *ad = SSL_AD_INTERNAL_ERROR; + return SSL3_AL_FATAL; + } + return SSL_ERROR_NONE; + } +#endif + static BIO *bio_err=NULL; static BIO *bio_stdout=NULL; +#ifndef OPENSSL_NO_NPN +/* Note that this code assumes that this is only a one element list: */ +static const char NEXT_PROTO_STRING[] = "\x09testproto"; +int npn_client = 0; +int npn_server = 0; +int npn_server_reject = 0; + +static int cb_client_npn(SSL *s, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg) + { + /* This callback only returns the protocol string, rather than a length + prefixed set. We assume that NEXT_PROTO_STRING is a one element list and + remove the first byte to chop off the length prefix. */ + *out = (unsigned char*) NEXT_PROTO_STRING + 1; + *outlen = sizeof(NEXT_PROTO_STRING) - 2; + return SSL_TLSEXT_ERR_OK; + } + +static int cb_server_npn(SSL *s, const unsigned char **data, unsigned int *len, void *arg) + { + *data = (const unsigned char *) NEXT_PROTO_STRING; + *len = sizeof(NEXT_PROTO_STRING) - 1; + return SSL_TLSEXT_ERR_OK; + } + +static int cb_server_rejects_npn(SSL *s, const unsigned char **data, unsigned int *len, void *arg) + { + return SSL_TLSEXT_ERR_NOACK; + } + +static int verify_npn(SSL *client, SSL *server) + { + const unsigned char *client_s; + unsigned client_len; + const unsigned char *server_s; + unsigned server_len; + + SSL_get0_next_proto_negotiated(client, &client_s, &client_len); + SSL_get0_next_proto_negotiated(server, &server_s, &server_len); + + if (client_len) + { + BIO_printf(bio_stdout, "Client NPN: "); + BIO_write(bio_stdout, client_s, client_len); + BIO_printf(bio_stdout, "\n"); + } + + if (server_len) + { + BIO_printf(bio_stdout, "Server NPN: "); + BIO_write(bio_stdout, server_s, server_len); + BIO_printf(bio_stdout, "\n"); + } + + /* If an NPN string was returned, it must be the protocol that we + * expected to negotiate. */ + if (client_len && (client_len != sizeof(NEXT_PROTO_STRING) - 2 || + memcmp(client_s, NEXT_PROTO_STRING + 1, client_len))) + return -1; + if (server_len && (server_len != sizeof(NEXT_PROTO_STRING) - 2 || + memcmp(server_s, NEXT_PROTO_STRING + 1, server_len))) + return -1; + + if (!npn_client && client_len) + return -1; + if (!npn_server && server_len) + return -1; + if (npn_server_reject && server_len) + return -1; + if (npn_client && npn_server && (!client_len || !server_len)) + return -1; + + return 0; + } +#endif + static char *cipher=NULL; static int verbose=0; static int debug=0; @@ -268,6 +389,9 @@ static void sv_usage(void) { fprintf(stderr,"usage: ssltest [args ...]\n"); fprintf(stderr,"\n"); +#ifdef OPENSSL_FIPS + fprintf(stderr,"-F - run test in FIPS mode\n"); +#endif fprintf(stderr," -server_auth - check server certificate\n"); fprintf(stderr," -client_auth - do client authentication\n"); fprintf(stderr," -proxy - allow proxy certificates\n"); @@ -289,6 +413,10 @@ static void sv_usage(void) #ifndef OPENSSL_NO_PSK fprintf(stderr," -psk arg - PSK in hex (without 0x)\n"); #endif +#ifndef OPENSSL_NO_SRP + fprintf(stderr," -srpuser user - SRP username to use\n"); + fprintf(stderr," -srppass arg - password for 'user'\n"); +#endif #ifndef OPENSSL_NO_SSL2 fprintf(stderr," -ssl2 - use SSLv2\n"); #endif @@ -316,6 +444,11 @@ static void sv_usage(void) " (default is sect163r2).\n"); #endif fprintf(stderr," -test_cipherlist - verifies the order of the ssl cipher lists\n"); +#ifndef OPENSSL_NO_NPN + fprintf(stderr," -npn_client - have client side offer NPN\n"); + fprintf(stderr," -npn_server - have server side offer NPN\n"); + fprintf(stderr," -npn_server_reject - have server reject NPN\n"); +#endif } static void print_details(SSL *c_ssl, const char *prefix) @@ -475,18 +608,27 @@ int main(int argc, char *argv[]) #endif #ifndef OPENSSL_NO_ECDH EC_KEY *ecdh = NULL; +#endif +#ifndef OPENSSL_NO_SRP + /* client */ + SRP_CLIENT_ARG srp_client_arg = {NULL,NULL}; + /* server */ + SRP_SERVER_ARG srp_server_arg = {NULL,NULL}; #endif int no_dhe = 0; int no_ecdhe = 0; int no_psk = 0; int print_time = 0; clock_t s_time = 0, c_time = 0; - int comp = 0; #ifndef OPENSSL_NO_COMP + int comp = 0; COMP_METHOD *cm = NULL; -#endif STACK_OF(SSL_COMP) *ssl_comp_methods = NULL; +#endif int test_cipherlist = 0; +#ifdef OPENSSL_FIPS + int fips_mode=0; +#endif verbose = 0; debug = 0; @@ -518,7 +660,16 @@ int main(int argc, char *argv[]) while (argc >= 1) { - if (strcmp(*argv,"-server_auth") == 0) + if(!strcmp(*argv,"-F")) + { +#ifdef OPENSSL_FIPS + fips_mode=1; +#else + fprintf(stderr,"not compiled with FIPS support, so exitting without running.\n"); + EXIT(0); +#endif + } + else if (strcmp(*argv,"-server_auth") == 0) server_auth=1; else if (strcmp(*argv,"-client_auth") == 0) client_auth=1; @@ -572,6 +723,20 @@ int main(int argc, char *argv[]) no_psk=1; #endif } +#ifndef OPENSSL_NO_SRP + else if (strcmp(*argv,"-srpuser") == 0) + { + if (--argc < 1) goto bad; + srp_server_arg.expected_user = srp_client_arg.srplogin= *(++argv); + tls1=1; + } + else if (strcmp(*argv,"-srppass") == 0) + { + if (--argc < 1) goto bad; + srp_server_arg.pass = srp_client_arg.srppassin= *(++argv); + tls1=1; + } +#endif else if (strcmp(*argv,"-ssl2") == 0) ssl2=1; else if (strcmp(*argv,"-tls1") == 0) @@ -650,6 +815,7 @@ int main(int argc, char *argv[]) { print_time = 1; } +#ifndef OPENSSL_NO_COMP else if (strcmp(*argv,"-zlib") == 0) { comp = COMP_ZLIB; @@ -658,6 +824,7 @@ int main(int argc, char *argv[]) { comp = COMP_RLE; } +#endif else if (strcmp(*argv,"-named_curve") == 0) { if (--argc < 1) goto bad; @@ -680,6 +847,20 @@ int main(int argc, char *argv[]) { test_cipherlist = 1; } +#ifndef OPENSSL_NO_NPN + else if (strcmp(*argv,"-npn_client") == 0) + { + npn_client = 1; + } + else if (strcmp(*argv,"-npn_server") == 0) + { + npn_server = 1; + } + else if (strcmp(*argv,"-npn_server_reject") == 0) + { + npn_server_reject = 1; + } +#endif else { fprintf(stderr,"unknown option %s\n",*argv); @@ -714,6 +895,20 @@ bad: EXIT(1); } +#ifdef OPENSSL_FIPS + if(fips_mode) + { + if(!FIPS_mode_set(1)) + { + ERR_load_crypto_strings(); + ERR_print_errors(BIO_new_fp(stderr,BIO_NOCLOSE)); + EXIT(1); + } + else + fprintf(stderr,"*** IN FIPS MODE ***\n"); + } +#endif + if (print_time) { if (!bio_pair) @@ -782,7 +977,13 @@ bad: meth=SSLv23_method(); #else #ifdef OPENSSL_NO_SSL2 - meth=SSLv3_method(); + if (tls1) + meth=TLSv1_method(); + else + if (ssl3) + meth=SSLv3_method(); + else + meth=SSLv23_method(); #else meth=SSLv2_method(); #endif @@ -837,7 +1038,11 @@ bad: } } else +#ifdef OPENSSL_NO_EC2M + nid = NID_X9_62_prime256v1; +#else nid = NID_sect163r2; +#endif ecdh = EC_KEY_new_by_curve_name(nid); if (ecdh == NULL) @@ -940,6 +1145,46 @@ bad: } #endif } +#ifndef OPENSSL_NO_SRP + if (srp_client_arg.srplogin) + { + if (!SSL_CTX_set_srp_username(c_ctx, srp_client_arg.srplogin)) + { + BIO_printf(bio_err,"Unable to set SRP username\n"); + goto end; + } + SSL_CTX_set_srp_cb_arg(c_ctx,&srp_client_arg); + SSL_CTX_set_srp_client_pwd_callback(c_ctx, ssl_give_srp_client_pwd_cb); + /*SSL_CTX_set_srp_strength(c_ctx, srp_client_arg.strength);*/ + } + + if (srp_server_arg.expected_user != NULL) + { + SSL_CTX_set_verify(s_ctx,SSL_VERIFY_NONE,verify_callback); + SSL_CTX_set_srp_cb_arg(s_ctx, &srp_server_arg); + SSL_CTX_set_srp_username_callback(s_ctx, ssl_srp_server_param_cb); + } +#endif + +#ifndef OPENSSL_NO_NPN + if (npn_client) + { + SSL_CTX_set_next_proto_select_cb(c_ctx, cb_client_npn, NULL); + } + if (npn_server) + { + if (npn_server_reject) + { + BIO_printf(bio_err, "Can't have both -npn_server and -npn_server_reject\n"); + goto end; + } + SSL_CTX_set_next_protos_advertised_cb(s_ctx, cb_server_npn, NULL); + } + if (npn_server_reject) + { + SSL_CTX_set_next_protos_advertised_cb(s_ctx, cb_server_rejects_npn, NULL); + } +#endif c_ssl=SSL_new(c_ctx); s_ssl=SSL_new(s_ctx); @@ -1391,6 +1636,13 @@ int doit_biopair(SSL *s_ssl, SSL *c_ssl, long count, if (verbose) print_details(c_ssl, "DONE via BIO pair: "); +#ifndef OPENSSL_NO_NPN + if (verify_npn(c_ssl, s_ssl) < 0) + { + ret = 1; + goto end; + } +#endif end: ret = 0; @@ -1430,7 +1682,6 @@ int doit(SSL *s_ssl, SSL *c_ssl, long count) BIO *c_bio=NULL; BIO *s_bio=NULL; int c_r,c_w,s_r,s_w; - int c_want,s_want; int i,j; int done=0; int c_write,s_write; @@ -1465,8 +1716,6 @@ int doit(SSL *s_ssl, SSL *c_ssl, long count) c_r=0; s_r=1; c_w=1; s_w=0; - c_want=W_WRITE; - s_want=0; c_write=1,s_write=0; /* We can always do writes */ @@ -1689,6 +1938,13 @@ int doit(SSL *s_ssl, SSL *c_ssl, long count) if (verbose) print_details(c_ssl, "DONE: "); +#ifndef OPENSSL_NO_NPN + if (verify_npn(c_ssl, s_ssl) < 0) + { + ret = 1; + goto err; + } +#endif ret=0; err: /* We have to set the BIO's to NULL otherwise they will be @@ -2167,15 +2423,7 @@ static int MS_CALLBACK app_verify_callback(X509_STORE_CTX *ctx, void *arg) } #ifndef OPENSSL_NO_X509_VERIFY -# ifdef OPENSSL_FIPS - if(s->version == TLS1_VERSION) - FIPS_allow_md5(1); -# endif ok = X509_verify_cert(ctx); -# ifdef OPENSSL_FIPS - if(s->version == TLS1_VERSION) - FIPS_allow_md5(0); -# endif #endif if (cb_arg->proxy_auth)