X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=apps%2Fs_server.c;h=002de84380a7c64948013e13abf7fcf09a41ad39;hp=8ea916d6e164d92f5a52483514ec5815a56ac11d;hb=2a7cbe77b3abb244c2211d22d7aa3416b97c9342;hpb=657e29c1999f02b8962ccbe26faa63cbccb4ff2e diff --git a/apps/s_server.c b/apps/s_server.c index 8ea916d6e1..002de84380 100644 --- a/apps/s_server.c +++ b/apps/s_server.c @@ -215,6 +215,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,7 +268,7 @@ 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; @@ -300,6 +303,7 @@ 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; @@ -463,6 +467,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; @@ -952,6 +957,8 @@ 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 @@ -961,6 +968,7 @@ int MAIN(int argc, char *argv[]) int ret=1; int off=0; unsigned int cert_flags = 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; @@ -1135,6 +1143,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) @@ -1153,6 +1171,8 @@ int MAIN(int argc, char *argv[]) } else if (strcmp(*argv,"-verify_return_error") == 0) verify_return_error = 1; + else if (strcmp(*argv,"-verify_quiet") == 0) + verify_quiet = 1; else if (strcmp(*argv,"-serverpref") == 0) { off|=SSL_OP_CIPHER_SERVER_PREFERENCE; } else if (strcmp(*argv,"-legacy_renegotiation") == 0) @@ -1162,11 +1182,23 @@ int MAIN(int argc, char *argv[]) if (--argc < 1) goto bad; cipher= *(++argv); } + else if (strcmp(*argv,"-build_chain") == 0) + build_chain = 1; else if (strcmp(*argv,"-CAfile") == 0) { if (--argc < 1) goto bad; CAfile= *(++argv); } + else if (strcmp(*argv,"-chainCAfile") == 0) + { + if (--argc < 1) goto bad; + chCAfile= *(++argv); + } + else if (strcmp(*argv,"-verifyCAfile") == 0) + { + if (--argc < 1) goto bad; + vfyCAfile= *(++argv); + } #ifdef FIONBIO else if (strcmp(*argv,"-nbio") == 0) { s_nbio=1; } @@ -1245,6 +1277,12 @@ int MAIN(int argc, char *argv[]) { s_crlf=1; } else if (strcmp(*argv,"-quiet") == 0) { s_quiet=1; } + else if (strcmp(*argv,"-brief") == 0) + { + s_quiet=1; + s_brief=1; + verify_quiet=1; + } else if (strcmp(*argv,"-bugs") == 0) { bugs=1; } else if (strcmp(*argv,"-no_tmp_rsa") == 0) @@ -1412,6 +1450,10 @@ int MAIN(int argc, char *argv[]) } else if (strcmp(*argv, "-cert_strict") == 0) cert_flags |= SSL_CERT_FLAG_TLS_STRICT; +#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL + else if (strcmp(*argv, "-debug_broken_protocol") == 0) + cert_flags |= SSL_CERT_FLAG_BROKEN_PROTCOL; +#endif else { BIO_printf(bio_err,"unknown option %s\n",*argv); @@ -1518,25 +1560,24 @@ bad: goto end; } } - -# ifndef OPENSSL_NO_NEXTPROTONEG - if (next_proto_neg_in) - { - unsigned short len; - next_proto.data = next_protos_parse(&len, - next_proto_neg_in); - if (next_proto.data == NULL) - goto end; - next_proto.len = len; - } - else - { - next_proto.data = NULL; - } -# endif #endif /* OPENSSL_NO_TLSEXT */ } +#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) + if (next_proto_neg_in) + { + unsigned short len; + next_proto.data = next_protos_parse(&len, next_proto_neg_in); + if (next_proto.data == NULL) + goto end; + next_proto.len = len; + } + else + { + next_proto.data = NULL; + } +#endif + if (s_dcert_file) { @@ -1673,6 +1714,13 @@ bad: if (vpm) SSL_CTX_set1_param(ctx, vpm); + if (!ssl_load_stores(ctx, vfyCApath, vfyCAfile, chCApath, chCAfile)) + { + BIO_printf(bio_err, "Error loading store locations\n"); + ERR_print_errors(bio_err); + goto end; + } + #ifndef OPENSSL_NO_TLSEXT if (s_cert2) { @@ -1835,19 +1883,19 @@ bad: } #endif - if (!set_cert_key_stuff(ctx, s_cert, s_key, s_chain)) + if (!set_cert_key_stuff(ctx, s_cert, s_key, s_chain, build_chain)) goto end; #ifndef OPENSSL_NO_TLSEXT if (s_authz_file != NULL && !SSL_CTX_use_authz_file(ctx, s_authz_file)) goto end; #endif #ifndef OPENSSL_NO_TLSEXT - if (ctx2 && !set_cert_key_stuff(ctx2,s_cert2,s_key2, NULL)) + if (ctx2 && !set_cert_key_stuff(ctx2,s_cert2,s_key2, NULL, build_chain)) goto end; #endif if (s_dcert != NULL) { - if (!set_cert_key_stuff(ctx, s_dcert, s_dkey, s_dchain)) + if (!set_cert_key_stuff(ctx, s_dcert, s_dkey, s_dchain, build_chain)) goto end; } @@ -2054,12 +2102,22 @@ end: EVP_PKEY_free(s_key); if (s_dkey) EVP_PKEY_free(s_dkey); + if (s_chain) + sk_X509_pop_free(s_chain, X509_free); + if (s_dchain) + sk_X509_pop_free(s_dchain, X509_free); if (pass) OPENSSL_free(pass); if (dpass) OPENSSL_free(dpass); free_sessions(); #ifndef OPENSSL_NO_TLSEXT + if (tlscstatp.host) + OPENSSL_free(tlscstatp.host); + if (tlscstatp.port) + OPENSSL_free(tlscstatp.port); + if (tlscstatp.path) + OPENSSL_free(tlscstatp.path); if (ctx2 != NULL) SSL_CTX_free(ctx2); if (s_cert2) X509_free(s_cert2); @@ -2341,7 +2399,7 @@ static int sv_body(char *hostname, int s, unsigned char *context) } else i=raw_read_stdin(buf,bufsize); - if (!s_quiet) + if (!s_quiet && !s_brief) { if ((i <= 0) || (buf[0] == 'Q')) { @@ -2589,11 +2647,14 @@ 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); + PEM_write_bio_SSL_SESSION(bio_s_out,SSL_get_session(con)); peer=SSL_get_peer_certificate(con); @@ -2611,8 +2672,8 @@ 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, 0); - ssl_print_curves(bio_s_out, 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) @@ -2954,8 +3015,8 @@ static int www_body(char *hostname, int s, unsigned char *context) } BIO_puts(io,"\n"); } - ssl_print_sigalgs(io, con, 0); - ssl_print_curves(io, con); + ssl_print_sigalgs(io, con); + ssl_print_curves(io, con, 0); BIO_printf(io,(SSL_cache_hit(con) ?"---\nReused, " :"---\nNew, ")); @@ -3306,7 +3367,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; + }