Commit e03c5b59 authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

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.
parent b362ccab
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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
+220 −22
Original line number Diff line number Diff line
@@ -120,6 +120,10 @@
#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,41 +617,38 @@ 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)
		{
		str_details1 = "???";
@@ -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);
	}


+8 −0
Original line number Diff line number Diff line
@@ -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);

+10 −0
Original line number Diff line number Diff line
@@ -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)