summaryrefslogtreecommitdiffstats
path: root/apps/s_cb.c
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2014-02-17 00:10:00 +0000
committerDr. Stephen Henson <steve@openssl.org>2014-03-28 14:56:43 +0000
commite03c5b59f04684c55a173d1a8ac38df7e4b21c48 (patch)
tree3f7caf78e530e810a0446db4025ab53a469f991d /apps/s_cb.c
parentb362ccab5c1d52086f19d29a32f4acc11073b86b (diff)
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.
Diffstat (limited to 'apps/s_cb.c')
-rw-r--r--apps/s_cb.c242
1 files changed, 220 insertions, 22 deletions
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 <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);
+ }
+
+
+