From e03c5b59f04684c55a173d1a8ac38df7e4b21c48 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Mon, 17 Feb 2014 00:10:00 +0000 Subject: 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_cb.c | 242 ++++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 220 insertions(+), 22 deletions(-) (limited to 'apps/s_cb.c') 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); + } + + + -- cgit v1.2.3