Skip to content

Commit 3b901d6

Browse files
authored
Merge pull request #32 from Unity-Technologies/alpn_support_exp
Add ALPN support via UnityTLS
2 parents bf8f35d + f10433a commit 3b901d6

File tree

2 files changed

+47
-2
lines changed

2 files changed

+47
-2
lines changed

lib/vtls/unitytls.c

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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. */

lib/vtls/unitytls_interface.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
#ifndef HEADER_CURL_UNITYTLS_INTERFACE_H
22
#define HEADER_CURL_UNITYTLS_INTERFACE_H
33

4+
/* ALPN for http2 */
5+
#ifdef USE_HTTP2
6+
#define HAS_ALPN
7+
#endif
8+
49
#include <stdint.h>
510

611
typedef int8_t SInt8;
@@ -264,6 +269,11 @@ typedef void (*unitytls_tlsctx_set_certificate_callback_t
264269

265270
typedef void (*unitytls_random_generate_bytes_t)(UInt8* buffer, size_t bufferLen, unitytls_errorstate* errorState);
266271

272+
#ifdef HAS_ALPN
273+
typedef void (*unitytls_tlsctx_set_alpn_protocols_t)(unitytls_tlsctx* ctx, const char **protocols, unitytls_errorstate * errorState);
274+
typedef const char* (*unitytls_tlsctx_get_alpn_protocol_t)(unitytls_tlsctx* ctx);
275+
#endif
276+
267277
/* Interface struct used to integrate UnityTLS into external libraries. */
268278
/* See InterfaceStruct.cpp in UnityTLS. */
269279
typedef struct unitytls_interface_struct
@@ -311,6 +321,11 @@ typedef struct unitytls_interface_struct
311321

312322
unitytls_x509verify_result_to_string_t unitytls_x509verify_result_to_string;
313323
unitytls_tlsctx_set_trace_level_t unitytls_tlsctx_set_trace_level;
324+
325+
#ifdef HAS_ALPN
326+
unitytls_tlsctx_set_alpn_protocols_t unitytls_tlsctx_set_alpn_protocols;
327+
unitytls_tlsctx_get_alpn_protocol_t unitytls_tlsctx_get_alpn_protocol;
328+
#endif
314329
} unitytls_interface_struct;
315330

316331

0 commit comments

Comments
 (0)