Add TLS support

This commit is contained in:
Flander Bojan 2022-10-24 10:52:03 +00:00 committed by Sukchan Lee
parent 517bb6ad85
commit 141c345b75
7 changed files with 135 additions and 2 deletions

View File

@ -372,6 +372,9 @@ static connection_t *connection_add(
request->h.uri = uri;
}
curl_easy_setopt(conn->easy, CURLOPT_SSL_VERIFYPEER, 0);
curl_easy_setopt(conn->easy, CURLOPT_SSL_VERIFYHOST, 0);
/* HTTP Method */
if (strcmp(request->h.method, OGS_SBI_HTTP_METHOD_PUT) == 0 ||
strcmp(request->h.method, OGS_SBI_HTTP_METHOD_PATCH) == 0 ||

View File

@ -56,6 +56,7 @@ typedef int (*ogs_sbi_client_cb_f)(
typedef struct ogs_sbi_client_s {
ogs_socknode_t node;
OpenAPI_uri_scheme_e scheme;
struct {
const char *key;

View File

@ -1473,6 +1473,7 @@ static void nf_service_associate_client(ogs_sbi_nf_service_t *nf_service)
client = ogs_sbi_client_find(addr);
if (!client) {
client = ogs_sbi_client_add(addr);
client->scheme = nf_service->scheme;
ogs_assert(client);
}
}

View File

@ -103,6 +103,8 @@ char *ogs_sbi_client_uri(ogs_sbi_client_t *client, ogs_sbi_header_t *h)
if (client->tls.key && client->tls.pem)
https = true;
else if (client->scheme == OpenAPI_uri_scheme_https)
https = true;
return ogs_uridup(https, client->node.addr, h);
}

View File

@ -52,6 +52,8 @@ libsbi_inc = include_directories('.')
sbi_cc_flags = ['-DOGS_SBI_COMPILATION']
libgnutls_dep = cc.find_library('gnutls', required : true)
libssl_dep = cc.find_library('ssl', required : true)
libcrypto_dep = cc.find_library('crypto', required : true)
libnghttp2_dep = dependency('libnghttp2', version: '>=1.18.1')
libmicrohttpd_dep = dependency('libmicrohttpd', version: '>=0.9.40')
libcurl_dep = dependency('libcurl', version: '>=7.52.1')
@ -65,6 +67,8 @@ libsbi = library('ogssbi',
libapp_dep,
libsbi_openapi_dep,
libgnutls_dep,
libssl_dep,
libcrypto_dep,
libnghttp2_dep,
libmicrohttpd_dep,
libcurl_dep],
@ -78,6 +82,8 @@ libsbi_dep = declare_dependency(
libapp_dep,
libsbi_openapi_dep,
libgnutls_dep,
libssl_dep,
libcrypto_dep,
libnghttp2_dep,
libmicrohttpd_dep,
libcurl_dep])

View File

@ -75,6 +75,7 @@ typedef struct ogs_sbi_session_s {
int32_t last_stream_id;
struct h2_settings settings;
SSL* ssl;
} ogs_sbi_session_t;
typedef struct ogs_sbi_stream_s {
@ -116,6 +117,78 @@ static void server_final(void)
ogs_pool_final(&session_pool);
}
#ifndef OPENSSL_NO_NEXTPROTONEG
static int next_proto_cb(SSL *ssl, const unsigned char **data,
unsigned int *len, void *arg) {
static unsigned char next_proto_list[256];
(void)ssl;
(void)arg;
next_proto_list[0] = NGHTTP2_PROTO_VERSION_ID_LEN;
memcpy(&next_proto_list[1], NGHTTP2_PROTO_VERSION_ID, NGHTTP2_PROTO_VERSION_ID_LEN);
*data = next_proto_list;
*len = 1 + NGHTTP2_PROTO_VERSION_ID_LEN;
return SSL_TLSEXT_ERR_OK;
}
#endif
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
static int alpn_select_proto_cb(SSL *ssl, const unsigned char **out,
unsigned char *outlen, const unsigned char *in,
unsigned int inlen, void *arg) {
int rv;
(void)ssl;
(void)arg;
rv = nghttp2_select_next_protocol((unsigned char **)out, outlen, in, inlen);
if (rv != 1) {
return SSL_TLSEXT_ERR_NOACK;
}
return SSL_TLSEXT_ERR_OK;
}
#endif /* OPENSSL_VERSION_NUMBER >= 0x10002000L */
static SSL_CTX *create_ssl_ctx(const char *key_file, const char *cert_file) {
SSL_CTX *ssl_ctx;
ssl_ctx = SSL_CTX_new(TLS_server_method());
if (!ssl_ctx) {
ogs_error("Could not create SSL/TLS context: %s", ERR_error_string(ERR_get_error(), NULL));
return NULL;
}
SSL_CTX_set_options(ssl_ctx,
SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |
SSL_OP_NO_COMPRESSION |
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
if (SSL_CTX_set1_curves_list(ssl_ctx, "P-256") != 1) {
ogs_error("SSL_CTX_set1_curves_list failed: %s", ERR_error_string(ERR_get_error(), NULL));
return NULL;
}
#endif /* !(OPENSSL_VERSION_NUMBER >= 0x30000000L) */
if (SSL_CTX_use_PrivateKey_file(ssl_ctx, key_file, SSL_FILETYPE_PEM) != 1) {
ogs_error("Could not read private key file - key_file=%s", key_file);
return NULL;
}
if (SSL_CTX_use_certificate_chain_file(ssl_ctx, cert_file) != 1) {
ogs_error("Could not read certificate file - cert_file=%s ", cert_file);
return NULL;
}
#ifndef OPENSSL_NO_NEXTPROTONEG
SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, next_proto_cb, NULL);
#endif /* !OPENSSL_NO_NEXTPROTONEG */
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
SSL_CTX_set_alpn_select_cb(ssl_ctx, alpn_select_proto_cb, NULL);
#endif /* OPENSSL_VERSION_NUMBER >= 0x10002000L */
return ssl_ctx;
}
static int server_start(ogs_sbi_server_t *server,
int (*cb)(ogs_sbi_request_t *request, void *data))
{
@ -127,6 +200,15 @@ static int server_start(ogs_sbi_server_t *server,
addr = server->node.addr;
ogs_assert(addr);
/* Create SSL CTX */
if (server->tls.key && server->tls.pem) {
server->ssl_ctx = create_ssl_ctx(server->tls.key, server->tls.pem);
if (!server->ssl_ctx) {
ogs_error("Cannot create SSL CTX");
return OGS_ERROR;
}
}
sock = ogs_tcp_server(addr, server->node.option);
if (!sock) {
ogs_error("Cannot start SBI server");
@ -157,6 +239,10 @@ static void server_stop(ogs_sbi_server_t *server)
{
ogs_assert(server);
/* Free SSL CTX */
if (server->ssl_ctx)
SSL_CTX_free(server->ssl_ctx);
if (server->node.poll)
ogs_pollset_remove(server->node.poll);
@ -485,6 +571,11 @@ static ogs_sbi_session_t *session_add(
ogs_expect_or_return_val(sbi_sess->addr, NULL);
memcpy(sbi_sess->addr, &sock->remote_addr, sizeof(ogs_sockaddr_t));
if (server->ssl_ctx) {
sbi_sess->ssl = SSL_new(server->ssl_ctx);
ogs_expect_or_return_val(sbi_sess->ssl, NULL);
}
ogs_list_add(&server->session_list, sbi_sess);
return sbi_sess;
@ -501,6 +592,9 @@ static void session_remove(ogs_sbi_session_t *sbi_sess)
ogs_list_remove(&server->session_list, sbi_sess);
if (sbi_sess->ssl)
SSL_free(sbi_sess->ssl);
stream_remove_all(sbi_sess);
nghttp2_session_del(sbi_sess->session);
@ -566,6 +660,19 @@ static void accept_handler(short when, ogs_socket_t fd, void *data)
sbi_sess = session_add(server, new);
ogs_assert(sbi_sess);
if (sbi_sess->ssl) {
int err ;
SSL_set_fd(sbi_sess->ssl, new->fd);
SSL_set_accept_state(sbi_sess->ssl);
err = SSL_accept(sbi_sess->ssl);
if (err <= 0) {
ogs_error("SSL_accept failed: %s", ERR_error_string(ERR_get_error(), NULL));
ogs_sock_destroy(new);
session_remove(sbi_sess);
return;
}
}
sbi_sess->poll.read = ogs_pollset_add(ogs_app()->pollset,
OGS_POLLIN, new->fd, recv_handler, sbi_sess);
ogs_assert(sbi_sess->poll.read);
@ -595,7 +702,11 @@ static void recv_handler(short when, ogs_socket_t fd, void *data)
pkbuf = ogs_pkbuf_alloc(NULL, OGS_MAX_SDU_LEN);
ogs_assert(pkbuf);
n = ogs_recv(fd, pkbuf->data, OGS_MAX_SDU_LEN, 0);
if (sbi_sess->ssl)
n = SSL_read(sbi_sess->ssl, pkbuf->data, OGS_MAX_SDU_LEN);
else
n = ogs_recv(fd, pkbuf->data, OGS_MAX_SDU_LEN, 0);
if (n > 0) {
ogs_pkbuf_put(pkbuf, n);
@ -1294,7 +1405,11 @@ static void session_write_callback(short when, ogs_socket_t fd, void *data)
ogs_assert(pkbuf);
ogs_list_remove(&sbi_sess->write_queue, pkbuf);
ogs_send(fd, pkbuf->data, pkbuf->len, 0);
if (sbi_sess->ssl)
SSL_write(sbi_sess->ssl, pkbuf->data, pkbuf->len);
else
ogs_send(fd, pkbuf->data, pkbuf->len, 0);
ogs_log_hexdump(OGS_LOG_DEBUG, pkbuf->data, pkbuf->len);
ogs_pkbuf_free(pkbuf);

View File

@ -28,6 +28,9 @@
extern "C" {
#endif
#include <openssl/ssl.h>
#include <openssl/err.h>
typedef struct ogs_sbi_stream_s ogs_sbi_stream_t;
typedef struct ogs_sbi_server_s {
@ -39,6 +42,8 @@ typedef struct ogs_sbi_server_s {
const char *pem;
} tls;
SSL_CTX *ssl_ctx;
int (*cb)(ogs_sbi_request_t *request, void *data);
ogs_list_t session_list;