diff options
author | jsing <> | 2014-12-10 15:24:01 +0000 |
---|---|---|
committer | jsing <> | 2014-12-10 15:24:01 +0000 |
commit | 7b2f3298f7eb7ce5cfd1c3eb55b1ecc89118f52c (patch) | |
tree | 4a25ae6462c869427ff08aebdc597ea5802b4ec6 /src/usr.bin/openssl/s_server.c | |
parent | e8934f925b10bc19b03a59e35d50bd496f57edff (diff) | |
download | openbsd-7b2f3298f7eb7ce5cfd1c3eb55b1ecc89118f52c.tar.gz openbsd-7b2f3298f7eb7ce5cfd1c3eb55b1ecc89118f52c.tar.bz2 openbsd-7b2f3298f7eb7ce5cfd1c3eb55b1ecc89118f52c.zip |
Add ALPN support to openssl(1).
Based on OpenSSL.
Diffstat (limited to 'src/usr.bin/openssl/s_server.c')
-rw-r--r-- | src/usr.bin/openssl/s_server.c | 74 |
1 files changed, 65 insertions, 9 deletions
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 */ | ||
550 | typedef struct tlsextalpnctx_st { | ||
551 | unsigned char *data; | ||
552 | unsigned short len; | ||
553 | } tlsextalpnctx; | ||
554 | |||
555 | static int | ||
556 | alpn_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 | ||
549 | int s_server_main(int, char **); | 589 | int 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 "); |