diff --git a/lib/mbedtls_wrapper/include/internal/ssl_lib.h b/lib/mbedtls_wrapper/include/internal/ssl_lib.h index bf7de22f..42b2de75 100644 --- a/lib/mbedtls_wrapper/include/internal/ssl_lib.h +++ b/lib/mbedtls_wrapper/include/internal/ssl_lib.h @@ -21,6 +21,8 @@ #include "ssl_types.h" + void _ssl_set_alpn_list(const SSL *ssl); + #ifdef __cplusplus } #endif diff --git a/lib/mbedtls_wrapper/include/internal/ssl_types.h b/lib/mbedtls_wrapper/include/internal/ssl_types.h index 5aaee941..5d7d9387 100644 --- a/lib/mbedtls_wrapper/include/internal/ssl_types.h +++ b/lib/mbedtls_wrapper/include/internal/ssl_types.h @@ -144,6 +144,10 @@ struct X509_VERIFY_PARAM_st { }; +typedef int (*next_proto_cb)(SSL *ssl, unsigned char **out, + unsigned char *outlen, const unsigned char *in, + unsigned int inlen, void *arg); + struct ssl_ctx_st { int version; @@ -152,16 +156,16 @@ struct ssl_ctx_st unsigned long options; - #if 0 - struct alpn_protocols alpn_protocol; - #endif - const SSL_METHOD *method; CERT *cert; X509 *client_CA; + const char **alpn_protos; + + next_proto_cb alpn_cb; + int verify_mode; int (*default_verify_callback) (int ok, X509_STORE_CTX *ctx); @@ -277,9 +281,7 @@ struct pkey_method_st { int (*pkey_load)(EVP_PKEY *pkey, const unsigned char *buf, int len); }; -typedef int (*next_proto_cb)(SSL *ssl, unsigned char **out, - unsigned char *outlen, const unsigned char *in, - unsigned int inlen, void *arg); +#define OPENSSL_NPN_NEGOTIATED 1 #ifdef __cplusplus } diff --git a/lib/mbedtls_wrapper/include/internal/tls1.h b/lib/mbedtls_wrapper/include/internal/tls1.h index a9da53e0..7af1b015 100644 --- a/lib/mbedtls_wrapper/include/internal/tls1.h +++ b/lib/mbedtls_wrapper/include/internal/tls1.h @@ -48,6 +48,9 @@ #define TLS1_1_VERSION 0x0302 #define TLS1_2_VERSION 0x0303 +#define SSL_TLSEXT_ERR_OK 0 +#define SSL_TLSEXT_ERR_NOACK 3 + #ifdef __cplusplus } #endif diff --git a/lib/mbedtls_wrapper/include/openssl/ssl.h b/lib/mbedtls_wrapper/include/openssl/ssl.h index dfda0cf3..bea50b75 100755 --- a/lib/mbedtls_wrapper/include/openssl/ssl.h +++ b/lib/mbedtls_wrapper/include/openssl/ssl.h @@ -337,6 +337,11 @@ void SSL_CTX_set_next_proto_select_cb(SSL_CTX *ctx, void *arg), void *arg); +void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data, + unsigned int *len); + +void _ssl_set_alpn_list(const SSL *ssl); + /** * @brief get SSL error code * diff --git a/lib/mbedtls_wrapper/library/ssl_lib.c b/lib/mbedtls_wrapper/library/ssl_lib.c index d94b4faa..ae6f02f3 100644 --- a/lib/mbedtls_wrapper/library/ssl_lib.c +++ b/lib/mbedtls_wrapper/library/ssl_lib.c @@ -224,6 +224,9 @@ void SSL_CTX_free(SSL_CTX* ctx) X509_free(ctx->client_CA); + if (ctx->alpn_protos) + ssl_mem_free(ctx->alpn_protos); + ssl_mem_free(ctx); } @@ -303,6 +306,8 @@ SSL *SSL_new(SSL_CTX *ctx) goto failed5; } + _ssl_set_alpn_list(ssl); + ssl->rwstate = SSL_NOTHING; return ssl; @@ -1577,3 +1582,78 @@ void *SSL_CTX_get_ex_data(const SSL_CTX *ctx, int idx) { return NULL; } + +/* + * Openssl wants the valid protocol names supplied like this: + * + * (unsigned char *)"\x02h2\x08http/1.1", 6 + 9 + * + * Mbedtls wants this: + * + * Pointer to a NULL-terminated list of supported protocols, in decreasing + * preference order. The pointer to the list is recorded by the library for + * later reference as required, so the lifetime of the table must be at least + * as long as the lifetime of the SSL configuration structure. + * + * So accept the OpenSSL style and convert to mbedtls style + */ + +struct alpn_ctx { + unsigned char *data; + unsigned short len; +}; + +void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx, next_proto_cb cb, void *arg) +{ + struct alpn_ctx *ac = arg; + unsigned char *p = ac->data, *q; + unsigned char len; + int count = 0; + + /* find out how many entries he gave us */ + + len = *p++; + while (p - ac->data < ac->len) { + if (len--) { + p++; + continue; + } + count++; + len = *p++; + if (!len) + break; + } + + if (!count) + return; + + /* allocate space for count + 1 pointers and the data afterwards */ + + ctx->alpn_protos = ssl_mem_zalloc((count + 1) * sizeof(char *) + ac->len + 1); + if (!ctx->alpn_protos) + return; + + /* convert to mbedtls format */ + + q = (unsigned char *)ctx->alpn_protos + (count + 1) * sizeof(char *); + p = ac->data; + count = 0; + + len = *p++; + ctx->alpn_protos[count] = (char *)q; + while (p - ac->data < ac->len) { + if (len--) { + *q++ = *p++; + continue; + } + *q++ = '\0'; + count++; + len = *p++; + ctx->alpn_protos[count] = (char *)q; + if (!len) + break; + } + ctx->alpn_protos[count] = NULL; /* last pointer ends list with NULL */ + + ctx->alpn_cb = cb; +} diff --git a/lib/mbedtls_wrapper/platform/ssl_pm.c b/lib/mbedtls_wrapper/platform/ssl_pm.c index 939f35de..0fef1889 100755 --- a/lib/mbedtls_wrapper/platform/ssl_pm.c +++ b/lib/mbedtls_wrapper/platform/ssl_pm.c @@ -687,3 +687,21 @@ int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param, return 1; } + +void _ssl_set_alpn_list(const SSL *ssl) +{ + if (!ssl->ctx->alpn_protos) + return; + if (mbedtls_ssl_conf_alpn_protocols(&((struct ssl_pm *)(ssl->ssl_pm))->conf, ssl->ctx->alpn_protos)) + fprintf(stderr, "mbedtls_ssl_conf_alpn_protocols failed\n"); +} + +void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data, + unsigned int *len) +{ + const char *alp = mbedtls_ssl_get_alpn_protocol(&((struct ssl_pm *)(ssl->ssl_pm))->ssl); + + *data = (const unsigned char *)alp; + *len = strlen(alp); +} +