SSL/TLS record tracing code (backport from HEAD).
This commit is contained in:
parent
a08f8d73cc
commit
bc200e691c
14 changed files with 1460 additions and 11 deletions
6
CHANGES
6
CHANGES
|
@ -4,6 +4,12 @@
|
|||
|
||||
Changes between 1.0.1 and 1.0.2 [xx XXX xxxx]
|
||||
|
||||
*) SSL/TLS tracing code. This parses out SSL/TLS records using the
|
||||
message callback and prints the results. Needs compile time option
|
||||
"enable-ssl-trace". New options to s_client and s_server to enable
|
||||
tracing.
|
||||
[Steve Henson]
|
||||
|
||||
*) New ctrl and macro to retrieve supported points extensions.
|
||||
Print out extension in s_server.
|
||||
[Steve Henson]
|
||||
|
|
|
@ -727,6 +727,7 @@ my %disabled = ( # "what" => "comment" [or special keyword "experimental
|
|||
"rfc3779" => "default",
|
||||
"sctp" => "default",
|
||||
"shared" => "default",
|
||||
"ssl-trace" => "default",
|
||||
"store" => "experimental",
|
||||
"zlib" => "default",
|
||||
"zlib-dynamic" => "default"
|
||||
|
|
|
@ -217,6 +217,7 @@ static int ocsp_resp_cb(SSL *s, void *arg);
|
|||
static int audit_proof_cb(SSL *s, void *arg);
|
||||
#endif
|
||||
static BIO *bio_c_out=NULL;
|
||||
static BIO *bio_c_msg=NULL;
|
||||
static int c_quiet=0;
|
||||
static int c_ign_eof=0;
|
||||
|
||||
|
@ -754,6 +755,15 @@ int MAIN(int argc, char **argv)
|
|||
#endif
|
||||
else if (strcmp(*argv,"-msg") == 0)
|
||||
c_msg=1;
|
||||
else if (strcmp(*argv,"-msgfile") == 0)
|
||||
{
|
||||
if (--argc < 1) goto bad;
|
||||
bio_c_msg = BIO_new_file(*(++argv), "w");
|
||||
}
|
||||
#ifndef OPENSSL_NO_SSL_TRACE
|
||||
else if (strcmp(*argv,"-trace") == 0)
|
||||
c_msg=2;
|
||||
#endif
|
||||
else if (strcmp(*argv,"-showcerts") == 0)
|
||||
c_showcerts=1;
|
||||
else if (strcmp(*argv,"-nbio_test") == 0)
|
||||
|
@ -1115,9 +1125,11 @@ bad:
|
|||
|
||||
if (bio_c_out == NULL)
|
||||
{
|
||||
if (c_quiet && !c_debug && !c_msg)
|
||||
if (c_quiet && !c_debug)
|
||||
{
|
||||
bio_c_out=BIO_new(BIO_s_null());
|
||||
if (c_msg && !bio_c_msg)
|
||||
bio_c_msg=BIO_new_fp(stdout,BIO_NOCLOSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1390,8 +1402,13 @@ re_start:
|
|||
}
|
||||
if (c_msg)
|
||||
{
|
||||
SSL_set_msg_callback(con, msg_cb);
|
||||
SSL_set_msg_callback_arg(con, bio_c_out);
|
||||
#ifndef OPENSSL_NO_SSL_TRACE
|
||||
if (c_msg == 2)
|
||||
SSL_set_msg_callback(con, SSL_trace);
|
||||
else
|
||||
#endif
|
||||
SSL_set_msg_callback(con, msg_cb);
|
||||
SSL_set_msg_callback_arg(con, bio_c_msg ? bio_c_msg : bio_c_out);
|
||||
}
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
if (c_tlsextdebug)
|
||||
|
@ -1975,6 +1992,11 @@ end:
|
|||
BIO_free(bio_c_out);
|
||||
bio_c_out=NULL;
|
||||
}
|
||||
if (bio_c_msg != NULL)
|
||||
{
|
||||
BIO_free(bio_c_msg);
|
||||
bio_c_msg=NULL;
|
||||
}
|
||||
apps_shutdown();
|
||||
OPENSSL_EXIT(ret);
|
||||
}
|
||||
|
|
|
@ -290,6 +290,7 @@ static SSL_CTX *ctx2=NULL;
|
|||
static int www=0;
|
||||
|
||||
static BIO *bio_s_out=NULL;
|
||||
static BIO *bio_s_msg = NULL;
|
||||
static int s_debug=0;
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
static int s_tlsextdebug=0;
|
||||
|
@ -1244,6 +1245,15 @@ int MAIN(int argc, char *argv[])
|
|||
#endif
|
||||
else if (strcmp(*argv,"-msg") == 0)
|
||||
{ s_msg=1; }
|
||||
else if (strcmp(*argv,"-msgfile") == 0)
|
||||
{
|
||||
if (--argc < 1) goto bad;
|
||||
bio_s_msg = BIO_new_file(*(++argv), "w");
|
||||
}
|
||||
#ifndef OPENSSL_NO_SSL_TRACE
|
||||
else if (strcmp(*argv,"-trace") == 0)
|
||||
{ s_msg=2; }
|
||||
#endif
|
||||
else if (strcmp(*argv,"-hack") == 0)
|
||||
{ hack=1; }
|
||||
else if (strcmp(*argv,"-state") == 0)
|
||||
|
@ -1589,6 +1599,8 @@ bad:
|
|||
if (s_quiet && !s_debug && !s_msg)
|
||||
{
|
||||
bio_s_out=BIO_new(BIO_s_null());
|
||||
if (s_msg && !bio_s_msg)
|
||||
bio_s_msg=BIO_new_fp(stdout,BIO_NOCLOSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2080,9 +2092,14 @@ end:
|
|||
ssl_excert_free(exc);
|
||||
if (bio_s_out != NULL)
|
||||
{
|
||||
BIO_free(bio_s_out);
|
||||
BIO_free(bio_s_out);
|
||||
bio_s_out=NULL;
|
||||
}
|
||||
if (bio_s_msg != NULL)
|
||||
{
|
||||
BIO_free(bio_s_msg);
|
||||
bio_s_msg = NULL;
|
||||
}
|
||||
apps_shutdown();
|
||||
OPENSSL_EXIT(ret);
|
||||
}
|
||||
|
@ -2237,8 +2254,13 @@ static int sv_body(char *hostname, int s, unsigned char *context)
|
|||
}
|
||||
if (s_msg)
|
||||
{
|
||||
SSL_set_msg_callback(con, msg_cb);
|
||||
SSL_set_msg_callback_arg(con, bio_s_out);
|
||||
#ifndef OPENSSL_NO_SSL_TRACE
|
||||
if (s_msg == 2)
|
||||
SSL_set_msg_callback(con, SSL_trace);
|
||||
else
|
||||
#endif
|
||||
SSL_set_msg_callback(con, msg_cb);
|
||||
SSL_set_msg_callback_arg(con, bio_s_msg ? bio_s_msg : bio_s_out);
|
||||
}
|
||||
#ifndef OPENSSL_NO_TLSEXT
|
||||
if (s_tlsextdebug)
|
||||
|
@ -2794,8 +2816,13 @@ static int www_body(char *hostname, int s, unsigned char *context)
|
|||
}
|
||||
if (s_msg)
|
||||
{
|
||||
SSL_set_msg_callback(con, msg_cb);
|
||||
SSL_set_msg_callback_arg(con, bio_s_out);
|
||||
#ifndef OPENSSL_NO_SSL_TRACE
|
||||
if (s_msg == 2)
|
||||
SSL_set_msg_callback(con, SSL_trace);
|
||||
else
|
||||
#endif
|
||||
SSL_set_msg_callback(con, msg_cb);
|
||||
SSL_set_msg_callback_arg(con, bio_s_msg ? bio_s_msg : bio_s_out);
|
||||
}
|
||||
|
||||
for (;;)
|
||||
|
|
|
@ -30,7 +30,7 @@ LIBSRC= \
|
|||
ssl_lib.c ssl_err2.c ssl_cert.c ssl_sess.c \
|
||||
ssl_ciph.c ssl_stat.c ssl_rsa.c \
|
||||
ssl_asn1.c ssl_txt.c ssl_algs.c \
|
||||
bio_ssl.c ssl_err.c kssl.c tls_srp.c t1_reneg.c
|
||||
bio_ssl.c ssl_err.c kssl.c tls_srp.c t1_reneg.c t1_trce.c
|
||||
LIBOBJ= \
|
||||
s2_meth.o s2_srvr.o s2_clnt.o s2_lib.o s2_enc.o s2_pkt.o \
|
||||
s3_meth.o s3_srvr.o s3_clnt.o s3_lib.o s3_enc.o s3_pkt.o s3_both.o \
|
||||
|
@ -41,7 +41,7 @@ LIBOBJ= \
|
|||
ssl_lib.o ssl_err2.o ssl_cert.o ssl_sess.o \
|
||||
ssl_ciph.o ssl_stat.o ssl_rsa.o \
|
||||
ssl_asn1.o ssl_txt.o ssl_algs.o \
|
||||
bio_ssl.o ssl_err.o kssl.o tls_srp.o t1_reneg.o
|
||||
bio_ssl.o ssl_err.o kssl.o tls_srp.o t1_reneg.o t1_trce.o
|
||||
|
||||
SRC= $(LIBSRC)
|
||||
|
||||
|
|
|
@ -587,7 +587,10 @@ static int ssl23_client_hello(SSL *s)
|
|||
if (ssl2_compat)
|
||||
s->msg_callback(1, SSL2_VERSION, 0, s->init_buf->data+2, ret-2, s, s->msg_callback_arg);
|
||||
else
|
||||
{
|
||||
s->msg_callback(1, version, SSL3_RT_HEADER, s->init_buf->data, 5, s, s->msg_callback_arg);
|
||||
s->msg_callback(1, version, SSL3_RT_HANDSHAKE, s->init_buf->data+5, ret-5, s, s->msg_callback_arg);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -743,7 +746,10 @@ static int ssl23_get_server_hello(SSL *s)
|
|||
}
|
||||
|
||||
if (s->msg_callback)
|
||||
{
|
||||
s->msg_callback(0, s->version, SSL3_RT_HEADER, p, 5, s, s->msg_callback_arg);
|
||||
s->msg_callback(0, s->version, SSL3_RT_ALERT, p+5, 2, s, s->msg_callback_arg);
|
||||
}
|
||||
|
||||
s->rwstate=SSL_NOTHING;
|
||||
SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_AD_REASON_OFFSET+p[6]);
|
||||
|
|
41
ssl/s3_enc.c
41
ssl/s3_enc.c
|
@ -375,6 +375,27 @@ int ssl3_change_cipher_state(SSL *s, int which)
|
|||
|
||||
EVP_CipherInit_ex(dd,c,NULL,key,iv,(which & SSL3_CC_WRITE));
|
||||
|
||||
#ifdef OPENSSL_SSL_TRACE_CRYPTO
|
||||
if (s->msg_callback)
|
||||
{
|
||||
|
||||
int wh = which & SSL3_CC_WRITE ?
|
||||
TLS1_RT_CRYPTO_WRITE : TLS1_RT_CRYPTO_READ;
|
||||
s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_MAC,
|
||||
mac_secret, EVP_MD_size(m),
|
||||
s, s->msg_callback_arg);
|
||||
if (c->key_len)
|
||||
s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_KEY,
|
||||
key, c->key_len,
|
||||
s, s->msg_callback_arg);
|
||||
if (k)
|
||||
{
|
||||
s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_IV,
|
||||
iv, k, s, s->msg_callback_arg);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
OPENSSL_cleanse(&(exp_key[0]),sizeof(exp_key));
|
||||
OPENSSL_cleanse(&(exp_iv[0]),sizeof(exp_iv));
|
||||
EVP_MD_CTX_cleanup(&md);
|
||||
|
@ -797,6 +818,9 @@ int ssl3_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
|
|||
EVP_MD_CTX ctx;
|
||||
int i,ret=0;
|
||||
unsigned int n;
|
||||
#ifdef OPENSSL_SSL_TRACE_CRYPTO
|
||||
unsigned char *tmpout = out;
|
||||
#endif
|
||||
|
||||
EVP_MD_CTX_init(&ctx);
|
||||
for (i=0; i<3; i++)
|
||||
|
@ -818,6 +842,23 @@ int ssl3_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
|
|||
ret+=n;
|
||||
}
|
||||
EVP_MD_CTX_cleanup(&ctx);
|
||||
|
||||
#ifdef OPENSSL_SSL_TRACE_CRYPTO
|
||||
if (s->msg_callback)
|
||||
{
|
||||
s->msg_callback(2, s->version, TLS1_RT_CRYPTO_PREMASTER,
|
||||
p, len, s, s->msg_callback_arg);
|
||||
s->msg_callback(2, s->version, TLS1_RT_CRYPTO_CLIENT_RANDOM,
|
||||
s->s3->client_random, SSL3_RANDOM_SIZE,
|
||||
s, s->msg_callback_arg);
|
||||
s->msg_callback(2, s->version, TLS1_RT_CRYPTO_SERVER_RANDOM,
|
||||
s->s3->server_random, SSL3_RANDOM_SIZE,
|
||||
s, s->msg_callback_arg);
|
||||
s->msg_callback(2, s->version, TLS1_RT_CRYPTO_MASTER,
|
||||
tmpout, SSL3_MASTER_SECRET_SIZE,
|
||||
s, s->msg_callback_arg);
|
||||
}
|
||||
#endif
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
|
|
@ -321,6 +321,8 @@ again:
|
|||
s->rstate=SSL_ST_READ_BODY;
|
||||
|
||||
p=s->packet;
|
||||
if (s->msg_callback)
|
||||
s->msg_callback(0, 0, SSL3_RT_HEADER, p, 5, s, s->msg_callback_arg);
|
||||
|
||||
/* Pull apart the header into the SSL3_RECORD */
|
||||
rr->type= *(p++);
|
||||
|
@ -822,6 +824,9 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
|
|||
/* record length after mac and block padding */
|
||||
s2n(wr->length,plen);
|
||||
|
||||
if (s->msg_callback)
|
||||
s->msg_callback(1, 0, SSL3_RT_HEADER, plen - 5, 5, s, s->msg_callback_arg);
|
||||
|
||||
/* we should now have
|
||||
* wr->data pointing to the encrypted data, which is
|
||||
* wr->length long */
|
||||
|
|
|
@ -2254,6 +2254,12 @@ void SSL_set_debug(SSL *s, int debug);
|
|||
int SSL_cache_hit(SSL *s);
|
||||
int SSL_is_server(SSL *s);
|
||||
|
||||
#ifndef OPENSSL_NO_SSL_TRACE
|
||||
void SSL_trace(int write_p, int version, int content_type,
|
||||
const void *buf, size_t len, SSL *ssl, void *arg);
|
||||
const char *SSL_CIPHER_standard_name(const SSL_CIPHER *c);
|
||||
#endif
|
||||
|
||||
/* BEGIN ERROR CODES */
|
||||
/* The following lines are auto generated by the script mkerr.pl. Any changes
|
||||
* made after this point may be overwritten when the script is next run.
|
||||
|
|
17
ssl/ssl3.h
17
ssl/ssl3.h
|
@ -324,6 +324,23 @@ extern "C" {
|
|||
#define SSL3_RT_APPLICATION_DATA 23
|
||||
#define TLS1_RT_HEARTBEAT 24
|
||||
|
||||
/* Pseudo content types to indicate additional parameters */
|
||||
#define TLS1_RT_CRYPTO 0x1000
|
||||
#define TLS1_RT_CRYPTO_PREMASTER (TLS1_RT_CRYPTO | 0x1)
|
||||
#define TLS1_RT_CRYPTO_CLIENT_RANDOM (TLS1_RT_CRYPTO | 0x2)
|
||||
#define TLS1_RT_CRYPTO_SERVER_RANDOM (TLS1_RT_CRYPTO | 0x3)
|
||||
#define TLS1_RT_CRYPTO_MASTER (TLS1_RT_CRYPTO | 0x4)
|
||||
|
||||
#define TLS1_RT_CRYPTO_READ 0x0000
|
||||
#define TLS1_RT_CRYPTO_WRITE 0x0100
|
||||
#define TLS1_RT_CRYPTO_MAC (TLS1_RT_CRYPTO | 0x5)
|
||||
#define TLS1_RT_CRYPTO_KEY (TLS1_RT_CRYPTO | 0x6)
|
||||
#define TLS1_RT_CRYPTO_IV (TLS1_RT_CRYPTO | 0x7)
|
||||
#define TLS1_RT_CRYPTO_FIXED_IV (TLS1_RT_CRYPTO | 0x8)
|
||||
|
||||
/* Pseudo content type for SSL/TLS header info */
|
||||
#define SSL3_RT_HEADER 0x100
|
||||
|
||||
#define SSL3_AL_WARNING 1
|
||||
#define SSL3_AL_FATAL 2
|
||||
|
||||
|
|
42
ssl/t1_enc.c
42
ssl/t1_enc.c
|
@ -556,6 +556,30 @@ printf("which = %04X\nmac key=",which);
|
|||
EVP_CIPHER_CTX_ctrl(dd,EVP_CTRL_AEAD_SET_MAC_KEY,
|
||||
*mac_secret_size,mac_secret);
|
||||
|
||||
#ifdef OPENSSL_SSL_TRACE_CRYPTO
|
||||
if (s->msg_callback)
|
||||
{
|
||||
int wh = which & SSL3_CC_WRITE ? TLS1_RT_CRYPTO_WRITE : 0;
|
||||
if (*mac_secret_size)
|
||||
s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_MAC,
|
||||
mac_secret, *mac_secret_size,
|
||||
s, s->msg_callback_arg);
|
||||
if (c->key_len)
|
||||
s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_KEY,
|
||||
key, c->key_len,
|
||||
s, s->msg_callback_arg);
|
||||
if (k)
|
||||
{
|
||||
if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE)
|
||||
wh |= TLS1_RT_CRYPTO_FIXED_IV;
|
||||
else
|
||||
wh |= TLS1_RT_CRYPTO_IV;
|
||||
s->msg_callback(2, s->version, wh, iv, k,
|
||||
s, s->msg_callback_arg);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TLS_DEBUG
|
||||
printf("which = %04X\nkey=",which);
|
||||
{ int z; for (z=0; z<EVP_CIPHER_key_length(c); z++) printf("%02X%c",key[z],((z+1)%16)?' ':'\n'); }
|
||||
|
@ -1118,6 +1142,24 @@ int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
|
|||
BIO_dump_fp(stderr, (char *)s->session->master_key, SSL3_MASTER_SECRET_SIZE);
|
||||
#endif
|
||||
|
||||
#ifdef OPENSSL_SSL_TRACE_CRYPTO
|
||||
if (s->msg_callback)
|
||||
{
|
||||
s->msg_callback(2, s->version, TLS1_RT_CRYPTO_PREMASTER,
|
||||
p, len, s, s->msg_callback_arg);
|
||||
s->msg_callback(2, s->version, TLS1_RT_CRYPTO_CLIENT_RANDOM,
|
||||
s->s3->client_random, SSL3_RANDOM_SIZE,
|
||||
s, s->msg_callback_arg);
|
||||
s->msg_callback(2, s->version, TLS1_RT_CRYPTO_SERVER_RANDOM,
|
||||
s->s3->server_random, SSL3_RANDOM_SIZE,
|
||||
s, s->msg_callback_arg);
|
||||
s->msg_callback(2, s->version, TLS1_RT_CRYPTO_MASTER,
|
||||
s->session->master_key,
|
||||
SSL3_MASTER_SECRET_SIZE,
|
||||
s, s->msg_callback_arg);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef KSSL_DEBUG
|
||||
printf ("tls1_generate_master_secret() complete\n");
|
||||
#endif /* KSSL_DEBUG */
|
||||
|
|
1272
ssl/t1_trce.c
Normal file
1272
ssl/t1_trce.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1152,6 +1152,7 @@ sub read_options
|
|||
"no-store" => 0,
|
||||
"no-zlib" => 0,
|
||||
"no-zlib-dynamic" => 0,
|
||||
"no-ssl-trace" => 0,
|
||||
"fips" => \$fips
|
||||
);
|
||||
|
||||
|
|
|
@ -115,6 +115,8 @@ my @known_algorithms = ( "RC2", "RC4", "RC5", "IDEA", "DES", "BF",
|
|||
"DEPRECATED",
|
||||
# Hide SSL internals
|
||||
"SSL_INTERN",
|
||||
# SSL TRACE
|
||||
"SSL_TRACE");
|
||||
# SCTP
|
||||
"SCTP");
|
||||
|
||||
|
@ -136,7 +138,7 @@ my $no_ec; my $no_ecdsa; my $no_ecdh; my $no_engine; my $no_hw;
|
|||
my $no_fp_api; my $no_static_engine=1; my $no_gmp; my $no_deprecated;
|
||||
my $no_rfc3779; my $no_psk; my $no_tlsext; my $no_cms; my $no_capieng;
|
||||
my $no_jpake; my $no_srp; my $no_ssl2; my $no_ec2m; my $no_nistp_gcc;
|
||||
my $no_nextprotoneg; my $no_sctp;
|
||||
my $no_nextprotoneg; my $no_sctp; my $no_ssl_trace;
|
||||
|
||||
my $fips;
|
||||
|
||||
|
@ -1202,6 +1204,7 @@ sub is_valid
|
|||
if ($keyword eq "EC_NISTP_64_GCC_128" && $no_nistp_gcc)
|
||||
{ return 0; }
|
||||
if ($keyword eq "SSL2" && $no_ssl2) { return 0; }
|
||||
if ($keyword eq "SSL_TRACE" && $no_ssl_trace) { return 0; }
|
||||
if ($keyword eq "CAPIENG" && $no_capieng) { return 0; }
|
||||
if ($keyword eq "JPAKE" && $no_jpake) { return 0; }
|
||||
if ($keyword eq "SRP" && $no_srp) { return 0; }
|
||||
|
|
Loading…
Reference in a new issue