Supports TLS with HTTP2 client

This commit is contained in:
Kedar Sovani 2017-11-30 11:35:34 +05:30 committed by Jitin George
parent eb051fe72f
commit 1c72c8d126
2 changed files with 42 additions and 5 deletions

View File

@ -95,7 +95,7 @@ err_freeaddr:
return -1; return -1;
} }
static int create_ssl_handle(struct esp_tls *tls) static int create_ssl_handle(struct esp_tls *tls, const char *hostname, size_t hostlen, struct esp_tls_cfg *cfg)
{ {
int ret; int ret;
@ -108,12 +108,23 @@ static int create_ssl_handle(struct esp_tls *tls)
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_AUTO_RETRY); SSL_CTX_set_mode(ssl_ctx, SSL_MODE_AUTO_RETRY);
SSL_CTX_set_mode(ssl_ctx, SSL_MODE_RELEASE_BUFFERS); SSL_CTX_set_mode(ssl_ctx, SSL_MODE_RELEASE_BUFFERS);
#endif #endif
if (cfg->alpn_protos) {
SSL_CTX_set_alpn_protos(ssl_ctx, cfg->alpn_protos, strlen((char *)cfg->alpn_protos));
}
SSL *ssl = SSL_new(ssl_ctx); SSL *ssl = SSL_new(ssl_ctx);
if (!ssl) { if (!ssl) {
SSL_CTX_free(ssl_ctx); SSL_CTX_free(ssl_ctx);
return -1; return -1;
} }
char *use_host = strndup(hostname, hostlen);
if (!use_host) {
SSL_CTX_free(ssl_ctx);
return -1;
}
SSL_set_tlsext_host_name(ssl, use_host);
free(use_host);
SSL_set_fd(ssl, tls->sockfd); SSL_set_fd(ssl, tls->sockfd);
ret = SSL_connect(ssl); ret = SSL_connect(ssl);
if (ret < 1) { if (ret < 1) {
@ -155,7 +166,7 @@ static ssize_t tls_write(struct esp_tls *tls, const char *data, size_t datalen)
return SSL_write(tls->ssl, data, datalen); return SSL_write(tls->ssl, data, datalen);
} }
struct esp_tls *esp_tls_conn_new(const char *hostname, int hostlen, int port, bool is_tls) struct esp_tls *esp_tls_conn_new(const char *hostname, int hostlen, int port, struct esp_tls_cfg *cfg)
{ {
int sockfd = esp_tcp_connect(hostname, hostlen, port); int sockfd = esp_tcp_connect(hostname, hostlen, port);
if (sockfd < 0) { if (sockfd < 0) {
@ -171,8 +182,8 @@ struct esp_tls *esp_tls_conn_new(const char *hostname, int hostlen, int port, bo
tls->read = tcp_read; tls->read = tcp_read;
tls->write = tcp_write; tls->write = tcp_write;
if (is_tls) { if (cfg) {
if (create_ssl_handle(tls) != 0) { if (create_ssl_handle(tls, hostname, hostlen, cfg) != 0) {
esp_tls_conn_delete(tls); esp_tls_conn_delete(tls);
return NULL; return NULL;
} }

View File

@ -5,6 +5,22 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <openssl/ssl.h> #include <openssl/ssl.h>
#ifdef __cplusplus
extern "C" {
#endif
struct esp_tls_cfg {
/* If HTTP2/ALPN support is required, a list of protocols that
* should be negotiated. The format is length followed by protocol
* name.
* For the most common cases the following is ok:
* "\x02h2"
* - where the first '2' is the length of the protocol and
* - the subsequent 'h2' is the protocol name
*/
const unsigned char *alpn_protos;
};
struct esp_tls { struct esp_tls {
SSL_CTX *ctx; SSL_CTX *ctx;
SSL *ssl; SSL *ssl;
@ -13,7 +29,13 @@ struct esp_tls {
ssize_t (*write)(struct esp_tls *tls, const char *data, size_t datalen); ssize_t (*write)(struct esp_tls *tls, const char *data, size_t datalen);
}; };
struct esp_tls *esp_tls_conn_new(const char *hostname, int hostlen, int port, bool is_tls); /*
*
* cfg: If you wish to open non-TLS connection, keep this NULL. For TLS
* connection, a pass pointer to 'struct esp_tls_cfg'. At a minimum, this
* structure should be zero-initialized.
*/
struct esp_tls *esp_tls_conn_new(const char *hostname, int hostlen, int port, struct esp_tls_cfg *cfg);
static inline ssize_t esp_tls_conn_write(struct esp_tls *tls, const char *data, size_t datalen) static inline ssize_t esp_tls_conn_write(struct esp_tls *tls, const char *data, size_t datalen)
{ {
@ -27,4 +49,8 @@ static inline ssize_t esp_tls_conn_read(struct esp_tls *tls, char *data, size_t
void esp_tls_conn_delete(struct esp_tls *tls); void esp_tls_conn_delete(struct esp_tls *tls);
#ifdef __cplusplus
}
#endif
#endif /* ! _ESP_TLS_H_ */ #endif /* ! _ESP_TLS_H_ */