From 2c159f5a2d5fa34de4040fd262754c56b6decbbd Mon Sep 17 00:00:00 2001 From: Determinant Date: Fri, 21 Jun 2019 17:54:32 -0400 Subject: adjust C API --- CMakeLists.txt | 1 + include/salticidae/conn.h | 2 +- include/salticidae/crypto.h | 66 ++++++++++++++++++++++++++++++-------- include/salticidae/network.h | 10 ++++-- include/salticidae/util.h | 8 +++++ src/network.cpp | 76 +++++++++++++++++++++++--------------------- test/test_msgnet_c.c | 18 ++++------- 7 files changed, 118 insertions(+), 63 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9c5c6e8..9a78538 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,6 +35,7 @@ add_library(salticidae src/type.cpp src/util.cpp src/event.cpp + src/crypto.cpp src/stream.cpp src/msg.cpp src/netaddr.cpp diff --git a/include/salticidae/conn.h b/include/salticidae/conn.h index a3da96c..ceec176 100644 --- a/include/salticidae/conn.h +++ b/include/salticidae/conn.h @@ -112,7 +112,7 @@ class ConnPool { void disp_terminate(); public: - Conn(): ready_send(false), + Conn(): worker(nullptr), ready_send(false), send_data_func(nullptr), recv_data_func(nullptr), tls(nullptr), peer_cert(nullptr) {} Conn(const Conn &) = delete; diff --git a/include/salticidae/crypto.h b/include/salticidae/crypto.h index 7eec030..d7231a4 100644 --- a/include/salticidae/crypto.h +++ b/include/salticidae/crypto.h @@ -27,6 +27,8 @@ #include "salticidae/type.h" #include "salticidae/util.h" + +#ifdef __cplusplus #include #include @@ -116,15 +118,15 @@ class SHA1 { } }; -static thread_local const char *_password; +static thread_local const char *_passwd; static inline int _tls_pem_no_passswd(char *, int, int, void *) { return -1; } static inline int _tls_pem_with_passwd(char *buf, int size, int, void *) { - size_t _size = strlen(_password) + 1; + size_t _size = strlen(_passwd) + 1; if (_size > (size_t)size) throw SalticidaeError(SALTI_ERROR_TLS_X509); - memmove(buf, _password, _size); + memmove(buf, _passwd, _size); return _size - 1; } @@ -140,14 +142,14 @@ class PKey { PKey(const PKey &) = delete; PKey(PKey &&other): key(other.key) { other.key = nullptr; } - PKey create_privkey_from_pem_file(std::string pem_fname, std::string *password = nullptr) { + static PKey create_privkey_from_pem_file(std::string pem_fname, std::string *passwd = nullptr) { FILE *fp = fopen(pem_fname.c_str(), "r"); EVP_PKEY *key; if (fp == nullptr) throw SalticidaeError(SALTI_ERROR_TLS_KEY); - if (password) + if (passwd) { - _password = password->c_str(); + _passwd = passwd->c_str(); key = PEM_read_PrivateKey(fp, NULL, _tls_pem_with_passwd, NULL); } else @@ -160,9 +162,10 @@ class PKey { return PKey(key); } - PKey create_privkey_from_der(const uint8_t *der, size_t size) { + static PKey create_privkey_from_der(const bytearray_t &der) { + const auto *_der = &der[0]; EVP_PKEY *key; - key = d2i_AutoPrivateKey(NULL, (const unsigned char **)&der, size); + key = d2i_AutoPrivateKey(NULL, (const unsigned char **)&_der, der.size()); if (key == nullptr) throw SalticidaeError(SALTI_ERROR_TLS_KEY); return PKey(key); @@ -201,14 +204,14 @@ class X509 { X509(const X509 &) = delete; X509(X509 &&other): x509(other.x509) { other.x509 = nullptr; } - X509 create_from_pem_file(std::string pem_fname, std::string *password = nullptr) { + static X509 create_from_pem_file(std::string pem_fname, std::string *passwd = nullptr) { FILE *fp = fopen(pem_fname.c_str(), "r"); ::X509 *x509; if (fp == nullptr) throw SalticidaeError(SALTI_ERROR_TLS_X509); - if (password) + if (passwd) { - _password = password->c_str(); + _passwd = passwd->c_str(); x509 = PEM_read_X509(fp, NULL, _tls_pem_with_passwd, NULL); } else @@ -221,9 +224,10 @@ class X509 { return X509(x509); } - X509 create_from_der(const uint8_t *der, size_t size) { + static X509 create_from_der(const bytearray_t &der) { + const auto *_der = &der[0]; ::X509 *x509; - x509 = d2i_X509(NULL, (const unsigned char **)&der, size); + x509 = d2i_X509(NULL, (const unsigned char **)&_der, der.size()); if (x509 == nullptr) throw SalticidaeError(SALTI_ERROR_TLS_X509); return X509(x509); @@ -356,4 +360,40 @@ class TLS { } +#ifdef SALTICIDAE_CBINDINGS +using x509_t = salticidae::X509; +using pkey_t = salticidae::PKey; +#endif + +#else + +#ifdef SALTICIDAE_CBINDINGS +typedef struct x509_t x509_t; +typedef struct pkey_t pkey_t; +#endif + +#endif + +#ifdef SALTICIDAE_CBINDINGS +#ifdef __cplusplus +extern "C" { +#endif + +x509_t *x509_new_from_pem_file(const char *pem_fname, const char *passwd, SalticidaeCError *err); +x509_t *x509_new_from_der(const bytearray_t *der, SalticidaeCError *err); +void x509_free(const x509_t *self); +pkey_t *x509_get_pubkey(const x509_t *self); +bytearray_t *x509_get_der(const x509_t *self); + +pkey_t *pkey_new_privkey_from_pem_file(const char *pem_fname, const char *passwd, SalticidaeCError *err); +pkey_t *pkey_new_privkey_from_der(const bytearray_t *der, SalticidaeCError *err); +void pkey_free(const pkey_t *self); +bytearray_t *pkey_get_pubkey_der(const pkey_t *self); +bytearray_t *pkey_get_privkey_der(const pkey_t *self); + +#ifdef __cplusplus +} +#endif +#endif + #endif diff --git a/include/salticidae/network.h b/include/salticidae/network.h index 3687c7e..6c8b7fd 100644 --- a/include/salticidae/network.h +++ b/include/salticidae/network.h @@ -26,6 +26,7 @@ #define _SALTICIDAE_NETWORK_H #include "salticidae/event.h" +#include "salticidae/crypto.h" #include "salticidae/netaddr.h" #include "salticidae/msg.h" #include "salticidae/conn.h" @@ -981,8 +982,13 @@ void msgnetwork_config_conn_server_timeout(msgnetwork_config_t *self, double tim void msgnetwork_config_seg_buff_size(msgnetwork_config_t *self, size_t size); void msgnetwork_config_nworker(msgnetwork_config_t *self, size_t nworker); void msgnetwork_config_queue_capacity(msgnetwork_config_t *self, size_t cap); +void msgnetwork_config_enable_tls(msgnetwork_config_t *self, bool enabled); +void msgnetwork_config_tls_key_file(msgnetwork_config_t *self, const char *pem_fname); +void msgnetwork_config_tls_cert_file(msgnetwork_config_t *self, const char *pem_fname); +void msgnetwork_config_tls_key_by_move(msgnetwork_config_t *self, pkey_t *key); +void msgnetwork_config_tls_cert_by_move(msgnetwork_config_t *self, x509_t *cert); -msgnetwork_t *msgnetwork_new(const eventcontext_t *ec, const msgnetwork_config_t *config); +msgnetwork_t *msgnetwork_new(const eventcontext_t *ec, const msgnetwork_config_t *config, SalticidaeCError *err); void msgnetwork_free(const msgnetwork_t *self); void msgnetwork_send_msg(msgnetwork_t *self, const msg_t *msg, const msgnetwork_conn_t *conn); void msgnetwork_send_msg_deferred_by_move(msgnetwork_t *self, msg_t *_moved_msg, const msgnetwork_conn_t *conn); @@ -1018,7 +1024,7 @@ void peernetwork_config_conn_timeout(peernetwork_config_t *self, double t); void peernetwork_config_id_mode(peernetwork_config_t *self, peernetwork_id_mode_t mode); msgnetwork_config_t *peernetwork_config_as_msgnetwork_config(peernetwork_config_t *self); -peernetwork_t *peernetwork_new(const eventcontext_t *ec, const peernetwork_config_t *config); +peernetwork_t *peernetwork_new(const eventcontext_t *ec, const peernetwork_config_t *config, SalticidaeCError *err); void peernetwork_free(const peernetwork_t *self); void peernetwork_add_peer(peernetwork_t *self, const netaddr_t *paddr); void peernetwork_del_peer(peernetwork_t *self, const netaddr_t *paddr); diff --git a/include/salticidae/util.h b/include/salticidae/util.h index 9a57ae8..9102842 100644 --- a/include/salticidae/util.h +++ b/include/salticidae/util.h @@ -43,6 +43,14 @@ SalticidaeCError salticidae_cerror_normal(); SalticidaeCError salticidae_cerror_unknown(); const char *salticidae_strerror(int code); +#define SALTICIDAE_CERROR_TRY(cerror) try { (*(cerror)) = salticidae_cerror_normal(); +#define SALTICIDAE_CERROR_CATCH(cerror) \ + } catch (const SalticidaeError &err) { \ + *cerror = err.get_cerr(); \ + } catch (const std::exception &err) { \ + *cerror = salticidae_cerror_unknown(); \ + } + #ifdef __cplusplus } #endif diff --git a/src/network.cpp b/src/network.cpp index 122270b..bc539f4 100644 --- a/src/network.cpp +++ b/src/network.cpp @@ -14,8 +14,11 @@ msgnetwork_config_t *msgnetwork_config_new() { void msgnetwork_config_free(const msgnetwork_config_t *self) { delete self; } -msgnetwork_t *msgnetwork_new(const eventcontext_t *ec, const msgnetwork_config_t *config) { +msgnetwork_t *msgnetwork_new(const eventcontext_t *ec, const msgnetwork_config_t *config, SalticidaeCError *cerror) { + SALTICIDAE_CERROR_TRY(cerror) return new msgnetwork_t(*ec, *config); + SALTICIDAE_CERROR_CATCH(cerror) + return nullptr; } void msgnetwork_free(const msgnetwork_t *self) { delete self; } @@ -44,6 +47,26 @@ void msgnetwork_config_queue_capacity(msgnetwork_config_t *self, size_t cap) { self->queue_capacity(cap); } +void msgnetwork_config_enable_tls(msgnetwork_config_t *self, bool enabled) { + self->enable_tls(enabled); +} + +void msgnetwork_config_tls_key_file(msgnetwork_config_t *self, const char *pem_fname) { + self->tls_key_file(pem_fname); +} + +void msgnetwork_config_tls_cert_file(msgnetwork_config_t *self, const char *pem_fname) { + self->tls_cert_file(pem_fname); +} + +void msgnetwork_config_tls_key_by_move(msgnetwork_config_t *self, pkey_t *key) { + self->tls_key(new pkey_t(std::move(*key))); +} + +void msgnetwork_config_tls_cert_by_move(msgnetwork_config_t *self, x509_t *cert) { + self->tls_cert(new x509_t(std::move(*cert))); +} + void msgnetwork_send_msg(msgnetwork_t *self, const msg_t *msg, const msgnetwork_conn_t *conn) { self->_send_msg(*msg, *conn); } @@ -54,15 +77,9 @@ void msgnetwork_send_msg_deferred_by_move(msgnetwork_t *self, } msgnetwork_conn_t *msgnetwork_connect(msgnetwork_t *self, const netaddr_t *addr, SalticidaeCError *cerror) { - try { - auto res = new msgnetwork_conn_t(self->connect(*addr)); - *cerror = salticidae_cerror_normal(); - return res; - } catch (const SalticidaeError &err) { - *cerror = err.get_cerr(); - } catch (const std::exception &err) { - *cerror = salticidae_cerror_unknown(); - } + SALTICIDAE_CERROR_TRY(cerror) + return new msgnetwork_conn_t(self->connect(*addr)); + SALTICIDAE_CERROR_CATCH(cerror) return nullptr; } @@ -74,14 +91,9 @@ msgnetwork_conn_t *msgnetwork_conn_copy(const msgnetwork_conn_t *self) { void msgnetwork_conn_free(const msgnetwork_conn_t *self) { delete self; } void msgnetwork_listen(msgnetwork_t *self, const netaddr_t *listen_addr, SalticidaeCError *cerror) { - try { - self->listen(*listen_addr); - *cerror = salticidae_cerror_normal(); - } catch (const SalticidaeError &err) { - *cerror = err.get_cerr(); - } catch (const std::exception &err) { - *cerror = salticidae_cerror_unknown(); - } + SALTICIDAE_CERROR_TRY(cerror) + self->listen(*listen_addr); + SALTICIDAE_CERROR_CATCH(cerror) } void msgnetwork_reg_handler(msgnetwork_t *self, @@ -169,8 +181,11 @@ peernetwork_t *msgnetwork_as_peernetwork_unsafe(msgnetwork_t *self) { return static_cast(self); } -peernetwork_t *peernetwork_new(const eventcontext_t *ec, const peernetwork_config_t *config) { +peernetwork_t *peernetwork_new(const eventcontext_t *ec, const peernetwork_config_t *config, SalticidaeCError *cerror) { + SALTICIDAE_CERROR_TRY(cerror) return new peernetwork_t(*ec, *config); + SALTICIDAE_CERROR_CATCH(cerror) + return nullptr; } void peernetwork_free(const peernetwork_t *self) { delete self; } @@ -186,15 +201,9 @@ bool peernetwork_has_peer(const peernetwork_t *self, const netaddr_t *paddr) { const peernetwork_conn_t *peernetwork_get_peer_conn(const peernetwork_t *self, const netaddr_t *paddr, SalticidaeCError *cerror) { - try { - auto res = new peernetwork_conn_t(self->get_peer_conn(*paddr)); - *cerror = salticidae_cerror_normal(); - return res; - } catch (const SalticidaeError &err) { - *cerror = err.get_cerr(); - } catch (const std::exception &err) { - *cerror = salticidae_cerror_unknown(); - } + SALTICIDAE_CERROR_TRY(cerror) + return new peernetwork_conn_t(self->get_peer_conn(*paddr)); + SALTICIDAE_CERROR_CATCH(cerror) return nullptr; } @@ -231,14 +240,9 @@ void peernetwork_multicast_msg_by_move(peernetwork_t *self, } void peernetwork_listen(peernetwork_t *self, const netaddr_t *listen_addr, SalticidaeCError *cerror) { - try { - self->listen(*listen_addr); - *cerror = salticidae_cerror_normal(); - } catch (const SalticidaeError &err) { - *cerror = err.get_cerr(); - } catch (const std::exception &err) { - *cerror = salticidae_cerror_unknown(); - } + SALTICIDAE_CERROR_TRY(cerror) + self->listen(*listen_addr); + SALTICIDAE_CERROR_CATCH(cerror) } void peernetwork_stop(peernetwork_t *self) { self->stop(); } diff --git a/test/test_msgnet_c.c b/test/test_msgnet_c.c index aeedd99..f938c82 100644 --- a/test/test_msgnet_c.c +++ b/test/test_msgnet_c.c @@ -139,8 +139,7 @@ bool conn_handler(const msgnetwork_conn_t *conn, bool connected, void *userdata) printf("[%s] Disconnected, retrying.\n", name); /* try to reconnect to the same address */ const netaddr_t *addr = msgnetwork_conn_get_addr(conn); - msgnetwork_connect(net, addr, &err); - check_err(&err); + msgnetwork_connect(net, addr, &err); check_err(&err); } return true; } @@ -155,8 +154,9 @@ void error_handler(const SalticidaeCError *err, bool fatal, void *userdata) { MyNet gen_mynet(const eventcontext_t *ec, const char *name) { MyNet res; + SalticidaeCError err; const msgnetwork_config_t *netconfig = msgnetwork_config_new(); - res.net = msgnetwork_new(ec, netconfig); + res.net = msgnetwork_new(ec, netconfig, &err); check_err(&err); msgnetwork_config_free(netconfig); res.name = name; return res; @@ -190,16 +190,12 @@ int main() { msgnetwork_start(bob.net); /* accept incoming connections */ - msgnetwork_listen(alice.net, alice_addr, &err); - check_err(&err); - msgnetwork_listen(bob.net, bob_addr, &err); - check_err(&err); + msgnetwork_listen(alice.net, alice_addr, &err); check_err(&err); + msgnetwork_listen(bob.net, bob_addr, &err); check_err(&err); /* try to connect once */ - msgnetwork_conn_free(msgnetwork_connect(alice.net, bob_addr, &err)); - check_err(&err); - msgnetwork_conn_free(msgnetwork_connect(bob.net, alice_addr, &err)); - check_err(&err); + msgnetwork_conn_free(msgnetwork_connect(alice.net, bob_addr, &err)); check_err(&err); + msgnetwork_conn_free(msgnetwork_connect(bob.net, alice_addr, &err)); check_err(&err); netaddr_free(alice_addr); netaddr_free(bob_addr); -- cgit v1.2.3-70-g09d2