Security callback debug print out.
authorDr. Stephen Henson <steve@openssl.org>
Mon, 17 Feb 2014 00:10:00 +0000 (00:10 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Fri, 28 Mar 2014 14:56:43 +0000 (14:56 +0000)
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
apps/s_cb.c
apps/s_client.c
apps/s_server.c

index f46d1ebe45e00b6066eae00dfad9a5a388dfebb1..ff616d7c0061e6636cc6e0a22f93503a9e2ca9d1 100644 (file)
@@ -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
index 04ebb79b932201d6e9477ea8e9742506c40190bd..9dda23c023a25ca64bb726429cdcecef189cd6c9 100644 (file)
 #include <openssl/rand.h>
 #include <openssl/x509.h>
 #include <openssl/ssl.h>
+#include <openssl/bn.h>
+#ifndef OPENSSL_NO_DH
+#include <openssl/dh.h>
+#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);
+       }
+
+
+
index af88ffdaada32a8d192d3fb627216c3281a4452c..f8c059a25ad5bbc1945d9c68d662b94f39aa3fce 100644 (file)
@@ -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);
 
index 9db57dff3c36733e1173f9b78d62f79826625785..10bfdd6b911e0a6ee669fe942de65edd8e6e80b1 100644 (file)
@@ -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)