@@ -32,6 +32,9 @@ struct ssl_backend_data {
3232 unitytls_x509list * clicert ;
3333 unitytls_key * pk ;
3434 unitytls_tlsctx * ctx ;
35+ #ifdef HAS_ALPN
36+ const char * protocols [ALPN_ENTRIES_MAX + 1 ];
37+ #endif
3538};
3639
3740/*
@@ -455,6 +458,26 @@ static CURLcode unitytls_connect_step1(struct Curl_cfilter *cf, struct Curl_easy
455458 return CURLE_SSL_CONNECT_ERROR ;
456459 }
457460
461+ #ifdef HAS_ALPN
462+ if (connssl -> alpn ) {
463+ struct alpn_proto_buf proto ;
464+ // mbedtls_ssl_conf_alpn_protocols does not clone the protocols array, which is why we need to keep it inside backend struct
465+ size_t i ;
466+ DEBUGASSERT (connssl -> alpn -> count <= ALPN_ENTRIES_MAX );
467+ for (i = 0 ; i < connssl -> alpn -> count ; ++ i ) {
468+ backend -> protocols [i ] = connssl -> alpn -> entries [i ];
469+ }
470+ backend -> protocols [connssl -> alpn -> count ] = NULL ; // the protocols array must be null-terminated
471+ unitytls -> unitytls_tlsctx_set_alpn_protocols (backend -> ctx , & backend -> protocols [0 ], & err );
472+ if (err .code != UNITYTLS_SUCCESS ) {
473+ failf (data , "Failed setting APLN protocols: %i" , err .code );
474+ return CURLE_SSL_CONNECT_ERROR ;
475+ }
476+ Curl_alpn_to_proto_str (& proto , connssl -> alpn );
477+ infof (data , VTLS_INFOF_ALPN_OFFER_1STR , proto .data );
478+ }
479+ #endif
480+
458481 /* give application a chance to interfere with SSL set up. */
459482 if (data -> set .ssl .fsslctx ) {
460483 CURLcode result = (* data -> set .ssl .fsslctx )(data , backend -> ctx , data -> set .ssl .fsslctxp );
@@ -469,7 +492,7 @@ static CURLcode unitytls_connect_step1(struct Curl_cfilter *cf, struct Curl_easy
469492 return CURLE_OK ;
470493}
471494
472- static CURLcode unitytls_connect_step2 (struct Curl_easy * data , struct ssl_connect_data * connssl )
495+ static CURLcode unitytls_connect_step2 (struct Curl_cfilter * cf , struct Curl_easy * data , struct ssl_connect_data * connssl )
473496{
474497 struct ssl_backend_data * backend = connssl -> backend ;
475498
@@ -510,6 +533,13 @@ static CURLcode unitytls_connect_step2(struct Curl_easy* data, struct ssl_connec
510533 }
511534 }
512535
536+ #ifdef HAS_ALPN
537+ if (connssl -> alpn ) {
538+ const char * proto = unitytls -> unitytls_tlsctx_get_alpn_protocol (backend -> ctx );
539+ Curl_alpn_set_negotiated (cf , data , (const unsigned char * )proto , proto ? strlen (proto ) : 0 );
540+ }
541+ #endif
542+
513543 /* We almost certainly have a verifyresult!=UNITYTLS_X509VERIFY_SUCCESS as well, but in theory it is still possible to hit this code. */
514544 if (err .code == UNITYTLS_SUCCESS ) {
515545 connssl -> connecting_state = ssl_connect_3 ;
@@ -567,7 +597,7 @@ static CURLcode unitytls_connect_common(struct Curl_cfilter *cf, struct Curl_eas
567597 return CURLE_OPERATION_TIMEDOUT ;
568598 }
569599
570- retcode = unitytls_connect_step2 (data , connssl );
600+ retcode = unitytls_connect_step2 (cf , data , connssl );
571601 if (retcode != CURLE_OK || (nonblocking && ssl_connect_2 == connssl -> connecting_state ))
572602 return retcode ;
573603 } /* repeat step2 until all transactions are done. */
0 commit comments