From e03c5b59f04684c55a173d1a8ac38df7e4b21c48 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Mon, 17 Feb 2014 00:10:00 +0000 Subject: [PATCH] Security callback debug print out. Add a debugging security callback option to s_client/s_server. This will print out each security parameter as it is accepted or rejected. --- apps/s_apps.h | 1 + apps/s_cb.c | 242 +++++++++++++++++++++++++++++++++++++++++++----- apps/s_client.c | 8 ++ apps/s_server.c | 10 ++ 4 files changed, 239 insertions(+), 22 deletions(-) diff --git a/apps/s_apps.h b/apps/s_apps.h index f46d1ebe45..ff616d7c00 100644 --- a/apps/s_apps.h +++ b/apps/s_apps.h @@ -198,4 +198,5 @@ int ssl_load_stores(SSL_CTX *ctx, const char *vfyCApath, const char *vfyCAfile, const char *chCApath, const char *chCAfile, STACK_OF(X509_CRL) *crls, int crl_download); +void ssl_ctx_security_debug(SSL_CTX *ctx, BIO *out, int verbose); #endif diff --git a/apps/s_cb.c b/apps/s_cb.c index 04ebb79b93..9dda23c023 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 @@ -613,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) { @@ -1759,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); + } + + + diff --git a/apps/s_client.c b/apps/s_client.c index af88ffdaad..f8c059a25a 100644 --- a/apps/s_client.c +++ b/apps/s_client.c @@ -702,6 +702,7 @@ static char *jpake_secret = NULL; int crl_format = FORMAT_PEM; int crl_download = 0; STACK_OF(X509_CRL) *crls = NULL; + int sdebug = 0; meth=SSLv23_client_method(); @@ -874,6 +875,10 @@ static char *jpake_secret = NULL; else if (strcmp(*argv,"-trace") == 0) c_msg=2; #endif + else if (strcmp(*argv,"-security_debug") == 0) + { sdebug=1; } + else if (strcmp(*argv,"-security_debug_verbose") == 0) + { sdebug=2; } else if (strcmp(*argv,"-showcerts") == 0) c_showcerts=1; else if (strcmp(*argv,"-nbio_test") == 0) @@ -1302,6 +1307,9 @@ bad: goto end; } + if (sdebug) + ssl_ctx_security_debug(ctx, bio_err, sdebug); + if (vpm) SSL_CTX_set1_param(ctx, vpm); diff --git a/apps/s_server.c b/apps/s_server.c index 9db57dff3c..10bfdd6b91 100644 --- a/apps/s_server.c +++ b/apps/s_server.c @@ -1030,6 +1030,7 @@ int MAIN(int argc, char *argv[]) EVP_PKEY *s_key = NULL, *s_dkey = NULL; int no_cache = 0, ext_cache = 0; int rev = 0, naccept = -1; + int sdebug = 0; #ifndef OPENSSL_NO_TLSEXT EVP_PKEY *s_key2 = NULL; X509 *s_cert2 = NULL; @@ -1344,6 +1345,10 @@ int MAIN(int argc, char *argv[]) else if (strcmp(*argv,"-trace") == 0) { s_msg=2; } #endif + else if (strcmp(*argv,"-security_debug") == 0) + { sdebug=1; } + else if (strcmp(*argv,"-security_debug_verbose") == 0) + { sdebug=2; } else if (strcmp(*argv,"-hack") == 0) { hack=1; } else if (strcmp(*argv,"-state") == 0) @@ -1743,6 +1748,8 @@ bad: } ctx=SSL_CTX_new(meth); + if (sdebug) + ssl_ctx_security_debug(ctx, bio_err, sdebug); if (ctx == NULL) { ERR_print_errors(bio_err); @@ -1832,6 +1839,9 @@ bad: { BIO_printf(bio_s_out,"Setting secondary ctx parameters\n"); + if (sdebug) + ssl_ctx_security_debug(ctx, bio_err, sdebug); + if (session_id_prefix) { if(strlen(session_id_prefix) >= 32) -- 2.40.0