X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fssltest.c;h=9ff21171b1cc543511b94cd49154fe4ef5b60973;hp=3c010409abeb5e3cd8d5908c867a074eb86b46da;hb=aae3233e1e08e9f11742f8f351af5c98cd8add16;hpb=2e00f46b515ecf3c6378d7e7362e7c0044a204cc diff --git a/ssl/ssltest.c b/ssl/ssltest.c index 3c010409ab..9ff21171b1 100644 --- a/ssl/ssltest.c +++ b/ssl/ssltest.c @@ -140,8 +140,8 @@ * OTHERWISE. */ -#define _BSD_SOURCE 1 /* Or gethostname won't be declared properly - on Linux and GNU platforms. */ +/* Or gethostname won't be declared properly on Linux and GNU platforms. */ +#define _BSD_SOURCE 1 #include #include @@ -155,8 +155,8 @@ #include "e_os.h" #ifdef OPENSSL_SYS_VMS -#define _XOPEN_SOURCE 500 /* Or isascii won't be declared properly on - VMS (at least with DECompHP C). */ +/* Or isascii won't be declared properly on VMS (at least with DECompHP C). */ +#define _XOPEN_SOURCE 500 #endif #include @@ -186,11 +186,13 @@ #endif #include -#define _XOPEN_SOURCE_EXTENDED 1 /* Or gethostname won't be declared properly - on Compaq platforms (at least with DEC C). - Do not try to put it earlier, or IPv6 includes - get screwed... - */ +/* + * Or gethostname won't be declared properly + * on Compaq platforms (at least with DEC C). + * Do not try to put it earlier, or IPv6 includes + * get screwed... +*/ +#define _XOPEN_SOURCE_EXTENDED 1 #ifdef OPENSSL_SYS_WINDOWS #include @@ -295,6 +297,364 @@ static int MS_CALLBACK ssl_srp_server_param_cb(SSL *s, int *ad, void *arg) static BIO *bio_err=NULL; static BIO *bio_stdout=NULL; +static const char *alpn_client; +static const char *alpn_server; +static const char *alpn_expected; +static unsigned char *alpn_selected; + +/*- + * next_protos_parse parses a comma separated list of strings into a string + * in a format suitable for passing to SSL_CTX_set_next_protos_advertised. + * outlen: (output) set to the length of the resulting buffer on success. + * err: (maybe NULL) on failure, an error message line is written to this BIO. + * in: a NUL terminated string like "abc,def,ghi" + * + * returns: a malloced buffer or NULL on failure. + */ +static unsigned char *next_protos_parse(unsigned short *outlen, const char *in) + { + size_t len; + unsigned char *out; + size_t i, start = 0; + + len = strlen(in); + if (len >= 65535) + return NULL; + + out = OPENSSL_malloc(strlen(in) + 1); + if (!out) + return NULL; + + for (i = 0; i <= len; ++i) + { + if (i == len || in[i] == ',') + { + if (i - start > 255) + { + OPENSSL_free(out); + return NULL; + } + out[start] = i - start; + start = i + 1; + } + else + out[i+1] = in[i]; + } + + *outlen = len + 1; + return out; + } + +static int cb_server_alpn(SSL *s, const unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg) + { + unsigned char *protos; + unsigned short protos_len; + + protos = next_protos_parse(&protos_len, alpn_server); + if (protos == NULL) + { + fprintf(stderr, "failed to parser ALPN server protocol string: %s\n", alpn_server); + abort(); + } + + if (SSL_select_next_proto((unsigned char**) out, outlen, protos, protos_len, in, inlen) != + OPENSSL_NPN_NEGOTIATED) + { + OPENSSL_free(protos); + return SSL_TLSEXT_ERR_NOACK; + } + + /* Make a copy of the selected protocol which will be freed in verify_alpn. */ + alpn_selected = OPENSSL_malloc(*outlen); + memcpy(alpn_selected, *out, *outlen); + *out = alpn_selected; + + OPENSSL_free(protos); + return SSL_TLSEXT_ERR_OK; + } + +static int verify_alpn(SSL *client, SSL *server) + { + const unsigned char *client_proto, *server_proto; + unsigned int client_proto_len = 0, server_proto_len = 0; + SSL_get0_alpn_selected(client, &client_proto, &client_proto_len); + SSL_get0_alpn_selected(server, &server_proto, &server_proto_len); + + if (alpn_selected != NULL) + { + OPENSSL_free(alpn_selected); + alpn_selected = NULL; + } + + if (client_proto_len != server_proto_len || + memcmp(client_proto, server_proto, client_proto_len) != 0) + { + BIO_printf(bio_stdout, "ALPN selected protocols differ!\n"); + goto err; + } + + if (client_proto_len > 0 && alpn_expected == NULL) + { + BIO_printf(bio_stdout, "ALPN unexpectedly negotiated\n"); + goto err; + } + + if (alpn_expected != NULL && + (client_proto_len != strlen(alpn_expected) || + memcmp(client_proto, alpn_expected, client_proto_len) != 0)) + { + BIO_printf(bio_stdout, "ALPN selected protocols not equal to expected protocol: %s\n", alpn_expected); + goto err; + } + + return 0; + +err: + BIO_printf(bio_stdout, "ALPN results: client: '"); + BIO_write(bio_stdout, client_proto, client_proto_len); + BIO_printf(bio_stdout, "', server: '"); + BIO_write(bio_stdout, server_proto, server_proto_len); + BIO_printf(bio_stdout, "'\n"); + BIO_printf(bio_stdout, "ALPN configured: client: '%s', server: '%s'\n", alpn_client, alpn_server); + return -1; + } + +#define SCT_EXT_TYPE 18 + +/* WARNING : below extension types are *NOT* IETF assigned, and + could conflict if these types are reassigned and handled + specially by OpenSSL in the future */ +#define TACK_EXT_TYPE 62208 +#define CUSTOM_EXT_TYPE_0 1000 +#define CUSTOM_EXT_TYPE_1 1001 +#define CUSTOM_EXT_TYPE_2 1002 +#define CUSTOM_EXT_TYPE_3 1003 + +const char custom_ext_cli_string[] = "abc"; +const char custom_ext_srv_string[] = "defg"; + +/* These set from cmdline */ +char* serverinfo_file = NULL; +int serverinfo_sct = 0; +int serverinfo_tack = 0; + +/* These set based on extension callbacks */ +int serverinfo_sct_seen = 0; +int serverinfo_tack_seen = 0; +int serverinfo_other_seen = 0; + +/* This set from cmdline */ +int custom_ext = 0; + +/* This set based on extension callbacks */ +int custom_ext_error = 0; + +static int serverinfo_cli_parse_cb(SSL *s, unsigned int ext_type, + const unsigned char *in, size_t inlen, + int *al, void *arg) + { + if (ext_type == SCT_EXT_TYPE) + serverinfo_sct_seen++; + else if (ext_type == TACK_EXT_TYPE) + serverinfo_tack_seen++; + else + serverinfo_other_seen++; + return 1; + } + +static int verify_serverinfo() + { + if (serverinfo_sct != serverinfo_sct_seen) + return -1; + if (serverinfo_tack != serverinfo_tack_seen) + return -1; + if (serverinfo_other_seen) + return -1; + return 0; + } + +/*- + * Four test cases for custom extensions: + * 0 - no ClientHello extension or ServerHello response + * 1 - ClientHello with "abc", no response + * 2 - ClientHello with "abc", empty response + * 3 - ClientHello with "abc", "defg" response + */ + +static int custom_ext_0_cli_add_cb(SSL *s, unsigned int ext_type, + const unsigned char **out, + size_t *outlen, int *al, void *arg) + { + if (ext_type != CUSTOM_EXT_TYPE_0) + custom_ext_error = 1; + return 0; /* Don't send an extension */ + } + +static int custom_ext_0_cli_parse_cb(SSL *s, unsigned int ext_type, + const unsigned char *in, + size_t inlen, int *al, + void *arg) + { + return 1; + } + +static int custom_ext_1_cli_add_cb(SSL *s, unsigned int ext_type, + const unsigned char **out, + size_t *outlen, int *al, void *arg) + { + if (ext_type != CUSTOM_EXT_TYPE_1) + custom_ext_error = 1; + *out = (const unsigned char*)custom_ext_cli_string; + *outlen = strlen(custom_ext_cli_string); + return 1; /* Send "abc" */ + } + +static int custom_ext_1_cli_parse_cb(SSL *s, unsigned int ext_type, + const unsigned char *in, + size_t inlen, int *al, + void *arg) + { + return 1; + } + +static int custom_ext_2_cli_add_cb(SSL *s, unsigned int ext_type, + const unsigned char **out, + size_t *outlen, int *al, void *arg) + { + if (ext_type != CUSTOM_EXT_TYPE_2) + custom_ext_error = 1; + *out = (const unsigned char*)custom_ext_cli_string; + *outlen = strlen(custom_ext_cli_string); + return 1; /* Send "abc" */ + } + +static int custom_ext_2_cli_parse_cb(SSL *s, unsigned int ext_type, + const unsigned char *in, + size_t inlen, int *al, + void *arg) + { + if (ext_type != CUSTOM_EXT_TYPE_2) + custom_ext_error = 1; + if (inlen != 0) + custom_ext_error = 1; /* Should be empty response */ + return 1; + } + +static int custom_ext_3_cli_add_cb(SSL *s, unsigned int ext_type, + const unsigned char **out, + size_t *outlen, int *al, void *arg) + { + if (ext_type != CUSTOM_EXT_TYPE_3) + custom_ext_error = 1; + *out = (const unsigned char*)custom_ext_cli_string; + *outlen = strlen(custom_ext_cli_string); + return 1; /* Send "abc" */ + } + +static int custom_ext_3_cli_parse_cb(SSL *s, unsigned int ext_type, + const unsigned char *in, + size_t inlen, int *al, + void *arg) + { + if (ext_type != CUSTOM_EXT_TYPE_3) + custom_ext_error = 1; + if (inlen != strlen(custom_ext_srv_string)) + custom_ext_error = 1; + if (memcmp(custom_ext_srv_string, in, inlen) != 0) + custom_ext_error = 1; /* Check for "defg" */ + return 1; + } + +/* custom_ext_0_cli_add_cb returns 0 - the server won't receive a callback for this extension */ +static int custom_ext_0_srv_parse_cb(SSL *s, unsigned int ext_type, + const unsigned char *in, + size_t inlen, int *al, + void *arg) + { + custom_ext_error = 1; + return 1; + } + +/* 'add' callbacks are only called if the 'parse' callback is called */ +static int custom_ext_0_srv_add_cb(SSL *s, unsigned int ext_type, + const unsigned char **out, + size_t *outlen, int *al, void *arg) + { + /* Error: should not have been called */ + custom_ext_error = 1; + return 0; /* Don't send an extension */ + } + +static int custom_ext_1_srv_parse_cb(SSL *s, unsigned int ext_type, + const unsigned char *in, + size_t inlen, int *al, + void *arg) + { + if (ext_type != CUSTOM_EXT_TYPE_1) + custom_ext_error = 1; + /* Check for "abc" */ + if (inlen != strlen(custom_ext_cli_string)) + custom_ext_error = 1; + if (memcmp(in, custom_ext_cli_string, inlen) != 0) + custom_ext_error = 1; + return 1; + } + +static int custom_ext_1_srv_add_cb(SSL *s, unsigned int ext_type, + const unsigned char **out, + size_t *outlen, int *al, void *arg) + { + return 0; /* Don't send an extension */ + } + +static int custom_ext_2_srv_parse_cb(SSL *s, unsigned int ext_type, + const unsigned char *in, + size_t inlen, int *al, + void *arg) + { + if (ext_type != CUSTOM_EXT_TYPE_2) + custom_ext_error = 1; + /* Check for "abc" */ + if (inlen != strlen(custom_ext_cli_string)) + custom_ext_error = 1; + if (memcmp(in, custom_ext_cli_string, inlen) != 0) + custom_ext_error = 1; + return 1; + } + +static int custom_ext_2_srv_add_cb(SSL *s, unsigned int ext_type, + const unsigned char **out, + size_t *outlen, int *al, void *arg) + { + *out = NULL; + *outlen = 0; + return 1; /* Send empty extension */ + } + +static int custom_ext_3_srv_parse_cb(SSL *s, unsigned int ext_type, + const unsigned char *in, + size_t inlen, int *al, + void *arg) + { + if (ext_type != CUSTOM_EXT_TYPE_3) + custom_ext_error = 1; + /* Check for "abc" */ + if (inlen != strlen(custom_ext_cli_string)) + custom_ext_error = 1; + if (memcmp(in, custom_ext_cli_string, inlen) != 0) + custom_ext_error = 1; + return 1; + } + +static int custom_ext_3_srv_add_cb(SSL *s, unsigned int ext_type, + const unsigned char **out, + size_t *outlen, int *al, void *arg) + { + *out = (const unsigned char*)custom_ext_srv_string; + *outlen = strlen(custom_ext_srv_string); + return 1; /* Send "defg" */ + } + static char *cipher=NULL; static int verbose=0; static int debug=0; @@ -321,7 +681,7 @@ static void sv_usage(void) fprintf(stderr," -client_auth - do client authentication\n"); fprintf(stderr," -proxy - allow proxy certificates\n"); fprintf(stderr," -proxy_auth - set proxy policy rights\n"); - fprintf(stderr," -proxy_cond - experssion to test proxy policy rights\n"); + fprintf(stderr," -proxy_cond - expression to test proxy policy rights\n"); fprintf(stderr," -v - more output\n"); fprintf(stderr," -d - debug output\n"); fprintf(stderr," -reuse - use session-id reuse\n"); @@ -345,7 +705,7 @@ static void sv_usage(void) #ifndef OPENSSL_NO_SSL2 fprintf(stderr," -ssl2 - use SSLv2\n"); #endif -#ifndef OPENSSL_NO_SSL3 +#ifndef OPENSSL_NO_SSL3_METHOD fprintf(stderr," -ssl3 - use SSLv3\n"); #endif #ifndef OPENSSL_NO_TLS1 @@ -368,12 +728,16 @@ static void sv_usage(void) " Use \"openssl ecparam -list_curves\" for all names\n" \ " (default is sect163r2).\n"); #endif - fprintf(stderr," -test_cipherlist - verifies the order of the ssl cipher lists\n"); -#ifndef OPENSSL_NO_TLSEXT - fprintf(stderr," -server_authz arg - binary authz file for certificate\n"); - fprintf(stderr," -c_support_proof - indicate client support for server_authz audit proofs\n"); - fprintf(stderr," -c_require_proof - fail if no audit proof is sent\n"); -#endif + fprintf(stderr," -test_cipherlist - Verifies the order of the ssl cipher lists.\n" + " When this option is requested, the cipherlist\n" + " tests are run instead of handshake tests.\n"); + fprintf(stderr," -serverinfo_file file - have server use this file\n"); + fprintf(stderr," -serverinfo_sct - have client offer and expect SCT\n"); + fprintf(stderr," -serverinfo_tack - have client offer and expect TACK\n"); + fprintf(stderr," -custom_ext - try various custom extension callbacks\n"); + fprintf(stderr," -alpn_client - have client side offer ALPN\n"); + fprintf(stderr," -alpn_server - have server side offer ALPN\n"); + fprintf(stderr," -alpn_expected - the ALPN protocol that should be negotiated\n"); } static void print_details(SSL *c_ssl, const char *prefix) @@ -503,56 +867,6 @@ int opaque_prf_input_cb(SSL *ssl, void *peerinput, size_t len, void *arg_) } #endif -#ifndef OPENSSL_NO_TLSEXT -struct audit_proof_cb_arg_st - { - unsigned char *expected_proof; - size_t expected_proof_length; - int require; - }; - -struct audit_proof_cb_arg_st c_expected = { NULL, 0, 0 }; - -static int audit_proof_cb(SSL *s, void *arg) - { - const unsigned char *proof; - size_t proof_len; - SSL_SESSION *sess = SSL_get_session(s); - struct audit_proof_cb_arg_st *cb_arg = (struct audit_proof_cb_arg_st*)arg; - - proof = SSL_SESSION_get_tlsext_authz_server_audit_proof(sess, - &proof_len); - if (proof != NULL) - { - if (proof_len == cb_arg->expected_proof_length && - cb_arg->expected_proof != NULL && - memcmp(proof, cb_arg->expected_proof, proof_len) == 0) - { - BIO_printf(bio_stdout, "Audit proof OK (%lu bytes).\n", - (long)proof_len); - return 1; - } - else - { - BIO_printf(bio_stdout, "Audit proof mismatch.\n"); - /* Cause handshake failure. */ - return 0; - } - } - - else /* proof == NULL */ - { - BIO_printf(bio_stdout, "No audit proof found.\n"); - if (cb_arg->require) - { - /* Cause handshake failure. */ - return 0; - } - return 1; - } - } -#endif - int main(int argc, char *argv[]) { char *CApath=NULL,*CAfile=NULL; @@ -604,11 +918,7 @@ int main(int argc, char *argv[]) #ifdef OPENSSL_FIPS int fips_mode=0; #endif -#ifndef OPENSSL_NO_TLSEXT - char *s_authz_file = NULL; - int c_support_proof = 0; - int c_require_proof = 0; -#endif + int no_protocol = 0; verbose = 0; debug = 0; @@ -645,7 +955,7 @@ int main(int argc, char *argv[]) #ifdef OPENSSL_FIPS fips_mode=1; #else - fprintf(stderr,"not compiled with FIPS support, so exitting without running.\n"); + fprintf(stderr,"not compiled with FIPS support, so exiting without running.\n"); EXIT(0); #endif } @@ -718,11 +1028,26 @@ int main(int argc, char *argv[]) } #endif else if (strcmp(*argv,"-ssl2") == 0) - ssl2=1; + { +#ifdef OPENSSL_NO_SSL2 + no_protocol = 1; +#endif + ssl2 = 1; + } else if (strcmp(*argv,"-tls1") == 0) - tls1=1; + { +#ifdef OPENSSL_NO_TLS1 + no_protocol = 1; +#endif + tls1 = 1; + } else if (strcmp(*argv,"-ssl3") == 0) - ssl3=1; + { +#ifdef OPENSSL_NO_SSL3_METHOD + no_protocol = 1; +#endif + ssl3 = 1; + } else if (strncmp(*argv,"-num",4) == 0) { if (--argc < 1) goto bad; @@ -827,24 +1152,38 @@ int main(int argc, char *argv[]) { test_cipherlist = 1; } -#ifndef OPENSSL_NO_TLSEXT - else if(strcmp(*argv,"-server_authz") == 0) + else if (strcmp(*argv,"-serverinfo_sct") == 0) + { + serverinfo_sct = 1; + } + else if (strcmp(*argv,"-serverinfo_tack") == 0) + { + serverinfo_tack = 1; + } + else if (strcmp(*argv,"-serverinfo_file") == 0) { if (--argc < 1) goto bad; - s_authz_file = *(++argv); - tls1 = 1; + serverinfo_file = *(++argv); } - else if (strcmp(*argv,"-c_support_proof") == 0) + else if (strcmp(*argv,"-custom_ext") == 0) { - c_support_proof = 1; - tls1 = 1; + custom_ext = 1; } - else if (strcmp(*argv,"-c_require_proof") == 0) + else if (strcmp(*argv,"-alpn_client") == 0) { - c_require_proof = 1; - tls1 = 1; + if (--argc < 1) goto bad; + alpn_client = *(++argv); + } + else if (strcmp(*argv,"-alpn_server") == 0) + { + if (--argc < 1) goto bad; + alpn_server = *(++argv); + } + else if (strcmp(*argv,"-alpn_expected") == 0) + { + if (--argc < 1) goto bad; + alpn_expected = *(++argv); } -#endif else { fprintf(stderr,"unknown option %s\n",*argv); @@ -861,15 +1200,41 @@ bad: goto end; } + /* + * test_cipherlist prevails over protocol switch: we test the cipherlist + * for all enabled protocols. + */ if (test_cipherlist == 1) { /* ensure that the cipher list are correctly sorted and exit */ + fprintf(stdout, "Testing cipherlist order only. Ignoring all " + "other options.\n"); if (do_test_cipherlist() == 0) EXIT(1); ret = 0; goto end; } + if (ssl2 + ssl3 + tls1 > 1) + { + fprintf(stderr, "At most one of -ssl2, -ssl3, or -tls1 should " + "be requested.\n"); + EXIT(1); + } + + /* + * Testing was requested for a compiled-out protocol (e.g. SSLv2). + * Ideally, we would error out, but the generic test wrapper can't know + * when to expect failure. So we do nothing and return success. + */ + if (no_protocol) + { + fprintf(stderr, "Testing was requested for a disabled protocol. " + "Skipping tests.\n"); + ret = 0; + goto end; + } + if (!ssl2 && !ssl3 && !tls1 && number > 1 && !reuse && !force) { fprintf(stderr, "This case cannot work. Use -f to perform " @@ -878,15 +1243,6 @@ bad: "to avoid protocol mismatch.\n"); EXIT(1); } - if (c_require_proof && s_authz_file == NULL && !force) - { - fprintf(stderr, "This case cannot work. -c_require_proof " - "requires an audit proof, but none was supplied. " - "Use -f to perform the test anyway (and\n-d to see " - "what happens), or use -server_authz to supply an " - "audit proof.\n"); - EXIT(1); - } #ifdef OPENSSL_FIPS if(fips_mode) @@ -957,24 +1313,25 @@ bad: } #endif -#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3) +/* At this point, ssl2/ssl3/tls1 is only set if the protocol is available. + * (Otherwise we exit early.) + * However the compiler doesn't know this, so we ifdef. */ +#ifndef OPENSSL_NO_SSL2 if (ssl2) meth=SSLv2_method(); - else - if (tls1) - meth=TLSv1_method(); else +#endif +#ifndef OPENSSL_NO_SSL3 if (ssl3) meth=SSLv3_method(); else - meth=SSLv23_method(); -#else -#ifdef OPENSSL_NO_SSL2 - meth=SSLv3_method(); -#else - meth=SSLv2_method(); #endif +#ifndef OPENSSL_NO_TLS1 + if (tls1) + meth=TLSv1_method(); + else #endif + meth=SSLv23_method(); c_ctx=SSL_CTX_new(meth); s_ctx=SSL_CTX_new(meth); @@ -1053,8 +1410,10 @@ bad: #ifdef TLSEXT_TYPE_opaque_prf_input SSL_CTX_set_tlsext_opaque_prf_input_callback(c_ctx, opaque_prf_input_cb); SSL_CTX_set_tlsext_opaque_prf_input_callback(s_ctx, opaque_prf_input_cb); - SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(c_ctx, &co1); /* or &co2 or NULL */ - SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(s_ctx, &so1); /* or &so2 or NULL */ + /* or &co2 or NULL */ + SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(c_ctx, &co1); + /* or &so2 or NULL */ + SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(s_ctx, &so1); #endif if (!SSL_CTX_use_certificate_file(s_ctx,server_cert,SSL_FILETYPE_PEM)) @@ -1152,34 +1511,77 @@ bad: SSL_CTX_set_srp_username_callback(s_ctx, ssl_srp_server_param_cb); } #endif -#ifndef OPENSSL_NO_TLSEXT - if (s_authz_file != NULL) - { - if(!SSL_CTX_use_authz_file(s_ctx, s_authz_file)) + + if (serverinfo_sct) + SSL_CTX_add_client_custom_ext(c_ctx, SCT_EXT_TYPE, + NULL, NULL, NULL, + serverinfo_cli_parse_cb, NULL); + if (serverinfo_tack) + SSL_CTX_add_client_custom_ext(c_ctx, TACK_EXT_TYPE, + NULL, NULL, NULL, + serverinfo_cli_parse_cb, NULL); + + if (serverinfo_file) + if (!SSL_CTX_use_serverinfo_file(s_ctx, serverinfo_file)) { - BIO_printf(bio_err, "Unable to set authz data\n"); + BIO_printf(bio_err, "missing serverinfo file\n"); goto end; } - } - if (c_support_proof || c_require_proof) - { - size_t proof_length; - const unsigned char *proof = SSL_CTX_get_authz_data(s_ctx, - TLSEXT_AUTHZDATAFORMAT_audit_proof, &proof_length); - if (proof != NULL) - { - /* Store a local copy. */ - c_expected.expected_proof = OPENSSL_malloc(proof_length); - c_expected.expected_proof_length = proof_length; - memcpy(c_expected.expected_proof, proof, proof_length); + + if (custom_ext) + { + SSL_CTX_add_client_custom_ext(c_ctx, CUSTOM_EXT_TYPE_0, + custom_ext_0_cli_add_cb, + NULL, NULL, + custom_ext_0_cli_parse_cb, NULL); + SSL_CTX_add_client_custom_ext(c_ctx, CUSTOM_EXT_TYPE_1, + custom_ext_1_cli_add_cb, + NULL, NULL, + custom_ext_1_cli_parse_cb, NULL); + SSL_CTX_add_client_custom_ext(c_ctx, CUSTOM_EXT_TYPE_2, + custom_ext_2_cli_add_cb, + NULL, NULL, + custom_ext_2_cli_parse_cb, NULL); + SSL_CTX_add_client_custom_ext(c_ctx, CUSTOM_EXT_TYPE_3, + custom_ext_3_cli_add_cb, + NULL, NULL, + custom_ext_3_cli_parse_cb, NULL); + + + SSL_CTX_add_server_custom_ext(s_ctx, CUSTOM_EXT_TYPE_0, + custom_ext_0_srv_add_cb, + NULL, NULL, + custom_ext_0_srv_parse_cb, NULL); + SSL_CTX_add_server_custom_ext(s_ctx, CUSTOM_EXT_TYPE_1, + custom_ext_1_srv_add_cb, + NULL, NULL, + custom_ext_1_srv_parse_cb, NULL); + SSL_CTX_add_server_custom_ext(s_ctx, CUSTOM_EXT_TYPE_2, + custom_ext_2_srv_add_cb, + NULL, NULL, + custom_ext_2_srv_parse_cb, NULL); + SSL_CTX_add_server_custom_ext(s_ctx, CUSTOM_EXT_TYPE_3, + custom_ext_3_srv_add_cb, + NULL, NULL, + custom_ext_3_srv_parse_cb, NULL); + } + + if (alpn_server) + SSL_CTX_set_alpn_select_cb(s_ctx, cb_server_alpn, NULL); + + if (alpn_client) + { + unsigned short alpn_len; + unsigned char *alpn = next_protos_parse(&alpn_len, alpn_client); + + if (alpn == NULL) + { + BIO_printf(bio_err, "Error parsing -alpn_client argument\n"); + goto end; } - c_expected.require = c_require_proof; - SSL_CTX_set_tlsext_authz_server_audit_proof_cb(c_ctx, - audit_proof_cb); - SSL_CTX_set_tlsext_authz_server_audit_proof_cb_arg(c_ctx, - &c_expected); + SSL_CTX_set_alpn_protos(c_ctx, alpn, alpn_len); + OPENSSL_free(alpn); } -#endif c_ssl=SSL_new(c_ctx); s_ssl=SSL_new(s_ctx); @@ -1254,10 +1656,6 @@ end: #endif #ifndef OPENSSL_NO_ENGINE ENGINE_cleanup(); -#endif -#ifndef OPENSSL_NO_TLSEXT - if (c_expected.expected_proof != NULL) - OPENSSL_free(c_expected.expected_proof); #endif CRYPTO_cleanup_all_ex_data(); ERR_free_strings(); @@ -1302,7 +1700,8 @@ int doit_biopair(SSL *s_ssl, SSL *c_ssl, long count, do { - /* c_ssl_bio: SSL filter BIO + /*- + * c_ssl_bio: SSL filter BIO * * client: pseudo-I/O for SSL library * @@ -1635,6 +2034,24 @@ int doit_biopair(SSL *s_ssl, SSL *c_ssl, long count, if (verbose) print_details(c_ssl, "DONE via BIO pair: "); + + if (verify_serverinfo() < 0) + { + ret = 1; + goto err; + } + if (verify_alpn(c_ssl, s_ssl) < 0) + { + ret = 1; + goto err; + } + + if (custom_ext_error) + { + ret = 1; + goto err; + } + end: ret = 0; @@ -1665,7 +2082,8 @@ end: int doit(SSL *s_ssl, SSL *c_ssl, long count) { - MS_STATIC char cbuf[1024*8],sbuf[1024*8]; + char *cbuf=NULL,*sbuf=NULL; + long bufsiz; long cw_num=count,cr_num=count; long sw_num=count,sr_num=count; int ret=1; @@ -1678,9 +2096,15 @@ int doit(SSL *s_ssl, SSL *c_ssl, long count) int done=0; int c_write,s_write; int do_server=0,do_client=0; + int max_frag = 5*1024; + + bufsiz = count>40*1024 ? 40*1024 : count; + + if ((cbuf = OPENSSL_malloc(bufsiz))==NULL) goto err; + if ((sbuf = OPENSSL_malloc(bufsiz))==NULL) goto err; - memset(cbuf,0,sizeof(cbuf)); - memset(sbuf,0,sizeof(sbuf)); + memset(cbuf,0,bufsiz); + memset(sbuf,0,bufsiz); c_to_s=BIO_new(BIO_s_mem()); s_to_c=BIO_new(BIO_s_mem()); @@ -1700,10 +2124,12 @@ int doit(SSL *s_ssl, SSL *c_ssl, long count) SSL_set_connect_state(c_ssl); SSL_set_bio(c_ssl,s_to_c,c_to_s); + SSL_set_max_send_fragment(c_ssl,max_frag); BIO_set_ssl(c_bio,c_ssl,BIO_NOCLOSE); SSL_set_accept_state(s_ssl); SSL_set_bio(s_ssl,c_to_s,s_to_c); + SSL_set_max_send_fragment(s_ssl,max_frag); BIO_set_ssl(s_bio,s_ssl,BIO_NOCLOSE); c_r=0; s_r=1; @@ -1727,7 +2153,8 @@ int doit(SSL *s_ssl, SSL *c_ssl, long count) if (SSL_in_init(s_ssl)) printf("server waiting in SSL_accept - %s\n", SSL_state_string_long(s_ssl)); -/* else if (s_write) +/*- + else if (s_write) printf("server:SSL_write()\n"); else printf("server:SSL_read()\n"); */ @@ -1738,7 +2165,8 @@ int doit(SSL *s_ssl, SSL *c_ssl, long count) if (SSL_in_init(c_ssl)) printf("client waiting in SSL_connect - %s\n", SSL_state_string_long(c_ssl)); -/* else if (c_write) +/*- + else if (c_write) printf("client:SSL_write()\n"); else printf("client:SSL_read()\n"); */ @@ -1754,8 +2182,8 @@ int doit(SSL *s_ssl, SSL *c_ssl, long count) { if (c_write) { - j = (cw_num > (long)sizeof(cbuf)) ? - (int)sizeof(cbuf) : (int)cw_num; + j = (cw_num > bufsiz) ? + (int)bufsiz : (int)cw_num; i=BIO_write(c_bio,cbuf,j); if (i < 0) { @@ -1788,11 +2216,13 @@ int doit(SSL *s_ssl, SSL *c_ssl, long count) s_r=1; c_write=0; cw_num-=i; + if (max_frag>1029) + SSL_set_max_send_fragment(c_ssl,max_frag-=5); } } else { - i=BIO_read(c_bio,cbuf,sizeof(cbuf)); + i=BIO_read(c_bio,cbuf,bufsiz); if (i < 0) { c_r=0; @@ -1840,7 +2270,7 @@ int doit(SSL *s_ssl, SSL *c_ssl, long count) { if (!s_write) { - i=BIO_read(s_bio,sbuf,sizeof(cbuf)); + i=BIO_read(s_bio,sbuf,bufsiz); if (i < 0) { s_r=0; @@ -1885,8 +2315,8 @@ int doit(SSL *s_ssl, SSL *c_ssl, long count) } else { - j = (sw_num > (long)sizeof(sbuf)) ? - (int)sizeof(sbuf) : (int)sw_num; + j = (sw_num > bufsiz) ? + (int)bufsiz : (int)sw_num; i=BIO_write(s_bio,sbuf,j); if (i < 0) { @@ -1921,6 +2351,8 @@ int doit(SSL *s_ssl, SSL *c_ssl, long count) c_r=1; if (sw_num <= 0) done|=S_DONE; + if (max_frag>1029) + SSL_set_max_send_fragment(s_ssl,max_frag-=5); } } } @@ -1930,6 +2362,16 @@ int doit(SSL *s_ssl, SSL *c_ssl, long count) if (verbose) print_details(c_ssl, "DONE: "); + if (verify_serverinfo() < 0) + { + ret = 1; + goto err; + } + if (custom_ext_error) + { + ret = 1; + goto err; + } ret=0; err: /* We have to set the BIO's to NULL otherwise they will be @@ -1954,6 +2396,10 @@ err: if (s_to_c != NULL) BIO_free(s_to_c); if (c_bio != NULL) BIO_free_all(c_bio); if (s_bio != NULL) BIO_free_all(s_bio); + + if (cbuf) OPENSSL_free(cbuf); + if (sbuf) OPENSSL_free(sbuf); + return(ret); } @@ -2111,9 +2557,10 @@ static int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx) static void process_proxy_debug(int indent, const char *format, ...) { + /* That's 80 > */ static const char indentation[] = ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" - ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"; /* That's 80 > */ + ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"; char my_format[256]; va_list args; @@ -2124,11 +2571,12 @@ static void process_proxy_debug(int indent, const char *format, ...) vfprintf(stderr, my_format, args); va_end(args); } -/* Priority levels: - 0 [!]var, () - 1 & ^ - 2 | -*/ +/*- + * Priority levels: + * 0 [!]var, () + * 1 & ^ + * 2 | + */ static int process_proxy_cond_adders(unsigned int letters[26], const char *cond, const char **cond_end, int *pos, int indent); static int process_proxy_cond_val(unsigned int letters[26], @@ -2480,7 +2928,8 @@ static void free_tmp_rsa(void) #endif #ifndef OPENSSL_NO_DH -/* These DH parameters have been generated as follows: +/*- + * These DH parameters have been generated as follows: * $ openssl dhparam -C -noout 512 * $ openssl dhparam -C -noout 1024 * $ openssl dhparam -C -noout -dsaparam 1024