MCPcopy Create free account
hub / github.com/apache/httpd / ssl_callback_alpn_select

Function ssl_callback_alpn_select

modules/ssl/ssl_engine_kernel.c:2529–2623  ·  view source on GitHub ↗

* This callback function is executed when the TLS Application-Layer * Protocol Negotiation Extension (ALPN, RFC 7301) is triggered by the Client * Hello, giving a list of desired protocol names (in descending preference) * to the server. * The callback has to select a protocol name or return an error if none of * the clients preferences is supported. * The selected protocol does not have to

Source from the content-addressed store, hash-verified

2527 * characters (not null-terminated), followed by the next protocol name.
2528 */
2529int ssl_callback_alpn_select(SSL *ssl,
2530 const unsigned char **out, unsigned char *outlen,
2531 const unsigned char *in, unsigned int inlen,
2532 void *arg)
2533{
2534 conn_rec *c = (conn_rec*)SSL_get_app_data(ssl);
2535 SSLConnRec *sslconn;
2536 apr_array_header_t *client_protos;
2537 const char *proposed;
2538 size_t len;
2539 int i;
2540
2541 /* If the connection object is not available,
2542 * then there's nothing for us to do. */
2543 if (c == NULL) {
2544 return SSL_TLSEXT_ERR_OK;
2545 }
2546 sslconn = myConnConfig(c);
2547
2548 if (inlen == 0) {
2549 /* someone tries to trick us? */
2550 ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(02837)
2551 "ALPN client protocol list empty");
2552 return SSL_TLSEXT_ERR_ALERT_FATAL;
2553 }
2554
2555 client_protos = apr_array_make(c->pool, 0, sizeof(char *));
2556 for (i = 0; i < inlen; /**/) {
2557 unsigned int plen = in[i++];
2558 if (plen + i > inlen) {
2559 /* someone tries to trick us? */
2560 ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(02838)
2561 "ALPN protocol identifier too long");
2562 return SSL_TLSEXT_ERR_ALERT_FATAL;
2563 }
2564 APR_ARRAY_PUSH(client_protos, char *) =
2565 apr_pstrndup(c->pool, (const char *)in+i, plen);
2566 i += plen;
2567 }
2568
2569 /* The order the callbacks are invoked from TLS extensions is, unfortunately
2570 * not defined and older openssl versions do call ALPN selection before
2571 * they callback the SNI. We need to make sure that we know which vhost
2572 * we are dealing with so we respect the correct protocols.
2573 */
2574 init_vhost(c, ssl, NULL);
2575
2576 proposed = ap_select_protocol(c, NULL, sslconn->server, client_protos);
2577 if (!proposed) {
2578 proposed = ap_get_protocol(c);
2579 }
2580
2581 len = strlen(proposed);
2582 if (len > 255) {
2583 ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(02840)
2584 "ALPN negotiated protocol name too long");
2585 return SSL_TLSEXT_ERR_ALERT_FATAL;
2586 }

Callers

nothing calls this directly

Calls 6

init_vhostFunction · 0.85
ap_select_protocolFunction · 0.85
ap_get_protocolFunction · 0.85
ap_switch_protocolFunction · 0.85
ssl_is_challengeFunction · 0.85
set_challenge_credsFunction · 0.85

Tested by

no test coverage detected