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:
parent
fc995df480
commit
796a5edb6c
6 changed files with 117 additions and 7 deletions
|
@ -21,6 +21,8 @@
|
|||
|
||||
#include "ssl_types.h"
|
||||
|
||||
void _ssl_set_alpn_list(const SSL *ssl);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue