forked from acouzens/open5gs
Add TLS support
This commit is contained in:
parent
517bb6ad85
commit
141c345b75
|
@ -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 ||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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])
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue