@@ -354,6 +354,9 @@ static void sc_usage(void)
354354 BIO_printf (bio_err ," -tlsextdebug - hex dump of all TLS extensions received\n" );
355355 BIO_printf (bio_err ," -status - request certificate status from server\n" );
356356 BIO_printf (bio_err ," -no_ticket - disable use of RFC4507bis session tickets\n" );
357+ # if !defined(OPENSSL_NO_NEXTPROTONEG )
358+ BIO_printf (bio_err ," -nextprotoneg arg - enable NPN extension, considering named protocols supported (comma-separated list)\n" );
359+ # endif
357360#endif
358361 BIO_printf (bio_err ," -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n" );
359362 }
@@ -484,6 +487,40 @@ static char * MS_CALLBACK missing_srp_username_callback(SSL *s, void *arg)
484487 }
485488
486489#endif
490+
491+ # ifndef OPENSSL_NO_NEXTPROTONEG
492+ /* This the context that we pass to next_proto_cb */
493+ typedef struct tlsextnextprotoctx_st {
494+ unsigned char * data ;
495+ unsigned short len ;
496+ int status ;
497+ } tlsextnextprotoctx ;
498+
499+ static tlsextnextprotoctx next_proto ;
500+
501+ static int next_proto_cb (SSL * s , unsigned char * * out , unsigned char * outlen , const unsigned char * in , unsigned int inlen , void * arg )
502+ {
503+ tlsextnextprotoctx * ctx = arg ;
504+
505+ if (!c_quiet )
506+ {
507+ /* We can assume that |in| is syntactically valid. */
508+ unsigned i ;
509+ BIO_printf (bio_c_out , "Protocols advertised by server: " );
510+ for (i = 0 ; i < inlen ; )
511+ {
512+ if (i )
513+ BIO_write (bio_c_out , ", " , 2 );
514+ BIO_write (bio_c_out , & in [i + 1 ], in [i ]);
515+ i += in [i ] + 1 ;
516+ }
517+ BIO_write (bio_c_out , "\n" , 1 );
518+ }
519+
520+ ctx -> status = SSL_select_next_proto (out , outlen , in , inlen , ctx -> data , ctx -> len );
521+ return SSL_TLSEXT_ERR_OK ;
522+ }
523+ # endif
487524#endif
488525
489526enum
@@ -550,6 +587,9 @@ int MAIN(int argc, char **argv)
550587 char * servername = NULL ;
551588 tlsextctx tlsextcbp =
552589 {NULL ,0 };
590+ # ifndef OPENSSL_NO_NEXTPROTONEG
591+ const char * next_proto_neg_in = NULL ;
592+ # endif
553593#endif
554594 char * sess_in = NULL ;
555595 char * sess_out = NULL ;
@@ -821,6 +861,13 @@ int MAIN(int argc, char **argv)
821861#ifndef OPENSSL_NO_TLSEXT
822862 else if (strcmp (* argv ,"- no_ticket ") == 0 )
823863 { off |=SSL_OP_NO_TICKET ; }
864+ # ifndef OPENSSL_NO_NEXTPROTONEG
865+ else if (strcmp (* argv ,"- nextprotoneg ") == 0 )
866+ {
867+ if (-- argc < 1 ) goto bad ;
868+ next_proto_neg_in = * (++ argv );
869+ }
870+ # endif
824871#endif
825872 else if (strcmp (* argv ,"- serverpref ") == 0 )
826873 off |=SSL_OP_CIPHER_SERVER_PREFERENCE ;
@@ -927,6 +974,21 @@ int MAIN(int argc, char **argv)
927974 OpenSSL_add_ssl_algorithms ();
928975 SSL_load_error_strings ();
929976
977+ #if !defined(OPENSSL_NO_TLSEXT ) && !defined(OPENSSL_NO_NEXTPROTONEG )
978+ next_proto .status = -1 ;
979+ if (next_proto_neg_in )
980+ {
981+ next_proto .data = next_protos_parse (& next_proto .len , next_proto_neg_in );
982+ if (next_proto .data == NULL )
983+ {
984+ BIO_printf (bio_err , "Error parsing -nextprotoneg argument\n" );
985+ goto end ;
986+ }
987+ }
988+ else
989+ next_proto .data = NULL ;
990+ #endif
991+
930992#ifndef OPENSSL_NO_ENGINE
931993 e = setup_engine (bio_err , engine_id , 1 );
932994 if (ssl_client_engine_id )
@@ -1056,6 +1118,11 @@ int MAIN(int argc, char **argv)
10561118 */
10571119 if (socket_type == SOCK_DGRAM ) SSL_CTX_set_read_ahead (ctx , 1 );
10581120
1121+ #if !defined(OPENSSL_NO_TLSEXT ) && !defined(OPENSSL_NO_NEXTPROTONEG )
1122+ if (next_proto .data )
1123+ SSL_CTX_set_next_proto_select_cb (ctx , next_proto_cb , & next_proto );
1124+ #endif
1125+
10591126 if (state ) SSL_CTX_set_info_callback (ctx ,apps_ssl_info_callback );
10601127 if (cipher != NULL )
10611128 if (!SSL_CTX_set_cipher_list (ctx ,cipher )) {
@@ -1949,6 +2016,17 @@ static void print_stuff(BIO *bio, SSL *s, int full)
19492016 }
19502017#endif
19512018
2019+ #if !defined(OPENSSL_NO_TLSEXT ) && !defined(OPENSSL_NO_NEXTPROTONEG )
2020+ if (next_proto .status != -1 ) {
2021+ const unsigned char * proto ;
2022+ unsigned int proto_len ;
2023+ SSL_get0_next_proto_negotiated (s , & proto , & proto_len );
2024+ BIO_printf (bio , "Next protocol: (%d) " , next_proto .status );
2025+ BIO_write (bio , proto , proto_len );
2026+ BIO_write (bio , "\n" , 1 );
2027+ }
2028+ #endif
2029+
19522030 SSL_SESSION_print (bio ,SSL_get_session (s ));
19532031 BIO_printf (bio ,"---\n" );
19542032 if (peer != NULL )
0 commit comments