X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=apps%2Fs_server.c;h=329f6c70832ad3f377161e931637a306d9cf7edb;hp=35b24ee54a70d6bfbf561f5ab27db0b62374318c;hb=98a7edf9f026e0071b2244faed29521de1fb2708;hpb=7d7c13cbab72b5afb37797fda8e8ac46af49a716 diff --git a/apps/s_server.c b/apps/s_server.c index 35b24ee54a..329f6c7083 100644 --- a/apps/s_server.c +++ b/apps/s_server.c @@ -207,6 +207,7 @@ static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength); static int not_resumable_sess_cb(SSL *s, int is_forward_secure); static int sv_body(char *hostname, int s, unsigned char *context); static int www_body(char *hostname, int s, unsigned char *context); +static int rev_body(char *hostname, int s, unsigned char *context); static void close_accept_socket(void ); static void sv_usage(void); static int init_ssl_connection(SSL *s); @@ -215,6 +216,9 @@ static int generate_session_id(const SSL *ssl, unsigned char *id, unsigned int *id_len); static void init_session_cache_ctx(SSL_CTX *sctx); static void free_sessions(void); +static int ssl_load_stores(SSL_CTX *sctx, + const char *vfyCApath, const char *vfyCAfile, + const char *chCApath, const char *chCAfile); #ifndef OPENSSL_NO_DH static DH *load_dh_param(const char *dhfile); static DH *get_dh512(void); @@ -265,16 +269,15 @@ static int accept_socket= -1; #undef PROG #define PROG s_server_main -extern int verify_depth, verify_return_error; +extern int verify_depth, verify_return_error, verify_quiet; -static char *cipher=NULL; static int s_server_verify=SSL_VERIFY_NONE; static int s_server_session_id_context = 1; /* anything will do */ -static const char *s_cert_file=TEST_CERT,*s_key_file=NULL; +static const char *s_cert_file=TEST_CERT,*s_key_file=NULL, *s_chain_file=NULL; #ifndef OPENSSL_NO_TLSEXT static const char *s_cert_file2=TEST_CERT2,*s_key_file2=NULL; #endif -static char *s_dcert_file=NULL,*s_dkey_file=NULL; +static char *s_dcert_file=NULL,*s_dkey_file=NULL, *s_dchain_file=NULL; #ifdef FIONBIO static int s_nbio=0; #endif @@ -287,6 +290,7 @@ static SSL_CTX *ctx2=NULL; static int www=0; static BIO *bio_s_out=NULL; +static BIO *bio_s_msg = NULL; static int s_debug=0; #ifndef OPENSSL_NO_TLSEXT static int s_tlsextdebug=0; @@ -296,6 +300,10 @@ static int cert_status_cb(SSL *s, void *arg); static int no_resume_ephemeral = 0; static int s_msg=0; static int s_quiet=0; +static int s_brief=0; + +static char *keymatexportlabel=NULL; +static int keymatexportlen=20; static int hack=0; #ifndef OPENSSL_NO_ENGINE @@ -309,6 +317,11 @@ static long socket_mtu; static int cert_chain = 0; #endif +#ifndef OPENSSL_NO_TLSEXT +static BIO *authz_in = NULL; +static const char *s_authz_file = NULL; +#endif + #ifndef OPENSSL_NO_PSK static char *psk_identity="Client_identity"; char *psk_key=NULL; /* by default PSK is not used */ @@ -380,31 +393,43 @@ static unsigned int psk_server_cb(SSL *ssl, const char *identity, /* 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 = 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; } @@ -414,12 +439,13 @@ static int MS_CALLBACK ssl_srp_server_param_cb(SSL *s, int *ad, void *arg) static void s_server_init(void) { accept_socket=-1; - cipher=NULL; s_server_verify=SSL_VERIFY_NONE; s_dcert_file=NULL; s_dkey_file=NULL; + s_dchain_file=NULL; s_cert_file=TEST_CERT; s_key_file=NULL; + s_chain_file=NULL; #ifndef OPENSSL_NO_TLSEXT s_cert_file2=TEST_CERT2; s_key_file2=NULL; @@ -436,6 +462,7 @@ static void s_server_init(void) s_debug=0; s_msg=0; s_quiet=0; + s_brief=0; hack=0; #ifndef OPENSSL_NO_ENGINE engine_id=NULL; @@ -453,6 +480,7 @@ static void sv_usage(void) BIO_printf(bio_err," -Verify arg - turn on peer certificate verification, must have a cert.\n"); BIO_printf(bio_err," -cert arg - certificate file to use\n"); BIO_printf(bio_err," (default is %s)\n",TEST_CERT); + BIO_printf(bio_err," -authz arg - binary authz file for certificate\n"); BIO_printf(bio_err," -crl_check - check the peer certificate has not been revoked by its CA.\n" \ " The CRL(s) are appended to the certificate file\n"); BIO_printf(bio_err," -crl_check_all - check the peer certificate has not been revoked by its CA\n" \ @@ -545,7 +573,10 @@ static void sv_usage(void) # 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\n"); #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; @@ -896,7 +927,7 @@ static int next_proto_cb(SSL *s, const unsigned char **data, unsigned int *len, return SSL_TLSEXT_ERR_OK; } -# endif /* ndef OPENSSL_NO_NPN */ +# endif /* ndef OPENSSL_NO_NEXTPROTONEG */ #endif static int not_resumable_sess_cb(SSL *s, int is_forward_secure) @@ -910,6 +941,13 @@ int MAIN(int, char **); #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; +static unsigned char *checkhost = NULL, *checkemail = NULL; +static char *checkip = NULL; + int MAIN(int argc, char *argv[]) { @@ -917,14 +955,16 @@ int MAIN(int argc, char *argv[]) int badarg = 0; short port=PORT; char *CApath=NULL,*CAfile=NULL; + char *chCApath=NULL,*chCAfile=NULL; + char *vfyCApath=NULL,*vfyCAfile=NULL; unsigned char *context = NULL; char *dhfile = NULL; #ifndef OPENSSL_NO_ECDH char *named_curve = NULL; #endif - int badop=0,bugs=0; + int badop=0; int ret=1; - int off=0; + int build_chain = 0; int no_tmp_rsa=0,no_dhe=0,no_ecdhe=0,nocert=0; int state=0; const SSL_METHOD *meth=NULL; @@ -936,13 +976,13 @@ int MAIN(int argc, char *argv[]) char *dpassarg = NULL, *dpass = NULL; int s_dcert_format = FORMAT_PEM, s_dkey_format = FORMAT_PEM; X509 *s_cert = NULL, *s_dcert = NULL; + STACK_OF(X509) *s_chain = NULL, *s_dchain = NULL; EVP_PKEY *s_key = NULL, *s_dkey = NULL; int no_cache = 0, ext_cache = 0; + int rev = 0, naccept = -1; #ifndef OPENSSL_NO_TLSEXT EVP_PKEY *s_key2 = NULL; X509 *s_cert2 = NULL; -#endif -#ifndef OPENSSL_NO_TLSEXT tlsextctx tlsextcbp = {NULL, NULL, SSL_TLSEXT_ERR_ALERT_WARNING}; # ifndef OPENSSL_NO_NEXTPROTONEG const char *next_proto_neg_in = NULL; @@ -956,19 +996,12 @@ 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) + SSL_EXCERT *exc = NULL; + SSL_CONF_CTX *cctx = NULL; + STACK_OF(OPENSSL_STRING) *ssl_args = NULL; + meth=SSLv23_server_method(); -#elif !defined(OPENSSL_NO_SSL3) - meth=SSLv3_server_method(); -#elif !defined(OPENSSL_NO_SSL2) - meth=SSLv2_server_method(); -#elif !defined(OPENSSL_NO_TLS1) - meth=TLSv1_server_method(); -#else - /* #error no SSL version enabled */ -#endif local_argc=argc; local_argv=argv; @@ -984,6 +1017,11 @@ int MAIN(int argc, char *argv[]) if (!load_config(bio_err, NULL)) goto end; + cctx = SSL_CONF_CTX_new(); + if (!cctx) + goto end; + SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SERVER); + verify_depth=0; #ifdef FIONBIO s_nbio=0; @@ -1002,6 +1040,17 @@ int MAIN(int argc, char *argv[]) if (!extract_port(*(++argv),&port)) goto bad; } + else if (strcmp(*argv,"-naccept") == 0) + { + if (--argc < 1) goto bad; + naccept = atol(*(++argv)); + if (naccept <= 0) + { + BIO_printf(bio_err, "bad accept value %s\n", + *argv); + goto bad; + } + } else if (strcmp(*argv,"-verify") == 0) { s_server_verify=SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE; @@ -1027,6 +1076,13 @@ int MAIN(int argc, char *argv[]) if (--argc < 1) goto bad; s_cert_file= *(++argv); } +#ifndef OPENSSL_NO_TLSEXT + else if (strcmp(*argv,"-authz") == 0) + { + if (--argc < 1) goto bad; + s_authz_file = *(++argv); + } +#endif else if (strcmp(*argv,"-certform") == 0) { if (--argc < 1) goto bad; @@ -1047,18 +1103,16 @@ int MAIN(int argc, char *argv[]) if (--argc < 1) goto bad; passarg = *(++argv); } - else if (strcmp(*argv,"-dhparam") == 0) + else if (strcmp(*argv,"-cert_chain") == 0) { if (--argc < 1) goto bad; - dhfile = *(++argv); + s_chain_file= *(++argv); } -#ifndef OPENSSL_NO_ECDH - else if (strcmp(*argv,"-named_curve") == 0) + else if (strcmp(*argv,"-dhparam") == 0) { if (--argc < 1) goto bad; - named_curve = *(++argv); + dhfile = *(++argv); } -#endif else if (strcmp(*argv,"-dcertform") == 0) { if (--argc < 1) goto bad; @@ -1084,6 +1138,11 @@ int MAIN(int argc, char *argv[]) if (--argc < 1) goto bad; s_dkey_file= *(++argv); } + else if (strcmp(*argv,"-dcert_chain") == 0) + { + if (--argc < 1) goto bad; + s_dchain_file= *(++argv); + } else if (strcmp(*argv,"-nocert") == 0) { nocert=1; @@ -1093,6 +1152,16 @@ int MAIN(int argc, char *argv[]) if (--argc < 1) goto bad; CApath= *(++argv); } + else if (strcmp(*argv,"-chainCApath") == 0) + { + if (--argc < 1) goto bad; + chCApath= *(++argv); + } + else if (strcmp(*argv,"-verifyCApath") == 0) + { + if (--argc < 1) goto bad; + vfyCApath= *(++argv); + } else if (strcmp(*argv,"-no_cache") == 0) no_cache = 1; else if (strcmp(*argv,"-ext_cache") == 0) @@ -1103,21 +1172,38 @@ int MAIN(int argc, char *argv[]) goto bad; continue; } + else if (args_excert(&argv, &argc, &badarg, bio_err, &exc)) + { + if (badarg) + goto bad; + continue; + } + else if (args_ssl(&argv, &argc, cctx, &badarg, bio_err, &ssl_args)) + { + if (badarg) + goto bad; + continue; + } else if (strcmp(*argv,"-verify_return_error") == 0) verify_return_error = 1; - else if (strcmp(*argv,"-serverpref") == 0) - { off|=SSL_OP_CIPHER_SERVER_PREFERENCE; } - else if (strcmp(*argv,"-legacy_renegotiation") == 0) - off|=SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION; - else if (strcmp(*argv,"-cipher") == 0) + else if (strcmp(*argv,"-verify_quiet") == 0) + verify_quiet = 1; + else if (strcmp(*argv,"-build_chain") == 0) + build_chain = 1; + else if (strcmp(*argv,"-CAfile") == 0) { if (--argc < 1) goto bad; - cipher= *(++argv); + CAfile= *(++argv); } - else if (strcmp(*argv,"-CAfile") == 0) + else if (strcmp(*argv,"-chainCAfile") == 0) { if (--argc < 1) goto bad; - CAfile= *(++argv); + chCAfile= *(++argv); + } + else if (strcmp(*argv,"-verifyCAfile") == 0) + { + if (--argc < 1) goto bad; + vfyCAfile= *(++argv); } #ifdef FIONBIO else if (strcmp(*argv,"-nbio") == 0) @@ -1163,8 +1249,32 @@ int MAIN(int argc, char *argv[]) } } #endif + else if (strcmp(*argv,"-checkhost") == 0) + { + if (--argc < 1) goto bad; + checkhost=(unsigned char *)*(++argv); + } + else if (strcmp(*argv,"-checkemail") == 0) + { + if (--argc < 1) goto bad; + checkemail=(unsigned char *)*(++argv); + } + else if (strcmp(*argv,"-checkip") == 0) + { + if (--argc < 1) goto bad; + checkip=*(++argv); + } else if (strcmp(*argv,"-msg") == 0) { s_msg=1; } + else if (strcmp(*argv,"-msgfile") == 0) + { + if (--argc < 1) goto bad; + bio_s_msg = BIO_new_file(*(++argv), "w"); + } +#ifndef OPENSSL_NO_SSL_TRACE + else if (strcmp(*argv,"-trace") == 0) + { s_msg=2; } +#endif else if (strcmp(*argv,"-hack") == 0) { hack=1; } else if (strcmp(*argv,"-state") == 0) @@ -1173,8 +1283,12 @@ int MAIN(int argc, char *argv[]) { s_crlf=1; } else if (strcmp(*argv,"-quiet") == 0) { s_quiet=1; } - else if (strcmp(*argv,"-bugs") == 0) - { bugs=1; } + else if (strcmp(*argv,"-brief") == 0) + { + s_quiet=1; + s_brief=1; + verify_quiet=1; + } else if (strcmp(*argv,"-no_tmp_rsa") == 0) { no_tmp_rsa=1; } else if (strcmp(*argv,"-no_dhe") == 0) @@ -1197,7 +1311,7 @@ int MAIN(int argc, char *argv[]) psk_key=*(++argv); for (i=0; iinfo); + 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: @@ -2269,6 +2457,18 @@ static int sv_body(char *hostname, int s, unsigned char *context) { 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: @@ -2281,7 +2481,6 @@ again: 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: @@ -2336,15 +2535,30 @@ static int init_ssl_connection(SSL *con) X509 *peer; long verify_error; MS_STATIC char buf[BUFSIZ]; +#ifndef OPENSSL_NO_KRB5 + char *client_princ; +#endif #if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) const unsigned char *next_proto_neg; unsigned next_proto_neg_len; #endif -#ifndef OPENSSL_NO_KRB5 - char *client_princ; -#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)) { @@ -2359,11 +2573,16 @@ static int init_ssl_connection(SSL *con) BIO_printf(bio_err,"verify error:%s\n", X509_verify_cert_error_string(verify_error)); } - else - ERR_print_errors(bio_err); + /* Always print any error messages */ + ERR_print_errors(bio_err); return(0); } + if (s_brief) + print_ssl_summary(bio_err, con); + + print_ssl_cert_checks(bio_err, con, checkhost, checkemail, checkip); + PEM_write_bio_SSL_SESSION(bio_s_out,SSL_get_session(con)); peer=SSL_get_peer_certificate(con); @@ -2381,7 +2600,10 @@ static int init_ssl_connection(SSL *con) if (SSL_get_shared_ciphers(con,buf,sizeof buf) != NULL) BIO_printf(bio_s_out,"Shared ciphers:%s\n",buf); str=SSL_CIPHER_get_name(SSL_get_current_cipher(con)); + ssl_print_sigalgs(bio_s_out, con); + ssl_print_curves(bio_s_out, con, 0); BIO_printf(bio_s_out,"CIPHER is %s\n",(str != NULL)?str:"(NONE)"); + #if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) SSL_get0_next_proto_negotiated(con, &next_proto_neg, &next_proto_neg_len); if (next_proto_neg) @@ -2391,10 +2613,19 @@ static int init_ssl_connection(SSL *con) 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) @@ -2405,6 +2636,35 @@ static int init_ssl_connection(SSL *con) #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) + { + if (!SSL_export_keying_material(con, exportedkeymat, + keymatexportlen, + keymatexportlabel, + strlen(keymatexportlabel), + NULL, 0, 0)) + { + BIO_printf(bio_s_out, " Error\n"); + } + else + { + BIO_printf(bio_s_out, " Keying material: "); + for (i=0; iinfo); + 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: @@ -2666,6 +2943,8 @@ static int www_body(char *hostname, int s, unsigned char *context) } BIO_puts(io,"\n"); } + ssl_print_sigalgs(io, con); + ssl_print_curves(io, con, 0); BIO_printf(io,(SSL_cache_hit(con) ?"---\nReused, " :"---\nNew, ")); @@ -2859,6 +3138,146 @@ err: return(ret); } +static int rev_body(char *hostname, int s, unsigned char *context) + { + char *buf=NULL; + int i; + int ret=1; + SSL *con; + BIO *io,*ssl_bio,*sbio; +#ifndef OPENSSL_NO_KRB5 + KSSL_CTX *kctx; +#endif + + buf=OPENSSL_malloc(bufsize); + if (buf == NULL) return(0); + io=BIO_new(BIO_f_buffer()); + ssl_bio=BIO_new(BIO_f_ssl()); + if ((io == NULL) || (ssl_bio == NULL)) goto err; + + /* lets make the output buffer a reasonable size */ + if (!BIO_set_write_buffer_size(io,bufsize)) goto err; + + if ((con=SSL_new(ctx)) == NULL) goto err; +#ifndef OPENSSL_NO_TLSEXT + if (s_tlsextdebug) + { + SSL_set_tlsext_debug_callback(con, tlsext_cb); + SSL_set_tlsext_debug_arg(con, bio_s_out); + } +#endif +#ifndef OPENSSL_NO_KRB5 + if ((kctx = kssl_ctx_new()) != NULL) + { + kssl_ctx_setstring(kctx, KSSL_SERVICE, KRB5SVC); + kssl_ctx_setstring(kctx, KSSL_KEYTAB, KRB5KEYTAB); + } +#endif /* OPENSSL_NO_KRB5 */ + if(context) SSL_set_session_id_context(con, context, + strlen((char *)context)); + + sbio=BIO_new_socket(s,BIO_NOCLOSE); + SSL_set_bio(con,sbio,sbio); + SSL_set_accept_state(con); + + BIO_set_ssl(ssl_bio,con,BIO_CLOSE); + BIO_push(io,ssl_bio); +#ifdef CHARSET_EBCDIC + io = BIO_push(BIO_new(BIO_f_ebcdic_filter()),io); +#endif + + if (s_debug) + { + SSL_set_debug(con, 1); + BIO_set_callback(SSL_get_rbio(con),bio_dump_callback); + BIO_set_callback_arg(SSL_get_rbio(con),(char *)bio_s_out); + } + if (s_msg) + { +#ifndef OPENSSL_NO_SSL_TRACE + if (s_msg == 2) + SSL_set_msg_callback(con, SSL_trace); + else +#endif + SSL_set_msg_callback(con, msg_cb); + SSL_set_msg_callback_arg(con, bio_s_msg ? bio_s_msg : bio_s_out); + } + + for (;;) + { + i = BIO_do_handshake(io); + if (i > 0) + break; + if (!BIO_should_retry(io)) + { + BIO_puts(bio_err, "CONNECTION FAILURE\n"); + ERR_print_errors(bio_err); + goto end; + } + } + BIO_printf(bio_err, "CONNECTION ESTABLISHED\n"); + print_ssl_summary(bio_err, con); + + for (;;) + { + i=BIO_gets(io,buf,bufsize-1); + if (i < 0) /* error */ + { + if (!BIO_should_retry(io)) + { + if (!s_quiet) + ERR_print_errors(bio_err); + goto err; + } + else + { + BIO_printf(bio_s_out,"read R BLOCK\n"); +#if defined(OPENSSL_SYS_NETWARE) + delay(1000); +#elif !defined(OPENSSL_SYS_MSDOS) && !defined(__DJGPP__) + sleep(1); +#endif + continue; + } + } + else if (i == 0) /* end of input */ + { + ret=1; + BIO_printf(bio_err, "CONNECTION CLOSED\n"); + goto end; + } + else + { + char *p = buf + i - 1; + while(i && (*p == '\n' || *p == '\r')) + { + p--; + i--; + } + BUF_reverse((unsigned char *)buf, NULL, i); + buf[i] = '\n'; + BIO_write(io, buf, i + 1); + for (;;) + { + i = BIO_flush(io); + if (i > 0) + break; + if (!BIO_should_retry(io)) + goto end; + } + } + } +end: + /* make sure we re-use sessions */ + SSL_set_shutdown(con,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN); + +err: + + if (buf != NULL) OPENSSL_free(buf); + if (io != NULL) BIO_free_all(io); + return(ret); + } + #ifndef OPENSSL_NO_RSA static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength) { @@ -2938,10 +3357,10 @@ static int add_session(SSL *ssl, SSL_SESSION *session) sess = OPENSSL_malloc(sizeof(simple_ssl_session)); - sess->idlen = SSL_SESSION_get_id_len(session); + SSL_SESSION_get_id(session, &sess->idlen); sess->derlen = i2d_SSL_SESSION(session, NULL); - sess->id = BUF_memdup(SSL_SESSION_get0_id(session), sess->idlen); + sess->id = BUF_memdup(SSL_SESSION_get_id(session, NULL), sess->idlen); sess->der = OPENSSL_malloc(sess->derlen); p = sess->der; @@ -2974,8 +3393,9 @@ static SSL_SESSION *get_session(SSL *ssl, unsigned char *id, int idlen, static void del_session(SSL_CTX *sctx, SSL_SESSION *session) { simple_ssl_session *sess, *prev = NULL; - const unsigned char *id = SSL_SESSION_get0_id(session); - unsigned int idlen = SSL_SESSION_get_id_len(session); + const unsigned char *id; + unsigned int idlen; + id = SSL_SESSION_get_id(session, &idlen); for (sess = first; sess; sess = sess->next) { if (idlen == sess->idlen && !memcmp(sess->id, id, idlen)) @@ -3015,7 +3435,36 @@ static void free_sessions(void) } first = NULL; } - + +static int ssl_load_stores(SSL_CTX *sctx, + const char *vfyCApath, const char *vfyCAfile, + const char *chCApath, const char *chCAfile) + { + X509_STORE *vfy = NULL, *ch = NULL; + int rv = 0; + if (vfyCApath || vfyCAfile) + { + vfy = X509_STORE_new(); + if (!X509_STORE_load_locations(vfy, vfyCAfile, vfyCApath)) + goto err; + SSL_CTX_set1_verify_cert_store(ctx, vfy); + } + if (chCApath || chCAfile) + { + ch = X509_STORE_new(); + if (!X509_STORE_load_locations(ch, chCAfile, chCApath)) + goto err; + /*X509_STORE_set_verify_cb(ch, verify_callback);*/ + SSL_CTX_set1_chain_cert_store(ctx, ch); + } + rv = 1; + err: + if (vfy) + X509_STORE_free(vfy); + if (ch) + X509_STORE_free(ch); + return rv; + }