mirror of
https://github.com/jorisvink/kore
synced 2025-03-09 12:39:01 -04:00
Initial work splitting OpenSSL code away.
This work moves all TLS / crypto related code into a tls_openssl.c file and adds a tls_none.c which contains just stubs. Allows compilation of Kore with TLS_BACKEND=none to remove building against OpenSSL. Also adds code for SHA1/SHA2 taken from openssh-portable so we don't depend on those being present anymore in libcrypto.
This commit is contained in:
parent
6dc162e7ee
commit
99a1581e19
20
Makefile
20
Makefile
@ -12,6 +12,7 @@ INSTALL_DIR=$(PREFIX)/bin
|
||||
MAN_DIR?=$(PREFIX)/share/man
|
||||
SHARE_DIR=$(PREFIX)/share/kore
|
||||
INCLUDE_DIR=$(PREFIX)/include/kore
|
||||
TLS_BACKEND?=openssl
|
||||
|
||||
TOOLS= kore-serve
|
||||
|
||||
@ -23,7 +24,8 @@ PYTHON_CURLOPT=misc/curl/python_curlopt.h
|
||||
S_SRC= src/kore.c src/buf.c src/config.c src/connection.c \
|
||||
src/domain.c src/filemap.c src/fileref.c src/json.c src/log.c \
|
||||
src/mem.c src/msg.c src/module.c src/net.c src/pool.c src/runtime.c \
|
||||
src/timer.c src/utils.c src/worker.c src/keymgr.c
|
||||
src/sha1.c src/sha2.c src/timer.c src/utils.c src/worker.c
|
||||
S_SRC+= src/tls_$(TLS_BACKEND).c
|
||||
|
||||
FEATURES=
|
||||
FEATURES_INC=
|
||||
@ -34,11 +36,15 @@ CFLAGS+=-Wsign-compare -Iinclude/kore -I$(OBJDIR) -std=c99 -pedantic
|
||||
CFLAGS+=-Wtype-limits -fno-common
|
||||
CFLAGS+=-DPREFIX='"$(PREFIX)"' -fstack-protector-all
|
||||
|
||||
ifneq ("$(OPENSSL_PATH)", "")
|
||||
CFLAGS+=-I$(OPENSSL_PATH)/include
|
||||
LDFLAGS+=-rdynamic -L$(OPENSSL_PATH)/lib -lssl -l$(KORE_CRYPTO)
|
||||
else
|
||||
LDFLAGS+=-rdynamic -lssl -l$(KORE_CRYPTO)
|
||||
ifeq ("$(TLS_BACKEND)", "openssl")
|
||||
S_SRC+=src/keymgr_openssl.c
|
||||
|
||||
ifneq ("$(OPENSSL_PATH)", "")
|
||||
CFLAGS+=-I$(OPENSSL_PATH)/include
|
||||
LDFLAGS+=-rdynamic -L$(OPENSSL_PATH)/lib -lssl -l$(KORE_CRYPTO)
|
||||
else
|
||||
LDFLAGS+=-rdynamic -lssl -l$(KORE_CRYPTO)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ("$(KORE_SINGLE_BINARY)", "")
|
||||
@ -132,10 +138,12 @@ ifneq ("$(SANITIZE)", "")
|
||||
endif
|
||||
|
||||
ifeq ("$(OSNAME)", "darwin")
|
||||
ifeq ("$(TLS_BACKEND)", "openssl")
|
||||
OSSL_INCL=$(shell pkg-config openssl --cflags)
|
||||
CFLAGS+=$(OSSL_INCL)
|
||||
LDFLAGS+=$(shell pkg-config openssl --libs)
|
||||
FEATURES_INC+=$(OSSL_INCL)
|
||||
endif
|
||||
S_SRC+=src/bsd.c
|
||||
else ifeq ("$(OSNAME)", "linux")
|
||||
CFLAGS+=-D_GNU_SOURCE=1 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2
|
||||
|
@ -49,10 +49,6 @@ void kore_acme_run(void);
|
||||
void kore_acme_setup(void);
|
||||
void kore_acme_get_paths(const char *, char **, char **);
|
||||
|
||||
void kore_acme_tls_challenge_use_cert(SSL *, struct kore_domain *);
|
||||
int kore_acme_tls_alpn(SSL *, const unsigned char **, unsigned char *,
|
||||
const unsigned char *, unsigned int, void *);
|
||||
|
||||
extern char *acme_email;
|
||||
extern int acme_domains;
|
||||
extern char *acme_provider;
|
||||
|
@ -22,7 +22,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/queue.h>
|
||||
|
||||
#include <openssl/sha.h>
|
||||
#include "sha2.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
@ -281,7 +281,7 @@ struct http_request {
|
||||
const char *agent;
|
||||
const char *referer;
|
||||
struct connection *owner;
|
||||
SHA256_CTX hashctx;
|
||||
SHA2_CTX hashctx;
|
||||
u_int8_t *headers;
|
||||
struct kore_buf *http_body;
|
||||
int http_body_fd;
|
||||
|
@ -30,10 +30,6 @@
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/dh.h>
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <regex.h>
|
||||
#include <stdarg.h>
|
||||
@ -61,24 +57,6 @@ extern int daemon(int, int);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Figure out what type of OpenSSL API we are dealing with.
|
||||
*/
|
||||
#if defined(LIBRESSL_VERSION_NUMBER)
|
||||
#if LIBRESSL_VERSION_NUMBER >= 0x3000000fL
|
||||
#define KORE_OPENSSL_NEWER_API 1
|
||||
#endif
|
||||
|
||||
#if LIBRESSL_VERSION_NUMBER >= 0x3020200fL
|
||||
#define TLS1_3_VERSION 0x0304
|
||||
#endif
|
||||
|
||||
#else
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
|
||||
#define KORE_OPENSSL_NEWER_API 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__OpenBSD__)
|
||||
#define KORE_USE_PLATFORM_PLEDGE 1
|
||||
#endif
|
||||
@ -236,8 +214,8 @@ struct connection {
|
||||
u_int8_t state;
|
||||
u_int8_t proto;
|
||||
struct listener *owner;
|
||||
X509 *cert;
|
||||
SSL *ssl;
|
||||
void *ssl;
|
||||
void *cert;
|
||||
char *tls_sni;
|
||||
int tls_reneg;
|
||||
u_int16_t flags;
|
||||
@ -359,7 +337,7 @@ struct kore_domain {
|
||||
char *crlfile;
|
||||
char *certfile;
|
||||
char *certkey;
|
||||
SSL_CTX *ssl_ctx;
|
||||
void *ssl_ctx;
|
||||
int x509_verify_depth;
|
||||
#if !defined(KORE_NO_HTTP)
|
||||
TAILQ_HEAD(, kore_route) routes;
|
||||
@ -720,14 +698,11 @@ extern int skip_runas;
|
||||
extern int kore_foreground;
|
||||
|
||||
extern char *kore_pidfile;
|
||||
extern char *kore_tls_cipher_list;
|
||||
|
||||
extern volatile sig_atomic_t sig_recv;
|
||||
|
||||
extern int tls_version;
|
||||
extern DH *tls_dhparam;
|
||||
extern char *rand_file;
|
||||
extern int keymgr_active;
|
||||
extern char *kore_rand_file;
|
||||
extern int kore_keymgr_active;
|
||||
|
||||
extern struct kore_privsep worker_privsep;
|
||||
extern struct kore_privsep keymgr_privsep;
|
||||
@ -753,6 +728,7 @@ extern struct kore_pool nb_pool;
|
||||
extern struct kore_domain *primary_dom;
|
||||
extern struct kore_server_list kore_servers;
|
||||
|
||||
/* kore.c */
|
||||
void kore_signal(int);
|
||||
void kore_shutdown(void);
|
||||
void kore_signal_trap(int);
|
||||
@ -760,6 +736,26 @@ void kore_signal_setup(void);
|
||||
void kore_proctitle(const char *);
|
||||
void kore_default_getopt(int, char **);
|
||||
|
||||
void kore_server_closeall(void);
|
||||
void kore_server_cleanup(void);
|
||||
void kore_server_free(struct kore_server *);
|
||||
void kore_server_finalize(struct kore_server *);
|
||||
|
||||
struct kore_server *kore_server_create(const char *);
|
||||
struct kore_server *kore_server_lookup(const char *);
|
||||
|
||||
void kore_listener_accept(void *, int);
|
||||
struct listener *kore_listener_lookup(const char *);
|
||||
void kore_listener_free(struct listener *);
|
||||
struct listener *kore_listener_create(struct kore_server *);
|
||||
int kore_listener_init(struct listener *, int, const char *);
|
||||
|
||||
int kore_sockopt(int, int, int);
|
||||
int kore_server_bind_unix(struct kore_server *,
|
||||
const char *, const char *);
|
||||
int kore_server_bind(struct kore_server *,
|
||||
const char *, const char *, const char *);
|
||||
/* worker.c */
|
||||
void kore_worker_reap(void);
|
||||
int kore_worker_init(void);
|
||||
void kore_worker_privsep(void);
|
||||
@ -776,6 +772,7 @@ void kore_worker_entry(struct kore_worker *) __attribute__((noreturn));
|
||||
struct kore_worker *kore_worker_data(u_int8_t);
|
||||
struct kore_worker *kore_worker_data_byid(u_int16_t);
|
||||
|
||||
/* platform code (linux.c, bsd.c) */
|
||||
void kore_platform_init(void);
|
||||
void kore_platform_sandbox(void);
|
||||
void kore_platform_event_init(void);
|
||||
@ -803,12 +800,43 @@ void kore_platform_pledge(void);
|
||||
void kore_platform_add_pledge(const char *);
|
||||
#endif
|
||||
|
||||
/* tls variants. */
|
||||
#define KORE_X509_NAME_COMMON_NAME 1
|
||||
|
||||
void kore_tls_init(void);
|
||||
void kore_tls_cleanup(void);
|
||||
void kore_tls_dh_check(void);
|
||||
int kore_tls_supported(void);
|
||||
void kore_tls_version_set(int);
|
||||
void kore_tls_keymgr_init(void);
|
||||
int kore_tls_dh_load(const char *);
|
||||
void kore_tls_seed(const void *, size_t);
|
||||
int kore_tls_ciphersuite_set(const char *);
|
||||
int kore_tls_read(struct connection *, size_t *);
|
||||
void kore_tls_domain_cleanup(struct kore_domain *);
|
||||
int kore_tls_connection_accept(struct connection *);
|
||||
void kore_tls_connection_cleanup(struct connection *);
|
||||
int kore_tls_write(struct connection *, size_t, size_t *);
|
||||
void kore_tls_domain_crl(struct kore_domain *, const void *, size_t);
|
||||
void kore_tls_domain_setup(struct kore_domain *,
|
||||
int, const void *, size_t);
|
||||
|
||||
void *kore_tls_rsakey_load(const char *);
|
||||
void *kore_tls_rsakey_generate(const char *);
|
||||
|
||||
void *kore_tls_x509_issuer_name(struct connection *);
|
||||
void *kore_tls_x509_subject_name(struct connection *);
|
||||
int kore_tls_x509name_foreach(void *, int, void *,
|
||||
int (*)(void *, int, int, const char *,
|
||||
const void *, size_t, int));
|
||||
/* accesslog.c */
|
||||
void kore_accesslog_init(u_int16_t);
|
||||
void kore_accesslog_worker_init(void);
|
||||
void kore_accesslog_run(void *, u_int64_t);
|
||||
void kore_accesslog_gather(void *, u_int64_t, int);
|
||||
|
||||
#if !defined(KORE_NO_HTTP)
|
||||
/* auth.c */
|
||||
int kore_auth_run(struct http_request *, struct kore_auth *);
|
||||
int kore_auth_cookie(struct http_request *, struct kore_auth *);
|
||||
int kore_auth_header(struct http_request *, struct kore_auth *);
|
||||
@ -818,6 +846,7 @@ int kore_auth_new(const char *);
|
||||
struct kore_auth *kore_auth_lookup(const char *);
|
||||
#endif
|
||||
|
||||
/* timer.c */
|
||||
void kore_timer_init(void);
|
||||
void kore_timer_run(u_int64_t);
|
||||
u_int64_t kore_timer_next_run(u_int64_t);
|
||||
@ -825,29 +854,7 @@ void kore_timer_remove(struct kore_timer *);
|
||||
struct kore_timer *kore_timer_add(void (*cb)(void *, u_int64_t),
|
||||
u_int64_t, void *, int);
|
||||
|
||||
void kore_server_closeall(void);
|
||||
void kore_server_cleanup(void);
|
||||
void kore_server_free(struct kore_server *);
|
||||
void kore_server_finalize(struct kore_server *);
|
||||
|
||||
struct kore_server *kore_server_create(const char *);
|
||||
struct kore_server *kore_server_lookup(const char *);
|
||||
|
||||
void kore_listener_accept(void *, int);
|
||||
struct listener *kore_listener_lookup(const char *);
|
||||
void kore_listener_free(struct listener *);
|
||||
struct listener *kore_listener_create(struct kore_server *);
|
||||
int kore_listener_init(struct listener *, int, const char *);
|
||||
|
||||
int kore_sockopt(int, int, int);
|
||||
int kore_server_bind_unix(struct kore_server *,
|
||||
const char *, const char *);
|
||||
int kore_server_bind(struct kore_server *,
|
||||
const char *, const char *, const char *);
|
||||
|
||||
int kore_tls_sni_cb(SSL *, int *, void *);
|
||||
void kore_tls_info_callback(const SSL *, int, int);
|
||||
|
||||
/* connection.c */
|
||||
void kore_connection_init(void);
|
||||
void kore_connection_cleanup(void);
|
||||
void kore_connection_prune(int);
|
||||
@ -865,7 +872,6 @@ void kore_connection_check_idletimer(u_int64_t,
|
||||
int kore_connection_accept(struct listener *,
|
||||
struct connection **);
|
||||
|
||||
u_int64_t kore_time_ms(void);
|
||||
void kore_log_init(void);
|
||||
void kore_log_file(const char *);
|
||||
|
||||
@ -873,9 +879,12 @@ void kore_log_file(const char *);
|
||||
int kore_configure_setting(const char *, char *);
|
||||
#endif
|
||||
|
||||
void *kore_malloc(size_t);
|
||||
/* config.c */
|
||||
void kore_parse_config(void);
|
||||
void kore_parse_config_file(FILE *);
|
||||
|
||||
/* mem.c */
|
||||
void *kore_malloc(size_t);
|
||||
void *kore_calloc(size_t, size_t);
|
||||
void *kore_realloc(void *, size_t);
|
||||
void kore_free(void *);
|
||||
@ -886,12 +895,19 @@ void *kore_mem_lookup(u_int32_t);
|
||||
void kore_mem_tag(void *, u_int32_t);
|
||||
void *kore_malloc_tagged(size_t, u_int32_t);
|
||||
|
||||
/* pool.c */
|
||||
void *kore_pool_get(struct kore_pool *);
|
||||
void kore_pool_put(struct kore_pool *, void *);
|
||||
void kore_pool_init(struct kore_pool *, const char *,
|
||||
size_t, size_t);
|
||||
void kore_pool_cleanup(struct kore_pool *);
|
||||
|
||||
/* utils.c */
|
||||
void kore_debug_internal(char *, int, const char *, ...);
|
||||
void fatal(const char *, ...) __attribute__((noreturn));
|
||||
void fatalx(const char *, ...) __attribute__((noreturn));
|
||||
|
||||
u_int64_t kore_time_ms(void);
|
||||
char *kore_time_to_date(time_t);
|
||||
char *kore_strdup(const char *);
|
||||
time_t kore_date_to_time(const char *);
|
||||
@ -909,19 +925,15 @@ int kore_base64_encode(const void *, size_t, char **);
|
||||
int kore_base64_decode(const char *, u_int8_t **, size_t *);
|
||||
int kore_base64url_encode(const void *, size_t, char **, int);
|
||||
int kore_base64url_decode(const char *, u_int8_t **, size_t *, int);
|
||||
int kore_x509_issuer_name(struct connection *, char **, int);
|
||||
int kore_x509_subject_name(struct connection *, char **, int);
|
||||
|
||||
void *kore_mem_find(void *, size_t, const void *, size_t);
|
||||
char *kore_text_trim(char *, size_t);
|
||||
char *kore_read_line(FILE *, char *, size_t);
|
||||
|
||||
EVP_PKEY *kore_rsakey_load(const char *);
|
||||
EVP_PKEY *kore_rsakey_generate(const char *);
|
||||
int kore_x509_issuer_name(struct connection *, char **, int);
|
||||
int kore_x509_subject_name(struct connection *, char **, int);
|
||||
int kore_x509name_foreach(X509_NAME *, int, void *,
|
||||
int (*)(void *, int, int, const char *,
|
||||
const void *, size_t, int));
|
||||
|
||||
#if !defined(KORE_NO_HTTP)
|
||||
/* websocket.c */
|
||||
void kore_websocket_handshake(struct http_request *,
|
||||
const char *, const char *, const char *);
|
||||
int kore_websocket_send_clean(struct netbuf *);
|
||||
@ -931,6 +943,7 @@ void kore_websocket_broadcast(struct connection *,
|
||||
u_int8_t, const void *, size_t, int);
|
||||
#endif
|
||||
|
||||
/* msg.c */
|
||||
void kore_msg_init(void);
|
||||
void kore_msg_worker_init(void);
|
||||
void kore_msg_parent_init(void);
|
||||
@ -942,6 +955,7 @@ int kore_msg_register(u_int8_t,
|
||||
void (*cb)(struct kore_msg *, const void *));
|
||||
|
||||
#if !defined(KORE_NO_HTTP)
|
||||
/* filemap.c */
|
||||
void kore_filemap_init(void);
|
||||
void kore_filemap_resolve_paths(void);
|
||||
int kore_filemap_create(struct kore_domain *, const char *,
|
||||
@ -950,13 +964,17 @@ extern char *kore_filemap_ext;
|
||||
extern char *kore_filemap_index;
|
||||
#endif
|
||||
|
||||
/* fileref.c */
|
||||
void kore_fileref_init(void);
|
||||
struct kore_fileref *kore_fileref_get(const char *, int);
|
||||
struct kore_fileref *kore_fileref_create(struct kore_server *,
|
||||
const char *, int, off_t, struct timespec *);
|
||||
void kore_fileref_release(struct kore_fileref *);
|
||||
|
||||
/* domain.c */
|
||||
struct kore_domain *kore_domain_new(const char *);
|
||||
struct kore_domain *kore_domain_byid(u_int16_t);
|
||||
struct kore_domain *kore_domain_lookup(struct kore_server *, const char *);
|
||||
|
||||
void kore_domain_init(void);
|
||||
void kore_domain_cleanup(void);
|
||||
@ -972,11 +990,9 @@ void kore_domain_load_crl(void);
|
||||
void kore_domain_keymgr_init(void);
|
||||
void kore_domain_callback(void (*cb)(struct kore_domain *));
|
||||
int kore_domain_attach(struct kore_domain *, struct kore_server *);
|
||||
void kore_domain_tlsinit(struct kore_domain *, int,
|
||||
const void *, size_t);
|
||||
void kore_domain_crl_add(struct kore_domain *, const void *, size_t);
|
||||
|
||||
#if !defined(KORE_NO_HTTP)
|
||||
/* route.c */
|
||||
void kore_route_reload(void);
|
||||
void kore_route_free(struct kore_route *);
|
||||
void kore_route_callback(struct kore_route *, const char *);
|
||||
@ -987,6 +1003,7 @@ int kore_route_lookup(struct http_request *,
|
||||
struct kore_domain *, int, struct kore_route **);
|
||||
#endif
|
||||
|
||||
/* runtime.c */
|
||||
struct kore_runtime_call *kore_runtime_getcall(const char *);
|
||||
struct kore_module *kore_module_load(const char *,
|
||||
const char *, int);
|
||||
@ -1012,10 +1029,8 @@ void kore_runtime_wsmessage(struct kore_runtime_call *,
|
||||
struct connection *, u_int8_t, const void *, size_t);
|
||||
#endif
|
||||
|
||||
struct kore_domain *kore_domain_byid(u_int16_t);
|
||||
struct kore_domain *kore_domain_lookup(struct kore_server *, const char *);
|
||||
|
||||
#if !defined(KORE_NO_HTTP)
|
||||
/* validator.c */
|
||||
void kore_validator_init(void);
|
||||
void kore_validator_reload(void);
|
||||
int kore_validator_add(const char *, u_int8_t, const char *);
|
||||
@ -1025,12 +1040,9 @@ int kore_validator_check(struct http_request *,
|
||||
struct kore_validator *kore_validator_lookup(const char *);
|
||||
#endif
|
||||
|
||||
void fatal(const char *, ...) __attribute__((noreturn));
|
||||
void fatalx(const char *, ...) __attribute__((noreturn));
|
||||
|
||||
const char *kore_worker_name(int);
|
||||
void kore_debug_internal(char *, int, const char *, ...);
|
||||
|
||||
/* net.c */
|
||||
u_int16_t net_read16(u_int8_t *);
|
||||
u_int32_t net_read32(u_int8_t *);
|
||||
u_int64_t net_read64(u_int8_t *);
|
||||
@ -1045,9 +1057,7 @@ int net_send(struct connection *);
|
||||
int net_send_flush(struct connection *);
|
||||
int net_recv_flush(struct connection *);
|
||||
int net_read(struct connection *, size_t *);
|
||||
int net_read_tls(struct connection *, size_t *);
|
||||
int net_write(struct connection *, size_t, size_t *);
|
||||
int net_write_tls(struct connection *, size_t, size_t *);
|
||||
void net_recv_reset(struct connection *, size_t,
|
||||
int (*cb)(struct netbuf *));
|
||||
void net_remove_netbuf(struct connection *, struct netbuf *);
|
||||
@ -1060,6 +1070,7 @@ void net_send_stream(struct connection *, void *,
|
||||
size_t, int (*cb)(struct netbuf *), struct netbuf **);
|
||||
void net_send_fileref(struct connection *, struct kore_fileref *);
|
||||
|
||||
/* buf.c */
|
||||
void kore_buf_free(struct kore_buf *);
|
||||
struct kore_buf *kore_buf_alloc(size_t);
|
||||
void kore_buf_init(struct kore_buf *, size_t);
|
||||
@ -1074,6 +1085,7 @@ void kore_buf_appendv(struct kore_buf *, const char *, va_list);
|
||||
void kore_buf_replace_string(struct kore_buf *,
|
||||
const char *, const void *, size_t);
|
||||
|
||||
/* json.c */
|
||||
int kore_json_errno(void);
|
||||
int kore_json_parse(struct kore_json *);
|
||||
void kore_json_cleanup(struct kore_json *);
|
||||
@ -1088,6 +1100,7 @@ struct kore_json_item *kore_json_find(struct kore_json_item *,
|
||||
struct kore_json_item *kore_json_create_item(struct kore_json_item *,
|
||||
const char *, u_int32_t, ...);
|
||||
|
||||
/* keymgr.c */
|
||||
void kore_keymgr_run(void);
|
||||
void kore_keymgr_cleanup(int);
|
||||
|
||||
|
73
src/acme.c
73
src/acme.c
@ -262,9 +262,6 @@ static char *revoke_url = NULL;
|
||||
static char *account_id = NULL;
|
||||
static char *account_url = NULL;
|
||||
|
||||
static u_int8_t acme_alpn_name[] =
|
||||
{ 0xa, 'a', 'c', 'm', 'e', '-', 't', 'l', 's', '/', '1' };
|
||||
|
||||
struct kore_privsep acme_privsep;
|
||||
int acme_domains = 0;
|
||||
char *acme_email = NULL;
|
||||
@ -358,39 +355,6 @@ kore_acme_run(void)
|
||||
net_cleanup();
|
||||
}
|
||||
|
||||
int
|
||||
kore_acme_tls_alpn(SSL *ssl, const unsigned char **out, unsigned char *outlen,
|
||||
const unsigned char *in, unsigned int inlen, void *udata)
|
||||
{
|
||||
struct connection *c;
|
||||
|
||||
if ((c = SSL_get_ex_data(ssl, 0)) == NULL)
|
||||
fatal("%s: no connection data present", __func__);
|
||||
|
||||
if (inlen != sizeof(acme_alpn_name))
|
||||
return (SSL_TLSEXT_ERR_NOACK);
|
||||
|
||||
if (memcmp(acme_alpn_name, in, sizeof(acme_alpn_name)))
|
||||
return (SSL_TLSEXT_ERR_NOACK);
|
||||
|
||||
*out = in + 1;
|
||||
*outlen = inlen - 1;
|
||||
|
||||
c->flags |= CONN_TLS_ALPN_ACME_SEEN;
|
||||
|
||||
/*
|
||||
* If SNI was already done, we can continue, otherwise we mark
|
||||
* that we saw the right ALPN negotiation on this connection
|
||||
* and wait for the SNI extension to be parsed.
|
||||
*/
|
||||
if (c->flags & CONN_TLS_SNI_SEEN) {
|
||||
/* SNI was seen, we are on the right domain. */
|
||||
kore_acme_tls_challenge_use_cert(ssl, udata);
|
||||
}
|
||||
|
||||
return (SSL_TLSEXT_ERR_OK);
|
||||
}
|
||||
|
||||
void
|
||||
kore_acme_get_paths(const char *domain, char **key, char **cert)
|
||||
{
|
||||
@ -412,43 +376,6 @@ kore_acme_get_paths(const char *domain, char **key, char **cert)
|
||||
*key = kore_strdup(path);
|
||||
}
|
||||
|
||||
void
|
||||
kore_acme_tls_challenge_use_cert(SSL *ssl, struct kore_domain *dom)
|
||||
{
|
||||
struct connection *c;
|
||||
const unsigned char *ptr;
|
||||
X509 *x509;
|
||||
|
||||
if (dom->acme == 0) {
|
||||
kore_log(LOG_NOTICE, "[%s] ACME not active", dom->domain);
|
||||
return;
|
||||
}
|
||||
|
||||
if (dom->acme_challenge == 0) {
|
||||
kore_log(LOG_NOTICE,
|
||||
"[%s] ACME auth challenge not active", dom->domain);
|
||||
return;
|
||||
}
|
||||
|
||||
kore_log(LOG_INFO, "[%s] acme-tls/1 challenge requested",
|
||||
dom->domain);
|
||||
|
||||
if ((c = SSL_get_ex_data(ssl, 0)) == NULL)
|
||||
fatal("%s: no connection data present", __func__);
|
||||
|
||||
ptr = dom->acme_cert;
|
||||
if ((x509 = d2i_X509(NULL, &ptr, dom->acme_cert_len)) == NULL)
|
||||
fatal("d2i_X509: %s", ssl_errno_s);
|
||||
|
||||
if (SSL_use_certificate(ssl, x509) == 0)
|
||||
fatal("SSL_use_certificate: %s", ssl_errno_s);
|
||||
|
||||
SSL_clear_chain_certs(ssl);
|
||||
SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL);
|
||||
|
||||
c->proto = CONN_PROTO_ACME_ALPN;
|
||||
}
|
||||
|
||||
static void
|
||||
acme_parse_directory(void)
|
||||
{
|
||||
|
71
src/config.c
71
src/config.c
@ -309,7 +309,6 @@ void
|
||||
kore_parse_config(void)
|
||||
{
|
||||
FILE *fp;
|
||||
BIO *bio;
|
||||
struct passwd *pwd;
|
||||
char path[PATH_MAX];
|
||||
|
||||
@ -334,16 +333,7 @@ kore_parse_config(void)
|
||||
(void)fclose(fp);
|
||||
}
|
||||
|
||||
if (tls_dhparam == NULL) {
|
||||
if ((bio = BIO_new_file(KORE_DHPARAM_PATH, "r")) == NULL)
|
||||
fatal("failed to open %s", KORE_DHPARAM_PATH);
|
||||
|
||||
tls_dhparam = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
|
||||
BIO_free(bio);
|
||||
|
||||
if (tls_dhparam == NULL)
|
||||
fatal("PEM_read_bio_DHparams(): %s", ssl_errno_s);
|
||||
}
|
||||
kore_tls_dh_check();
|
||||
|
||||
if (!kore_module_loaded())
|
||||
fatal("no application module was loaded");
|
||||
@ -631,8 +621,19 @@ configure_server(char *options)
|
||||
static int
|
||||
configure_tls(char *yesno)
|
||||
{
|
||||
if (!kore_tls_supported()) {
|
||||
current_server->tls = 0;
|
||||
|
||||
if (!strcmp(yesno, "yes")) {
|
||||
kore_log(LOG_ERR, "TLS not supported in this build");
|
||||
return (KORE_RESULT_ERROR);
|
||||
}
|
||||
|
||||
return (KORE_RESULT_OK);
|
||||
}
|
||||
|
||||
if (current_server == NULL) {
|
||||
kore_log(LOG_ERR, "bind keyword not inside a server context");
|
||||
kore_log(LOG_ERR, "tls keyword not inside a server context");
|
||||
return (KORE_RESULT_ERROR);
|
||||
}
|
||||
|
||||
@ -805,12 +806,14 @@ configure_file(char *file)
|
||||
static int
|
||||
configure_tls_version(char *version)
|
||||
{
|
||||
int ver;
|
||||
|
||||
if (!strcmp(version, "1.3")) {
|
||||
tls_version = KORE_TLS_VERSION_1_3;
|
||||
ver = KORE_TLS_VERSION_1_3;
|
||||
} else if (!strcmp(version, "1.2")) {
|
||||
tls_version = KORE_TLS_VERSION_1_2;
|
||||
ver = KORE_TLS_VERSION_1_2;
|
||||
} else if (!strcmp(version, "both")) {
|
||||
tls_version = KORE_TLS_VERSION_BOTH;
|
||||
ver = KORE_TLS_VERSION_BOTH;
|
||||
} else {
|
||||
kore_log(LOG_ERR,
|
||||
"unknown value for tls_version: %s (use 1.3, 1.2, both)",
|
||||
@ -818,45 +821,21 @@ configure_tls_version(char *version)
|
||||
return (KORE_RESULT_ERROR);
|
||||
}
|
||||
|
||||
kore_tls_version_set(ver);
|
||||
|
||||
return (KORE_RESULT_OK);
|
||||
}
|
||||
|
||||
static int
|
||||
configure_tls_cipher(char *cipherlist)
|
||||
{
|
||||
if (strcmp(kore_tls_cipher_list, KORE_DEFAULT_CIPHER_LIST)) {
|
||||
kore_log(LOG_ERR, "tls_cipher specified twice");
|
||||
return (KORE_RESULT_ERROR);
|
||||
}
|
||||
|
||||
kore_tls_cipher_list = kore_strdup(cipherlist);
|
||||
return (KORE_RESULT_OK);
|
||||
return (kore_tls_ciphersuite_set(cipherlist));
|
||||
}
|
||||
|
||||
static int
|
||||
configure_tls_dhparam(char *path)
|
||||
{
|
||||
BIO *bio;
|
||||
|
||||
if (tls_dhparam != NULL) {
|
||||
kore_log(LOG_ERR, "tls_dhparam specified twice");
|
||||
return (KORE_RESULT_ERROR);
|
||||
}
|
||||
|
||||
if ((bio = BIO_new_file(path, "r")) == NULL) {
|
||||
kore_log(LOG_ERR, "tls_dhparam file '%s' not accessible", path);
|
||||
return (KORE_RESULT_ERROR);
|
||||
}
|
||||
|
||||
tls_dhparam = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
|
||||
BIO_free(bio);
|
||||
|
||||
if (tls_dhparam == NULL) {
|
||||
kore_log(LOG_ERR, "PEM_read_bio_DHparams(): %s", ssl_errno_s);
|
||||
return (KORE_RESULT_ERROR);
|
||||
}
|
||||
|
||||
return (KORE_RESULT_OK);
|
||||
return (kore_tls_dh_load(path));
|
||||
}
|
||||
|
||||
static int
|
||||
@ -914,10 +893,10 @@ configure_client_verify(char *options)
|
||||
static int
|
||||
configure_rand_file(char *path)
|
||||
{
|
||||
if (rand_file != NULL)
|
||||
kore_free(rand_file);
|
||||
if (kore_rand_file != NULL)
|
||||
kore_free(kore_rand_file);
|
||||
|
||||
rand_file = kore_strdup(path);
|
||||
kore_rand_file = kore_strdup(path);
|
||||
|
||||
return (KORE_RESULT_OK);
|
||||
}
|
||||
|
@ -147,8 +147,8 @@ kore_connection_accept(struct listener *listener, struct connection **out)
|
||||
|
||||
if (listener->server->tls) {
|
||||
c->state = CONN_STATE_TLS_SHAKE;
|
||||
c->write = net_write_tls;
|
||||
c->read = net_read_tls;
|
||||
c->write = kore_tls_write;
|
||||
c->read = kore_tls_read;
|
||||
} else {
|
||||
c->state = CONN_STATE_ESTABLISHED;
|
||||
c->write = net_write;
|
||||
@ -250,7 +250,6 @@ kore_connection_event(void *arg, int error)
|
||||
int
|
||||
kore_connection_handle(struct connection *c)
|
||||
{
|
||||
int r;
|
||||
struct listener *listener;
|
||||
|
||||
kore_debug("kore_connection_handle(%p) -> %d", c, c->state);
|
||||
@ -258,75 +257,8 @@ kore_connection_handle(struct connection *c)
|
||||
|
||||
switch (c->state) {
|
||||
case CONN_STATE_TLS_SHAKE:
|
||||
if (primary_dom == NULL) {
|
||||
kore_log(LOG_NOTICE,
|
||||
"TLS handshake but no TLS configured on server");
|
||||
if (!kore_tls_connection_accept(c))
|
||||
return (KORE_RESULT_ERROR);
|
||||
}
|
||||
|
||||
if (primary_dom->ssl_ctx == NULL) {
|
||||
kore_log(LOG_NOTICE,
|
||||
"TLS configuration for %s not yet complete",
|
||||
primary_dom->domain);
|
||||
return (KORE_RESULT_ERROR);
|
||||
}
|
||||
|
||||
if (c->ssl == NULL) {
|
||||
c->ssl = SSL_new(primary_dom->ssl_ctx);
|
||||
if (c->ssl == NULL) {
|
||||
kore_debug("SSL_new(): %s", ssl_errno_s);
|
||||
return (KORE_RESULT_ERROR);
|
||||
}
|
||||
|
||||
SSL_set_fd(c->ssl, c->fd);
|
||||
SSL_set_accept_state(c->ssl);
|
||||
|
||||
if (!SSL_set_ex_data(c->ssl, 0, c)) {
|
||||
kore_debug("SSL_set_ex_data(): %s",
|
||||
ssl_errno_s);
|
||||
return (KORE_RESULT_ERROR);
|
||||
}
|
||||
|
||||
if (primary_dom->cafile != NULL)
|
||||
c->flags |= CONN_LOG_TLS_FAILURE;
|
||||
}
|
||||
|
||||
ERR_clear_error();
|
||||
r = SSL_accept(c->ssl);
|
||||
if (r <= 0) {
|
||||
r = SSL_get_error(c->ssl, r);
|
||||
switch (r) {
|
||||
case SSL_ERROR_WANT_READ:
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
kore_connection_start_idletimer(c);
|
||||
return (KORE_RESULT_OK);
|
||||
default:
|
||||
kore_debug("SSL_accept(): %s", ssl_errno_s);
|
||||
if (c->flags & CONN_LOG_TLS_FAILURE) {
|
||||
kore_log(LOG_NOTICE,
|
||||
"SSL_accept: %s", ssl_errno_s);
|
||||
}
|
||||
return (KORE_RESULT_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(KORE_USE_ACME)
|
||||
if (c->proto == CONN_PROTO_ACME_ALPN) {
|
||||
kore_log(LOG_INFO, "disconnecting acme client");
|
||||
kore_connection_disconnect(c);
|
||||
return (KORE_RESULT_OK);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (SSL_get_verify_mode(c->ssl) & SSL_VERIFY_PEER) {
|
||||
c->cert = SSL_get_peer_certificate(c->ssl);
|
||||
if (c->cert == NULL) {
|
||||
kore_log(LOG_NOTICE, "no peer certificate");
|
||||
return (KORE_RESULT_ERROR);
|
||||
}
|
||||
} else {
|
||||
c->cert = NULL;
|
||||
}
|
||||
|
||||
if (c->owner != NULL) {
|
||||
listener = (struct listener *)c->owner;
|
||||
@ -383,16 +315,7 @@ kore_connection_remove(struct connection *c)
|
||||
|
||||
kore_debug("kore_connection_remove(%p)", c);
|
||||
|
||||
if (c->ssl != NULL) {
|
||||
SSL_shutdown(c->ssl);
|
||||
SSL_free(c->ssl);
|
||||
}
|
||||
|
||||
if (c->cert != NULL)
|
||||
X509_free(c->cert);
|
||||
|
||||
if (c->tls_sni != NULL)
|
||||
kore_free(c->tls_sni);
|
||||
kore_tls_connection_cleanup(c);
|
||||
|
||||
close(c->fd);
|
||||
|
||||
|
590
src/domain.c
590
src/domain.c
@ -17,13 +17,6 @@
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/ecdsa.h>
|
||||
#include <poll.h>
|
||||
|
||||
#include <fnmatch.h>
|
||||
|
||||
#include "kore.h"
|
||||
@ -37,35 +30,9 @@
|
||||
#endif
|
||||
|
||||
#define KORE_DOMAIN_CACHE 16
|
||||
#define SSL_SESSION_ID "kore_ssl_sessionid"
|
||||
|
||||
struct kore_domain *primary_dom = NULL;
|
||||
|
||||
static u_int8_t keymgr_buf[2048];
|
||||
static size_t keymgr_buflen = 0;
|
||||
static int keymgr_response = 0;
|
||||
DH *tls_dhparam = NULL;
|
||||
int tls_version = KORE_TLS_VERSION_BOTH;
|
||||
|
||||
static int domain_x509_verify(int, X509_STORE_CTX *);
|
||||
static X509 *domain_load_certificate_chain(SSL_CTX *, const void *, size_t);
|
||||
|
||||
static void keymgr_init(void);
|
||||
static void keymgr_await_data(void);
|
||||
static void keymgr_msg_response(struct kore_msg *, const void *);
|
||||
|
||||
static int keymgr_rsa_init(RSA *);
|
||||
static int keymgr_rsa_finish(RSA *);
|
||||
static int keymgr_rsa_privenc(int, const unsigned char *,
|
||||
unsigned char *, RSA *, int);
|
||||
|
||||
static ECDSA_SIG *keymgr_ecdsa_sign(const unsigned char *, int,
|
||||
const BIGNUM *, const BIGNUM *, EC_KEY *);
|
||||
|
||||
static RSA_METHOD *keymgr_rsa_meth = NULL;
|
||||
static EC_KEY_METHOD *keymgr_ec_meth = NULL;
|
||||
|
||||
static u_int16_t domain_id = 0;
|
||||
struct kore_domain *primary_dom = NULL;
|
||||
static struct kore_domain *cached[KORE_DOMAIN_CACHE];
|
||||
|
||||
void
|
||||
@ -75,45 +42,11 @@ kore_domain_init(void)
|
||||
|
||||
for (i = 0; i < KORE_DOMAIN_CACHE; i++)
|
||||
cached[i] = NULL;
|
||||
|
||||
if (keymgr_rsa_meth == NULL) {
|
||||
if ((keymgr_rsa_meth = RSA_meth_new("kore RSA keymgr method",
|
||||
RSA_METHOD_FLAG_NO_CHECK)) == NULL)
|
||||
fatal("failed to allocate RSA method");
|
||||
}
|
||||
|
||||
RSA_meth_set_init(keymgr_rsa_meth, keymgr_rsa_init);
|
||||
RSA_meth_set_finish(keymgr_rsa_meth, keymgr_rsa_finish);
|
||||
RSA_meth_set_priv_enc(keymgr_rsa_meth, keymgr_rsa_privenc);
|
||||
|
||||
if (keymgr_ec_meth == NULL) {
|
||||
if ((keymgr_ec_meth = EC_KEY_METHOD_new(NULL)) == NULL)
|
||||
fatal("failed to allocate EC KEY method");
|
||||
}
|
||||
|
||||
EC_KEY_METHOD_set_sign(keymgr_ec_meth, NULL, NULL, keymgr_ecdsa_sign);
|
||||
|
||||
#if !defined(TLS1_3_VERSION)
|
||||
if (!kore_quiet) {
|
||||
kore_log(LOG_NOTICE,
|
||||
"%s has no TLS 1.3 - will only use TLS 1.2",
|
||||
OPENSSL_VERSION_TEXT);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
kore_domain_cleanup(void)
|
||||
{
|
||||
if (keymgr_rsa_meth != NULL) {
|
||||
RSA_meth_free(keymgr_rsa_meth);
|
||||
keymgr_rsa_meth = NULL;
|
||||
}
|
||||
|
||||
if (keymgr_ec_meth != NULL) {
|
||||
EC_KEY_METHOD_free(keymgr_ec_meth);
|
||||
keymgr_ec_meth = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
struct kore_domain *
|
||||
@ -125,9 +58,10 @@ kore_domain_new(const char *domain)
|
||||
|
||||
dom = kore_calloc(1, sizeof(*dom));
|
||||
dom->id = domain_id++;
|
||||
dom->accesslog = -1;
|
||||
|
||||
dom->accesslog = -1;
|
||||
dom->x509_verify_depth = 1;
|
||||
|
||||
dom->domain = kore_strdup(domain);
|
||||
|
||||
#if !defined(KORE_NO_HTTP)
|
||||
@ -188,8 +122,7 @@ kore_domain_free(struct kore_domain *dom)
|
||||
if (dom->domain != NULL)
|
||||
kore_free(dom->domain);
|
||||
|
||||
if (dom->ssl_ctx != NULL)
|
||||
SSL_CTX_free(dom->ssl_ctx);
|
||||
kore_tls_domain_cleanup(dom);
|
||||
|
||||
kore_free(dom->cafile);
|
||||
kore_free(dom->certkey);
|
||||
@ -213,216 +146,6 @@ kore_domain_free(struct kore_domain *dom)
|
||||
kore_free(dom);
|
||||
}
|
||||
|
||||
void
|
||||
kore_domain_tlsinit(struct kore_domain *dom, int type,
|
||||
const void *data, size_t datalen)
|
||||
{
|
||||
const u_int8_t *ptr;
|
||||
RSA *rsa;
|
||||
X509 *x509;
|
||||
EVP_PKEY *pkey;
|
||||
STACK_OF(X509_NAME) *certs;
|
||||
EC_KEY *eckey;
|
||||
const SSL_METHOD *method;
|
||||
|
||||
kore_debug("kore_domain_tlsinit(%s)", dom->domain);
|
||||
|
||||
if (dom->ssl_ctx != NULL)
|
||||
SSL_CTX_free(dom->ssl_ctx);
|
||||
|
||||
if ((method = TLS_method()) == NULL)
|
||||
fatalx("TLS_method(): %s", ssl_errno_s);
|
||||
|
||||
if ((dom->ssl_ctx = SSL_CTX_new(method)) == NULL)
|
||||
fatalx("SSL_ctx_new(): %s", ssl_errno_s);
|
||||
|
||||
if (!SSL_CTX_set_min_proto_version(dom->ssl_ctx, TLS1_2_VERSION))
|
||||
fatalx("SSL_CTX_set_min_proto_version: %s", ssl_errno_s);
|
||||
|
||||
#if defined(TLS1_3_VERSION)
|
||||
if (!SSL_CTX_set_max_proto_version(dom->ssl_ctx, TLS1_3_VERSION))
|
||||
fatalx("SSL_CTX_set_max_proto_version: %s", ssl_errno_s);
|
||||
#else
|
||||
if (!SSL_CTX_set_max_proto_version(dom->ssl_ctx, TLS1_2_VERSION))
|
||||
fatalx("SSL_CTX_set_min_proto_version: %s", ssl_errno_s);
|
||||
#endif
|
||||
|
||||
switch (tls_version) {
|
||||
case KORE_TLS_VERSION_1_3:
|
||||
#if defined(TLS1_3_VERSION)
|
||||
if (!SSL_CTX_set_min_proto_version(dom->ssl_ctx,
|
||||
TLS1_3_VERSION)) {
|
||||
fatalx("SSL_CTX_set_min_proto_version: %s",
|
||||
ssl_errno_s);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case KORE_TLS_VERSION_1_2:
|
||||
if (!SSL_CTX_set_max_proto_version(dom->ssl_ctx,
|
||||
TLS1_2_VERSION)) {
|
||||
fatalx("SSL_CTX_set_min_proto_version: %s",
|
||||
ssl_errno_s);
|
||||
}
|
||||
break;
|
||||
case KORE_TLS_VERSION_BOTH:
|
||||
break;
|
||||
default:
|
||||
fatalx("unknown tls_version: %d", tls_version);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case KORE_PEM_CERT_CHAIN:
|
||||
x509 = domain_load_certificate_chain(dom->ssl_ctx,
|
||||
data, datalen);
|
||||
break;
|
||||
case KORE_DER_CERT_DATA:
|
||||
ptr = data;
|
||||
if ((x509 = d2i_X509(NULL, &ptr, datalen)) == NULL)
|
||||
fatalx("d2i_X509: %s", ssl_errno_s);
|
||||
if (SSL_CTX_use_certificate(dom->ssl_ctx, x509) == 0)
|
||||
fatalx("SSL_CTX_use_certificate: %s", ssl_errno_s);
|
||||
break;
|
||||
default:
|
||||
fatalx("%s: unknown type %d", __func__, type);
|
||||
}
|
||||
|
||||
if (x509 == NULL) {
|
||||
kore_log(LOG_NOTICE, "failed to load certificate for '%s': %s",
|
||||
dom->domain, ssl_errno_s);
|
||||
SSL_CTX_free(dom->ssl_ctx);
|
||||
dom->ssl_ctx = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((pkey = X509_get_pubkey(x509)) == NULL)
|
||||
fatalx("certificate has no public key");
|
||||
|
||||
switch (EVP_PKEY_id(pkey)) {
|
||||
case EVP_PKEY_RSA:
|
||||
if ((rsa = EVP_PKEY_get1_RSA(pkey)) == NULL)
|
||||
fatalx("no RSA public key present");
|
||||
RSA_set_app_data(rsa, dom);
|
||||
RSA_set_method(rsa, keymgr_rsa_meth);
|
||||
break;
|
||||
case EVP_PKEY_EC:
|
||||
if ((eckey = EVP_PKEY_get1_EC_KEY(pkey)) == NULL)
|
||||
fatalx("no EC public key present");
|
||||
EC_KEY_set_ex_data(eckey, 0, dom);
|
||||
EC_KEY_set_method(eckey, keymgr_ec_meth);
|
||||
break;
|
||||
default:
|
||||
fatalx("unknown public key in certificate");
|
||||
}
|
||||
|
||||
if (!SSL_CTX_use_PrivateKey(dom->ssl_ctx, pkey))
|
||||
fatalx("SSL_CTX_use_PrivateKey(): %s", ssl_errno_s);
|
||||
|
||||
if (!SSL_CTX_check_private_key(dom->ssl_ctx)) {
|
||||
fatalx("Public/Private key for %s do not match (%s)",
|
||||
dom->domain, ssl_errno_s);
|
||||
}
|
||||
|
||||
if (tls_dhparam == NULL)
|
||||
fatal("no DH parameters specified");
|
||||
|
||||
SSL_CTX_set_tmp_dh(dom->ssl_ctx, tls_dhparam);
|
||||
SSL_CTX_set_options(dom->ssl_ctx, SSL_OP_SINGLE_DH_USE);
|
||||
|
||||
if (!SSL_CTX_set_ecdh_auto(dom->ssl_ctx, 1))
|
||||
fatalx("SSL_CTX_set_ecdh_auto: %s", ssl_errno_s);
|
||||
|
||||
SSL_CTX_set_options(dom->ssl_ctx, SSL_OP_SINGLE_ECDH_USE);
|
||||
SSL_CTX_set_options(dom->ssl_ctx, SSL_OP_NO_COMPRESSION);
|
||||
|
||||
if (dom->cafile != NULL) {
|
||||
if ((certs = SSL_load_client_CA_file(dom->cafile)) == NULL) {
|
||||
fatalx("SSL_load_client_CA_file(%s): %s",
|
||||
dom->cafile, ssl_errno_s);
|
||||
}
|
||||
|
||||
SSL_CTX_load_verify_locations(dom->ssl_ctx, dom->cafile, NULL);
|
||||
SSL_CTX_set_verify_depth(dom->ssl_ctx, dom->x509_verify_depth);
|
||||
SSL_CTX_set_client_CA_list(dom->ssl_ctx, certs);
|
||||
SSL_CTX_set_verify(dom->ssl_ctx, SSL_VERIFY_PEER |
|
||||
SSL_VERIFY_FAIL_IF_NO_PEER_CERT, domain_x509_verify);
|
||||
}
|
||||
|
||||
SSL_CTX_set_session_id_context(dom->ssl_ctx,
|
||||
(unsigned char *)SSL_SESSION_ID, strlen(SSL_SESSION_ID));
|
||||
SSL_CTX_set_mode(dom->ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
|
||||
|
||||
if (tls_version == KORE_TLS_VERSION_BOTH) {
|
||||
SSL_CTX_set_options(dom->ssl_ctx, SSL_OP_NO_SSLv2);
|
||||
SSL_CTX_set_options(dom->ssl_ctx, SSL_OP_NO_SSLv3);
|
||||
SSL_CTX_set_options(dom->ssl_ctx, SSL_OP_NO_TLSv1);
|
||||
SSL_CTX_set_options(dom->ssl_ctx, SSL_OP_NO_TLSv1_1);
|
||||
}
|
||||
|
||||
SSL_CTX_set_options(dom->ssl_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
|
||||
SSL_CTX_set_cipher_list(dom->ssl_ctx, kore_tls_cipher_list);
|
||||
|
||||
SSL_CTX_set_info_callback(dom->ssl_ctx, kore_tls_info_callback);
|
||||
SSL_CTX_set_tlsext_servername_callback(dom->ssl_ctx, kore_tls_sni_cb);
|
||||
|
||||
#if defined(KORE_USE_ACME)
|
||||
SSL_CTX_set_alpn_select_cb(dom->ssl_ctx, kore_acme_tls_alpn, dom);
|
||||
#endif
|
||||
|
||||
X509_free(x509);
|
||||
}
|
||||
|
||||
void
|
||||
kore_domain_crl_add(struct kore_domain *dom, const void *pem, size_t pemlen)
|
||||
{
|
||||
int err;
|
||||
BIO *in;
|
||||
X509_CRL *crl;
|
||||
X509_STORE *store;
|
||||
|
||||
ERR_clear_error();
|
||||
in = BIO_new_mem_buf(pem, pemlen);
|
||||
|
||||
if ((store = SSL_CTX_get_cert_store(dom->ssl_ctx)) == NULL) {
|
||||
BIO_free(in);
|
||||
kore_log(LOG_ERR, "SSL_CTX_get_cert_store(): %s", ssl_errno_s);
|
||||
return;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
crl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
|
||||
if (crl == NULL) {
|
||||
err = ERR_GET_REASON(ERR_peek_last_error());
|
||||
if (err == PEM_R_NO_START_LINE) {
|
||||
ERR_clear_error();
|
||||
break;
|
||||
}
|
||||
|
||||
kore_log(LOG_WARNING, "failed to read CRL %s: %s",
|
||||
dom->crlfile, ssl_errno_s);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!X509_STORE_add_crl(store, crl)) {
|
||||
err = ERR_GET_REASON(ERR_peek_last_error());
|
||||
if (err == X509_R_CERT_ALREADY_IN_HASH_TABLE) {
|
||||
X509_CRL_free(crl);
|
||||
continue;
|
||||
}
|
||||
|
||||
kore_log(LOG_WARNING, "failed to add CRL %s: %s",
|
||||
dom->crlfile, ssl_errno_s);
|
||||
X509_CRL_free(crl);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
BIO_free(in);
|
||||
|
||||
X509_STORE_set_flags(store,
|
||||
X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
|
||||
}
|
||||
|
||||
void
|
||||
kore_domain_callback(void (*cb)(struct kore_domain *))
|
||||
{
|
||||
@ -495,308 +218,3 @@ kore_domain_closelogs(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
kore_domain_keymgr_init(void)
|
||||
{
|
||||
keymgr_init();
|
||||
kore_msg_register(KORE_MSG_KEYMGR_RESP, keymgr_msg_response);
|
||||
}
|
||||
|
||||
static void
|
||||
keymgr_init(void)
|
||||
{
|
||||
const RSA_METHOD *meth;
|
||||
|
||||
if ((meth = RSA_get_default_method()) == NULL)
|
||||
fatal("failed to obtain RSA method");
|
||||
|
||||
RSA_meth_set_pub_enc(keymgr_rsa_meth, RSA_meth_get_pub_enc(meth));
|
||||
RSA_meth_set_pub_dec(keymgr_rsa_meth, RSA_meth_get_pub_dec(meth));
|
||||
RSA_meth_set_bn_mod_exp(keymgr_rsa_meth, RSA_meth_get_bn_mod_exp(meth));
|
||||
}
|
||||
|
||||
static int
|
||||
keymgr_rsa_init(RSA *rsa)
|
||||
{
|
||||
if (rsa != NULL) {
|
||||
RSA_set_flags(rsa, RSA_flags(rsa) |
|
||||
RSA_FLAG_EXT_PKEY | RSA_METHOD_FLAG_NO_CHECK);
|
||||
return (1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
keymgr_rsa_privenc(int flen, const unsigned char *from, unsigned char *to,
|
||||
RSA *rsa, int padding)
|
||||
{
|
||||
int ret;
|
||||
size_t len;
|
||||
struct kore_keyreq *req;
|
||||
struct kore_domain *dom;
|
||||
|
||||
len = sizeof(*req) + flen;
|
||||
if (len > sizeof(keymgr_buf))
|
||||
fatal("keymgr_buf too small");
|
||||
|
||||
if ((dom = RSA_get_app_data(rsa)) == NULL)
|
||||
fatal("RSA key has no domain attached");
|
||||
|
||||
memset(keymgr_buf, 0, sizeof(keymgr_buf));
|
||||
|
||||
req = (struct kore_keyreq *)keymgr_buf;
|
||||
|
||||
if (kore_strlcpy(req->domain, dom->domain, sizeof(req->domain)) >=
|
||||
sizeof(req->domain))
|
||||
fatal("%s: domain truncated", __func__);
|
||||
|
||||
req->data_len = flen;
|
||||
req->padding = padding;
|
||||
memcpy(&req->data[0], from, req->data_len);
|
||||
|
||||
kore_msg_send(KORE_WORKER_KEYMGR, KORE_MSG_KEYMGR_REQ, keymgr_buf, len);
|
||||
keymgr_await_data();
|
||||
|
||||
ret = -1;
|
||||
if (keymgr_response) {
|
||||
if (keymgr_buflen < INT_MAX &&
|
||||
(int)keymgr_buflen == RSA_size(rsa)) {
|
||||
ret = RSA_size(rsa);
|
||||
memcpy(to, keymgr_buf, RSA_size(rsa));
|
||||
}
|
||||
}
|
||||
|
||||
keymgr_buflen = 0;
|
||||
keymgr_response = 0;
|
||||
kore_platform_event_all(worker->msg[1]->fd, worker->msg[1]);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
keymgr_rsa_finish(RSA *rsa)
|
||||
{
|
||||
return (1);
|
||||
}
|
||||
|
||||
static ECDSA_SIG *
|
||||
keymgr_ecdsa_sign(const unsigned char *dgst, int dgst_len,
|
||||
const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey)
|
||||
{
|
||||
size_t len;
|
||||
ECDSA_SIG *sig;
|
||||
const u_int8_t *ptr;
|
||||
struct kore_domain *dom;
|
||||
struct kore_keyreq *req;
|
||||
|
||||
if (in_kinv != NULL || in_r != NULL)
|
||||
return (NULL);
|
||||
|
||||
len = sizeof(*req) + dgst_len;
|
||||
if (len > sizeof(keymgr_buf))
|
||||
fatal("keymgr_buf too small");
|
||||
|
||||
if ((dom = EC_KEY_get_ex_data(eckey, 0)) == NULL)
|
||||
fatal("EC_KEY has no domain");
|
||||
|
||||
memset(keymgr_buf, 0, sizeof(keymgr_buf));
|
||||
req = (struct kore_keyreq *)keymgr_buf;
|
||||
|
||||
if (kore_strlcpy(req->domain, dom->domain, sizeof(req->domain)) >=
|
||||
sizeof(req->domain))
|
||||
fatal("%s: domain truncated", __func__);
|
||||
|
||||
req->data_len = dgst_len;
|
||||
memcpy(&req->data[0], dgst, req->data_len);
|
||||
|
||||
kore_msg_send(KORE_WORKER_KEYMGR, KORE_MSG_KEYMGR_REQ, keymgr_buf, len);
|
||||
keymgr_await_data();
|
||||
|
||||
if (keymgr_response) {
|
||||
ptr = keymgr_buf;
|
||||
sig = d2i_ECDSA_SIG(NULL, &ptr, keymgr_buflen);
|
||||
} else {
|
||||
sig = NULL;
|
||||
}
|
||||
|
||||
keymgr_buflen = 0;
|
||||
keymgr_response = 0;
|
||||
kore_platform_event_all(worker->msg[1]->fd, worker->msg[1]);
|
||||
|
||||
return (sig);
|
||||
}
|
||||
|
||||
static void
|
||||
keymgr_await_data(void)
|
||||
{
|
||||
int ret;
|
||||
struct pollfd pfd[1];
|
||||
u_int64_t start, cur;
|
||||
#if !defined(KORE_NO_HTTP)
|
||||
int process_requests;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We need to wait until the keymgr responds to us, so keep doing
|
||||
* net_recv_flush() until our callback for KORE_MSG_KEYMGR_RESP
|
||||
* tells us that we have obtained the response.
|
||||
*
|
||||
* This means other internal messages can still be delivered by
|
||||
* this worker process to the appropriate callbacks but we do not
|
||||
* drop out until we've either received an answer from the keymgr
|
||||
* or until the timeout has been reached (1 second currently).
|
||||
*
|
||||
* If we end up waiting for the keymgr process we will call
|
||||
* http_process (if not built with NOHTTP=1) to further existing
|
||||
* requests so those do not block too much.
|
||||
*
|
||||
* This means that all incoming data will stop being processed
|
||||
* while existing requests will get processed until we return
|
||||
* from this call.
|
||||
*/
|
||||
start = kore_time_ms();
|
||||
kore_platform_disable_read(worker->msg[1]->fd);
|
||||
|
||||
keymgr_response = 0;
|
||||
memset(keymgr_buf, 0, sizeof(keymgr_buf));
|
||||
|
||||
#if !defined(KORE_NO_HTTP)
|
||||
process_requests = 0;
|
||||
#endif
|
||||
|
||||
for (;;) {
|
||||
#if !defined(KORE_NO_HTTP)
|
||||
if (process_requests) {
|
||||
http_process();
|
||||
process_requests = 0;
|
||||
}
|
||||
#endif
|
||||
pfd[0].fd = worker->msg[1]->fd;
|
||||
pfd[0].events = POLLIN;
|
||||
pfd[0].revents = 0;
|
||||
|
||||
ret = poll(pfd, 1, 100);
|
||||
if (ret == -1) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
fatal("poll: %s", errno_s);
|
||||
}
|
||||
|
||||
cur = kore_time_ms();
|
||||
if ((cur - start) > 1000)
|
||||
break;
|
||||
|
||||
if (ret == 0) {
|
||||
#if !defined(KORE_NO_HTTP)
|
||||
/* No activity on channel, process HTTP requests. */
|
||||
process_requests = 1;
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pfd[0].revents & (POLLERR | POLLHUP))
|
||||
break;
|
||||
if (!(pfd[0].revents & POLLIN))
|
||||
break;
|
||||
|
||||
worker->msg[1]->evt.flags |= KORE_EVENT_READ;
|
||||
if (!net_recv_flush(worker->msg[1]))
|
||||
break;
|
||||
|
||||
if (keymgr_response)
|
||||
break;
|
||||
|
||||
#if !defined(KORE_NO_HTTP)
|
||||
/* If we've spent 100ms already, process HTTP requests. */
|
||||
if ((cur - start) > 100) {
|
||||
process_requests = 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
keymgr_msg_response(struct kore_msg *msg, const void *data)
|
||||
{
|
||||
keymgr_response = 1;
|
||||
keymgr_buflen = msg->length;
|
||||
|
||||
if (keymgr_buflen > sizeof(keymgr_buf))
|
||||
return;
|
||||
|
||||
memcpy(keymgr_buf, data, keymgr_buflen);
|
||||
}
|
||||
|
||||
static int
|
||||
domain_x509_verify(int ok, X509_STORE_CTX *ctx)
|
||||
{
|
||||
X509 *cert;
|
||||
const char *text;
|
||||
int error, depth;
|
||||
|
||||
error = X509_STORE_CTX_get_error(ctx);
|
||||
cert = X509_STORE_CTX_get_current_cert(ctx);
|
||||
|
||||
if (ok == 0 && cert != NULL) {
|
||||
text = X509_verify_cert_error_string(error);
|
||||
depth = X509_STORE_CTX_get_error_depth(ctx);
|
||||
|
||||
kore_log(LOG_WARNING, "X509 verification error depth:%d - %s",
|
||||
depth, text);
|
||||
|
||||
/* Continue on CRL validity errors. */
|
||||
switch (error) {
|
||||
case X509_V_ERR_CRL_HAS_EXPIRED:
|
||||
case X509_V_ERR_CRL_NOT_YET_VALID:
|
||||
case X509_V_ERR_UNABLE_TO_GET_CRL:
|
||||
ok = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (ok);
|
||||
}
|
||||
|
||||
/*
|
||||
* What follows is basically a reimplementation of
|
||||
* SSL_CTX_use_certificate_chain_file() from OpenSSL but with our
|
||||
* BIO set to the pem data that we received.
|
||||
*/
|
||||
static X509 *
|
||||
domain_load_certificate_chain(SSL_CTX *ctx, const void *data, size_t len)
|
||||
{
|
||||
unsigned long err;
|
||||
BIO *in;
|
||||
X509 *x, *ca;
|
||||
|
||||
ERR_clear_error();
|
||||
in = BIO_new_mem_buf(data, len);
|
||||
|
||||
if ((x = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL)) == NULL)
|
||||
return (NULL);
|
||||
|
||||
/* refcount for x509 will go up one. */
|
||||
if (SSL_CTX_use_certificate(ctx, x) == 0)
|
||||
return (NULL);
|
||||
|
||||
SSL_CTX_clear_chain_certs(ctx);
|
||||
|
||||
ERR_clear_error();
|
||||
while ((ca = PEM_read_bio_X509(in, NULL, NULL, NULL)) != NULL) {
|
||||
/* ca its reference count won't be increased. */
|
||||
if (SSL_CTX_add0_chain_cert(ctx, ca) == 0)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
err = ERR_peek_last_error();
|
||||
|
||||
if (ERR_GET_LIB(err) != ERR_LIB_PEM ||
|
||||
ERR_GET_REASON(err) != PEM_R_NO_START_LINE)
|
||||
return (NULL);
|
||||
|
||||
BIO_free(in);
|
||||
|
||||
return (x);
|
||||
}
|
||||
|
@ -976,7 +976,7 @@ http_header_recv(struct netbuf *nb)
|
||||
req->http_body = kore_buf_alloc(req->content_length);
|
||||
}
|
||||
|
||||
SHA256_Init(&req->hashctx);
|
||||
SHA256Init(&req->hashctx);
|
||||
c->http_timeout = http_body_timeout * 1000;
|
||||
|
||||
if (!http_body_update(req, end_headers, nb->s_off - len)) {
|
||||
@ -2349,7 +2349,7 @@ http_body_update(struct http_request *req, const void *data, size_t len)
|
||||
ssize_t ret;
|
||||
u_int64_t bytes_left;
|
||||
|
||||
SHA256_Update(&req->hashctx, data, len);
|
||||
SHA256Update(&req->hashctx, data, len);
|
||||
|
||||
if (req->http_body_fd != -1) {
|
||||
ret = write(req->http_body_fd, data, len);
|
||||
@ -2382,7 +2382,7 @@ http_body_update(struct http_request *req, const void *data, size_t len)
|
||||
HTTP_STATUS_INTERNAL_ERROR);
|
||||
return (KORE_RESULT_ERROR);
|
||||
}
|
||||
SHA256_Final(req->http_body_digest, &req->hashctx);
|
||||
SHA256Final(req->http_body_digest, &req->hashctx);
|
||||
} else {
|
||||
bytes_left = req->content_length;
|
||||
net_recv_reset(req->owner,
|
||||
|
@ -40,9 +40,11 @@
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/x509v3.h>
|
||||
@ -166,7 +168,7 @@ struct key {
|
||||
TAILQ_ENTRY(key) list;
|
||||
};
|
||||
|
||||
char *rand_file = NULL;
|
||||
char *kore_rand_file = NULL;
|
||||
|
||||
static TAILQ_HEAD(, key) keys;
|
||||
static int initialized = 0;
|
||||
@ -251,9 +253,6 @@ static void keymgr_rsa_encrypt(struct kore_msg *, const void *,
|
||||
static void keymgr_ecdsa_sign(struct kore_msg *, const void *,
|
||||
struct key *);
|
||||
|
||||
struct kore_privsep keymgr_privsep;
|
||||
int keymgr_active = 0;
|
||||
|
||||
#if defined(__OpenBSD__)
|
||||
#if defined(KORE_USE_ACME)
|
||||
static const char *keymgr_pledges = "stdio rpath wpath cpath";
|
||||
@ -268,8 +267,8 @@ kore_keymgr_run(void)
|
||||
int quit;
|
||||
u_int64_t now, netwait, last_seed;
|
||||
|
||||
if (keymgr_active == 0)
|
||||
fatalx("%s: called with keymgr_active == 0", __func__);
|
||||
if (kore_keymgr_active == 0)
|
||||
fatalx("%s: called with kore_keymgr_active == 0", __func__);
|
||||
|
||||
quit = 0;
|
||||
|
||||
@ -297,7 +296,7 @@ kore_keymgr_run(void)
|
||||
#endif
|
||||
kore_worker_privsep();
|
||||
|
||||
if (rand_file != NULL) {
|
||||
if (kore_rand_file != NULL) {
|
||||
keymgr_load_randfile();
|
||||
keymgr_save_randfile();
|
||||
} else if (!kore_quiet) {
|
||||
@ -463,30 +462,30 @@ keymgr_load_randfile(void)
|
||||
size_t total;
|
||||
u_int8_t buf[RAND_FILE_SIZE];
|
||||
|
||||
if (rand_file == NULL)
|
||||
if (kore_rand_file == NULL)
|
||||
return;
|
||||
|
||||
if ((fd = open(rand_file, O_RDONLY)) == -1)
|
||||
fatalx("open(%s): %s", rand_file, errno_s);
|
||||
if ((fd = open(kore_rand_file, O_RDONLY)) == -1)
|
||||
fatalx("open(%s): %s", kore_rand_file, errno_s);
|
||||
|
||||
if (fstat(fd, &st) == -1)
|
||||
fatalx("stat(%s): %s", rand_file, errno_s);
|
||||
fatalx("stat(%s): %s", kore_rand_file, errno_s);
|
||||
if (!S_ISREG(st.st_mode))
|
||||
fatalx("%s is not a file", rand_file);
|
||||
fatalx("%s is not a file", kore_rand_file);
|
||||
if (st.st_size != RAND_FILE_SIZE)
|
||||
fatalx("%s has an invalid size", rand_file);
|
||||
fatalx("%s has an invalid size", kore_rand_file);
|
||||
|
||||
total = 0;
|
||||
|
||||
while (total != RAND_FILE_SIZE) {
|
||||
ret = read(fd, buf, sizeof(buf));
|
||||
if (ret == 0)
|
||||
fatalx("EOF on %s", rand_file);
|
||||
fatalx("EOF on %s", kore_rand_file);
|
||||
|
||||
if (ret == -1) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
fatalx("read(%s): %s", rand_file, errno_s);
|
||||
fatalx("read(%s): %s", kore_rand_file, errno_s);
|
||||
}
|
||||
|
||||
total += (size_t)ret;
|
||||
@ -495,9 +494,9 @@ keymgr_load_randfile(void)
|
||||
}
|
||||
|
||||
(void)close(fd);
|
||||
if (unlink(rand_file) == -1) {
|
||||
if (unlink(kore_rand_file) == -1) {
|
||||
kore_log(LOG_WARNING, "failed to unlink %s: %s",
|
||||
rand_file, errno_s);
|
||||
kore_rand_file, errno_s);
|
||||
}
|
||||
}
|
||||
|
||||
@ -509,7 +508,7 @@ keymgr_save_randfile(void)
|
||||
ssize_t ret;
|
||||
u_int8_t buf[RAND_FILE_SIZE];
|
||||
|
||||
if (rand_file == NULL)
|
||||
if (kore_rand_file == NULL)
|
||||
return;
|
||||
|
||||
if (stat(RAND_TMP_FILE, &st) != -1) {
|
||||
@ -541,10 +540,10 @@ keymgr_save_randfile(void)
|
||||
if (close(fd) == -1)
|
||||
kore_log(LOG_WARNING, "close(%s): %s", RAND_TMP_FILE, errno_s);
|
||||
|
||||
if (rename(RAND_TMP_FILE, rand_file) == -1) {
|
||||
if (rename(RAND_TMP_FILE, kore_rand_file) == -1) {
|
||||
kore_log(LOG_WARNING, "rename(%s, %s): %s",
|
||||
RAND_TMP_FILE, rand_file, errno_s);
|
||||
(void)unlink(rand_file);
|
||||
RAND_TMP_FILE, kore_rand_file, errno_s);
|
||||
(void)unlink(kore_rand_file);
|
||||
(void)unlink(RAND_TMP_FILE);
|
||||
}
|
||||
|
||||
@ -589,7 +588,7 @@ keymgr_load_privatekey(const char *path)
|
||||
|
||||
/* Caller should check if pkey was loaded. */
|
||||
if (path)
|
||||
key->pkey = kore_rsakey_load(path);
|
||||
key->pkey = kore_tls_rsakey_load(path);
|
||||
|
||||
return (key);
|
||||
}
|
||||
@ -787,7 +786,7 @@ keymgr_acme_init(void)
|
||||
|
||||
if (key->pkey == NULL) {
|
||||
kore_log(LOG_INFO, "generating new ACME account key");
|
||||
key->pkey = kore_rsakey_generate(KORE_ACME_ACCOUNT_KEY);
|
||||
key->pkey = kore_tls_rsakey_generate(KORE_ACME_ACCOUNT_KEY);
|
||||
needsreg = 1;
|
||||
} else {
|
||||
kore_log(LOG_INFO, "loaded existing ACME account key");
|
||||
@ -839,7 +838,7 @@ keymgr_acme_domainkey(struct kore_domain *dom, struct key *key)
|
||||
}
|
||||
|
||||
*p = '/';
|
||||
key->pkey = kore_rsakey_generate(dom->certkey);
|
||||
key->pkey = kore_tls_rsakey_generate(dom->certkey);
|
||||
}
|
||||
|
||||
static void
|
92
src/kore.c
92
src/kore.c
@ -67,7 +67,6 @@ int kore_foreground = 0;
|
||||
char *kore_progname = NULL;
|
||||
u_int32_t kore_socket_backlog = 5000;
|
||||
char *kore_pidfile = KORE_PIDFILE_DEFAULT;
|
||||
char *kore_tls_cipher_list = KORE_DEFAULT_CIPHER_LIST;
|
||||
|
||||
struct kore_privsep worker_privsep;
|
||||
|
||||
@ -80,7 +79,6 @@ static void version(void);
|
||||
|
||||
static void kore_write_kore_pid(void);
|
||||
static void kore_proctitle_setup(void);
|
||||
static void kore_server_sslstart(void);
|
||||
static void kore_server_shutdown(void);
|
||||
static void kore_server_start(int, char *[]);
|
||||
static void kore_call_parent_configure(int, char **);
|
||||
@ -150,6 +148,8 @@ version(void)
|
||||
#if defined(KORE_USE_ACME)
|
||||
printf("acme ");
|
||||
#endif
|
||||
if (!kore_tls_supported())
|
||||
printf("notls ");
|
||||
printf("\n");
|
||||
exit(0);
|
||||
}
|
||||
@ -223,7 +223,7 @@ main(int argc, char *argv[])
|
||||
#endif
|
||||
kore_domain_init();
|
||||
kore_module_init();
|
||||
kore_server_sslstart();
|
||||
kore_tls_init();
|
||||
|
||||
#if !defined(KORE_SINGLE_BINARY) && !defined(KORE_USE_PYTHON)
|
||||
if (config_file == NULL)
|
||||
@ -345,74 +345,6 @@ kore_default_getopt(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
kore_tls_sni_cb(SSL *ssl, int *ad, void *arg)
|
||||
{
|
||||
struct connection *c;
|
||||
struct kore_domain *dom;
|
||||
const char *sname;
|
||||
|
||||
if ((c = SSL_get_ex_data(ssl, 0)) == NULL)
|
||||
fatal("no connection data in %s", __func__);
|
||||
|
||||
sname = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
|
||||
kore_debug("kore_tls_sni_cb(): received host %s", sname);
|
||||
|
||||
if (sname != NULL)
|
||||
c->tls_sni = kore_strdup(sname);
|
||||
|
||||
if (sname != NULL &&
|
||||
(dom = kore_domain_lookup(c->owner->server, sname)) != NULL) {
|
||||
if (dom->ssl_ctx == NULL) {
|
||||
kore_log(LOG_NOTICE,
|
||||
"TLS configuration for %s not complete",
|
||||
dom->domain);
|
||||
return (SSL_TLSEXT_ERR_NOACK);
|
||||
}
|
||||
|
||||
kore_debug("kore_ssl_sni_cb(): Using %s CTX", sname);
|
||||
SSL_set_SSL_CTX(ssl, dom->ssl_ctx);
|
||||
|
||||
if (dom->cafile != NULL) {
|
||||
SSL_set_verify(ssl, SSL_VERIFY_PEER |
|
||||
SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
|
||||
c->flags |= CONN_LOG_TLS_FAILURE;
|
||||
} else {
|
||||
SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL);
|
||||
}
|
||||
|
||||
#if defined(KORE_USE_ACME)
|
||||
/*
|
||||
* If ALPN callback was called before SNI was parsed we
|
||||
* must make sure we swap to the correct certificate now.
|
||||
*/
|
||||
if (c->flags & CONN_TLS_ALPN_ACME_SEEN)
|
||||
kore_acme_tls_challenge_use_cert(ssl, dom);
|
||||
|
||||
c->flags |= CONN_TLS_SNI_SEEN;
|
||||
#endif
|
||||
return (SSL_TLSEXT_ERR_OK);
|
||||
}
|
||||
|
||||
return (SSL_TLSEXT_ERR_NOACK);
|
||||
}
|
||||
|
||||
void
|
||||
kore_tls_info_callback(const SSL *ssl, int flags, int ret)
|
||||
{
|
||||
struct connection *c;
|
||||
|
||||
if (flags & SSL_CB_HANDSHAKE_START) {
|
||||
if ((c = SSL_get_app_data(ssl)) == NULL)
|
||||
fatal("no SSL_get_app_data");
|
||||
|
||||
#if defined(TLS1_3_VERSION)
|
||||
if (SSL_version(ssl) != TLS1_3_VERSION)
|
||||
#endif
|
||||
c->tls_reneg++;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
kore_server_bind(struct kore_server *srv, const char *ip, const char *port,
|
||||
const char *ccb)
|
||||
@ -523,7 +455,11 @@ kore_server_create(const char *name)
|
||||
|
||||
srv = kore_calloc(1, sizeof(struct kore_server));
|
||||
srv->name = kore_strdup(name);
|
||||
|
||||
if (kore_tls_supported())
|
||||
srv->tls = 1;
|
||||
else
|
||||
srv->tls = 0;
|
||||
|
||||
TAILQ_INIT(&srv->domains);
|
||||
LIST_INIT(&srv->listeners);
|
||||
@ -843,13 +779,6 @@ kore_proctitle_setup(void)
|
||||
proctitle_maxlen += strlen(kore_argv[i]) + 1;
|
||||
}
|
||||
|
||||
static void
|
||||
kore_server_sslstart(void)
|
||||
{
|
||||
SSL_library_init();
|
||||
SSL_load_error_strings();
|
||||
}
|
||||
|
||||
static void
|
||||
kore_server_start(int argc, char *argv[])
|
||||
{
|
||||
@ -922,12 +851,16 @@ kore_server_start(int argc, char *argv[])
|
||||
#endif
|
||||
|
||||
/* Check if keymgr will be active. */
|
||||
if (kore_tls_supported()) {
|
||||
LIST_FOREACH(srv, &kore_servers, list) {
|
||||
if (srv->tls) {
|
||||
keymgr_active = 1;
|
||||
kore_keymgr_active = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
kore_keymgr_active = 0;
|
||||
}
|
||||
|
||||
kore_platform_proctitle("[parent]");
|
||||
|
||||
@ -1033,6 +966,7 @@ kore_server_shutdown(void)
|
||||
kore_platform_event_cleanup();
|
||||
kore_connection_cleanup();
|
||||
kore_domain_cleanup();
|
||||
kore_tls_cleanup();
|
||||
net_cleanup();
|
||||
}
|
||||
|
||||
|
@ -237,7 +237,7 @@ msg_recv_data(struct netbuf *nb)
|
||||
dst = *(u_int16_t *)c->hdlr_extra;
|
||||
|
||||
if (destination == KORE_MSG_WORKER_ALL) {
|
||||
if (keymgr_active && dst == 0)
|
||||
if (kore_keymgr_active && dst == 0)
|
||||
deliver = 0;
|
||||
} else {
|
||||
if (dst != destination)
|
||||
|
98
src/net.c
98
src/net.c
@ -340,104 +340,6 @@ net_remove_netbuf(struct connection *c, struct netbuf *nb)
|
||||
kore_pool_put(&nb_pool, nb);
|
||||
}
|
||||
|
||||
int
|
||||
net_write_tls(struct connection *c, size_t len, size_t *written)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (len > INT_MAX)
|
||||
return (KORE_RESULT_ERROR);
|
||||
|
||||
ERR_clear_error();
|
||||
r = SSL_write(c->ssl, (c->snb->buf + c->snb->s_off), len);
|
||||
if (c->tls_reneg > 1)
|
||||
return (KORE_RESULT_ERROR);
|
||||
|
||||
if (r <= 0) {
|
||||
r = SSL_get_error(c->ssl, r);
|
||||
switch (r) {
|
||||
case SSL_ERROR_WANT_READ:
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
c->evt.flags &= ~KORE_EVENT_WRITE;
|
||||
c->snb->flags |= NETBUF_MUST_RESEND;
|
||||
return (KORE_RESULT_OK);
|
||||
case SSL_ERROR_SYSCALL:
|
||||
switch (errno) {
|
||||
case EINTR:
|
||||
*written = 0;
|
||||
return (KORE_RESULT_OK);
|
||||
case EAGAIN:
|
||||
c->evt.flags &= ~KORE_EVENT_WRITE;
|
||||
c->snb->flags |= NETBUF_MUST_RESEND;
|
||||
return (KORE_RESULT_OK);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
kore_debug("SSL_write(): %s", ssl_errno_s);
|
||||
if (c->flags & CONN_LOG_TLS_FAILURE) {
|
||||
kore_log(LOG_NOTICE,
|
||||
"SSL_write(): %s", ssl_errno_s);
|
||||
}
|
||||
return (KORE_RESULT_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
*written = (size_t)r;
|
||||
|
||||
return (KORE_RESULT_OK);
|
||||
}
|
||||
|
||||
int
|
||||
net_read_tls(struct connection *c, size_t *bytes)
|
||||
{
|
||||
int r;
|
||||
|
||||
ERR_clear_error();
|
||||
r = SSL_read(c->ssl, (c->rnb->buf + c->rnb->s_off),
|
||||
(c->rnb->b_len - c->rnb->s_off));
|
||||
|
||||
if (c->tls_reneg > 1)
|
||||
return (KORE_RESULT_ERROR);
|
||||
|
||||
if (r <= 0) {
|
||||
r = SSL_get_error(c->ssl, r);
|
||||
switch (r) {
|
||||
case SSL_ERROR_WANT_READ:
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
c->evt.flags &= ~KORE_EVENT_READ;
|
||||
return (KORE_RESULT_OK);
|
||||
case SSL_ERROR_ZERO_RETURN:
|
||||
return (KORE_RESULT_ERROR);
|
||||
case SSL_ERROR_SYSCALL:
|
||||
switch (errno) {
|
||||
case EINTR:
|
||||
*bytes = 0;
|
||||
return (KORE_RESULT_OK);
|
||||
case EAGAIN:
|
||||
c->evt.flags &= ~KORE_EVENT_READ;
|
||||
c->snb->flags |= NETBUF_MUST_RESEND;
|
||||
return (KORE_RESULT_OK);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
kore_debug("SSL_read(): %s", ssl_errno_s);
|
||||
if (c->flags & CONN_LOG_TLS_FAILURE) {
|
||||
kore_log(LOG_NOTICE,
|
||||
"SSL_read(): %s", ssl_errno_s);
|
||||
}
|
||||
return (KORE_RESULT_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
*bytes = (size_t)r;
|
||||
|
||||
return (KORE_RESULT_OK);
|
||||
}
|
||||
|
||||
int
|
||||
net_write(struct connection *c, size_t len, size_t *written)
|
||||
{
|
||||
|
171
src/sha1.c
Normal file
171
src/sha1.c
Normal file
@ -0,0 +1,171 @@
|
||||
/* $OpenBSD: sha1.c,v 1.27 2019/06/07 22:56:36 dtucker Exp $ */
|
||||
|
||||
/*
|
||||
* SHA-1 in C
|
||||
* By Steve Reid <steve@edmweb.com>
|
||||
* 100% Public Domain
|
||||
*
|
||||
* Test Vectors (from FIPS PUB 180-1)
|
||||
* "abc"
|
||||
* A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
|
||||
* "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
|
||||
* 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
|
||||
* A million repetitions of "a"
|
||||
* 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "sha1.h"
|
||||
|
||||
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
|
||||
|
||||
/*
|
||||
* blk0() and blk() perform the initial expand.
|
||||
* I got the idea of expanding during the round function from SSLeay
|
||||
*/
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
# define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
|
||||
|(rol(block->l[i],8)&0x00FF00FF))
|
||||
#else
|
||||
# define blk0(i) block->l[i]
|
||||
#endif
|
||||
#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
|
||||
^block->l[(i+2)&15]^block->l[i&15],1))
|
||||
|
||||
/*
|
||||
* (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1
|
||||
*/
|
||||
#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
|
||||
#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
|
||||
#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
|
||||
#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
|
||||
#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
|
||||
|
||||
typedef union {
|
||||
u_int8_t c[64];
|
||||
u_int32_t l[16];
|
||||
} CHAR64LONG16;
|
||||
|
||||
/*
|
||||
* Hash a single 512-bit block. This is the core of the algorithm.
|
||||
*/
|
||||
void
|
||||
SHA1Transform(u_int32_t state[5], const u_int8_t buffer[SHA1_BLOCK_LENGTH])
|
||||
{
|
||||
u_int32_t a, b, c, d, e;
|
||||
u_int8_t workspace[SHA1_BLOCK_LENGTH];
|
||||
CHAR64LONG16 *block = (CHAR64LONG16 *)workspace;
|
||||
|
||||
(void)memcpy(block, buffer, SHA1_BLOCK_LENGTH);
|
||||
|
||||
/* Copy context->state[] to working vars */
|
||||
a = state[0];
|
||||
b = state[1];
|
||||
c = state[2];
|
||||
d = state[3];
|
||||
e = state[4];
|
||||
|
||||
/* 4 rounds of 20 operations each. Loop unrolled. */
|
||||
R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
|
||||
R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
|
||||
R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
|
||||
R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
|
||||
R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
|
||||
R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
|
||||
R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
|
||||
R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
|
||||
R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
|
||||
R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
|
||||
R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
|
||||
R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
|
||||
R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
|
||||
R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
|
||||
R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
|
||||
R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
|
||||
R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
|
||||
R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
|
||||
R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
|
||||
R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
|
||||
|
||||
/* Add the working vars back into context.state[] */
|
||||
state[0] += a;
|
||||
state[1] += b;
|
||||
state[2] += c;
|
||||
state[3] += d;
|
||||
state[4] += e;
|
||||
|
||||
/* Wipe variables */
|
||||
a = b = c = d = e = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA1Init - Initialize new context
|
||||
*/
|
||||
void
|
||||
SHA1Init(SHA1_CTX *context)
|
||||
{
|
||||
/* SHA1 initialization constants */
|
||||
context->count = 0;
|
||||
context->state[0] = 0x67452301;
|
||||
context->state[1] = 0xEFCDAB89;
|
||||
context->state[2] = 0x98BADCFE;
|
||||
context->state[3] = 0x10325476;
|
||||
context->state[4] = 0xC3D2E1F0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Run your data through this.
|
||||
*/
|
||||
void
|
||||
SHA1Update(SHA1_CTX *context, const u_int8_t *data, size_t len)
|
||||
{
|
||||
size_t i, j;
|
||||
|
||||
j = (size_t)((context->count >> 3) & 63);
|
||||
context->count += ((u_int64_t)len << 3);
|
||||
if ((j + len) > 63) {
|
||||
(void)memcpy(&context->buffer[j], data, (i = 64-j));
|
||||
SHA1Transform(context->state, context->buffer);
|
||||
for ( ; i + 63 < len; i += 64)
|
||||
SHA1Transform(context->state, &data[i]);
|
||||
j = 0;
|
||||
} else {
|
||||
i = 0;
|
||||
}
|
||||
(void)memcpy(&context->buffer[j], &data[i], len - i);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add padding and return the message digest.
|
||||
*/
|
||||
void
|
||||
SHA1Pad(SHA1_CTX *context)
|
||||
{
|
||||
u_int8_t finalcount[8];
|
||||
u_int i;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
finalcount[i] = (u_int8_t)((context->count >>
|
||||
((7 - (i & 7)) * 8)) & 255); /* Endian independent */
|
||||
}
|
||||
SHA1Update(context, (u_int8_t *)"\200", 1);
|
||||
while ((context->count & 504) != 448)
|
||||
SHA1Update(context, (u_int8_t *)"\0", 1);
|
||||
SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
|
||||
}
|
||||
|
||||
void
|
||||
SHA1Final(u_int8_t digest[SHA1_DIGEST_LENGTH], SHA1_CTX *context)
|
||||
{
|
||||
u_int i;
|
||||
|
||||
SHA1Pad(context);
|
||||
for (i = 0; i < SHA1_DIGEST_LENGTH; i++) {
|
||||
digest[i] = (u_int8_t)
|
||||
((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
|
||||
}
|
||||
|
||||
//explicit_bzero(context, sizeof(*context));
|
||||
}
|
885
src/sha2.c
Normal file
885
src/sha2.c
Normal file
@ -0,0 +1,885 @@
|
||||
/* $OpenBSD: sha2.c,v 1.28 2019/07/23 12:35:22 dtucker Exp $ */
|
||||
|
||||
/*
|
||||
* FILE: sha2.c
|
||||
* AUTHOR: Aaron D. Gifford <me@aarongifford.com>
|
||||
*
|
||||
* Copyright (c) 2000-2001, Aaron D. Gifford
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the names of contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $From: sha2.c,v 1.1 2001/11/08 00:01:51 adg Exp adg $
|
||||
*/
|
||||
|
||||
/* OPENBSD ORIGINAL: lib/libc/hash/sha2.c */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include <machine/endian.h>
|
||||
#else
|
||||
#include <endian.h>
|
||||
#endif
|
||||
|
||||
#include "sha2.h"
|
||||
|
||||
/* no-op out, similar to DEF_WEAK but only needed here */
|
||||
#define MAKE_CLONE(x, y) void __ssh_compat_make_clone_##x_##y(void)
|
||||
|
||||
/*
|
||||
* UNROLLED TRANSFORM LOOP NOTE:
|
||||
* You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform
|
||||
* loop version for the hash transform rounds (defined using macros
|
||||
* later in this file). Either define on the command line, for example:
|
||||
*
|
||||
* cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c
|
||||
*
|
||||
* or define below:
|
||||
*
|
||||
* #define SHA2_UNROLL_TRANSFORM
|
||||
*
|
||||
*/
|
||||
#if defined(__amd64__) || defined(__i386__)
|
||||
#define SHA2_UNROLL_TRANSFORM
|
||||
#endif
|
||||
|
||||
/*** SHA-224/256/384/512 Machine Architecture Definitions *****************/
|
||||
/*
|
||||
* BYTE_ORDER NOTE:
|
||||
*
|
||||
* Please make sure that your system defines BYTE_ORDER. If your
|
||||
* architecture is little-endian, make sure it also defines
|
||||
* LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are
|
||||
* equivalent.
|
||||
*
|
||||
* If your system does not define the above, then you can do so by
|
||||
* hand like this:
|
||||
*
|
||||
* #define LITTLE_ENDIAN 1234
|
||||
* #define BIG_ENDIAN 4321
|
||||
*
|
||||
* And for little-endian machines, add:
|
||||
*
|
||||
* #define BYTE_ORDER LITTLE_ENDIAN
|
||||
*
|
||||
* Or for big-endian machines:
|
||||
*
|
||||
* #define BYTE_ORDER BIG_ENDIAN
|
||||
*
|
||||
* The FreeBSD machine this was written on defines BYTE_ORDER
|
||||
* appropriately by including <sys/types.h> (which in turn includes
|
||||
* <machine/endian.h> where the appropriate definitions are actually
|
||||
* made).
|
||||
*/
|
||||
#if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN)
|
||||
#error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN
|
||||
#endif
|
||||
|
||||
|
||||
/*** SHA-224/256/384/512 Various Length Definitions ***********************/
|
||||
/* NOTE: Most of these are in sha2.h */
|
||||
#define SHA224_SHORT_BLOCK_LENGTH (SHA224_BLOCK_LENGTH - 8)
|
||||
#define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8)
|
||||
#define SHA384_SHORT_BLOCK_LENGTH (SHA384_BLOCK_LENGTH - 16)
|
||||
#define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16)
|
||||
|
||||
/*** ENDIAN SPECIFIC COPY MACROS **************************************/
|
||||
#define BE_8_TO_32(dst, cp) do { \
|
||||
(dst) = (u_int32_t)(cp)[3] | ((u_int32_t)(cp)[2] << 8) | \
|
||||
((u_int32_t)(cp)[1] << 16) | ((u_int32_t)(cp)[0] << 24); \
|
||||
} while(0)
|
||||
|
||||
#define BE_8_TO_64(dst, cp) do { \
|
||||
(dst) = (u_int64_t)(cp)[7] | ((u_int64_t)(cp)[6] << 8) | \
|
||||
((u_int64_t)(cp)[5] << 16) | ((u_int64_t)(cp)[4] << 24) | \
|
||||
((u_int64_t)(cp)[3] << 32) | ((u_int64_t)(cp)[2] << 40) | \
|
||||
((u_int64_t)(cp)[1] << 48) | ((u_int64_t)(cp)[0] << 56); \
|
||||
} while (0)
|
||||
|
||||
#define BE_64_TO_8(cp, src) do { \
|
||||
(cp)[0] = (src) >> 56; \
|
||||
(cp)[1] = (src) >> 48; \
|
||||
(cp)[2] = (src) >> 40; \
|
||||
(cp)[3] = (src) >> 32; \
|
||||
(cp)[4] = (src) >> 24; \
|
||||
(cp)[5] = (src) >> 16; \
|
||||
(cp)[6] = (src) >> 8; \
|
||||
(cp)[7] = (src); \
|
||||
} while (0)
|
||||
|
||||
#define BE_32_TO_8(cp, src) do { \
|
||||
(cp)[0] = (src) >> 24; \
|
||||
(cp)[1] = (src) >> 16; \
|
||||
(cp)[2] = (src) >> 8; \
|
||||
(cp)[3] = (src); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Macro for incrementally adding the unsigned 64-bit integer n to the
|
||||
* unsigned 128-bit integer (represented using a two-element array of
|
||||
* 64-bit words):
|
||||
*/
|
||||
#define ADDINC128(w,n) do { \
|
||||
(w)[0] += (u_int64_t)(n); \
|
||||
if ((w)[0] < (n)) { \
|
||||
(w)[1]++; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/*** THE SIX LOGICAL FUNCTIONS ****************************************/
|
||||
/*
|
||||
* Bit shifting and rotation (used by the six SHA-XYZ logical functions:
|
||||
*
|
||||
* NOTE: The naming of R and S appears backwards here (R is a SHIFT and
|
||||
* S is a ROTATION) because the SHA-224/256/384/512 description document
|
||||
* (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this
|
||||
* same "backwards" definition.
|
||||
*/
|
||||
/* Shift-right (used in SHA-224, SHA-256, SHA-384, and SHA-512): */
|
||||
#define R(b,x) ((x) >> (b))
|
||||
/* 32-bit Rotate-right (used in SHA-224 and SHA-256): */
|
||||
#define S32(b,x) (((x) >> (b)) | ((x) << (32 - (b))))
|
||||
/* 64-bit Rotate-right (used in SHA-384 and SHA-512): */
|
||||
#define S64(b,x) (((x) >> (b)) | ((x) << (64 - (b))))
|
||||
|
||||
/* Two of six logical functions used in SHA-224, SHA-256, SHA-384, and SHA-512: */
|
||||
#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
|
||||
#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
|
||||
|
||||
/* Four of six logical functions used in SHA-224 and SHA-256: */
|
||||
#define Sigma0_256(x) (S32(2, (x)) ^ S32(13, (x)) ^ S32(22, (x)))
|
||||
#define Sigma1_256(x) (S32(6, (x)) ^ S32(11, (x)) ^ S32(25, (x)))
|
||||
#define sigma0_256(x) (S32(7, (x)) ^ S32(18, (x)) ^ R(3 , (x)))
|
||||
#define sigma1_256(x) (S32(17, (x)) ^ S32(19, (x)) ^ R(10, (x)))
|
||||
|
||||
/* Four of six logical functions used in SHA-384 and SHA-512: */
|
||||
#define Sigma0_512(x) (S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x)))
|
||||
#define Sigma1_512(x) (S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x)))
|
||||
#define sigma0_512(x) (S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7, (x)))
|
||||
#define sigma1_512(x) (S64(19, (x)) ^ S64(61, (x)) ^ R( 6, (x)))
|
||||
|
||||
|
||||
/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/
|
||||
/* Hash constant words K for SHA-224 and SHA-256: */
|
||||
static const u_int32_t K256[64] = {
|
||||
0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
|
||||
0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
|
||||
0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
|
||||
0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
|
||||
0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
|
||||
0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
|
||||
0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
|
||||
0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
|
||||
0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
|
||||
0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
|
||||
0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
|
||||
0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
|
||||
0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
|
||||
0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
|
||||
0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
|
||||
0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
|
||||
};
|
||||
|
||||
/* Initial hash value H for SHA-256: */
|
||||
static const u_int32_t sha256_initial_hash_value[8] = {
|
||||
0x6a09e667UL,
|
||||
0xbb67ae85UL,
|
||||
0x3c6ef372UL,
|
||||
0xa54ff53aUL,
|
||||
0x510e527fUL,
|
||||
0x9b05688cUL,
|
||||
0x1f83d9abUL,
|
||||
0x5be0cd19UL
|
||||
};
|
||||
|
||||
/* Hash constant words K for SHA-384 and SHA-512: */
|
||||
static const u_int64_t K512[80] = {
|
||||
0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
|
||||
0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
|
||||
0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
|
||||
0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
|
||||
0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
|
||||
0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
|
||||
0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
|
||||
0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
|
||||
0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
|
||||
0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
|
||||
0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
|
||||
0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
|
||||
0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
|
||||
0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
|
||||
0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
|
||||
0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
|
||||
0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
|
||||
0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
|
||||
0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
|
||||
0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
|
||||
0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
|
||||
0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
|
||||
0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
|
||||
0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
|
||||
0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
|
||||
0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
|
||||
0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
|
||||
0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
|
||||
0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
|
||||
0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
|
||||
0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
|
||||
0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
|
||||
0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
|
||||
0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
|
||||
0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
|
||||
0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
|
||||
0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
|
||||
0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
|
||||
0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
|
||||
0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
|
||||
};
|
||||
|
||||
/* Initial hash value H for SHA-512 */
|
||||
static const u_int64_t sha512_initial_hash_value[8] = {
|
||||
0x6a09e667f3bcc908ULL,
|
||||
0xbb67ae8584caa73bULL,
|
||||
0x3c6ef372fe94f82bULL,
|
||||
0xa54ff53a5f1d36f1ULL,
|
||||
0x510e527fade682d1ULL,
|
||||
0x9b05688c2b3e6c1fULL,
|
||||
0x1f83d9abfb41bd6bULL,
|
||||
0x5be0cd19137e2179ULL
|
||||
};
|
||||
|
||||
/* Initial hash value H for SHA-384 */
|
||||
static const u_int64_t sha384_initial_hash_value[8] = {
|
||||
0xcbbb9d5dc1059ed8ULL,
|
||||
0x629a292a367cd507ULL,
|
||||
0x9159015a3070dd17ULL,
|
||||
0x152fecd8f70e5939ULL,
|
||||
0x67332667ffc00b31ULL,
|
||||
0x8eb44a8768581511ULL,
|
||||
0xdb0c2e0d64f98fa7ULL,
|
||||
0x47b5481dbefa4fa4ULL
|
||||
};
|
||||
|
||||
/*** SHA-256: *********************************************************/
|
||||
void
|
||||
SHA256Init(SHA2_CTX *context)
|
||||
{
|
||||
memcpy(context->state.st32, sha256_initial_hash_value,
|
||||
sizeof(sha256_initial_hash_value));
|
||||
memset(context->buffer, 0, sizeof(context->buffer));
|
||||
context->bitcount[0] = 0;
|
||||
}
|
||||
|
||||
#ifdef SHA2_UNROLL_TRANSFORM
|
||||
|
||||
/* Unrolled SHA-256 round macros: */
|
||||
|
||||
#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) do { \
|
||||
BE_8_TO_32(W256[j], data); \
|
||||
data += 4; \
|
||||
T1 = (h) + Sigma1_256((e)) + Ch((e), (f), (g)) + K256[j] + W256[j]; \
|
||||
(d) += T1; \
|
||||
(h) = T1 + Sigma0_256((a)) + Maj((a), (b), (c)); \
|
||||
j++; \
|
||||
} while(0)
|
||||
|
||||
#define ROUND256(a,b,c,d,e,f,g,h) do { \
|
||||
s0 = W256[(j+1)&0x0f]; \
|
||||
s0 = sigma0_256(s0); \
|
||||
s1 = W256[(j+14)&0x0f]; \
|
||||
s1 = sigma1_256(s1); \
|
||||
T1 = (h) + Sigma1_256((e)) + Ch((e), (f), (g)) + K256[j] + \
|
||||
(W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \
|
||||
(d) += T1; \
|
||||
(h) = T1 + Sigma0_256((a)) + Maj((a), (b), (c)); \
|
||||
j++; \
|
||||
} while(0)
|
||||
|
||||
void
|
||||
SHA256Transform(u_int32_t state[8], const u_int8_t data[SHA256_BLOCK_LENGTH])
|
||||
{
|
||||
u_int32_t a, b, c, d, e, f, g, h, s0, s1;
|
||||
u_int32_t T1, W256[16];
|
||||
int j;
|
||||
|
||||
/* Initialize registers with the prev. intermediate value */
|
||||
a = state[0];
|
||||
b = state[1];
|
||||
c = state[2];
|
||||
d = state[3];
|
||||
e = state[4];
|
||||
f = state[5];
|
||||
g = state[6];
|
||||
h = state[7];
|
||||
|
||||
j = 0;
|
||||
do {
|
||||
/* Rounds 0 to 15 (unrolled): */
|
||||
ROUND256_0_TO_15(a,b,c,d,e,f,g,h);
|
||||
ROUND256_0_TO_15(h,a,b,c,d,e,f,g);
|
||||
ROUND256_0_TO_15(g,h,a,b,c,d,e,f);
|
||||
ROUND256_0_TO_15(f,g,h,a,b,c,d,e);
|
||||
ROUND256_0_TO_15(e,f,g,h,a,b,c,d);
|
||||
ROUND256_0_TO_15(d,e,f,g,h,a,b,c);
|
||||
ROUND256_0_TO_15(c,d,e,f,g,h,a,b);
|
||||
ROUND256_0_TO_15(b,c,d,e,f,g,h,a);
|
||||
} while (j < 16);
|
||||
|
||||
/* Now for the remaining rounds up to 63: */
|
||||
do {
|
||||
ROUND256(a,b,c,d,e,f,g,h);
|
||||
ROUND256(h,a,b,c,d,e,f,g);
|
||||
ROUND256(g,h,a,b,c,d,e,f);
|
||||
ROUND256(f,g,h,a,b,c,d,e);
|
||||
ROUND256(e,f,g,h,a,b,c,d);
|
||||
ROUND256(d,e,f,g,h,a,b,c);
|
||||
ROUND256(c,d,e,f,g,h,a,b);
|
||||
ROUND256(b,c,d,e,f,g,h,a);
|
||||
} while (j < 64);
|
||||
|
||||
/* Compute the current intermediate hash value */
|
||||
state[0] += a;
|
||||
state[1] += b;
|
||||
state[2] += c;
|
||||
state[3] += d;
|
||||
state[4] += e;
|
||||
state[5] += f;
|
||||
state[6] += g;
|
||||
state[7] += h;
|
||||
|
||||
/* Clean up */
|
||||
a = b = c = d = e = f = g = h = T1 = 0;
|
||||
}
|
||||
|
||||
#else /* SHA2_UNROLL_TRANSFORM */
|
||||
|
||||
void
|
||||
SHA256Transform(u_int32_t state[8], const u_int8_t data[SHA256_BLOCK_LENGTH])
|
||||
{
|
||||
u_int32_t a, b, c, d, e, f, g, h, s0, s1;
|
||||
u_int32_t T1, T2, W256[16];
|
||||
int j;
|
||||
|
||||
/* Initialize registers with the prev. intermediate value */
|
||||
a = state[0];
|
||||
b = state[1];
|
||||
c = state[2];
|
||||
d = state[3];
|
||||
e = state[4];
|
||||
f = state[5];
|
||||
g = state[6];
|
||||
h = state[7];
|
||||
|
||||
j = 0;
|
||||
do {
|
||||
BE_8_TO_32(W256[j], data);
|
||||
data += 4;
|
||||
/* Apply the SHA-256 compression function to update a..h */
|
||||
T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j];
|
||||
T2 = Sigma0_256(a) + Maj(a, b, c);
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + T1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = T1 + T2;
|
||||
|
||||
j++;
|
||||
} while (j < 16);
|
||||
|
||||
do {
|
||||
/* Part of the message block expansion: */
|
||||
s0 = W256[(j+1)&0x0f];
|
||||
s0 = sigma0_256(s0);
|
||||
s1 = W256[(j+14)&0x0f];
|
||||
s1 = sigma1_256(s1);
|
||||
|
||||
/* Apply the SHA-256 compression function to update a..h */
|
||||
T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] +
|
||||
(W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0);
|
||||
T2 = Sigma0_256(a) + Maj(a, b, c);
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + T1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = T1 + T2;
|
||||
|
||||
j++;
|
||||
} while (j < 64);
|
||||
|
||||
/* Compute the current intermediate hash value */
|
||||
state[0] += a;
|
||||
state[1] += b;
|
||||
state[2] += c;
|
||||
state[3] += d;
|
||||
state[4] += e;
|
||||
state[5] += f;
|
||||
state[6] += g;
|
||||
state[7] += h;
|
||||
|
||||
/* Clean up */
|
||||
a = b = c = d = e = f = g = h = T1 = T2 = 0;
|
||||
}
|
||||
#endif /* SHA2_UNROLL_TRANSFORM */
|
||||
|
||||
void
|
||||
SHA256Update(SHA2_CTX *context, const u_int8_t *data, size_t len)
|
||||
{
|
||||
u_int64_t freespace, usedspace;
|
||||
|
||||
/* Calling with no data is valid (we do nothing) */
|
||||
if (len == 0)
|
||||
return;
|
||||
|
||||
usedspace = (context->bitcount[0] >> 3) % SHA256_BLOCK_LENGTH;
|
||||
if (usedspace > 0) {
|
||||
/* Calculate how much free space is available in the buffer */
|
||||
freespace = SHA256_BLOCK_LENGTH - usedspace;
|
||||
|
||||
if (len >= freespace) {
|
||||
/* Fill the buffer completely and process it */
|
||||
memcpy(&context->buffer[usedspace], data, freespace);
|
||||
context->bitcount[0] += freespace << 3;
|
||||
len -= freespace;
|
||||
data += freespace;
|
||||
SHA256Transform(context->state.st32, context->buffer);
|
||||
} else {
|
||||
/* The buffer is not yet full */
|
||||
memcpy(&context->buffer[usedspace], data, len);
|
||||
context->bitcount[0] += (u_int64_t)len << 3;
|
||||
/* Clean up: */
|
||||
usedspace = freespace = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
while (len >= SHA256_BLOCK_LENGTH) {
|
||||
/* Process as many complete blocks as we can */
|
||||
SHA256Transform(context->state.st32, data);
|
||||
context->bitcount[0] += SHA256_BLOCK_LENGTH << 3;
|
||||
len -= SHA256_BLOCK_LENGTH;
|
||||
data += SHA256_BLOCK_LENGTH;
|
||||
}
|
||||
if (len > 0) {
|
||||
/* There's left-overs, so save 'em */
|
||||
memcpy(context->buffer, data, len);
|
||||
context->bitcount[0] += len << 3;
|
||||
}
|
||||
/* Clean up: */
|
||||
usedspace = freespace = 0;
|
||||
}
|
||||
|
||||
void
|
||||
SHA256Pad(SHA2_CTX *context)
|
||||
{
|
||||
unsigned int usedspace;
|
||||
|
||||
usedspace = (context->bitcount[0] >> 3) % SHA256_BLOCK_LENGTH;
|
||||
if (usedspace > 0) {
|
||||
/* Begin padding with a 1 bit: */
|
||||
context->buffer[usedspace++] = 0x80;
|
||||
|
||||
if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) {
|
||||
/* Set-up for the last transform: */
|
||||
memset(&context->buffer[usedspace], 0,
|
||||
SHA256_SHORT_BLOCK_LENGTH - usedspace);
|
||||
} else {
|
||||
if (usedspace < SHA256_BLOCK_LENGTH) {
|
||||
memset(&context->buffer[usedspace], 0,
|
||||
SHA256_BLOCK_LENGTH - usedspace);
|
||||
}
|
||||
/* Do second-to-last transform: */
|
||||
SHA256Transform(context->state.st32, context->buffer);
|
||||
|
||||
/* Prepare for last transform: */
|
||||
memset(context->buffer, 0, SHA256_SHORT_BLOCK_LENGTH);
|
||||
}
|
||||
} else {
|
||||
/* Set-up for the last transform: */
|
||||
memset(context->buffer, 0, SHA256_SHORT_BLOCK_LENGTH);
|
||||
|
||||
/* Begin padding with a 1 bit: */
|
||||
*context->buffer = 0x80;
|
||||
}
|
||||
/* Store the length of input data (in bits) in big endian format: */
|
||||
BE_64_TO_8(&context->buffer[SHA256_SHORT_BLOCK_LENGTH],
|
||||
context->bitcount[0]);
|
||||
|
||||
/* Final transform: */
|
||||
SHA256Transform(context->state.st32, context->buffer);
|
||||
|
||||
/* Clean up: */
|
||||
usedspace = 0;
|
||||
}
|
||||
|
||||
void
|
||||
SHA256Final(u_int8_t digest[SHA256_DIGEST_LENGTH], SHA2_CTX *context)
|
||||
{
|
||||
SHA256Pad(context);
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
int i;
|
||||
|
||||
/* Convert TO host byte order */
|
||||
for (i = 0; i < 8; i++)
|
||||
BE_32_TO_8(digest + i * 4, context->state.st32[i]);
|
||||
#else
|
||||
memcpy(digest, context->state.st32, SHA256_DIGEST_LENGTH);
|
||||
#endif
|
||||
//explicit_bzero(context, sizeof(*context));
|
||||
}
|
||||
|
||||
|
||||
/*** SHA-512: *********************************************************/
|
||||
void
|
||||
SHA512Init(SHA2_CTX *context)
|
||||
{
|
||||
memcpy(context->state.st64, sha512_initial_hash_value,
|
||||
sizeof(sha512_initial_hash_value));
|
||||
memset(context->buffer, 0, sizeof(context->buffer));
|
||||
context->bitcount[0] = context->bitcount[1] = 0;
|
||||
}
|
||||
|
||||
#ifdef SHA2_UNROLL_TRANSFORM
|
||||
|
||||
/* Unrolled SHA-512 round macros: */
|
||||
|
||||
#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) do { \
|
||||
BE_8_TO_64(W512[j], data); \
|
||||
data += 8; \
|
||||
T1 = (h) + Sigma1_512((e)) + Ch((e), (f), (g)) + K512[j] + W512[j]; \
|
||||
(d) += T1; \
|
||||
(h) = T1 + Sigma0_512((a)) + Maj((a), (b), (c)); \
|
||||
j++; \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define ROUND512(a,b,c,d,e,f,g,h) do { \
|
||||
s0 = W512[(j+1)&0x0f]; \
|
||||
s0 = sigma0_512(s0); \
|
||||
s1 = W512[(j+14)&0x0f]; \
|
||||
s1 = sigma1_512(s1); \
|
||||
T1 = (h) + Sigma1_512((e)) + Ch((e), (f), (g)) + K512[j] + \
|
||||
(W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \
|
||||
(d) += T1; \
|
||||
(h) = T1 + Sigma0_512((a)) + Maj((a), (b), (c)); \
|
||||
j++; \
|
||||
} while(0)
|
||||
|
||||
void
|
||||
SHA512Transform(u_int64_t state[8], const u_int8_t data[SHA512_BLOCK_LENGTH])
|
||||
{
|
||||
u_int64_t a, b, c, d, e, f, g, h, s0, s1;
|
||||
u_int64_t T1, W512[16];
|
||||
int j;
|
||||
|
||||
/* Initialize registers with the prev. intermediate value */
|
||||
a = state[0];
|
||||
b = state[1];
|
||||
c = state[2];
|
||||
d = state[3];
|
||||
e = state[4];
|
||||
f = state[5];
|
||||
g = state[6];
|
||||
h = state[7];
|
||||
|
||||
j = 0;
|
||||
do {
|
||||
/* Rounds 0 to 15 (unrolled): */
|
||||
ROUND512_0_TO_15(a,b,c,d,e,f,g,h);
|
||||
ROUND512_0_TO_15(h,a,b,c,d,e,f,g);
|
||||
ROUND512_0_TO_15(g,h,a,b,c,d,e,f);
|
||||
ROUND512_0_TO_15(f,g,h,a,b,c,d,e);
|
||||
ROUND512_0_TO_15(e,f,g,h,a,b,c,d);
|
||||
ROUND512_0_TO_15(d,e,f,g,h,a,b,c);
|
||||
ROUND512_0_TO_15(c,d,e,f,g,h,a,b);
|
||||
ROUND512_0_TO_15(b,c,d,e,f,g,h,a);
|
||||
} while (j < 16);
|
||||
|
||||
/* Now for the remaining rounds up to 79: */
|
||||
do {
|
||||
ROUND512(a,b,c,d,e,f,g,h);
|
||||
ROUND512(h,a,b,c,d,e,f,g);
|
||||
ROUND512(g,h,a,b,c,d,e,f);
|
||||
ROUND512(f,g,h,a,b,c,d,e);
|
||||
ROUND512(e,f,g,h,a,b,c,d);
|
||||
ROUND512(d,e,f,g,h,a,b,c);
|
||||
ROUND512(c,d,e,f,g,h,a,b);
|
||||
ROUND512(b,c,d,e,f,g,h,a);
|
||||
} while (j < 80);
|
||||
|
||||
/* Compute the current intermediate hash value */
|
||||
state[0] += a;
|
||||
state[1] += b;
|
||||
state[2] += c;
|
||||
state[3] += d;
|
||||
state[4] += e;
|
||||
state[5] += f;
|
||||
state[6] += g;
|
||||
state[7] += h;
|
||||
|
||||
/* Clean up */
|
||||
a = b = c = d = e = f = g = h = T1 = 0;
|
||||
}
|
||||
|
||||
#else /* SHA2_UNROLL_TRANSFORM */
|
||||
|
||||
void
|
||||
SHA512Transform(u_int64_t state[8], const u_int8_t data[SHA512_BLOCK_LENGTH])
|
||||
{
|
||||
u_int64_t a, b, c, d, e, f, g, h, s0, s1;
|
||||
u_int64_t T1, T2, W512[16];
|
||||
int j;
|
||||
|
||||
/* Initialize registers with the prev. intermediate value */
|
||||
a = state[0];
|
||||
b = state[1];
|
||||
c = state[2];
|
||||
d = state[3];
|
||||
e = state[4];
|
||||
f = state[5];
|
||||
g = state[6];
|
||||
h = state[7];
|
||||
|
||||
j = 0;
|
||||
do {
|
||||
BE_8_TO_64(W512[j], data);
|
||||
data += 8;
|
||||
/* Apply the SHA-512 compression function to update a..h */
|
||||
T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j];
|
||||
T2 = Sigma0_512(a) + Maj(a, b, c);
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + T1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = T1 + T2;
|
||||
|
||||
j++;
|
||||
} while (j < 16);
|
||||
|
||||
do {
|
||||
/* Part of the message block expansion: */
|
||||
s0 = W512[(j+1)&0x0f];
|
||||
s0 = sigma0_512(s0);
|
||||
s1 = W512[(j+14)&0x0f];
|
||||
s1 = sigma1_512(s1);
|
||||
|
||||
/* Apply the SHA-512 compression function to update a..h */
|
||||
T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] +
|
||||
(W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0);
|
||||
T2 = Sigma0_512(a) + Maj(a, b, c);
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + T1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = T1 + T2;
|
||||
|
||||
j++;
|
||||
} while (j < 80);
|
||||
|
||||
/* Compute the current intermediate hash value */
|
||||
state[0] += a;
|
||||
state[1] += b;
|
||||
state[2] += c;
|
||||
state[3] += d;
|
||||
state[4] += e;
|
||||
state[5] += f;
|
||||
state[6] += g;
|
||||
state[7] += h;
|
||||
|
||||
/* Clean up */
|
||||
a = b = c = d = e = f = g = h = T1 = T2 = 0;
|
||||
}
|
||||
|
||||
#endif /* SHA2_UNROLL_TRANSFORM */
|
||||
|
||||
void
|
||||
SHA512Update(SHA2_CTX *context, const u_int8_t *data, size_t len)
|
||||
{
|
||||
size_t freespace, usedspace;
|
||||
|
||||
/* Calling with no data is valid (we do nothing) */
|
||||
if (len == 0)
|
||||
return;
|
||||
|
||||
usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
|
||||
if (usedspace > 0) {
|
||||
/* Calculate how much free space is available in the buffer */
|
||||
freespace = SHA512_BLOCK_LENGTH - usedspace;
|
||||
|
||||
if (len >= freespace) {
|
||||
/* Fill the buffer completely and process it */
|
||||
memcpy(&context->buffer[usedspace], data, freespace);
|
||||
ADDINC128(context->bitcount, freespace << 3);
|
||||
len -= freespace;
|
||||
data += freespace;
|
||||
SHA512Transform(context->state.st64, context->buffer);
|
||||
} else {
|
||||
/* The buffer is not yet full */
|
||||
memcpy(&context->buffer[usedspace], data, len);
|
||||
ADDINC128(context->bitcount, len << 3);
|
||||
/* Clean up: */
|
||||
usedspace = freespace = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
while (len >= SHA512_BLOCK_LENGTH) {
|
||||
/* Process as many complete blocks as we can */
|
||||
SHA512Transform(context->state.st64, data);
|
||||
ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3);
|
||||
len -= SHA512_BLOCK_LENGTH;
|
||||
data += SHA512_BLOCK_LENGTH;
|
||||
}
|
||||
if (len > 0) {
|
||||
/* There's left-overs, so save 'em */
|
||||
memcpy(context->buffer, data, len);
|
||||
ADDINC128(context->bitcount, len << 3);
|
||||
}
|
||||
/* Clean up: */
|
||||
usedspace = freespace = 0;
|
||||
}
|
||||
|
||||
void
|
||||
SHA512Pad(SHA2_CTX *context)
|
||||
{
|
||||
unsigned int usedspace;
|
||||
|
||||
usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
|
||||
if (usedspace > 0) {
|
||||
/* Begin padding with a 1 bit: */
|
||||
context->buffer[usedspace++] = 0x80;
|
||||
|
||||
if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) {
|
||||
/* Set-up for the last transform: */
|
||||
memset(&context->buffer[usedspace], 0, SHA512_SHORT_BLOCK_LENGTH - usedspace);
|
||||
} else {
|
||||
if (usedspace < SHA512_BLOCK_LENGTH) {
|
||||
memset(&context->buffer[usedspace], 0, SHA512_BLOCK_LENGTH - usedspace);
|
||||
}
|
||||
/* Do second-to-last transform: */
|
||||
SHA512Transform(context->state.st64, context->buffer);
|
||||
|
||||
/* And set-up for the last transform: */
|
||||
memset(context->buffer, 0, SHA512_BLOCK_LENGTH - 2);
|
||||
}
|
||||
} else {
|
||||
/* Prepare for final transform: */
|
||||
memset(context->buffer, 0, SHA512_SHORT_BLOCK_LENGTH);
|
||||
|
||||
/* Begin padding with a 1 bit: */
|
||||
*context->buffer = 0x80;
|
||||
}
|
||||
/* Store the length of input data (in bits) in big endian format: */
|
||||
BE_64_TO_8(&context->buffer[SHA512_SHORT_BLOCK_LENGTH],
|
||||
context->bitcount[1]);
|
||||
BE_64_TO_8(&context->buffer[SHA512_SHORT_BLOCK_LENGTH + 8],
|
||||
context->bitcount[0]);
|
||||
|
||||
/* Final transform: */
|
||||
SHA512Transform(context->state.st64, context->buffer);
|
||||
|
||||
/* Clean up: */
|
||||
usedspace = 0;
|
||||
}
|
||||
|
||||
void
|
||||
SHA512Final(u_int8_t digest[SHA512_DIGEST_LENGTH], SHA2_CTX *context)
|
||||
{
|
||||
SHA512Pad(context);
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
int i;
|
||||
|
||||
/* Convert TO host byte order */
|
||||
for (i = 0; i < 8; i++)
|
||||
BE_64_TO_8(digest + i * 8, context->state.st64[i]);
|
||||
#else
|
||||
memcpy(digest, context->state.st64, SHA512_DIGEST_LENGTH);
|
||||
#endif
|
||||
//explicit_bzero(context, sizeof(*context));
|
||||
}
|
||||
|
||||
/*** SHA-384: *********************************************************/
|
||||
void
|
||||
SHA384Init(SHA2_CTX *context)
|
||||
{
|
||||
memcpy(context->state.st64, sha384_initial_hash_value,
|
||||
sizeof(sha384_initial_hash_value));
|
||||
memset(context->buffer, 0, sizeof(context->buffer));
|
||||
context->bitcount[0] = context->bitcount[1] = 0;
|
||||
}
|
||||
|
||||
MAKE_CLONE(SHA384Transform, SHA512Transform);
|
||||
MAKE_CLONE(SHA384Update, SHA512Update);
|
||||
MAKE_CLONE(SHA384Pad, SHA512Pad);
|
||||
|
||||
/* Equivalent of MAKE_CLONE (which is a no-op) for SHA384 funcs */
|
||||
void
|
||||
SHA384Transform(u_int64_t state[8], const u_int8_t data[SHA512_BLOCK_LENGTH])
|
||||
{
|
||||
SHA512Transform(state, data);
|
||||
}
|
||||
|
||||
void
|
||||
SHA384Update(SHA2_CTX *context, const u_int8_t *data, size_t len)
|
||||
{
|
||||
SHA512Update(context, data, len);
|
||||
}
|
||||
|
||||
void
|
||||
SHA384Pad(SHA2_CTX *context)
|
||||
{
|
||||
SHA512Pad(context);
|
||||
}
|
||||
|
||||
void
|
||||
SHA384Final(u_int8_t digest[SHA384_DIGEST_LENGTH], SHA2_CTX *context)
|
||||
{
|
||||
SHA384Pad(context);
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
int i;
|
||||
|
||||
/* Convert TO host byte order */
|
||||
for (i = 0; i < 6; i++)
|
||||
BE_64_TO_8(digest + i * 8, context->state.st64[i]);
|
||||
#else
|
||||
memcpy(digest, context->state.st64, SHA384_DIGEST_LENGTH);
|
||||
#endif
|
||||
/* Zero out state data */
|
||||
//explicit_bzero(context, sizeof(*context));
|
||||
}
|
161
src/tls_none.c
Normal file
161
src/tls_none.c
Normal file
@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Copyright (c) 2022 Joris Vink <joris@coders.se>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* An empty TLS backend that does nothing, useful if you do
|
||||
* not require any TLS stuff in Kore.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "kore.h"
|
||||
|
||||
struct kore_privsep keymgr_privsep;
|
||||
char *kore_rand_file = NULL;
|
||||
int kore_keymgr_active = 0;
|
||||
|
||||
int
|
||||
kore_tls_supported(void)
|
||||
{
|
||||
return (KORE_RESULT_ERROR);
|
||||
}
|
||||
|
||||
void
|
||||
kore_keymgr_cleanup(int final)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
kore_tls_init(void)
|
||||
{
|
||||
kore_log(LOG_ERR, "No compiled in TLS backend");
|
||||
}
|
||||
|
||||
void
|
||||
kore_tls_cleanup(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
kore_tls_dh_check(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
kore_tls_keymgr_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
kore_tls_connection_cleanup(struct connection *c)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
kore_tls_domain_cleanup(struct kore_domain *dom)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
kore_tls_seed(const void *data, size_t len)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
kore_keymgr_run(void)
|
||||
{
|
||||
fatal("%s: not supported", __func__);
|
||||
}
|
||||
|
||||
void
|
||||
kore_tls_version_set(int version)
|
||||
{
|
||||
fatal("%s: not supported", __func__);
|
||||
}
|
||||
|
||||
int
|
||||
kore_tls_dh_load(const char *path)
|
||||
{
|
||||
fatal("%s: not supported", __func__);
|
||||
}
|
||||
|
||||
int
|
||||
kore_tls_ciphersuite_set(const char *list)
|
||||
{
|
||||
fatal("%s: not supported", __func__);
|
||||
}
|
||||
|
||||
void
|
||||
kore_tls_domain_setup(struct kore_domain *dom, int type,
|
||||
const void *data, size_t datalen)
|
||||
{
|
||||
fatal("%s: not supported", __func__);
|
||||
}
|
||||
|
||||
void
|
||||
kore_tls_domain_crl(struct kore_domain *dom, const void *pem, size_t pemlen)
|
||||
{
|
||||
fatal("%s: not supported", __func__);
|
||||
}
|
||||
|
||||
int
|
||||
kore_tls_connection_accept(struct connection *c)
|
||||
{
|
||||
fatal("%s: not supported", __func__);
|
||||
}
|
||||
|
||||
int
|
||||
kore_tls_read(struct connection *c, size_t *bytes)
|
||||
{
|
||||
fatal("%s: not supported", __func__);
|
||||
}
|
||||
|
||||
int
|
||||
kore_tls_write(struct connection *c, size_t len, size_t *written)
|
||||
{
|
||||
fatal("%s: not supported", __func__);
|
||||
}
|
||||
|
||||
void *
|
||||
kore_tls_rsakey_load(const char *path)
|
||||
{
|
||||
fatal("%s: not supported", __func__);
|
||||
}
|
||||
|
||||
void *
|
||||
kore_tls_rsakey_generate(const char *path)
|
||||
{
|
||||
fatal("%s: not supported", __func__);
|
||||
}
|
||||
|
||||
void *
|
||||
kore_tls_x509_subject_name(struct connection *c)
|
||||
{
|
||||
fatal("%s: not supported", __func__);
|
||||
}
|
||||
|
||||
void *
|
||||
kore_tls_x509_issuer_name(struct connection *c)
|
||||
{
|
||||
fatal("%s: not supported", __func__);
|
||||
}
|
||||
|
||||
int
|
||||
kore_tls_x509name_foreach(void *name, int flags, void *udata,
|
||||
int (*cb)(void *, int, int, const char *, const void *, size_t, int))
|
||||
{
|
||||
fatal("%s: not supported", __func__);
|
||||
}
|
1156
src/tls_openssl.c
Normal file
1156
src/tls_openssl.c
Normal file
File diff suppressed because it is too large
Load Diff
125
src/utils.c
125
src/utils.c
@ -17,9 +17,6 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/rsa.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
@ -57,7 +54,6 @@ static int utils_base64_decode(const char *, u_int8_t **,
|
||||
static int utils_x509name_tobuf(void *, int, int, const char *,
|
||||
const void *, size_t, int);
|
||||
|
||||
|
||||
static char b64_table[] = \
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
@ -475,59 +471,6 @@ kore_read_line(FILE *fp, char *in, size_t len)
|
||||
return (p);
|
||||
}
|
||||
|
||||
EVP_PKEY *
|
||||
kore_rsakey_load(const char *path)
|
||||
{
|
||||
FILE *fp;
|
||||
EVP_PKEY *pkey;
|
||||
|
||||
if (access(path, R_OK) == -1)
|
||||
return (NULL);
|
||||
|
||||
if ((fp = fopen(path, "r")) == NULL)
|
||||
fatalx("%s(%s): %s", __func__, path, errno_s);
|
||||
|
||||
if ((pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL)) == NULL)
|
||||
fatalx("PEM_read_PrivateKey: %s", ssl_errno_s);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return (pkey);
|
||||
}
|
||||
|
||||
EVP_PKEY *
|
||||
kore_rsakey_generate(const char *path)
|
||||
{
|
||||
FILE *fp;
|
||||
EVP_PKEY_CTX *ctx;
|
||||
EVP_PKEY *pkey;
|
||||
|
||||
if ((ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL)) == NULL)
|
||||
fatalx("EVP_PKEY_CTX_new_id: %s", ssl_errno_s);
|
||||
|
||||
if (EVP_PKEY_keygen_init(ctx) <= 0)
|
||||
fatalx("EVP_PKEY_keygen_init: %s", ssl_errno_s);
|
||||
|
||||
if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, KORE_RSAKEY_BITS) <= 0)
|
||||
fatalx("EVP_PKEY_CTX_set_rsa_keygen_bits: %s", ssl_errno_s);
|
||||
|
||||
pkey = NULL;
|
||||
if (EVP_PKEY_keygen(ctx, &pkey) <= 0)
|
||||
fatalx("EVP_PKEY_keygen: %s", ssl_errno_s);
|
||||
|
||||
if (path != NULL) {
|
||||
if ((fp = fopen(path, "w")) == NULL)
|
||||
fatalx("fopen(%s): %s", path, errno_s);
|
||||
|
||||
if (!PEM_write_PrivateKey(fp, pkey, NULL, NULL, 0, NULL, NULL))
|
||||
fatalx("PEM_write_PrivateKey: %s", ssl_errno_s);
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
return (pkey);
|
||||
}
|
||||
|
||||
const char *
|
||||
kore_worker_name(int id)
|
||||
{
|
||||
@ -552,14 +495,15 @@ int
|
||||
kore_x509_issuer_name(struct connection *c, char **out, int flags)
|
||||
{
|
||||
struct kore_buf buf;
|
||||
X509_NAME *name;
|
||||
void *name;
|
||||
|
||||
if ((name = X509_get_issuer_name(c->cert)) == NULL)
|
||||
if ((name = kore_tls_x509_issuer_name(c->cert)) == NULL)
|
||||
return (KORE_RESULT_ERROR);
|
||||
|
||||
kore_buf_init(&buf, 1024);
|
||||
|
||||
if (!kore_x509name_foreach(name, flags, &buf, utils_x509name_tobuf)) {
|
||||
if (!kore_tls_x509name_foreach(name, flags, &buf,
|
||||
utils_x509name_tobuf)) {
|
||||
kore_buf_cleanup(&buf);
|
||||
return (KORE_RESULT_ERROR);
|
||||
}
|
||||
@ -576,14 +520,15 @@ int
|
||||
kore_x509_subject_name(struct connection *c, char **out, int flags)
|
||||
{
|
||||
struct kore_buf buf;
|
||||
X509_NAME *name;
|
||||
void *name;
|
||||
|
||||
if ((name = X509_get_subject_name(c->cert)) == NULL)
|
||||
if ((name = kore_tls_x509_subject_name(c)) == NULL)
|
||||
return (KORE_RESULT_ERROR);
|
||||
|
||||
kore_buf_init(&buf, 1024);
|
||||
|
||||
if (!kore_x509name_foreach(name, flags, &buf, utils_x509name_tobuf)) {
|
||||
if (!kore_tls_x509name_foreach(name, flags, &buf,
|
||||
utils_x509name_tobuf)) {
|
||||
kore_buf_cleanup(&buf);
|
||||
return (KORE_RESULT_ERROR);
|
||||
}
|
||||
@ -596,58 +541,6 @@ kore_x509_subject_name(struct connection *c, char **out, int flags)
|
||||
return (KORE_RESULT_OK);
|
||||
}
|
||||
|
||||
int
|
||||
kore_x509name_foreach(X509_NAME *name, int flags, void *udata,
|
||||
int (*cb)(void *, int, int, const char *, const void *, size_t, int))
|
||||
{
|
||||
u_int8_t *data;
|
||||
ASN1_STRING *astr;
|
||||
X509_NAME_ENTRY *entry;
|
||||
const char *field;
|
||||
int islast, ret, idx, namelen, nid, len;
|
||||
|
||||
data = NULL;
|
||||
ret = KORE_RESULT_ERROR;
|
||||
|
||||
if ((namelen = X509_NAME_entry_count(name)) == 0)
|
||||
goto cleanup;
|
||||
|
||||
for (idx = 0; idx < namelen; idx++) {
|
||||
if ((entry = X509_NAME_get_entry(name, idx)) == NULL)
|
||||
goto cleanup;
|
||||
|
||||
nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(entry));
|
||||
if ((field = OBJ_nid2sn(nid)) == NULL)
|
||||
goto cleanup;
|
||||
|
||||
if ((astr = X509_NAME_ENTRY_get_data(entry)) == NULL)
|
||||
goto cleanup;
|
||||
|
||||
data = NULL;
|
||||
if ((len = ASN1_STRING_to_UTF8(&data, astr)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (idx != (namelen - 1))
|
||||
islast = 0;
|
||||
else
|
||||
islast = 1;
|
||||
|
||||
if (!cb(udata, islast, nid, field, data, len, flags))
|
||||
goto cleanup;
|
||||
|
||||
OPENSSL_free(data);
|
||||
data = NULL;
|
||||
}
|
||||
|
||||
ret = KORE_RESULT_OK;
|
||||
|
||||
cleanup:
|
||||
if (data != NULL)
|
||||
OPENSSL_free(data);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
void
|
||||
fatal(const char *fmt, ...)
|
||||
{
|
||||
@ -695,7 +588,7 @@ utils_x509name_tobuf(void *udata, int islast, int nid, const char *field,
|
||||
struct kore_buf *buf = udata;
|
||||
|
||||
if (flags & KORE_X509_COMMON_NAME_ONLY) {
|
||||
if (nid == NID_commonName)
|
||||
if (nid == KORE_X509_NAME_COMMON_NAME)
|
||||
kore_buf_append(buf, data, len);
|
||||
} else {
|
||||
kore_buf_appendf(buf, "%s=", field);
|
||||
|
@ -17,13 +17,12 @@
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <openssl/sha.h>
|
||||
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "kore.h"
|
||||
#include "http.h"
|
||||
#include "sha1.h"
|
||||
|
||||
#define WEBSOCKET_FRAME_HDR 2
|
||||
#define WEBSOCKET_MASK_LEN 4
|
||||
@ -53,11 +52,11 @@ void
|
||||
kore_websocket_handshake(struct http_request *req, const char *onconnect,
|
||||
const char *onmessage, const char *ondisconnect)
|
||||
{
|
||||
SHA_CTX sctx;
|
||||
SHA1_CTX sctx;
|
||||
struct kore_buf *buf;
|
||||
char *base64;
|
||||
const char *key, *version;
|
||||
u_int8_t digest[SHA_DIGEST_LENGTH];
|
||||
u_int8_t digest[SHA1_DIGEST_LENGTH];
|
||||
|
||||
if (!http_request_header(req, "sec-websocket-key", &key)) {
|
||||
http_response(req, HTTP_STATUS_BAD_REQUEST, NULL, 0);
|
||||
@ -79,9 +78,9 @@ kore_websocket_handshake(struct http_request *req, const char *onconnect,
|
||||
buf = kore_buf_alloc(128);
|
||||
kore_buf_appendf(buf, "%s%s", key, WEBSOCKET_SERVER_RESPONSE);
|
||||
|
||||
(void)SHA1_Init(&sctx);
|
||||
(void)SHA1_Update(&sctx, buf->data, buf->offset);
|
||||
(void)SHA1_Final(digest, &sctx);
|
||||
SHA1Init(&sctx);
|
||||
SHA1Update(&sctx, buf->data, buf->offset);
|
||||
SHA1Final(digest, &sctx);
|
||||
|
||||
kore_buf_free(buf);
|
||||
|
||||
|
21
src/worker.c
21
src/worker.c
@ -23,8 +23,6 @@
|
||||
#include <sys/resource.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <openssl/rand.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
@ -163,7 +161,7 @@ kore_worker_init(void)
|
||||
return (KORE_RESULT_ERROR);
|
||||
}
|
||||
|
||||
if (keymgr_active) {
|
||||
if (kore_keymgr_active) {
|
||||
#if defined(KORE_USE_ACME)
|
||||
/* The ACME process is only started if we need it. */
|
||||
if (acme_domains) {
|
||||
@ -491,7 +489,7 @@ kore_worker_entry(struct kore_worker *kw)
|
||||
#endif
|
||||
kore_timer_init();
|
||||
kore_fileref_init();
|
||||
kore_domain_keymgr_init();
|
||||
kore_tls_keymgr_init();
|
||||
|
||||
quit = 0;
|
||||
had_lock = 0;
|
||||
@ -501,7 +499,7 @@ kore_worker_entry(struct kore_worker *kw)
|
||||
|
||||
last_seed = 0;
|
||||
|
||||
if (keymgr_active) {
|
||||
if (kore_keymgr_active) {
|
||||
kore_msg_register(KORE_MSG_CRL, worker_keymgr_response);
|
||||
kore_msg_register(KORE_MSG_ENTROPY_RESP, worker_entropy_recv);
|
||||
kore_msg_register(KORE_MSG_CERTIFICATE, worker_keymgr_response);
|
||||
@ -536,7 +534,8 @@ kore_worker_entry(struct kore_worker *kw)
|
||||
for (;;) {
|
||||
now = kore_time_ms();
|
||||
|
||||
if (keymgr_active && (now - last_seed) > KORE_RESEED_TIME) {
|
||||
if (kore_keymgr_active &&
|
||||
(now - last_seed) > KORE_RESEED_TIME) {
|
||||
kore_msg_send(KORE_WORKER_KEYMGR,
|
||||
KORE_MSG_ENTROPY_REQ, NULL, 0);
|
||||
last_seed = now;
|
||||
@ -636,6 +635,7 @@ kore_worker_entry(struct kore_worker *kw)
|
||||
kore_platform_event_cleanup();
|
||||
kore_connection_cleanup();
|
||||
kore_domain_cleanup();
|
||||
kore_tls_cleanup();
|
||||
kore_module_cleanup();
|
||||
#if !defined(KORE_NO_HTTP)
|
||||
http_cleanup();
|
||||
@ -1035,8 +1035,7 @@ worker_entropy_recv(struct kore_msg *msg, const void *data)
|
||||
msg->length);
|
||||
}
|
||||
|
||||
RAND_poll();
|
||||
RAND_seed(data, msg->length);
|
||||
kore_tls_seed(data, msg->length);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1052,16 +1051,16 @@ worker_keymgr_response(struct kore_msg *msg, const void *data)
|
||||
|
||||
switch (msg->id) {
|
||||
case KORE_MSG_CERTIFICATE:
|
||||
kore_domain_tlsinit(dom, KORE_PEM_CERT_CHAIN,
|
||||
kore_tls_domain_setup(dom, KORE_PEM_CERT_CHAIN,
|
||||
req->data, req->data_len);
|
||||
break;
|
||||
case KORE_MSG_CRL:
|
||||
kore_domain_crl_add(dom, req->data, req->data_len);
|
||||
kore_tls_domain_crl(dom, req->data, req->data_len);
|
||||
break;
|
||||
#if defined(KORE_USE_ACME)
|
||||
case KORE_ACME_CHALLENGE_SET_CERT:
|
||||
if (dom->ssl_ctx == NULL) {
|
||||
kore_domain_tlsinit(dom, KORE_DER_CERT_DATA,
|
||||
kore_tls_domain_setup(dom, KORE_DER_CERT_DATA,
|
||||
req->data, req->data_len);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user