Merge remote-tracking branch 'agl/1.0.2alpn' into agl-alpn
[oweals/openssl.git] / apps / s_client.c
index bec6dbfb4e23c1e835e5cfdc628a017d2e6e4b5c..421cb017236fb997065b4f1248efa5fa74918050 100644 (file)
@@ -368,6 +368,7 @@ static void sc_usage(void)
        BIO_printf(bio_err," -proof_debug      - request an audit proof and print its hex dump\n");
 # ifndef OPENSSL_NO_NEXTPROTONEG
        BIO_printf(bio_err," -nextprotoneg arg - enable NPN extension, considering named protocols supported (comma-separated list)\n");
+       BIO_printf(bio_err," -alpn arg         - enable ALPN extension, considering named protocols supported (comma-separated list)\n");
 # endif
 #ifndef OPENSSL_NO_TLSEXT
        BIO_printf(bio_err," -serverinfo types - send empty ClientHello extensions (comma-separated numbers)\n");
@@ -564,7 +565,8 @@ static int serverinfo_cli_cb(SSL* s, unsigned short ext_type,
        ext_buf[3] = inlen & 0xFF;
        memcpy(ext_buf+4, in, inlen);
 
-       BIO_snprintf(pem_name, sizeof(pem_name), "SERVER_INFO %d", ext_type);
+       BIO_snprintf(pem_name, sizeof(pem_name), "SERVERINFO FOR EXTENSION %d",
+                    ext_type);
        PEM_write_bio(bio_c_out, pem_name, "", ext_buf, 4 + inlen);
        return 1;
        }
@@ -640,6 +642,7 @@ int MAIN(int argc, char **argv)
         {NULL,0};
 # ifndef OPENSSL_NO_NEXTPROTONEG
        const char *next_proto_neg_in = NULL;
+       const char *alpn_in = NULL;
 # endif
 # define MAX_SI_TYPES 100
        unsigned short serverinfo_types[MAX_SI_TYPES];
@@ -912,6 +915,11 @@ static char *jpake_secret = NULL;
                        meth=TLSv1_client_method();
 #endif
 #ifndef OPENSSL_NO_DTLS1
+               else if (strcmp(*argv,"-dtls") == 0)
+                       {
+                       meth=DTLS_client_method();
+                       socket_type=SOCK_DGRAM;
+                       }
                else if (strcmp(*argv,"-dtls1") == 0)
                        {
                        meth=DTLSv1_client_method();
@@ -993,6 +1001,11 @@ static char *jpake_secret = NULL;
                        if (--argc < 1) goto bad;
                        next_proto_neg_in = *(++argv);
                        }
+               else if (strcmp(*argv,"-alpn") == 0)
+                       {
+                       if (--argc < 1) goto bad;
+                       alpn_in = *(++argv);
+                       }
 # endif
                else if (strcmp(*argv,"-serverinfo") == 0)
                        {
@@ -1306,9 +1319,24 @@ bad:
         */
        if (socket_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1);
 
-#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+#if !defined(OPENSSL_NO_TLSEXT)
+# if !defined(OPENSSL_NO_NEXTPROTONEG)
        if (next_proto.data)
                SSL_CTX_set_next_proto_select_cb(ctx, next_proto_cb, &next_proto);
+# endif
+       if (alpn_in)
+               {
+               unsigned short alpn_len;
+               unsigned char *alpn = next_protos_parse(&alpn_len, alpn_in);
+
+               if (alpn == NULL)
+                       {
+                       BIO_printf(bio_err, "Error parsing -alpn argument\n");
+                       goto end;
+                       }
+               SSL_CTX_set_alpn_protos(ctx, alpn, alpn_len);
+               OPENSSL_free(alpn);
+               }
 #endif
 #ifndef OPENSSL_NO_TLSEXT
                if (serverinfo_types_count)
@@ -2267,7 +2295,8 @@ static void print_stuff(BIO *bio, SSL *s, int full)
        }
 #endif
 
-#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+#if !defined(OPENSSL_NO_TLSEXT)
+# if !defined(OPENSSL_NO_NEXTPROTONEG)
        if (next_proto.status != -1) {
                const unsigned char *proto;
                unsigned int proto_len;
@@ -2276,6 +2305,20 @@ static void print_stuff(BIO *bio, SSL *s, int full)
                BIO_write(bio, proto, proto_len);
                BIO_write(bio, "\n", 1);
        }
+       {
+               const unsigned char *proto;
+               unsigned int proto_len;
+               SSL_get0_alpn_selected(s, &proto, &proto_len);
+               if (proto_len > 0)
+                       {
+                       BIO_printf(bio, "ALPN protocol: ");
+                       BIO_write(bio, proto, proto_len);
+                       BIO_write(bio, "\n", 1);
+                       }
+               else
+                       BIO_printf(bio, "No ALPN negotiated\n");
+       }
+# endif
 #endif
 
        {