X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fssltest.c;h=3c232115f2122730d963b872f39fdcfe79d6bbfd;hp=085456c90ec126bc896a4a3d752abd9304e9d649;hb=29b490a45886b409fd402c233acda9659e3f2094;hpb=f795123c4a846048ca246dcaff3bae581cc19770 diff --git a/ssl/ssltest.c b/ssl/ssltest.c index 085456c90e..3c232115f2 100644 --- a/ssl/ssltest.c +++ b/ssl/ssltest.c @@ -113,6 +113,32 @@ * ECC cipher suite support in OpenSSL originally developed by * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ #define _BSD_SOURCE 1 /* Or gethostname won't be declared properly on Linux and GNU platforms. */ @@ -128,8 +154,11 @@ #define USE_SOCKETS #include "e_os.h" -#define _XOPEN_SOURCE 1 /* Or isascii won't be declared properly on +#ifdef OPENSSL_SYS_VMS +#define _XOPEN_SOURCE 500 /* Or isascii won't be declared properly on VMS (at least with DECompHP C). */ +#endif + #include #include @@ -143,9 +172,18 @@ #endif #include #include +#ifndef OPENSSL_NO_RSA #include +#endif +#ifndef OPENSSL_NO_DSA #include +#endif +#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 @@ -201,9 +239,607 @@ static DH *get_dh1024(void); static DH *get_dh1024dsa(void); #endif + +static char *psk_key=NULL; /* by default PSK is not used */ +#ifndef OPENSSL_NO_PSK +static unsigned int psk_client_callback(SSL *ssl, const char *hint, char *identity, + unsigned int max_identity_len, unsigned char *psk, + unsigned int max_psk_len); +static unsigned int psk_server_callback(SSL *ssl, const char *identity, unsigned char *psk, + 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 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 termianted 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; + +/* Not IETF assigned supplemental data types */ +#define CUSTOM_SUPP_DATA_TYPE_0 100 +#define CUSTOM_SUPP_DATA_TYPE_1 101 +#define CUSTOM_SUPP_DATA_TYPE_2 102 + +const char supp_data_0_string[] = "00000"; + +int suppdata = 0; +int suppdata_error = 0; + +static int serverinfo_cli_cb(SSL* s, unsigned short ext_type, + const unsigned char* in, unsigned short 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_first_cb(SSL *s, unsigned short ext_type, + const unsigned char **out, + unsigned short *outlen, void *arg) + { + if (ext_type != CUSTOM_EXT_TYPE_0) + custom_ext_error = 1; + return -1; /* Don't send an extension */ + } + +static int custom_ext_0_cli_second_cb(SSL *s, unsigned short ext_type, + const unsigned char *in, + unsigned short inlen, int *al, + void *arg) + { + custom_ext_error = 1; /* Shouldn't be called */ + return 0; + } + +static int custom_ext_1_cli_first_cb(SSL *s, unsigned short ext_type, + const unsigned char **out, + unsigned short *outlen, 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_second_cb(SSL *s, unsigned short ext_type, + const unsigned char *in, + unsigned short inlen, int *al, + void *arg) + { + custom_ext_error = 1; /* Shouldn't be called */ + return 0; + } + +static int custom_ext_2_cli_first_cb(SSL *s, unsigned short ext_type, + const unsigned char **out, + unsigned short *outlen, 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_second_cb(SSL *s, unsigned short ext_type, + const unsigned char *in, + unsigned short 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_first_cb(SSL *s, unsigned short ext_type, + const unsigned char **out, + unsigned short *outlen, 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_second_cb(SSL *s, unsigned short ext_type, + const unsigned char *in, + unsigned short 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; + } + + +static int custom_ext_0_srv_first_cb(SSL *s, unsigned short ext_type, + const unsigned char *in, + unsigned short inlen, int *al, + void *arg) + { + custom_ext_error = 1; + return 0; /* Shouldn't be called */ + } + +static int custom_ext_0_srv_second_cb(SSL *s, unsigned short ext_type, + const unsigned char **out, + unsigned short *outlen, void *arg) + { + custom_ext_error = 1; + return 0; /* Shouldn't be called */ + } + +static int custom_ext_1_srv_first_cb(SSL *s, unsigned short ext_type, + const unsigned char *in, + unsigned short 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_second_cb(SSL *s, unsigned short ext_type, + const unsigned char **out, + unsigned short *outlen, void *arg) + { + return -1; /* Don't send an extension */ + } + +static int custom_ext_2_srv_first_cb(SSL *s, unsigned short ext_type, + const unsigned char *in, + unsigned short 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_second_cb(SSL *s, unsigned short ext_type, + const unsigned char **out, + unsigned short *outlen, void *arg) + { + *out = NULL; + *outlen = 0; + return 1; /* Send empty extension */ + } + +static int custom_ext_3_srv_first_cb(SSL *s, unsigned short ext_type, + const unsigned char *in, + unsigned short 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_second_cb(SSL *s, unsigned short ext_type, + const unsigned char **out, + unsigned short *outlen, void *arg) + { + *out = (const unsigned char*)custom_ext_srv_string; + *outlen = strlen(custom_ext_srv_string); + return 1; /* Send "defg" */ + } + +static int supp_data_0_srv_first_cb(SSL *s, unsigned short supp_data_type, + const unsigned char **out, + unsigned short *outlen, void *arg) + { + *out = (const unsigned char*)supp_data_0_string; + *outlen = strlen(supp_data_0_string); + if (arg != s) + suppdata_error = 1; + return 1; + } + +static int supp_data_0_srv_second_cb(SSL *s, unsigned short supp_data_type, + const unsigned char *in, + unsigned short inlen, int *al, + void *arg) + { + if (supp_data_type != CUSTOM_SUPP_DATA_TYPE_0) + suppdata_error = 1; + if (inlen != strlen(supp_data_0_string)) + suppdata_error = 1; + if (memcmp(in, supp_data_0_string, inlen) != 0) + suppdata_error = 1; + if (arg != s) + suppdata_error = 1; + return 1; + } + +static int supp_data_1_srv_first_cb(SSL *s, unsigned short supp_data_type, + const unsigned char **out, + unsigned short *outlen, void *arg) + { + return -1; + } + +static int supp_data_1_srv_second_cb(SSL *s, unsigned short supp_data_type, + const unsigned char *in, + unsigned short inlen, int *al, + void *arg) + { + suppdata_error = 1; + return 1; + } + +static int supp_data_2_srv_second_cb(SSL *s, unsigned short supp_data_type, + const unsigned char *in, + unsigned short inlen, int *al, + void *arg) + { + suppdata_error = 1; + return 1; + } + +static int supp_data_0_cli_first_cb(SSL *s, unsigned short supp_data_type, + const unsigned char *in, + unsigned short inlen, int *al, + void *arg) + { + if (supp_data_type != CUSTOM_SUPP_DATA_TYPE_0) + suppdata_error = 1; + if (inlen != strlen(supp_data_0_string)) + suppdata_error = 1; + if (memcmp(in, supp_data_0_string, inlen) != 0) + suppdata_error = 1; + if (arg != s) + suppdata_error = 1; + return 1; + } + +static int supp_data_0_cli_second_cb(SSL *s, unsigned short supp_data_type, + const unsigned char **out, + unsigned short *outlen, void *arg) + { + *out = (const unsigned char*)supp_data_0_string; + *outlen = strlen(supp_data_0_string); + if (arg != s) + suppdata_error = 1; + return 1; + } + +static int supp_data_1_cli_first_cb(SSL *s, unsigned short supp_data_type, + const unsigned char *in, + unsigned short inlen, int *al, + void *arg) + { + suppdata_error = 1; + return 1; + } + +static int supp_data_1_cli_second_cb(SSL *s, unsigned short supp_data_type, + const unsigned char **out, + unsigned short *outlen, void *arg) + { + return -1; + } + +static int supp_data_2_cli_first_cb(SSL *s, unsigned short supp_data_type, + const unsigned char *in, + unsigned short inlen, int *al, + void *arg) + { + suppdata_error = 1; + return 1; + } + static char *cipher=NULL; static int verbose=0; static int debug=0; @@ -218,10 +854,14 @@ static const char rnd_seed[] = "string to make the random number generator think int doit_biopair(SSL *s_ssl,SSL *c_ssl,long bytes,clock_t *s_time,clock_t *c_time); int doit(SSL *s_ssl,SSL *c_ssl,long bytes); +static int do_test_cipherlist(void); 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"); @@ -240,6 +880,13 @@ static void sv_usage(void) #ifndef OPENSSL_NO_ECDH fprintf(stderr," -no_ecdhe - disable ECDHE\n"); #endif +#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 @@ -266,11 +913,25 @@ 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_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 + 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"); + fprintf(stderr, "-suppdata - exercise supplemental data callbacks\n"); } static void print_details(SSL *c_ssl, const char *prefix) { - SSL_CIPHER *ciph; + const SSL_CIPHER *ciph; X509 *cert; ciph=SSL_get_current_cipher(c_ssl); @@ -375,6 +1036,26 @@ static void lock_dbg_cb(int mode, int type, const char *file, int line) } } +#ifdef TLSEXT_TYPE_opaque_prf_input +struct cb_info_st { void *input; size_t len; int ret; }; +struct cb_info_st co1 = { "C", 1, 1 }; /* try to negotiate oqaque PRF input */ +struct cb_info_st co2 = { "C", 1, 2 }; /* insist on oqaque PRF input */ +struct cb_info_st so1 = { "S", 1, 1 }; /* try to negotiate oqaque PRF input */ +struct cb_info_st so2 = { "S", 1, 2 }; /* insist on oqaque PRF input */ + +int opaque_prf_input_cb(SSL *ssl, void *peerinput, size_t len, void *arg_) + { + struct cb_info_st *arg = arg_; + + if (arg == NULL) + return 1; + + if (!SSL_set_tlsext_opaque_prf_input(ssl, arg->input, arg->len)) + return 0; + return arg->ret; + } +#endif + int main(int argc, char *argv[]) { char *CApath=NULL,*CAfile=NULL; @@ -390,10 +1071,12 @@ int main(int argc, char *argv[]) char *server_key=NULL; char *client_cert=TEST_CLIENT_CERT; char *client_key=NULL; +#ifndef OPENSSL_NO_ECDH char *named_curve = NULL; +#endif SSL_CTX *s_ctx=NULL; SSL_CTX *c_ctx=NULL; - SSL_METHOD *meth=NULL; + const SSL_METHOD *meth=NULL; SSL *c_ssl,*s_ssl; int number=1,reuse=0; long bytes=256L; @@ -403,20 +1086,33 @@ 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; +#ifndef OPENSSL_NO_COMP int comp = 0; COMP_METHOD *cm = NULL; 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; cipher = 0; - bio_err=BIO_new_fp(stderr,BIO_NOCLOSE); + bio_err=BIO_new_fp(stderr,BIO_NOCLOSE|BIO_FP_TEXT); CRYPTO_set_locking_callback(lock_dbg_cb); @@ -435,14 +1131,23 @@ int main(int argc, char *argv[]) RAND_seed(rnd_seed, sizeof rnd_seed); - bio_stdout=BIO_new_fp(stdout,BIO_NOCLOSE); + bio_stdout=BIO_new_fp(stdout,BIO_NOCLOSE|BIO_FP_TEXT); argc--; 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; @@ -482,6 +1187,34 @@ int main(int argc, char *argv[]) no_dhe=1; else if (strcmp(*argv,"-no_ecdhe") == 0) no_ecdhe=1; + else if (strcmp(*argv,"-psk") == 0) + { + if (--argc < 1) goto bad; + psk_key=*(++argv); +#ifndef OPENSSL_NO_PSK + if (strspn(psk_key, "abcdefABCDEF1234567890") != strlen(psk_key)) + { + BIO_printf(bio_err,"Not a hex number '%s'\n",*argv); + goto bad; + } +#else + 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) @@ -560,6 +1293,7 @@ int main(int argc, char *argv[]) { print_time = 1; } +#ifndef OPENSSL_NO_COMP else if (strcmp(*argv,"-zlib") == 0) { comp = COMP_ZLIB; @@ -568,6 +1302,7 @@ int main(int argc, char *argv[]) { comp = COMP_RLE; } +#endif else if (strcmp(*argv,"-named_curve") == 0) { if (--argc < 1) goto bad; @@ -586,6 +1321,60 @@ int main(int argc, char *argv[]) { app_verify_arg.allow_proxy_certs = 1; } + else if (strcmp(*argv,"-test_cipherlist") == 0) + { + 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 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; + serverinfo_file = *(++argv); + } + else if (strcmp(*argv,"-custom_ext") == 0) + { + custom_ext = 1; + } + else if (strcmp(*argv,"-alpn_client") == 0) + { + 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); + } + else if (strcmp(*argv,"-suppdata") == 0) + { + suppdata = 1; + } else { fprintf(stderr,"unknown option %s\n",*argv); @@ -602,6 +1391,15 @@ bad: goto end; } + if (test_cipherlist == 1) + { + /* ensure that the cipher list are correctly sorted and exit */ + if (do_test_cipherlist() == 0) + EXIT(1); + ret = 0; + goto end; + } + if (!ssl2 && !ssl3 && !tls1 && number > 1 && !reuse && !force) { fprintf(stderr, "This case cannot work. Use -f to perform " @@ -611,6 +1409,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) @@ -627,6 +1439,7 @@ bad: SSL_library_init(); SSL_load_error_strings(); +#ifndef OPENSSL_NO_COMP if (comp == COMP_ZLIB) cm = COMP_zlib(); if (comp == COMP_RLE) cm = COMP_rle(); if (cm != NULL) @@ -663,6 +1476,7 @@ bad: fprintf(stderr, " %d: %s\n", c->id, c->name); } } +#endif #if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3) if (ssl2) @@ -677,7 +1491,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 @@ -720,36 +1540,34 @@ bad: #ifndef OPENSSL_NO_ECDH if (!no_ecdhe) { - ecdh = EC_KEY_new(); - if (ecdh != NULL) - { - if (named_curve) - { - int nid = OBJ_sn2nid(named_curve); + int nid; - if (nid == 0) - { - BIO_printf(bio_err, "unknown curve name (%s)\n", named_curve); - EC_KEY_free(ecdh); - goto end; - } - - ecdh->group = EC_GROUP_new_by_curve_name(nid); - if (ecdh->group == NULL) - { - BIO_printf(bio_err, "unable to create curve (%s)\n", named_curve); - EC_KEY_free(ecdh); - goto end; - } + if (named_curve != NULL) + { + nid = OBJ_sn2nid(named_curve); + if (nid == 0) + { + BIO_printf(bio_err, "unknown curve name (%s)\n", named_curve); + goto end; } - - if (ecdh->group == NULL) - ecdh->group=EC_GROUP_new_by_curve_name(NID_sect163r2); + } + else +#ifdef OPENSSL_NO_EC2M + nid = NID_X9_62_prime256v1; +#else + nid = NID_sect163r2; +#endif - SSL_CTX_set_tmp_ecdh(s_ctx, ecdh); - SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_ECDH_USE); - EC_KEY_free(ecdh); + ecdh = EC_KEY_new_by_curve_name(nid); + if (ecdh == NULL) + { + BIO_printf(bio_err, "unable to create curve\n"); + goto end; } + + SSL_CTX_set_tmp_ecdh(s_ctx, ecdh); + SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_ECDH_USE); + EC_KEY_free(ecdh); } #else (void)no_ecdhe; @@ -759,6 +1577,13 @@ bad: SSL_CTX_set_tmp_rsa_callback(s_ctx,tmp_rsa_cb); #endif +#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 */ +#endif + if (!SSL_CTX_use_certificate_file(s_ctx,server_cert,SSL_FILETYPE_PEM)) { ERR_print_errors(bio_err); @@ -810,9 +1635,169 @@ bad: SSL_CTX_set_session_id_context(s_ctx, (void *)&session_id_context, sizeof session_id_context); } + /* Use PSK only if PSK key is given */ + if (psk_key != NULL) + { + /* no_psk is used to avoid putting psk command to openssl tool */ + if (no_psk) + { + /* if PSK is not compiled in and psk key is + * given, do nothing and exit successfully */ + ret=0; + goto end; + } +#ifndef OPENSSL_NO_PSK + SSL_CTX_set_psk_client_callback(c_ctx, psk_client_callback); + SSL_CTX_set_psk_server_callback(s_ctx, psk_server_callback); + if (debug) + BIO_printf(bio_err,"setting PSK identity hint to s_ctx\n"); + if (!SSL_CTX_use_psk_identity_hint(s_ctx, "ctx server identity_hint")) + { + BIO_printf(bio_err,"error setting PSK identity hint to s_ctx\n"); + ERR_print_errors(bio_err); + goto end; + } +#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 + + if (serverinfo_sct) + SSL_CTX_set_custom_cli_ext(c_ctx, SCT_EXT_TYPE, NULL, + serverinfo_cli_cb, NULL); + if (serverinfo_tack) + SSL_CTX_set_custom_cli_ext(c_ctx, TACK_EXT_TYPE, NULL, + serverinfo_cli_cb, NULL); + + if (serverinfo_file) + if (!SSL_CTX_use_serverinfo_file(s_ctx, serverinfo_file)) + { + BIO_printf(bio_err, "missing serverinfo file\n"); + goto end; + } + + if (custom_ext) + { + SSL_CTX_set_custom_cli_ext(c_ctx, CUSTOM_EXT_TYPE_0, + custom_ext_0_cli_first_cb, + custom_ext_0_cli_second_cb, NULL); + SSL_CTX_set_custom_cli_ext(c_ctx, CUSTOM_EXT_TYPE_1, + custom_ext_1_cli_first_cb, + custom_ext_1_cli_second_cb, NULL); + SSL_CTX_set_custom_cli_ext(c_ctx, CUSTOM_EXT_TYPE_2, + custom_ext_2_cli_first_cb, + custom_ext_2_cli_second_cb, NULL); + SSL_CTX_set_custom_cli_ext(c_ctx, CUSTOM_EXT_TYPE_3, + custom_ext_3_cli_first_cb, + custom_ext_3_cli_second_cb, NULL); + + + SSL_CTX_set_custom_srv_ext(s_ctx, CUSTOM_EXT_TYPE_0, + custom_ext_0_srv_first_cb, + custom_ext_0_srv_second_cb, NULL); + SSL_CTX_set_custom_srv_ext(s_ctx, CUSTOM_EXT_TYPE_1, + custom_ext_1_srv_first_cb, + custom_ext_1_srv_second_cb, NULL); + SSL_CTX_set_custom_srv_ext(s_ctx, CUSTOM_EXT_TYPE_2, + custom_ext_2_srv_first_cb, + custom_ext_2_srv_second_cb, NULL); + SSL_CTX_set_custom_srv_ext(s_ctx, CUSTOM_EXT_TYPE_3, + custom_ext_3_srv_first_cb, + custom_ext_3_srv_second_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; + } + SSL_CTX_set_alpn_protos(c_ctx, alpn, alpn_len); + OPENSSL_free(alpn); + } + c_ssl=SSL_new(c_ctx); s_ssl=SSL_new(s_ctx); + if (suppdata) + { + /* TEST CASES */ + /* client and server both send and receive, verify + * additional arg passed back */ + SSL_CTX_set_srv_supp_data(s_ctx, CUSTOM_SUPP_DATA_TYPE_0, + supp_data_0_srv_first_cb, + supp_data_0_srv_second_cb, s_ssl); + SSL_CTX_set_cli_supp_data(c_ctx, CUSTOM_SUPP_DATA_TYPE_0, + supp_data_0_cli_first_cb, + supp_data_0_cli_second_cb, c_ssl); + + /* -1 response from sending server/client doesn't + * receive, -1 response from sending client/server + * doesn't receive */ + SSL_CTX_set_srv_supp_data(s_ctx, CUSTOM_SUPP_DATA_TYPE_1, + supp_data_1_srv_first_cb, + supp_data_1_srv_second_cb, NULL); + SSL_CTX_set_cli_supp_data(c_ctx, CUSTOM_SUPP_DATA_TYPE_1, + supp_data_1_cli_first_cb, + supp_data_1_cli_second_cb, NULL); + + /* null sending server/client doesn't receive, null + sending client/server doesn't receive */ + SSL_CTX_set_srv_supp_data(s_ctx, CUSTOM_SUPP_DATA_TYPE_2, + /*supp_data_2_srv_first_cb*/NULL, + supp_data_2_srv_second_cb, NULL); + SSL_CTX_set_cli_supp_data(c_ctx, CUSTOM_SUPP_DATA_TYPE_2, + supp_data_2_cli_first_cb, + /*supp_data_2_cli_second_cb*/NULL, + NULL); + + /* alerts set to non-zero and zero return values not tested */ + } #ifndef OPENSSL_NO_KRB5 if (c_ssl && c_ssl->kssl_ctx) { @@ -886,11 +1871,12 @@ end: #endif CRYPTO_cleanup_all_ex_data(); ERR_free_strings(); - ERR_remove_state(0); + ERR_remove_thread_state(NULL); EVP_cleanup(); CRYPTO_mem_leaks(bio_err); if (bio_err != NULL) BIO_free(bio_err); EXIT(ret); + return ret; } int doit_biopair(SSL *s_ssl, SSL *c_ssl, long count, @@ -1259,6 +2245,30 @@ 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 + 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; @@ -1298,7 +2308,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; @@ -1333,8 +2342,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 */ @@ -1557,6 +2564,28 @@ 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 + if (suppdata_error < 0) + { + ret = 1; + goto err; + } + 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 @@ -1700,7 +2729,7 @@ static int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx) fprintf(stderr, " Certificate proxy rights = %*.*s", i, i, s); while(i-- > 0) { - char c = *s++; + int c = *s++; if (isascii(c) && isalpha(c)) { if (islower(c)) @@ -1761,11 +2790,11 @@ static int process_proxy_cond_adders(unsigned int letters[26], static int process_proxy_cond_val(unsigned int letters[26], const char *cond, const char **cond_end, int *pos, int indent) { - char c; + int c; int ok = 1; int negate = 0; - while(isspace(*cond)) + while(isspace((int)*cond)) { cond++; (*pos)++; } @@ -1780,7 +2809,7 @@ static int process_proxy_cond_val(unsigned int letters[26], { negate = !negate; cond++; (*pos)++; - while(isspace(*cond)) + while(isspace((int)*cond)) { cond++; (*pos)++; } @@ -1795,7 +2824,7 @@ static int process_proxy_cond_val(unsigned int letters[26], cond = *cond_end; if (ok < 0) goto end; - while(isspace(*cond)) + while(isspace((int)*cond)) { cond++; (*pos)++; } @@ -1855,7 +2884,7 @@ static int process_proxy_cond_multipliers(unsigned int letters[26], while(ok >= 0) { - while(isspace(*cond)) + while(isspace((int)*cond)) { cond++; (*pos)++; } @@ -1922,7 +2951,7 @@ static int process_proxy_cond_adders(unsigned int letters[26], while(ok >= 0) { - while(isspace(*cond)) + while(isspace((int)*cond)) { cond++; (*pos)++; } @@ -2005,7 +3034,7 @@ static int MS_CALLBACK app_verify_callback(X509_STORE_CTX *ctx, void *arg) letters[i] = 0; for(sp = cb_arg->proxy_auth; *sp; sp++) { - char c = *sp; + int c = *sp; if (isascii(c) && isalpha(c)) { if (islower(c)) @@ -2035,20 +3064,12 @@ 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) { - if (ok) + if (ok > 0) { const char *cond_end = NULL; @@ -2211,3 +3232,123 @@ static DH *get_dh1024dsa() return(dh); } #endif + +#ifndef OPENSSL_NO_PSK +/* convert the PSK key (psk_key) in ascii to binary (psk) */ +static int psk_key2bn(const char *pskkey, unsigned char *psk, + unsigned int max_psk_len) + { + int ret; + BIGNUM *bn = NULL; + + ret = BN_hex2bn(&bn, pskkey); + if (!ret) + { + BIO_printf(bio_err,"Could not convert PSK key '%s' to BIGNUM\n", pskkey); + if (bn) + BN_free(bn); + return 0; + } + if (BN_num_bytes(bn) > (int)max_psk_len) + { + BIO_printf(bio_err,"psk buffer of callback is too small (%d) for key (%d)\n", + max_psk_len, BN_num_bytes(bn)); + BN_free(bn); + return 0; + } + ret = BN_bn2bin(bn, psk); + BN_free(bn); + return ret; + } + +static unsigned int psk_client_callback(SSL *ssl, const char *hint, char *identity, + unsigned int max_identity_len, unsigned char *psk, + unsigned int max_psk_len) + { + int ret; + unsigned int psk_len = 0; + + ret = BIO_snprintf(identity, max_identity_len, "Client_identity"); + if (ret < 0) + goto out_err; + if (debug) + fprintf(stderr, "client: created identity '%s' len=%d\n", identity, ret); + ret = psk_key2bn(psk_key, psk, max_psk_len); + if (ret < 0) + goto out_err; + psk_len = ret; +out_err: + return psk_len; + } + +static unsigned int psk_server_callback(SSL *ssl, const char *identity, + unsigned char *psk, unsigned int max_psk_len) + { + unsigned int psk_len=0; + + if (strcmp(identity, "Client_identity") != 0) + { + BIO_printf(bio_err, "server: PSK error: client identity not found\n"); + return 0; + } + psk_len=psk_key2bn(psk_key, psk, max_psk_len); + return psk_len; + } +#endif + +static int do_test_cipherlist(void) + { + int i = 0; + const SSL_METHOD *meth; + const SSL_CIPHER *ci, *tci = NULL; + +#ifndef OPENSSL_NO_SSL2 + fprintf(stderr, "testing SSLv2 cipher list order: "); + meth = SSLv2_method(); + while ((ci = meth->get_cipher(i++)) != NULL) + { + if (tci != NULL) + if (ci->id >= tci->id) + { + fprintf(stderr, "failed %lx vs. %lx\n", ci->id, tci->id); + return 0; + } + tci = ci; + } + fprintf(stderr, "ok\n"); +#endif +#ifndef OPENSSL_NO_SSL3 + fprintf(stderr, "testing SSLv3 cipher list order: "); + meth = SSLv3_method(); + tci = NULL; + while ((ci = meth->get_cipher(i++)) != NULL) + { + if (tci != NULL) + if (ci->id >= tci->id) + { + fprintf(stderr, "failed %lx vs. %lx\n", ci->id, tci->id); + return 0; + } + tci = ci; + } + fprintf(stderr, "ok\n"); +#endif +#ifndef OPENSSL_NO_TLS1 + fprintf(stderr, "testing TLSv1 cipher list order: "); + meth = TLSv1_method(); + tci = NULL; + while ((ci = meth->get_cipher(i++)) != NULL) + { + if (tci != NULL) + if (ci->id >= tci->id) + { + fprintf(stderr, "failed %lx vs. %lx\n", ci->id, tci->id); + return 0; + } + tci = ci; + } + fprintf(stderr, "ok\n"); +#endif + + return 1; + }