X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=apps%2Fs_cb.c;h=cf34e00a4c22bda3f4f8fd8e5677240c34c53232;hp=0759c8a7c9f8f0bbd2fb98e01da1c727733b7a03;hb=da92be4d68bec81030838e3228ef0238c565af85;hpb=84bafb747108486ea8e9716abb7a61285e9126ee diff --git a/apps/s_cb.c b/apps/s_cb.c index 0759c8a7c9..cf34e00a4c 100644 --- a/apps/s_cb.c +++ b/apps/s_cb.c @@ -120,6 +120,10 @@ #include #include #include +#include +#ifndef OPENSSL_NO_DH +#include +#endif #include "s_apps.h" #define COOKIE_SECRET_LENGTH 16 @@ -190,7 +194,8 @@ int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx) BIO_printf(bio_err,"\n"); break; case X509_V_ERR_NO_EXPLICIT_POLICY: - policies_print(bio_err, ctx); + if (!verify_quiet) + policies_print(bio_err, ctx); break; } if (err == X509_V_OK && ok == 2 && !verify_quiet) @@ -258,6 +263,7 @@ int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file) int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key, STACK_OF(X509) *chain, int build_chain) { + int chflags = chain ? SSL_BUILD_CHAIN_FLAG_CHECK : 0; if (cert == NULL) return 1; if (SSL_CTX_use_certificate(ctx,cert) <= 0) @@ -287,13 +293,12 @@ int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key, ERR_print_errors(bio_err); return 0; } - if (!chain && build_chain && !SSL_CTX_build_cert_chain(ctx, 0)) + if (build_chain && !SSL_CTX_build_cert_chain(ctx, chflags)) { BIO_printf(bio_err,"error building certificate chain\n"); ERR_print_errors(bio_err); return 0; } - return 1; } @@ -423,7 +428,7 @@ int ssl_print_sigalgs(BIO *out, SSL *s) BIO_printf(out, "Peer signing digest: %s\n", OBJ_nid2sn(mdnid)); return 1; } - +#ifndef OPENSSL_NO_EC int ssl_print_point_formats(BIO *out, SSL *s) { int i, nformats; @@ -515,7 +520,7 @@ int ssl_print_curves(BIO *out, SSL *s, int noshared) BIO_puts(out, "\n"); return 1; } - +#endif int ssl_print_tmp_key(BIO *out, SSL *s) { EVP_PKEY *key; @@ -531,7 +536,7 @@ int ssl_print_tmp_key(BIO *out, SSL *s) case EVP_PKEY_DH: BIO_printf(out, "DH, %d bits\n", EVP_PKEY_bits(key)); break; - +#ifndef OPENSSL_NO_ECDH case EVP_PKEY_EC: { EC_KEY *ec = EVP_PKEY_get1_EC_KEY(key); @@ -545,6 +550,7 @@ int ssl_print_tmp_key(BIO *out, SSL *s) BIO_printf(out, "ECDH, %s, %d bits\n", cname, EVP_PKEY_bits(key)); } +#endif } EVP_PKEY_free(key); return 1; @@ -611,40 +617,37 @@ void MS_CALLBACK apps_ssl_info_callback(const SSL *s, int where, int ret) } } - -void MS_CALLBACK msg_cb(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg) +static const char *ssl_version_str(int version) { - BIO *bio = arg; - const char *str_write_p, *str_version, *str_content_type = "", *str_details1 = "", *str_details2= ""; - - str_write_p = write_p ? ">>>" : "<<<"; - switch (version) { case SSL2_VERSION: - str_version = "SSL 2.0"; - break; + return "SSL 2.0"; case SSL3_VERSION: - str_version = "SSL 3.0 "; - break; + return "SSL 3.0"; case TLS1_VERSION: - str_version = "TLS 1.0 "; - break; + return "TLS 1.0"; case TLS1_1_VERSION: - str_version = "TLS 1.1 "; - break; + return "TLS 1.1"; case TLS1_2_VERSION: - str_version = "TLS 1.2 "; - break; + return "TLS 1.2"; case DTLS1_VERSION: - str_version = "DTLS 1.0 "; - break; + return "DTLS 1.0"; case DTLS1_BAD_VER: - str_version = "DTLS 1.0 (bad) "; - break; + return "DTLS 1.0 (bad)"; default: - str_version = "???"; + return "???"; } + } + +void MS_CALLBACK msg_cb(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg) + { + BIO *bio = arg; + const char *str_write_p, *str_version, *str_content_type = "", *str_details1 = "", *str_details2= ""; + + str_write_p = write_p ? ">>>" : "<<<"; + + str_version = ssl_version_str(version); if (version == SSL2_VERSION) { @@ -1019,6 +1022,14 @@ void MS_CALLBACK tlsext_cb(SSL *s, int client_server, int type, extname = "next protocol"; break; #endif +#ifdef TLSEXT_TYPE_encrypt_then_mac + case TLSEXT_TYPE_encrypt_then_mac: + extname = "encrypt-then-mac"; + break; +#endif + case TLSEXT_TYPE_padding: + extname = "TLS padding"; + break; default: extname = "unknown"; @@ -1263,6 +1274,16 @@ static int set_cert_cb(SSL *ssl, void *arg) { int i, rv; SSL_EXCERT *exc = arg; +#ifdef CERT_CB_TEST_RETRY + static int retry_cnt; + if (retry_cnt < 5) + { + retry_cnt++; + fprintf(stderr, "Certificate callback retry test: count %d\n", + retry_cnt); + return -1; + } +#endif SSL_certs_clear(ssl); if (!exc) @@ -1565,25 +1586,16 @@ void print_ssl_summary(BIO *bio, SSL *s) BIO_puts(bio, "No peer certificate\n"); if (peer) X509_free(peer); +#ifndef OPENSSL_NO_EC ssl_print_point_formats(bio, s); if (SSL_is_server(s)) ssl_print_curves(bio, s, 1); else ssl_print_tmp_key(bio, s); - } - -void print_ssl_cert_checks(BIO *bio, SSL *s, - const unsigned char *checkhost, - const unsigned char *checkemail, - const char *checkip) - { - X509 *peer; - peer = SSL_get_peer_certificate(s); - if (peer) - { - print_cert_checks(bio, peer, checkhost, checkemail, checkip); - X509_free(peer); - } +#else + if (!SSL_is_server(s)) + ssl_print_tmp_key(bio, s); +#endif } int args_ssl(char ***pargs, int *pargc, SSL_CONF_CTX *cctx, @@ -1633,7 +1645,7 @@ int args_ssl(char ***pargs, int *pargc, SSL_CONF_CTX *cctx, } int args_ssl_call(SSL_CTX *ctx, BIO *err, SSL_CONF_CTX *cctx, - STACK_OF(OPENSSL_STRING) *str, int no_ecdhe) + STACK_OF(OPENSSL_STRING) *str, int no_ecdhe, int no_jpake) { int i; SSL_CONF_CTX_set_ssl_ctx(cctx, ctx); @@ -1646,6 +1658,13 @@ int args_ssl_call(SSL_CTX *ctx, BIO *err, SSL_CONF_CTX *cctx, */ if (!no_ecdhe && !strcmp(param, "-named_curve")) no_ecdhe = 1; +#ifndef OPENSSL_NO_JPAKE + if (!no_jpake && !strcmp(param, "-cipher")) + { + BIO_puts(err, "JPAKE sets cipher to PSK\n"); + return 0; + } +#endif if (SSL_CONF_cmd(cctx, param, value) <= 0) { BIO_printf(err, "Error with command: \"%s %s\"\n", @@ -1667,12 +1686,52 @@ int args_ssl_call(SSL_CTX *ctx, BIO *err, SSL_CONF_CTX *cctx, return 0; } } +#ifndef OPENSSL_NO_JPAKE + if (!no_jpake) + { + if (SSL_CONF_cmd(cctx, "-cipher", "PSK") <= 0) + { + BIO_puts(err, "Error setting cipher to PSK\n"); + ERR_print_errors(err); + return 0; + } + } +#endif + if (!SSL_CONF_CTX_finish(cctx)) + { + BIO_puts(err, "Error finishing context\n"); + ERR_print_errors(err); + return 0; + } + return 1; + } + +static int add_crls_store(X509_STORE *st, STACK_OF(X509_CRL) *crls) + { + X509_CRL *crl; + int i; + for (i = 0; i < sk_X509_CRL_num(crls); i++) + { + crl = sk_X509_CRL_value(crls, i); + X509_STORE_add_crl(st, crl); + } + return 1; + } + +int ssl_ctx_add_crls(SSL_CTX *ctx, STACK_OF(X509_CRL) *crls, int crl_download) + { + X509_STORE *st; + st = SSL_CTX_get_cert_store(ctx); + add_crls_store(st, crls); + if (crl_download) + store_setup_crl_download(st); return 1; } int ssl_load_stores(SSL_CTX *ctx, const char *vfyCApath, const char *vfyCAfile, - const char *chCApath, const char *chCAfile) + const char *chCApath, const char *chCAfile, + STACK_OF(X509_CRL) *crls, int crl_download) { X509_STORE *vfy = NULL, *ch = NULL; int rv = 0; @@ -1681,7 +1740,10 @@ int ssl_load_stores(SSL_CTX *ctx, vfy = X509_STORE_new(); if (!X509_STORE_load_locations(vfy, vfyCAfile, vfyCApath)) goto err; + add_crls_store(vfy, crls); SSL_CTX_set1_verify_cert_store(ctx, vfy); + if (crl_download) + store_setup_crl_download(vfy); } if (chCApath || chCAfile) { @@ -1698,3 +1760,200 @@ int ssl_load_stores(SSL_CTX *ctx, X509_STORE_free(ch); return rv; } + +/* Verbose print out of security callback */ + +typedef struct + { + BIO *out; + int verbose; + int (*old_cb)(SSL *s, SSL_CTX *ctx, int op, int bits, int nid, + void *other, void *ex); + } security_debug_ex; + +static int security_callback_debug(SSL *s, SSL_CTX *ctx, + int op, int bits, int nid, + void *other, void *ex) + { + security_debug_ex *sdb = ex; + int rv, show_bits = 1, cert_md = 0; + const char *nm; + rv = sdb->old_cb(s, ctx, op, bits, nid, other, ex); + if (rv == 1 && sdb->verbose < 2) + return 1; + BIO_puts(sdb->out, "Security callback: "); + + switch (op) + { + case SSL_SECOP_CIPHER_SUPPORTED: + nm = "Supported Ciphersuite"; + break; + case SSL_SECOP_CIPHER_SHARED: + nm = "Shared Ciphersuite"; + break; + case SSL_SECOP_CIPHER_CHECK: + nm = "Check Ciphersuite"; + break; + case SSL_SECOP_TICKET: + BIO_puts(sdb->out, "Session ticket"); + show_bits = 0; + nm = NULL; + break; + case SSL_SECOP_COMPRESSION: + BIO_puts(sdb->out, "SSL compression"); + show_bits = 0; + nm = NULL; + break; +#ifndef OPENSSL_NO_DH + case SSL_SECOP_TMP_DH: + nm = "Temp DH key bits"; + break; +#endif + case SSL_SECOP_CURVE_SUPPORTED: + nm = "Supported Curve"; + break; + case SSL_SECOP_CURVE_SHARED: + nm = "Shared Curve"; + break; + case SSL_SECOP_CURVE_CHECK: + nm = "Check Curve"; + break; + case SSL_SECOP_SSL2_COMPAT: + BIO_puts(sdb->out, "SSLv2 compatible"); + show_bits = 0; + nm = NULL; + break; + case SSL_SECOP_VERSION: + BIO_printf(sdb->out, "Version=%s", ssl_version_str(nid)); + show_bits = 0; + nm = NULL; + break; + case SSL_SECOP_SIGALG_SUPPORTED: + nm = "Supported Signature Algorithm digest"; + break; + case SSL_SECOP_SIGALG_SHARED: + nm = "Shared Signature Algorithm digest"; + break; + case SSL_SECOP_SIGALG_CHECK: + nm = "Check Signature Algorithm digest"; + break; + case SSL_SECOP_SIGALG_MASK: + nm = "Signature Algorithm mask"; + break; + case SSL_SECOP_EE_KEY: + nm = "Certificate chain EE key"; + break; + case SSL_SECOP_CA_KEY: + nm = "Certificate chain CA key"; + break; + case SSL_SECOP_CA_MD: + cert_md = 1; + nm = "Certificate chain CA digest"; + break; + case SSL_SECOP_PEER_EE_KEY: + nm = "Peer Chain EE key"; + break; + case SSL_SECOP_PEER_CA_KEY: + nm = "Peer Chain CA key"; + break; + case SSL_SECOP_PEER_CA_MD: + cert_md = 1; + nm = "Peer chain CA digest"; + break; + default: + nm = NULL; + } + if (nm) + BIO_printf(sdb->out, "%s=", nm); + + switch (op & SSL_SECOP_OTHER_TYPE) + { + + case SSL_SECOP_OTHER_CIPHER: + BIO_puts(sdb->out, SSL_CIPHER_get_name(other)); + break; + + case SSL_SECOP_OTHER_CURVE: + { + const char *cname; + cname = EC_curve_nid2nist(nid); + if (cname == NULL) + cname = OBJ_nid2sn(nid); + BIO_puts(sdb->out, cname); + } + break; + + case SSL_SECOP_OTHER_DH: + { + DH *dh = other; + BIO_printf(sdb->out, "%d", BN_num_bits(dh->p)); + break; + } + case SSL_SECOP_OTHER_CERT: + { + if (cert_md) + { + int sig_nid = X509_get_signature_nid(other); + BIO_puts(sdb->out, OBJ_nid2sn(sig_nid)); + } + else + { + EVP_PKEY *pkey = X509_get_pubkey(other); + const char *algname = ""; + EVP_PKEY_asn1_get0_info(NULL, NULL, NULL, NULL, + &algname, + EVP_PKEY_get0_asn1(pkey)); + BIO_printf(sdb->out, "%s, bits=%d", + algname, EVP_PKEY_bits(pkey)); + EVP_PKEY_free(pkey); + } + break; + } + case SSL_SECOP_OTHER_SIGALG: + { + const unsigned char *salg = other; + const char *sname = NULL; + switch (salg[1]) + { + case TLSEXT_signature_anonymous: + sname = "anonymous"; + break; + case TLSEXT_signature_rsa: + sname = "RSA"; + break; + case TLSEXT_signature_dsa: + sname = "DSA"; + break; + case TLSEXT_signature_ecdsa: + sname = "ECDSA"; + break; + } + + BIO_puts(sdb->out, OBJ_nid2sn(nid)); + if (sname) + BIO_printf(sdb->out, ", algorithm=%s", sname); + else + BIO_printf(sdb->out, ", algid=%d", salg[1]); + break; + } + + } + + if (show_bits) + BIO_printf(sdb->out, ", security bits=%d", bits); + BIO_printf(sdb->out, ": %s\n", rv ? "yes" : "no"); + return rv; + } + +void ssl_ctx_security_debug(SSL_CTX *ctx, BIO *out, int verbose) + { + static security_debug_ex sdb; + sdb.out = out; + sdb.verbose = verbose; + sdb.old_cb = SSL_CTX_get_security_callback(ctx); + SSL_CTX_set_security_callback(ctx, security_callback_debug); + SSL_CTX_set0_security_ex_data(ctx, &sdb); + } + + +