summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjsing <>2014-12-10 15:06:50 +0000
committerjsing <>2014-12-10 15:06:50 +0000
commite8934f925b10bc19b03a59e35d50bd496f57edff (patch)
treeca3c1ccfc79c9a642c89eb73b9079893e0443f67 /src
parent648ebfc9b9a624a392062d19385a13d9604fb4c7 (diff)
downloadopenbsd-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.c162
-rw-r--r--src/regress/lib/libssl/ssl/testssl19
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
287static const char *alpn_client;
288static const char *alpn_server;
289static const char *alpn_expected;
290static 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 */
301static unsigned char *
302next_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
329static int
330cb_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
364static int
365verify_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
397err:
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
287static char *cipher = NULL; 409static char *cipher = NULL;
288static int verbose = 0; 410static int verbose = 0;
289static int debug = 0; 411static 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
339static void 464static 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
1167end: 1323end:
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;
1421err: 1581err:
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#
162echo "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