summaryrefslogtreecommitdiffstats
path: root/ssl/ssltest.c
diff options
context:
space:
mode:
authorTrevor <trevp@trevp.net>2013-05-12 18:55:27 -0700
committerBen Laurie <ben@links.org>2013-07-03 11:53:30 +0100
commite27711cfddb15b3bd0c42c804d37ea0f33a3e4e5 (patch)
tree80076d131dbb4be7039da0dc20b96d1654e9610c /ssl/ssltest.c
parent28c08222c058eb3106fa559df05a8a822cc159de (diff)
Trying cherrypick:
Add support for arbitrary TLS extensions. Contributed by Trevor Perrin. Conflicts: CHANGES ssl/ssl.h ssl/ssltest.c test/testssl Fix compilation due to #endif. Cherrypicking more stuff. Cleanup of custom extension stuff. serverinfo rejects non-empty extensions. Omit extension if no relevant serverinfo data. Improve error-handling in serverinfo callback. Cosmetic cleanups. s_client documentation. s_server documentation. SSL_CTX_serverinfo documentation. Cleaup -1 and NULL callback handling for custom extensions, add tests. Cleanup ssl_rsa.c serverinfo code. Whitespace cleanup. Improve comments in ssl.h for serverinfo. Whitespace. Cosmetic cleanup. Reject non-zero-len serverinfo extensions. Whitespace. Make it build. Conflicts: test/testssl
Diffstat (limited to 'ssl/ssltest.c')
-rw-r--r--ssl/ssltest.c325
1 files changed, 325 insertions, 0 deletions
diff --git a/ssl/ssltest.c b/ssl/ssltest.c
index f8c75c09d7..ab60664f1a 100644
--- a/ssl/ssltest.c
+++ b/ssl/ssltest.c
@@ -295,6 +295,242 @@ static int MS_CALLBACK ssl_srp_server_param_cb(SSL *s, int *ad, void *arg)
static BIO *bio_err=NULL;
static BIO *bio_stdout=NULL;
+#define SCT_EXT_TYPE 18
+
+/* WARNING : below extension types are *NOT* IETF assigned, and
+ could conflict if these types are reassigned and handled
+ specially by OpenSSL in the future */
+#define TACK_EXT_TYPE 62208
+#define CUSTOM_EXT_TYPE_0 1000
+#define CUSTOM_EXT_TYPE_1 1001
+#define CUSTOM_EXT_TYPE_2 1002
+#define CUSTOM_EXT_TYPE_3 1003
+
+const char custom_ext_cli_string[] = "abc";
+const char custom_ext_srv_string[] = "defg";
+
+/* These set from cmdline */
+char* serverinfo_file = NULL;
+int serverinfo_sct = 0;
+int serverinfo_tack = 0;
+
+/* These set based on extension callbacks */
+int serverinfo_sct_seen = 0;
+int serverinfo_tack_seen = 0;
+int serverinfo_other_seen = 0;
+
+/* This set from cmdline */
+int custom_ext = 0;
+
+/* This set based on extension callbacks */
+int custom_ext_error = 0;
+
+static int serverinfo_cli_cb(SSL* s, unsigned short ext_type,
+ const unsigned char* in, unsigned short inlen,
+ int* al, void* arg)
+ {
+ if (ext_type == SCT_EXT_TYPE)
+ serverinfo_sct_seen++;
+ else if (ext_type == TACK_EXT_TYPE)
+ serverinfo_tack_seen++;
+ else
+ serverinfo_other_seen++;
+ return 1;
+ }
+
+static int verify_serverinfo()
+ {
+ if (serverinfo_sct != serverinfo_sct_seen)
+ return -1;
+ if (serverinfo_tack != serverinfo_tack_seen)
+ return -1;
+ if (serverinfo_other_seen)
+ return -1;
+ return 0;
+ }
+
+/* Four test cases for custom extensions:
+ * 0 - no ClientHello extension or ServerHello response
+ * 1 - ClientHello with "abc", no response
+ * 2 - ClientHello with "abc", empty response
+ * 3 - ClientHello with "abc", "defg" response
+ */
+
+static int custom_ext_0_cli_first_cb(SSL *s, unsigned short ext_type,
+ const unsigned char **out,
+ unsigned short *outlen, void *arg)
+ {
+ if (ext_type != CUSTOM_EXT_TYPE_0)
+ custom_ext_error = 1;
+ return -1; /* Don't send an extension */
+ }
+
+static int custom_ext_0_cli_second_cb(SSL *s, unsigned short ext_type,
+ const unsigned char *in,
+ unsigned short inlen, int *al,
+ void *arg)
+ {
+ custom_ext_error = 1; /* Shouldn't be called */
+ return 0;
+ }
+
+static int custom_ext_1_cli_first_cb(SSL *s, unsigned short ext_type,
+ const unsigned char **out,
+ unsigned short *outlen, void *arg)
+ {
+ if (ext_type != CUSTOM_EXT_TYPE_1)
+ custom_ext_error = 1;
+ *out = (const unsigned char*)custom_ext_cli_string;
+ *outlen = strlen(custom_ext_cli_string);
+ return 1; /* Send "abc" */
+ }
+
+static int custom_ext_1_cli_second_cb(SSL *s, unsigned short ext_type,
+ const unsigned char *in,
+ unsigned short inlen, int *al,
+ void *arg)
+ {
+ custom_ext_error = 1; /* Shouldn't be called */
+ return 0;
+ }
+
+static int custom_ext_2_cli_first_cb(SSL *s, unsigned short ext_type,
+ const unsigned char **out,
+ unsigned short *outlen, void *arg)
+ {
+ if (ext_type != CUSTOM_EXT_TYPE_2)
+ custom_ext_error = 1;
+ *out = (const unsigned char*)custom_ext_cli_string;
+ *outlen = strlen(custom_ext_cli_string);
+ return 1; /* Send "abc" */
+ }
+
+static int custom_ext_2_cli_second_cb(SSL *s, unsigned short ext_type,
+ const unsigned char *in,
+ unsigned short inlen, int *al,
+ void *arg)
+ {
+ if (ext_type != CUSTOM_EXT_TYPE_2)
+ custom_ext_error = 1;
+ if (inlen != 0)
+ custom_ext_error = 1; /* Should be empty response */
+ return 1;
+ }
+
+static int custom_ext_3_cli_first_cb(SSL *s, unsigned short ext_type,
+ const unsigned char **out,
+ unsigned short *outlen, void *arg)
+ {
+ if (ext_type != CUSTOM_EXT_TYPE_3)
+ custom_ext_error = 1;
+ *out = (const unsigned char*)custom_ext_cli_string;
+ *outlen = strlen(custom_ext_cli_string);
+ return 1; /* Send "abc" */
+ }
+
+static int custom_ext_3_cli_second_cb(SSL *s, unsigned short ext_type,
+ const unsigned char *in,
+ unsigned short inlen, int *al,
+ void *arg)
+ {
+ if (ext_type != CUSTOM_EXT_TYPE_3)
+ custom_ext_error = 1;
+ if (inlen != strlen(custom_ext_srv_string))
+ custom_ext_error = 1;
+ if (memcmp(custom_ext_srv_string, in, inlen) != 0)
+ custom_ext_error = 1; /* Check for "defg" */
+ return 1;
+ }
+
+
+static int custom_ext_0_srv_first_cb(SSL *s, unsigned short ext_type,
+ const unsigned char *in,
+ unsigned short inlen, int *al,
+ void *arg)
+ {
+ custom_ext_error = 1;
+ return 0; /* Shouldn't be called */
+ }
+
+static int custom_ext_0_srv_second_cb(SSL *s, unsigned short ext_type,
+ const unsigned char **out,
+ unsigned short *outlen, void *arg)
+ {
+ custom_ext_error = 1;
+ return 0; /* Shouldn't be called */
+ }
+
+static int custom_ext_1_srv_first_cb(SSL *s, unsigned short ext_type,
+ const unsigned char *in,
+ unsigned short inlen, int *al,
+ void *arg)
+ {
+ if (ext_type != CUSTOM_EXT_TYPE_1)
+ custom_ext_error = 1;
+ /* Check for "abc" */
+ if (inlen != strlen(custom_ext_cli_string))
+ custom_ext_error = 1;
+ if (memcmp(in, custom_ext_cli_string, inlen) != 0)
+ custom_ext_error = 1;
+ return 1;
+ }
+
+static int custom_ext_1_srv_second_cb(SSL *s, unsigned short ext_type,
+ const unsigned char **out,
+ unsigned short *outlen, void *arg)
+ {
+ return -1; /* Don't send an extension */
+ }
+
+static int custom_ext_2_srv_first_cb(SSL *s, unsigned short ext_type,
+ const unsigned char *in,
+ unsigned short inlen, int *al,
+ void *arg)
+ {
+ if (ext_type != CUSTOM_EXT_TYPE_2)
+ custom_ext_error = 1;
+ /* Check for "abc" */
+ if (inlen != strlen(custom_ext_cli_string))
+ custom_ext_error = 1;
+ if (memcmp(in, custom_ext_cli_string, inlen) != 0)
+ custom_ext_error = 1;
+ return 1;
+ }
+
+static int custom_ext_2_srv_second_cb(SSL *s, unsigned short ext_type,
+ const unsigned char **out,
+ unsigned short *outlen, void *arg)
+ {
+ *out = NULL;
+ *outlen = 0;
+ return 1; /* Send empty extension */
+ }
+
+static int custom_ext_3_srv_first_cb(SSL *s, unsigned short ext_type,
+ const unsigned char *in,
+ unsigned short inlen, int *al,
+ void *arg)
+ {
+ if (ext_type != CUSTOM_EXT_TYPE_3)
+ custom_ext_error = 1;
+ /* Check for "abc" */
+ if (inlen != strlen(custom_ext_cli_string))
+ custom_ext_error = 1;
+ if (memcmp(in, custom_ext_cli_string, inlen) != 0)
+ custom_ext_error = 1;
+ return 1;
+ }
+
+static int custom_ext_3_srv_second_cb(SSL *s, unsigned short ext_type,
+ const unsigned char **out,
+ unsigned short *outlen, void *arg)
+ {
+ *out = (const unsigned char*)custom_ext_srv_string;
+ *outlen = strlen(custom_ext_srv_string);
+ return 1; /* Send "defg" */
+ }
+
+
static char *cipher=NULL;
static int verbose=0;
static int debug=0;
@@ -374,6 +610,10 @@ static void sv_usage(void)
fprintf(stderr," -c_support_proof - indicate client support for server_authz audit proofs\n");
fprintf(stderr," -c_require_proof - fail if no audit proof is sent\n");
#endif
+ fprintf(stderr," -serverinfo_file file - have server use this file\n");
+ fprintf(stderr," -serverinfo_sct - have client offer and expect SCT\n");
+ fprintf(stderr," -serverinfo_tack - have client offer and expect TACK\n");
+ fprintf(stderr," -custom_ext - try various custom extension callbacks\n");
}
static void print_details(SSL *c_ssl, const char *prefix)
@@ -845,6 +1085,23 @@ int main(int argc, char *argv[])
tls1 = 1;
}
#endif
+ else if (strcmp(*argv,"-serverinfo_sct") == 0)
+ {
+ serverinfo_sct = 1;
+ }
+ else if (strcmp(*argv,"-serverinfo_tack") == 0)
+ {
+ serverinfo_tack = 1;
+ }
+ else if (strcmp(*argv,"-serverinfo_file") == 0)
+ {
+ if (--argc < 1) goto bad;
+ serverinfo_file = *(++argv);
+ }
+ else if (strcmp(*argv,"-custom_ext") == 0)
+ {
+ custom_ext = 1;
+ }
else
{
fprintf(stderr,"unknown option %s\n",*argv);
@@ -1187,6 +1444,50 @@ bad:
}
#endif
+ if (serverinfo_sct)
+ SSL_CTX_set_custom_cli_ext(c_ctx, SCT_EXT_TYPE, NULL,
+ serverinfo_cli_cb, NULL);
+ if (serverinfo_tack)
+ SSL_CTX_set_custom_cli_ext(c_ctx, TACK_EXT_TYPE, NULL,
+ serverinfo_cli_cb, NULL);
+
+ if (serverinfo_file)
+ if (!SSL_CTX_use_serverinfo_file(s_ctx, serverinfo_file))
+ {
+ BIO_printf(bio_err, "missing serverinfo file\n");
+ goto end;
+ }
+
+ if (custom_ext)
+ {
+ SSL_CTX_set_custom_cli_ext(c_ctx, CUSTOM_EXT_TYPE_0,
+ custom_ext_0_cli_first_cb,
+ custom_ext_0_cli_second_cb, NULL);
+ SSL_CTX_set_custom_cli_ext(c_ctx, CUSTOM_EXT_TYPE_1,
+ custom_ext_1_cli_first_cb,
+ custom_ext_1_cli_second_cb, NULL);
+ SSL_CTX_set_custom_cli_ext(c_ctx, CUSTOM_EXT_TYPE_2,
+ custom_ext_2_cli_first_cb,
+ custom_ext_2_cli_second_cb, NULL);
+ SSL_CTX_set_custom_cli_ext(c_ctx, CUSTOM_EXT_TYPE_3,
+ custom_ext_3_cli_first_cb,
+ custom_ext_3_cli_second_cb, NULL);
+
+
+ SSL_CTX_set_custom_srv_ext(s_ctx, CUSTOM_EXT_TYPE_0,
+ custom_ext_0_srv_first_cb,
+ custom_ext_0_srv_second_cb, NULL);
+ SSL_CTX_set_custom_srv_ext(s_ctx, CUSTOM_EXT_TYPE_1,
+ custom_ext_1_srv_first_cb,
+ custom_ext_1_srv_second_cb, NULL);
+ SSL_CTX_set_custom_srv_ext(s_ctx, CUSTOM_EXT_TYPE_2,
+ custom_ext_2_srv_first_cb,
+ custom_ext_2_srv_second_cb, NULL);
+ SSL_CTX_set_custom_srv_ext(s_ctx, CUSTOM_EXT_TYPE_3,
+ custom_ext_3_srv_first_cb,
+ custom_ext_3_srv_second_cb, NULL);
+ }
+
c_ssl=SSL_new(c_ctx);
s_ssl=SSL_new(s_ctx);
@@ -1641,6 +1942,19 @@ int doit_biopair(SSL *s_ssl, SSL *c_ssl, long count,
if (verbose)
print_details(c_ssl, "DONE via BIO pair: ");
+
+ if (verify_serverinfo() < 0)
+ {
+ ret = 1;
+ goto err;
+ }
+
+ if (custom_ext_error)
+ {
+ ret = 1;
+ goto err;
+ }
+
end:
ret = 0;
@@ -1936,6 +2250,17 @@ int doit(SSL *s_ssl, SSL *c_ssl, long count)
if (verbose)
print_details(c_ssl, "DONE: ");
+
+ if (verify_serverinfo() < 0)
+ {
+ ret = 1;
+ goto err;
+ }
+ if (custom_ext_error)
+ {
+ ret = 1;
+ goto err;
+ }
ret=0;
err:
/* We have to set the BIO's to NULL otherwise they will be