summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjsing <>2014-12-10 15:24:01 +0000
committerjsing <>2014-12-10 15:24:01 +0000
commit7b2f3298f7eb7ce5cfd1c3eb55b1ecc89118f52c (patch)
tree4a25ae6462c869427ff08aebdc597ea5802b4ec6
parente8934f925b10bc19b03a59e35d50bd496f57edff (diff)
downloadopenbsd-7b2f3298f7eb7ce5cfd1c3eb55b1ecc89118f52c.tar.gz
openbsd-7b2f3298f7eb7ce5cfd1c3eb55b1ecc89118f52c.tar.bz2
openbsd-7b2f3298f7eb7ce5cfd1c3eb55b1ecc89118f52c.zip
Add ALPN support to openssl(1).
Based on OpenSSL.
-rw-r--r--src/usr.bin/openssl/s_client.c32
-rw-r--r--src/usr.bin/openssl/s_server.c74
2 files changed, 95 insertions, 11 deletions
diff --git a/src/usr.bin/openssl/s_client.c b/src/usr.bin/openssl/s_client.c
index 94e24dacaa..4476852cdb 100644
--- a/src/usr.bin/openssl/s_client.c
+++ b/src/usr.bin/openssl/s_client.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: s_client.c,v 1.9 2014/12/02 19:44:49 deraadt Exp $ */ 1/* $OpenBSD: s_client.c,v 1.10 2014/12/10 15:24:01 jsing Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -253,6 +253,7 @@ sc_usage(void)
253#ifndef OPENSSL_NO_NEXTPROTONEG 253#ifndef OPENSSL_NO_NEXTPROTONEG
254 BIO_printf(bio_err, " -nextprotoneg arg - enable NPN extension, considering named protocols supported (comma-separated list)\n"); 254 BIO_printf(bio_err, " -nextprotoneg arg - enable NPN extension, considering named protocols supported (comma-separated list)\n");
255#endif 255#endif
256 BIO_printf(bio_err, " -alpn arg - enable ALPN extension, considering named protocols supported (comma-separated list)\n");
256#ifndef OPENSSL_NO_SRTP 257#ifndef OPENSSL_NO_SRTP
257 BIO_printf(bio_err, " -use_srtp profiles - Offer SRTP key management with a colon-separated profile list\n"); 258 BIO_printf(bio_err, " -use_srtp profiles - Offer SRTP key management with a colon-separated profile list\n");
258#endif 259#endif
@@ -374,6 +375,7 @@ s_client_main(int argc, char **argv)
374#ifndef OPENSSL_NO_NEXTPROTONEG 375#ifndef OPENSSL_NO_NEXTPROTONEG
375 const char *next_proto_neg_in = NULL; 376 const char *next_proto_neg_in = NULL;
376#endif 377#endif
378 const char *alpn_in = NULL;
377 char *sess_in = NULL; 379 char *sess_in = NULL;
378 char *sess_out = NULL; 380 char *sess_out = NULL;
379 struct sockaddr peer; 381 struct sockaddr peer;
@@ -544,7 +546,11 @@ s_client_main(int argc, char **argv)
544 next_proto_neg_in = *(++argv); 546 next_proto_neg_in = *(++argv);
545 } 547 }
546#endif 548#endif
547 else if (strcmp(*argv, "-serverpref") == 0) 549 else if (strcmp(*argv, "-alpn") == 0) {
550 if (--argc < 1)
551 goto bad;
552 alpn_in = *(++argv);
553 } else if (strcmp(*argv, "-serverpref") == 0)
548 off |= SSL_OP_CIPHER_SERVER_PREFERENCE; 554 off |= SSL_OP_CIPHER_SERVER_PREFERENCE;
549 else if (strcmp(*argv, "-legacy_renegotiation") == 0) 555 else if (strcmp(*argv, "-legacy_renegotiation") == 0)
550 ; /* no-op */ 556 ; /* no-op */
@@ -736,6 +742,17 @@ bad:
736 if (next_proto.data) 742 if (next_proto.data)
737 SSL_CTX_set_next_proto_select_cb(ctx, next_proto_cb, &next_proto); 743 SSL_CTX_set_next_proto_select_cb(ctx, next_proto_cb, &next_proto);
738#endif 744#endif
745 if (alpn_in) {
746 unsigned short alpn_len;
747 unsigned char *alpn = next_protos_parse(&alpn_len, alpn_in);
748
749 if (alpn == NULL) {
750 BIO_printf(bio_err, "Error parsing -alpn argument\n");
751 goto end;
752 }
753 SSL_CTX_set_alpn_protos(ctx, alpn, alpn_len);
754 free(alpn);
755 }
739 756
740 if (state) 757 if (state)
741 SSL_CTX_set_info_callback(ctx, apps_ssl_info_callback); 758 SSL_CTX_set_info_callback(ctx, apps_ssl_info_callback);
@@ -1423,6 +1440,17 @@ print_stuff(BIO * bio, SSL * s, int full)
1423 BIO_write(bio, "\n", 1); 1440 BIO_write(bio, "\n", 1);
1424 } 1441 }
1425#endif 1442#endif
1443 {
1444 const unsigned char *proto;
1445 unsigned int proto_len;
1446 SSL_get0_alpn_selected(s, &proto, &proto_len);
1447 if (proto_len > 0) {
1448 BIO_printf(bio, "ALPN protocol: ");
1449 BIO_write(bio, proto, proto_len);
1450 BIO_write(bio, "\n", 1);
1451 } else
1452 BIO_printf(bio, "No ALPN negotiated\n");
1453 }
1426 1454
1427#ifndef OPENSSL_NO_SRTP 1455#ifndef OPENSSL_NO_SRTP
1428 { 1456 {
diff --git a/src/usr.bin/openssl/s_server.c b/src/usr.bin/openssl/s_server.c
index b3cdb30a61..35ed6d169c 100644
--- a/src/usr.bin/openssl/s_server.c
+++ b/src/usr.bin/openssl/s_server.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: s_server.c,v 1.7 2014/12/02 19:44:49 deraadt Exp $ */ 1/* $OpenBSD: s_server.c,v 1.8 2014/12/10 15:24:01 jsing Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -351,6 +351,7 @@ sv_usage(void)
351#ifndef OPENSSL_NO_NEXTPROTONEG 351#ifndef OPENSSL_NO_NEXTPROTONEG
352 BIO_printf(bio_err, " -nextprotoneg arg - set the advertised protocols for the NPN extension (comma-separated list)\n"); 352 BIO_printf(bio_err, " -nextprotoneg arg - set the advertised protocols for the NPN extension (comma-separated list)\n");
353#endif 353#endif
354 BIO_printf(bio_err," -alpn arg - set the advertised protocols for the ALPN extension (comma-separated list)\n");
354#ifndef OPENSSL_NO_SRTP 355#ifndef OPENSSL_NO_SRTP
355 BIO_printf(bio_err, " -use_srtp profiles - Offer SRTP key management with a colon-separated profile list\n"); 356 BIO_printf(bio_err, " -use_srtp profiles - Offer SRTP key management with a colon-separated profile list\n");
356#endif 357#endif
@@ -545,6 +546,45 @@ next_proto_cb(SSL * s, const unsigned char **data, unsigned int *len, void *arg)
545#endif /* ndef OPENSSL_NO_NEXTPROTONEG */ 546#endif /* ndef OPENSSL_NO_NEXTPROTONEG */
546 547
547 548
549/* This the context that we pass to alpn_cb */
550typedef struct tlsextalpnctx_st {
551 unsigned char *data;
552 unsigned short len;
553} tlsextalpnctx;
554
555static int
556alpn_cb(SSL *s, const unsigned char **out, unsigned char *outlen,
557 const unsigned char *in, unsigned int inlen, void *arg)
558{
559 tlsextalpnctx *alpn_ctx = arg;
560
561 if (!s_quiet) {
562 /* We can assume that in is syntactically valid. */
563 unsigned i;
564
565 BIO_printf(bio_s_out,
566 "ALPN protocols advertised by the client: ");
567 for (i = 0; i < inlen; ) {
568 if (i)
569 BIO_write(bio_s_out, ", ", 2);
570 BIO_write(bio_s_out, &in[i + 1], in[i]);
571 i += in[i] + 1;
572 }
573 BIO_write(bio_s_out, "\n", 1);
574 }
575
576 if (SSL_select_next_proto((unsigned char**)out, outlen, alpn_ctx->data,
577 alpn_ctx->len, in, inlen) != OPENSSL_NPN_NEGOTIATED)
578 return (SSL_TLSEXT_ERR_NOACK);
579
580 if (!s_quiet) {
581 BIO_printf(bio_s_out, "ALPN protocols selected: ");
582 BIO_write(bio_s_out, *out, *outlen);
583 BIO_write(bio_s_out, "\n", 1);
584 }
585
586 return (SSL_TLSEXT_ERR_OK);
587}
548 588
549int s_server_main(int, char **); 589int s_server_main(int, char **);
550 590
@@ -583,8 +623,10 @@ s_server_main(int argc, char *argv[])
583 tlsextctx tlsextcbp = {NULL, NULL, SSL_TLSEXT_ERR_ALERT_WARNING}; 623 tlsextctx tlsextcbp = {NULL, NULL, SSL_TLSEXT_ERR_ALERT_WARNING};
584#ifndef OPENSSL_NO_NEXTPROTONEG 624#ifndef OPENSSL_NO_NEXTPROTONEG
585 const char *next_proto_neg_in = NULL; 625 const char *next_proto_neg_in = NULL;
586 tlsextnextprotoctx next_proto; 626 tlsextnextprotoctx next_proto = { NULL, 0 };
587#endif 627#endif
628 const char *alpn_in = NULL;
629 tlsextalpnctx alpn_ctx = { NULL, 0 };
588 meth = SSLv23_server_method(); 630 meth = SSLv23_server_method();
589 631
590 local_argc = argc; 632 local_argc = argc;
@@ -838,6 +880,11 @@ s_server_main(int argc, char *argv[])
838 next_proto_neg_in = *(++argv); 880 next_proto_neg_in = *(++argv);
839 } 881 }
840#endif 882#endif
883 else if (strcmp(*argv,"-alpn") == 0) {
884 if (--argc < 1)
885 goto bad;
886 alpn_in = *(++argv);
887 }
841#ifndef OPENSSL_NO_SRTP 888#ifndef OPENSSL_NO_SRTP
842 else if (strcmp(*argv, "-use_srtp") == 0) { 889 else if (strcmp(*argv, "-use_srtp") == 0) {
843 if (--argc < 1) 890 if (--argc < 1)
@@ -916,7 +963,7 @@ bad:
916 } 963 }
917 } 964 }
918 } 965 }
919#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) 966#if !defined(OPENSSL_NO_NEXTPROTONEG)
920 if (next_proto_neg_in) { 967 if (next_proto_neg_in) {
921 unsigned short len; 968 unsigned short len;
922 next_proto.data = next_protos_parse(&len, next_proto_neg_in); 969 next_proto.data = next_protos_parse(&len, next_proto_neg_in);
@@ -927,7 +974,14 @@ bad:
927 next_proto.data = NULL; 974 next_proto.data = NULL;
928 } 975 }
929#endif 976#endif
930 977 alpn_ctx.data = NULL;
978 if (alpn_in) {
979 unsigned short len;
980 alpn_ctx.data = next_protos_parse(&len, alpn_in);
981 if (alpn_ctx.data == NULL)
982 goto end;
983 alpn_ctx.len = len;
984 }
931 985
932 if (s_dcert_file) { 986 if (s_dcert_file) {
933 987
@@ -957,8 +1011,7 @@ bad:
957 bio_s_out = BIO_new_fp(stdout, BIO_NOCLOSE); 1011 bio_s_out = BIO_new_fp(stdout, BIO_NOCLOSE);
958 } 1012 }
959 } 1013 }
960 if (nocert) 1014 if (nocert) {
961 {
962 s_cert_file = NULL; 1015 s_cert_file = NULL;
963 s_key_file = NULL; 1016 s_key_file = NULL;
964 s_dcert_file = NULL; 1017 s_dcert_file = NULL;
@@ -1076,6 +1129,8 @@ bad:
1076 if (next_proto.data) 1129 if (next_proto.data)
1077 SSL_CTX_set_next_protos_advertised_cb(ctx, next_proto_cb, &next_proto); 1130 SSL_CTX_set_next_protos_advertised_cb(ctx, next_proto_cb, &next_proto);
1078#endif 1131#endif
1132 if (alpn_ctx.data)
1133 SSL_CTX_set_alpn_select_cb(ctx, alpn_cb, &alpn_ctx);
1079 1134
1080#ifndef OPENSSL_NO_DH 1135#ifndef OPENSSL_NO_DH
1081 if (!no_dhe) { 1136 if (!no_dhe) {
@@ -1241,6 +1296,8 @@ end:
1241 X509_free(s_cert2); 1296 X509_free(s_cert2);
1242 if (s_key2) 1297 if (s_key2)
1243 EVP_PKEY_free(s_key2); 1298 EVP_PKEY_free(s_key2);
1299 free(next_proto.data);
1300 free(alpn_ctx.data);
1244 if (bio_s_out != NULL) { 1301 if (bio_s_out != NULL) {
1245 BIO_free(bio_s_out); 1302 BIO_free(bio_s_out);
1246 bio_s_out = NULL; 1303 bio_s_out = NULL;
@@ -1603,13 +1660,12 @@ init_ssl_connection(SSL * con)
1603 X509 *peer; 1660 X509 *peer;
1604 long verify_error; 1661 long verify_error;
1605 char buf[BUFSIZ]; 1662 char buf[BUFSIZ];
1606#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) 1663#if !defined(OPENSSL_NO_NEXTPROTONEG)
1607 const unsigned char *next_proto_neg; 1664 const unsigned char *next_proto_neg;
1608 unsigned next_proto_neg_len; 1665 unsigned next_proto_neg_len;
1609#endif 1666#endif
1610 unsigned char *exportedkeymat; 1667 unsigned char *exportedkeymat;
1611 1668
1612
1613 i = SSL_accept(con); 1669 i = SSL_accept(con);
1614 if (i <= 0) { 1670 if (i <= 0) {
1615 if (BIO_sock_should_retry(i)) { 1671 if (BIO_sock_should_retry(i)) {
@@ -1642,7 +1698,7 @@ init_ssl_connection(SSL * con)
1642 str = SSL_CIPHER_get_name(SSL_get_current_cipher(con)); 1698 str = SSL_CIPHER_get_name(SSL_get_current_cipher(con));
1643 BIO_printf(bio_s_out, "CIPHER is %s\n", (str != NULL) ? str : "(NONE)"); 1699 BIO_printf(bio_s_out, "CIPHER is %s\n", (str != NULL) ? str : "(NONE)");
1644 1700
1645#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) 1701#if !defined(OPENSSL_NO_NEXTPROTONEG)
1646 SSL_get0_next_proto_negotiated(con, &next_proto_neg, &next_proto_neg_len); 1702 SSL_get0_next_proto_negotiated(con, &next_proto_neg, &next_proto_neg_len);
1647 if (next_proto_neg) { 1703 if (next_proto_neg) {
1648 BIO_printf(bio_s_out, "NEXTPROTO is "); 1704 BIO_printf(bio_s_out, "NEXTPROTO is ");