*Igor Ustinov*
+ * Added SSL_CTX_get0_alpn_protos() and SSL_get0_alpn_protos().
+
+ *Daniel Kubec*
+
* Enabled Server verification by default in `s_server` when option
verify_return_error is enabled.
=head1 NAME
-SSL_CTX_set_alpn_protos, SSL_set_alpn_protos, SSL_CTX_set_alpn_select_cb,
+SSL_CTX_set_alpn_protos, SSL_set_alpn_protos, SSL_CTX_get0_alpn_protos,
+SSL_get0_alpn_protos, SSL_CTX_set_alpn_select_cb,
SSL_CTX_set_next_proto_select_cb, SSL_CTX_set_next_protos_advertised_cb,
SSL_select_next_proto, SSL_get0_alpn_selected, SSL_get0_next_proto_negotiated
- handle application layer protocol negotiation (ALPN)
void SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data,
unsigned *len);
+ void SSL_CTX_get0_alpn_protos(SSL_CTX *ctx, const unsigned char **protos,
+ unsigned int *protos_len);
+ void SSL_get0_alpn_protos(SSL *ssl, const unsigned char **protos,
+ unsigned int *protos_len);
+
=head1 DESCRIPTION
SSL_CTX_set_alpn_protos() and SSL_set_alpn_protos() are used by the client to
B<protos_len>. Setting B<protos_len> to 0 clears any existing list of ALPN
protocols and no ALPN extension will be sent to the server.
+SSL_CTX_get0_alpn_protos() and SSL_get0_alpn_protos() are used by the client to
+get the list of protocols available to be negotiated. The B<protos> are in
+protocol-list format, described below. Returns a pointer to protocol list in
+B<protos> with length B<protos_len>. It is not NUL-terminated. B<protos> must
+not be freed.
+
SSL_CTX_set_alpn_select_cb() sets the application callback B<cb> used by a
server to select which protocol to use for the incoming connection. When B<cb>
is NULL, ALPN is not used. The B<arg> value is a pointer which is passed to
void *arg);
void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data,
unsigned int *len);
+void SSL_CTX_get0_alpn_protos(SSL_CTX *ctx, const unsigned char **protos,
+ unsigned int *protos_len);
+void SSL_get0_alpn_protos(SSL *ssl, const unsigned char **protos,
+ unsigned int *protos_len);
#ifndef OPENSSL_NO_PSK
/*
return 0;
}
+/*
+ * SSL_CTX_set_get0_protos gets the ALPN protocol list on |ctx| to |protos|.
+ */
+void SSL_CTX_get0_alpn_protos(SSL_CTX *ctx, const unsigned char **protos,
+ unsigned int *protos_len)
+{
+ unsigned char *p = NULL;
+ unsigned int len = 0;
+
+ if (ctx != NULL) {
+ p = ctx->ext.alpn;
+ len = (unsigned int)ctx->ext.alpn_len;
+ }
+
+ if (protos != NULL)
+ *protos = p;
+ if (protos_len != NULL)
+ *protos_len = len;
+}
+
+/*
+ * SSL_get0_alpn_protos gets the ALPN protocol list on |ssl| to |protos|.
+ */
+void SSL_get0_alpn_protos(SSL *ssl, const unsigned char **protos,
+ unsigned int *protos_len)
+{
+ SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl);
+ unsigned char *p = NULL;
+ unsigned int len = 0;
+
+ if (sc != NULL) {
+ p = sc->ext.alpn;
+ len = (unsigned int)sc->ext.alpn_len;
+ }
+
+ if (protos != NULL)
+ *protos = p;
+ if (protos_len != NULL)
+ *protos_len = len;
+}
+
/*
* SSL_CTX_set_alpn_select_cb sets a callback function on |ctx| that is
* called during ClientHello processing in order to select an ALPN protocol
return testresult;
}
+static int test_get_alpn(void)
+{
+ SSL_CTX *ctx = NULL;
+ SSL *ssl = NULL;
+ int testresult = 0;
+ unsigned char good[] = { 0x04, 'g', 'o', 'o', 'd' };
+ const unsigned char *expect;
+ unsigned int expect_len;
+
+ /* Create an initial SSL_CTX with no certificate configured */
+ ctx = SSL_CTX_new_ex(libctx, NULL, TLS_server_method());
+ if (!TEST_ptr(ctx))
+ goto end;
+
+ SSL_CTX_get0_alpn_protos(NULL, &expect, &expect_len);
+ if (!TEST_ptr_null(expect))
+ goto end;
+ if (!TEST_int_eq(expect_len, 0))
+ goto end;
+ if (!TEST_false(SSL_CTX_set_alpn_protos(ctx, good, sizeof(good))))
+ goto end;
+
+ SSL_CTX_get0_alpn_protos(ctx, &expect, &expect_len);
+ if (!TEST_mem_eq(expect, expect_len, good, sizeof(good)))
+ goto end;
+
+ ssl = SSL_new(ctx);
+ if (!TEST_ptr(ssl))
+ goto end;
+
+ SSL_get0_alpn_protos(NULL, &expect, &expect_len);
+ if (!TEST_ptr_null(expect))
+ goto end;
+ if (!TEST_int_eq(expect_len, 0))
+ goto end;
+
+ if (!TEST_false(SSL_set_alpn_protos(ssl, good, sizeof(good))))
+ goto end;
+
+ SSL_get0_alpn_protos(ssl, &expect, &expect_len);
+ if (!TEST_mem_eq(expect, expect_len, good, sizeof(good)))
+ goto end;
+
+ testresult = 1;
+
+end:
+ SSL_free(ssl);
+ SSL_CTX_free(ctx);
+ return testresult;
+}
+
#if !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_TLS1_2)
/*
* Complete a connection with legacy EC point format configuration
#endif
ADD_TEST(test_inherit_verify_param);
ADD_TEST(test_set_alpn);
+ ADD_TEST(test_get_alpn);
#if !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_TLS1_2)
ADD_TEST(test_legacy_ec_point_formats);
#endif
SSL_select_next_proto ? 4_0_0 EXIST::FUNCTION:
SSL_CTX_set_alpn_protos ? 4_0_0 EXIST::FUNCTION:
SSL_set_alpn_protos ? 4_0_0 EXIST::FUNCTION:
+SSL_CTX_get0_alpn_protos ? 4_0_0 EXIST::FUNCTION:
+SSL_get0_alpn_protos ? 4_0_0 EXIST::FUNCTION:
SSL_CTX_set_alpn_select_cb ? 4_0_0 EXIST::FUNCTION:
SSL_get0_alpn_selected ? 4_0_0 EXIST::FUNCTION:
SSL_CTX_set_psk_client_callback ? 4_0_0 EXIST::FUNCTION:PSK