1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-16 00:00:07 +01:00

openssl-wrapper: add APLN accessors

This adds the necessary OpenSSL Apis to the mbedTLS openssl wrapper
to allow ALPN negotiation OpenSSL-style.

The OpenSSL upgrade list format is supported and converted to mbedtls
format at runtime.
This commit is contained in:
Andy Green 2017-09-28 13:55:16 +08:00
parent fc995df480
commit 796a5edb6c
6 changed files with 117 additions and 7 deletions

View file

@ -21,6 +21,8 @@
#include "ssl_types.h"
void _ssl_set_alpn_list(const SSL *ssl);
#ifdef __cplusplus
}
#endif

View file

@ -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
}

View file

@ -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

View file

@ -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
*

View file

@ -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;
}

View file

@ -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);
}