diff options
author | jsing <> | 2014-12-10 15:06:50 +0000 |
---|---|---|
committer | jsing <> | 2014-12-10 15:06:50 +0000 |
commit | e8934f925b10bc19b03a59e35d50bd496f57edff (patch) | |
tree | ca3c1ccfc79c9a642c89eb73b9079893e0443f67 /src | |
parent | 648ebfc9b9a624a392062d19385a13d9604fb4c7 (diff) | |
download | openbsd-e8934f925b10bc19b03a59e35d50bd496f57edff.tar.gz openbsd-e8934f925b10bc19b03a59e35d50bd496f57edff.tar.bz2 openbsd-e8934f925b10bc19b03a59e35d50bd496f57edff.zip |
Add regress for ALPN.
Based on OpenSSL.
Diffstat (limited to 'src')
-rw-r--r-- | src/regress/lib/libssl/ssl/ssltest.c | 162 | ||||
-rw-r--r-- | src/regress/lib/libssl/ssl/testssl | 19 |
2 files changed, 180 insertions, 1 deletions
diff --git a/src/regress/lib/libssl/ssl/ssltest.c b/src/regress/lib/libssl/ssl/ssltest.c index b1ca0d8c7d..fa869d0f24 100644 --- a/src/regress/lib/libssl/ssl/ssltest.c +++ b/src/regress/lib/libssl/ssl/ssltest.c | |||
@@ -284,6 +284,128 @@ verify_npn(SSL *client, SSL *server) | |||
284 | } | 284 | } |
285 | #endif | 285 | #endif |
286 | 286 | ||
287 | static const char *alpn_client; | ||
288 | static const char *alpn_server; | ||
289 | static const char *alpn_expected; | ||
290 | static unsigned char *alpn_selected; | ||
291 | |||
292 | /* | ||
293 | * next_protos_parse parses a comma separated list of strings into a string | ||
294 | * in a format suitable for passing to SSL_CTX_set_next_protos_advertised. | ||
295 | * outlen: (output) set to the length of the resulting buffer on success. | ||
296 | * err: (maybe NULL) on failure, an error message line is written to this BIO. | ||
297 | * in: a NUL terminated string like "abc,def,ghi" | ||
298 | * | ||
299 | * returns: a malloced buffer or NULL on failure. | ||
300 | */ | ||
301 | static unsigned char * | ||
302 | next_protos_parse(unsigned short *outlen, const char *in) | ||
303 | { | ||
304 | size_t i, len, start = 0; | ||
305 | unsigned char *out; | ||
306 | |||
307 | len = strlen(in); | ||
308 | if (len >= 65535) | ||
309 | return (NULL); | ||
310 | |||
311 | if ((out = malloc(strlen(in) + 1)) == NULL) | ||
312 | return (NULL); | ||
313 | |||
314 | for (i = 0; i <= len; ++i) { | ||
315 | if (i == len || in[i] == ',') { | ||
316 | if (i - start > 255) { | ||
317 | free(out); | ||
318 | return (NULL); | ||
319 | } | ||
320 | out[start] = i - start; | ||
321 | start = i + 1; | ||
322 | } else | ||
323 | out[i+1] = in[i]; | ||
324 | } | ||
325 | *outlen = len + 1; | ||
326 | return (out); | ||
327 | } | ||
328 | |||
329 | static int | ||
330 | cb_server_alpn(SSL *s, const unsigned char **out, unsigned char *outlen, | ||
331 | const unsigned char *in, unsigned int inlen, void *arg) | ||
332 | { | ||
333 | unsigned char *protos; | ||
334 | unsigned short protos_len; | ||
335 | |||
336 | if ((protos = next_protos_parse(&protos_len, alpn_server)) == NULL) { | ||
337 | fprintf(stderr, | ||
338 | "failed to parser ALPN server protocol string: %s\n", | ||
339 | alpn_server); | ||
340 | abort(); | ||
341 | } | ||
342 | |||
343 | if (SSL_select_next_proto((unsigned char **)out, outlen, protos, | ||
344 | protos_len, in, inlen) != OPENSSL_NPN_NEGOTIATED) { | ||
345 | free(protos); | ||
346 | return (SSL_TLSEXT_ERR_NOACK); | ||
347 | } | ||
348 | |||
349 | /* | ||
350 | * Make a copy of the selected protocol which will be freed in | ||
351 | * verify_alpn. | ||
352 | */ | ||
353 | if ((alpn_selected = malloc(*outlen)) == NULL) { | ||
354 | fprintf(stderr, "malloc failed\n"); | ||
355 | abort(); | ||
356 | } | ||
357 | memcpy(alpn_selected, *out, *outlen); | ||
358 | *out = alpn_selected; | ||
359 | free(protos); | ||
360 | |||
361 | return (SSL_TLSEXT_ERR_OK); | ||
362 | } | ||
363 | |||
364 | static int | ||
365 | verify_alpn(SSL *client, SSL *server) | ||
366 | { | ||
367 | const unsigned char *client_proto, *server_proto; | ||
368 | unsigned int client_proto_len = 0, server_proto_len = 0; | ||
369 | |||
370 | SSL_get0_alpn_selected(client, &client_proto, &client_proto_len); | ||
371 | SSL_get0_alpn_selected(server, &server_proto, &server_proto_len); | ||
372 | |||
373 | free(alpn_selected); | ||
374 | alpn_selected = NULL; | ||
375 | |||
376 | if (client_proto_len != server_proto_len || | ||
377 | memcmp(client_proto, server_proto, client_proto_len) != 0) { | ||
378 | BIO_printf(bio_stdout, "ALPN selected protocols differ!\n"); | ||
379 | goto err; | ||
380 | } | ||
381 | |||
382 | if (client_proto_len > 0 && alpn_expected == NULL) { | ||
383 | BIO_printf(bio_stdout, "ALPN unexpectedly negotiated\n"); | ||
384 | goto err; | ||
385 | } | ||
386 | |||
387 | if (alpn_expected != NULL && | ||
388 | (client_proto_len != strlen(alpn_expected) || | ||
389 | memcmp(client_proto, alpn_expected, client_proto_len) != 0)) { | ||
390 | BIO_printf(bio_stdout, "ALPN selected protocols not equal to " | ||
391 | "expected protocol: %s\n", alpn_expected); | ||
392 | goto err; | ||
393 | } | ||
394 | |||
395 | return (0); | ||
396 | |||
397 | err: | ||
398 | BIO_printf(bio_stdout, "ALPN results: client: '"); | ||
399 | BIO_write(bio_stdout, client_proto, client_proto_len); | ||
400 | BIO_printf(bio_stdout, "', server: '"); | ||
401 | BIO_write(bio_stdout, server_proto, server_proto_len); | ||
402 | BIO_printf(bio_stdout, "'\n"); | ||
403 | BIO_printf(bio_stdout, "ALPN configured: client: '%s', server: '%s'\n", | ||
404 | alpn_client, alpn_server); | ||
405 | |||
406 | return (-1); | ||
407 | } | ||
408 | |||
287 | static char *cipher = NULL; | 409 | static char *cipher = NULL; |
288 | static int verbose = 0; | 410 | static int verbose = 0; |
289 | static int debug = 0; | 411 | static int debug = 0; |
@@ -334,6 +456,9 @@ sv_usage(void) | |||
334 | fprintf(stderr, " -npn_server - have server side offer NPN\n"); | 456 | fprintf(stderr, " -npn_server - have server side offer NPN\n"); |
335 | fprintf(stderr, " -npn_server_reject - have server reject NPN\n"); | 457 | fprintf(stderr, " -npn_server_reject - have server reject NPN\n"); |
336 | #endif | 458 | #endif |
459 | fprintf(stderr, " -alpn_client <string> - have client side offer ALPN\n"); | ||
460 | fprintf(stderr, " -alpn_server <string> - have server side offer ALPN\n"); | ||
461 | fprintf(stderr, " -alpn_expected <string> - the ALPN protocol that should be negotiated\n"); | ||
337 | } | 462 | } |
338 | 463 | ||
339 | static void | 464 | static void |
@@ -584,7 +709,19 @@ main(int argc, char *argv[]) | |||
584 | npn_server_reject = 1; | 709 | npn_server_reject = 1; |
585 | } | 710 | } |
586 | #endif | 711 | #endif |
587 | else { | 712 | else if (strcmp(*argv, "-alpn_client") == 0) { |
713 | if (--argc < 1) | ||
714 | goto bad; | ||
715 | alpn_client = *(++argv); | ||
716 | } else if (strcmp(*argv, "-alpn_server") == 0) { | ||
717 | if (--argc < 1) | ||
718 | goto bad; | ||
719 | alpn_server = *(++argv); | ||
720 | } else if (strcmp(*argv, "-alpn_expected") == 0) { | ||
721 | if (--argc < 1) | ||
722 | goto bad; | ||
723 | alpn_expected = *(++argv); | ||
724 | } else { | ||
588 | fprintf(stderr, "unknown option %s\n", *argv); | 725 | fprintf(stderr, "unknown option %s\n", *argv); |
589 | badop = 1; | 726 | badop = 1; |
590 | break; | 727 | break; |
@@ -759,6 +896,21 @@ bad: | |||
759 | } | 896 | } |
760 | #endif | 897 | #endif |
761 | 898 | ||
899 | if (alpn_server != NULL) | ||
900 | SSL_CTX_set_alpn_select_cb(s_ctx, cb_server_alpn, NULL); | ||
901 | |||
902 | if (alpn_client != NULL) { | ||
903 | unsigned short alpn_len; | ||
904 | unsigned char *alpn = next_protos_parse(&alpn_len, alpn_client); | ||
905 | |||
906 | if (alpn == NULL) { | ||
907 | BIO_printf(bio_err, "Error parsing -alpn_client argument\n"); | ||
908 | goto end; | ||
909 | } | ||
910 | SSL_CTX_set_alpn_protos(c_ctx, alpn, alpn_len); | ||
911 | free(alpn); | ||
912 | } | ||
913 | |||
762 | c_ssl = SSL_new(c_ctx); | 914 | c_ssl = SSL_new(c_ctx); |
763 | s_ssl = SSL_new(s_ctx); | 915 | s_ssl = SSL_new(s_ctx); |
764 | 916 | ||
@@ -1163,6 +1315,10 @@ doit_biopair(SSL *s_ssl, SSL *c_ssl, long count, clock_t *s_time, | |||
1163 | goto err; | 1315 | goto err; |
1164 | } | 1316 | } |
1165 | #endif | 1317 | #endif |
1318 | if (verify_alpn(c_ssl, s_ssl) < 0) { | ||
1319 | ret = 1; | ||
1320 | goto err; | ||
1321 | } | ||
1166 | 1322 | ||
1167 | end: | 1323 | end: |
1168 | ret = 0; | 1324 | ret = 0; |
@@ -1416,6 +1572,10 @@ doit(SSL *s_ssl, SSL *c_ssl, long count) | |||
1416 | goto err; | 1572 | goto err; |
1417 | } | 1573 | } |
1418 | #endif | 1574 | #endif |
1575 | if (verify_alpn(c_ssl, s_ssl) < 0) { | ||
1576 | ret = 1; | ||
1577 | goto err; | ||
1578 | } | ||
1419 | 1579 | ||
1420 | ret = 0; | 1580 | ret = 0; |
1421 | err: | 1581 | err: |
diff --git a/src/regress/lib/libssl/ssl/testssl b/src/regress/lib/libssl/ssl/testssl index a8ecab263e..379ddfcc50 100644 --- a/src/regress/lib/libssl/ssl/testssl +++ b/src/regress/lib/libssl/ssl/testssl | |||
@@ -155,3 +155,22 @@ $ssltest -bio_pair -tls1 -npn_client -npn_server_reject || exit 1 | |||
155 | $ssltest -bio_pair -tls1 -npn_client -npn_server || exit 1 | 155 | $ssltest -bio_pair -tls1 -npn_client -npn_server || exit 1 |
156 | $ssltest -bio_pair -tls1 -npn_client -npn_server -num 2 || exit 1 | 156 | $ssltest -bio_pair -tls1 -npn_client -npn_server -num 2 || exit 1 |
157 | $ssltest -bio_pair -tls1 -npn_client -npn_server -num 2 -reuse || exit 1 | 157 | $ssltest -bio_pair -tls1 -npn_client -npn_server -num 2 -reuse || exit 1 |
158 | |||
159 | # | ||
160 | # ALPN tests | ||
161 | # | ||
162 | echo "Testing ALPN..." | ||
163 | $ssltest -bio_pair -tls1 -alpn_client foo -alpn_server bar || exit 1 | ||
164 | $ssltest -bio_pair -tls1 -alpn_client foo -alpn_server foo \ | ||
165 | -alpn_expected foo || exit 1 | ||
166 | $ssltest -bio_pair -tls1 -alpn_client foo,bar -alpn_server foo \ | ||
167 | -alpn_expected foo || exit 1 | ||
168 | $ssltest -bio_pair -tls1 -alpn_client bar,foo -alpn_server foo \ | ||
169 | -alpn_expected foo || exit 1 | ||
170 | $ssltest -bio_pair -tls1 -alpn_client bar,foo -alpn_server foo,bar \ | ||
171 | -alpn_expected foo || exit 1 | ||
172 | $ssltest -bio_pair -tls1 -alpn_client bar,foo -alpn_server bar,foo \ | ||
173 | -alpn_expected bar || exit 1 | ||
174 | $ssltest -bio_pair -tls1 -alpn_client foo,bar -alpn_server bar,foo \ | ||
175 | -alpn_expected bar || exit 1 | ||
176 | $ssltest -bio_pair -tls1 -alpn_client baz -alpn_server bar,foo || exit 1 | ||