From 49353ed2783531b3c8fcb7a522dc6f578ea5414c Mon Sep 17 00:00:00 2001 From: Tobias Pape Date: Tue, 30 Jan 2018 20:09:38 +0100 Subject: [PATCH 1/4] [SqueakSSL] Overlay OpenSSL for linux/unix When we dynamically link against OpenSSL, the bundles are not portable, as CentOS and friends use other SO_NAMEs than Debian and friends. Also, soft-fallback for later features such as host name verification is hard. When we statically link, we might lack behind the OS, the binaries are bigger, and the legal situation is less clear. So we now support not linking at all but rather lookup all necessary functions/symbols at runtime. This can be disabled with SQSSL_OPENSSL_LINKED which effectively results in the dynamically-linked behavior. (This is preferable for platform builds, eg, debs and rpms) --- platforms/unix/plugins/SqueakSSL/Makefile.inc | 9 +- platforms/unix/plugins/SqueakSSL/config.cmake | 10 +- .../unix/plugins/SqueakSSL/openssl_overlay.h | 299 ++++++++++++++++++ .../unix/plugins/SqueakSSL/sqUnixOpenSSL.c | 173 +++++----- 4 files changed, 406 insertions(+), 85 deletions(-) create mode 100644 platforms/unix/plugins/SqueakSSL/openssl_overlay.h diff --git a/platforms/unix/plugins/SqueakSSL/Makefile.inc b/platforms/unix/plugins/SqueakSSL/Makefile.inc index 524eda7d29..56bbe5138f 100644 --- a/platforms/unix/plugins/SqueakSSL/Makefile.inc +++ b/platforms/unix/plugins/SqueakSSL/Makefile.inc @@ -1,2 +1,9 @@ +# +# For platform builds, use + #XLDFLAGS= -lcrypto -lssl -XLDFLAGS= -Wl,--no-as-needed -lrt -Wl,-Bstatic -lcrypto -lssl -Wl,-Bdynamic -lrt +#XCFLAGS= -DSQSSL_OPENSSL_LINKED + +# otherwise the OpenSSL libs will be looked up at runtime. +# +# diff --git a/platforms/unix/plugins/SqueakSSL/config.cmake b/platforms/unix/plugins/SqueakSSL/config.cmake index 08b53ce4da..07c14cfbe1 100644 --- a/platforms/unix/plugins/SqueakSSL/config.cmake +++ b/platforms/unix/plugins/SqueakSSL/config.cmake @@ -1 +1,9 @@ -PLUGIN_REQUIRE_PACKAGE (OPENSSL openssl) +# +# For platform builds, use + +# PLUGIN_REQUIRE_PACKAGE (OPENSSL openssl) +# add_definitions(-DSQSSL_OPENSSL_LINKED) + +# otherwise the OpenSSL libs will be looked up at runtime. +# +# \ No newline at end of file diff --git a/platforms/unix/plugins/SqueakSSL/openssl_overlay.h b/platforms/unix/plugins/SqueakSSL/openssl_overlay.h new file mode 100644 index 0000000000..d426b445cc --- /dev/null +++ b/platforms/unix/plugins/SqueakSSL/openssl_overlay.h @@ -0,0 +1,299 @@ +#ifndef SQ_OPENSSL_OVERLAY_H +#define SQ_OPENSSL_OVERLAY_H 1 + +#include +#include +#include +#include +#include + + +static void* dlhandle_self = NULL; +static void* dlhandle_crypto = NULL; +static void* dlhandle_ssl = NULL; + +#ifndef __has_attribute +#define __has_attribute(x) 0 +#endif + +#if __has_attribute(constructor) \ + || defined(__GNUC__) +#define SQO_CONSTRUCTOR __attribute__((constructor)) +#else +#define SQO_CONSTRUCTOR /**/ +#endif + +void SQO_CONSTRUCTOR fini(void) +{ + if (dlhandle_self) { dlclose(dlhandle_self); } + if (dlhandle_crypto) { dlclose(dlhandle_crypto); } + if (dlhandle_ssl) { dlclose(dlhandle_ssl);} +} + +#if (defined(DEBUG) || defined(DEBUGVM)) && !defined(NDEBUG) +#define SQO_HAS_FOUND_SYM(s,n,h) \ + do { \ + s = dlsym(h, n); \ + if (s) { \ + fprintf(stderr, "Found symbol %s in " #h "\n", n); \ + return s; \ + } \ + } while (0) +#else +#define SQO_HAS_FOUND_SYM(s,n,h) \ + do { \ + if ((s = dlsym(h, n))) { \ + return s; \ + } \ + } while (0) +#endif + +#if !defined(SQO_DL_FLAGS) +#define SQO_DL_FLAGS RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE +#endif + +#define SQO_FIND_SYM(sym, name, where, dlname) \ + do { \ + if (!dlhandle_ ## where) { \ + dlhandle_ ## where = dlopen(dlname, SQO_DL_FLAGS); \ + if (!dlhandle_ ## where) { \ + fprintf(stderr, "cannot load from " #dlname "\n"); \ + abort(); \ + } \ + } \ + if (dlhandle_ ## where) { \ + SQO_HAS_FOUND_SYM(sym, name, dlhandle_ ## where); \ + } \ + } while (0) + + +static inline void* _sqo_find(const char* name) +{ + void* sym = NULL; + SQO_HAS_FOUND_SYM(sym, name, RTLD_DEFAULT); + SQO_FIND_SYM(sym, name, self, NULL); + SQO_FIND_SYM(sym, name, ssl, "libssl.so"); + SQO_FIND_SYM(sym, name, crypto, "libcrypto.so"); + return sym; +} + + +unsigned char *(*sqo_ASN1_STRING_data)(ASN1_STRING *x); +int (*sqo_ASN1_STRING_length)(const ASN1_STRING *x); +void (*sqo_BIO_free_all)(BIO *a); +BIO *(*sqo_BIO_new)(BIO_METHOD *type); +BIO_METHOD *(*sqo_BIO_s_mem)(void); +long (*sqo_BIO_ctrl)(BIO *bp, int cmd, long larg, void *parg); +size_t (*sqo_BIO_ctrl_pending)(BIO *bp); +int (*sqo_BIO_write)(BIO *b, const void *data, int len); +int (*sqo_BIO_read)(BIO *b, void *data, int len); +void (*sqo_ERR_print_errors_fp)(FILE *fp); +void (*sqo_SSL_CTX_free)(SSL_CTX *); + +#if OPENSSL_VERSION_NUMBER >= 0x10000000L +const SSL_METHOD *(*sqo_SSLv23_method)(void); +SSL_CTX *(*sqo_SSL_CTX_new)(const SSL_METHOD *a); +#else +SSL_METHOD *(*sqo_SSLv23_method)(void); +SSL_CTX *(*sqo_SSL_CTX_new)(SSL_METHOD *a); +#endif + +int (*sqo_SSL_CTX_set_cipher_list)(SSL_CTX *, const char *str); +int (*sqo_SSL_CTX_set_default_verify_paths)(SSL_CTX *ctx); +long (*sqo_SSL_CTX_ctrl)(SSL_CTX *ctx, int cmd, long larg, void *parg); +int (*sqo_SSL_CTX_use_PrivateKey_file)(SSL_CTX *ctx, const char *file, int type); +int (*sqo_SSL_CTX_use_certificate_file)(SSL_CTX *ctx, const char *file, int type); +int (*sqo_SSL_accept)(SSL *ssl); +int (*sqo_SSL_connect)(SSL *ssl); +void (*sqo_SSL_free)(SSL *ssl); +long (*sqo_SSL_ctrl)(SSL *ssl, int cmd, long larg, void *parg); +int (*sqo_SSL_get_error)(const SSL *s, int ret_code); +X509 *(*sqo_SSL_get_peer_certificate)(const SSL *s); +long (*sqo_SSL_get_verify_result)(const SSL *ssl); +int (*sqo_SSL_library_init)(void); +void (*sqo_SSL_load_error_strings)(void); +SSL *(*sqo_SSL_new)(SSL_CTX *ctx); +int (*sqo_SSL_read)(SSL *ssl, void *buf, int num); +void (*sqo_SSL_set_accept_state)(SSL *s); +void (*sqo_SSL_set_bio)(SSL *s, BIO *rbio, BIO *wbio); +void (*sqo_SSL_set_connect_state)(SSL *s); +int (*sqo_SSL_write)(SSL *ssl, const void *buf, int num); +int (*sqo_X509_NAME_get_text_by_NID)(X509_NAME *name, int nid, char *buf, int len); +X509_NAME *(*sqo_X509_get_subject_name)(X509 *a); +void *(*sqo_X509_get_ext_d2i)(X509 *x, int nid, int *crit, int *idx); +void (*sqo_X509_free)(X509 *ssl); + +// OPENSSL_VERSION_NUMBER >= 0x10002000L +int (*sqo_X509_check_ip_asc)(X509 *x, const char *ipasc, unsigned int flags); +int (*sqo_X509_check_host)(X509 *x, const char *chk, size_t chklen, unsigned int flags, char **peername); + +#if OPENSSL_VERSION_NUMBER >= 0x10000000L +_STACK *(*sqo_sk_new_null)(void); +int (*sqo_sk_push)(_STACK *st, void *data); +void (*sqo_sk_free)(_STACK *st); +void *(*sqo_sk_value)(const _STACK *st, int i); +int (*sqo_sk_num)(const _STACK *st); +void (*sqo_sk_pop_free)(_STACK *st, void (*func) (void *)); +#else +STACK *(*sqo_sk_new_null)(void); +int (*sqo_sk_push)(STACK *st, char *data); +void (*sqo_sk_free)(STACK *st); +char *(*sqo_sk_value)(STACK *st, int i); +int (*sqo_sk_num)(STACK *st); +void (*sqo_sk_pop_free)(STACK *st, void (*func) (void *)); +#endif // OPENSSL_VERSION_NUMBER >= 0x10000000L + +#define sqo_BIO_set_close(b,c) \ + (int)sqo_BIO_ctrl(b,BIO_CTRL_SET_CLOSE,(c),NULL) + +#define sqo_SSL_set_tlsext_host_name(s,name) \ + sqo_SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_HOSTNAME,TLSEXT_NAMETYPE_host_name,(char *)name) + +#define sqo_SSL_CTX_set_options(ctx,op) \ + sqo_SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,(op),NULL) + +#define sqo_SKM_sk_num(type, st) \ + sqo_sk_num(CHECKED_STACK_OF(type, st)) +#define sqo_SKM_sk_value(type, st,i) \ + ((type *)sqo_sk_value(CHECKED_STACK_OF(type, st), i)) +#define sqo_SKM_sk_free(type, st) \ + sqo_sk_free(CHECKED_STACK_OF(type, st)) +#define sqo_SKM_sk_pop_free(type, st, free_func) \ + sqo_sk_pop_free(CHECKED_STACK_OF(type, st), CHECKED_SK_FREE_FUNC(type, free_func)) +#define sqo_sk_GENERAL_NAME_num(st) \ + sqo_SKM_sk_num(GENERAL_NAME, (st)) +#define sqo_sk_GENERAL_NAME_value(st, i) \ + sqo_SKM_sk_value(GENERAL_NAME, (st), (i)) +#define sqo_sk_GENERAL_NAME_free(st) \ + sqo_SKM_sk_free(GENERAL_NAME, (st)) +#define sqo_sk_GENERAL_NAME_pop_free(st, free_func) \ + sqo_SKM_sk_pop_free(GENERAL_NAME, (st), (free_func)) + + + +bool loadLibrary(void) +{ +#if defined(SQSSL_FORCE_LINK_OPENSSL) + sqo_ASN1_STRING_data = &ASN1_STRING_data; + sqo_ASN1_STRING_length = &ASN1_STRING_length; + sqo_BIO_free_all = &BIO_free_all; + sqo_BIO_new = &BIO_new; + sqo_BIO_s_mem = &BIO_s_mem; + sqo_BIO_ctrl = &BIO_ctrl; + sqo_BIO_ctrl_pending = &BIO_ctrl_pending; + sqo_BIO_write = &BIO_write; + sqo_BIO_read = &BIO_read; + sqo_ERR_print_errors_fp = &ERR_print_errors_fp; + sqo_SSL_CTX_free = &SSL_CTX_free; + sqo_SSLv23_method = &SSLv23_method; + sqo_SSL_CTX_new = &SSL_CTX_new; + sqo_SSL_CTX_set_cipher_list = &SSL_CTX_set_cipher_list; + sqo_SSL_CTX_set_default_verify_paths = &SSL_CTX_set_default_verify_paths; + sqo_SSL_CTX_ctrl = &SSL_CTX_ctrl; + sqo_SSL_CTX_use_PrivateKey_file = &SSL_CTX_use_PrivateKey_file; + sqo_SSL_CTX_use_certificate_file = &SSL_CTX_use_certificate_file; + sqo_SSL_accept = &SSL_accept; + sqo_SSL_connect = &SSL_connect; + sqo_SSL_free = &SSL_free; + sqo_SSL_ctrl = &SSL_ctrl; + sqo_SSL_get_error = &SSL_get_error; + sqo_SSL_get_peer_certificate = &SSL_get_peer_certificate; + sqo_SSL_get_verify_result = &SSL_get_verify_result; + sqo_SSL_library_init = &SSL_library_init; + sqo_SSL_load_error_strings = &SSL_load_error_strings; + sqo_SSL_new = &SSL_new; + sqo_SSL_read = &SSL_read; + sqo_SSL_set_accept_state = &SSL_set_accept_state; + sqo_SSL_set_bio = &SSL_set_bio; + sqo_SSL_set_connect_state = &SSL_set_connect_state; + sqo_SSL_write = &SSL_write; + sqo_X509_NAME_get_text_by_NID = &X509_NAME_get_text_by_NID; + sqo_X509_get_subject_name = &X509_get_subject_name; + sqo_X509_get_ext_d2i = &X509_get_ext_d2i; + sqo_X509_free = &X509_free; +#if OPENSSL_VERSION_NUMBER >= 0x10002000L + sqo_X509_check_ip_asc = &X509_check_ip_asc; + sqo_X509_check_host = &X509_check_host; +#else + sqo_X509_check_ip_asc = NULL; + sqo_X509_check_host = NULL; +#endif + + sqo_sk_new_null = &sk_new_null; + sqo_sk_push = &sk_push; + sqo_sk_free = &sk_free; + sqo_sk_value = &sk_value; + sqo_sk_num = &sk_num; + sqo_sk_pop_free = &sk_pop_free; + + return true; +#else + +#define _C(X) if ((X) == NULL) return false + _C(sqo_ASN1_STRING_data = (unsigned char *(*)(ASN1_STRING *x)) _sqo_find("ASN1_STRING_data")); + _C(sqo_ASN1_STRING_length = (int (*)(const ASN1_STRING *x)) _sqo_find("ASN1_STRING_length")); + _C(sqo_BIO_free_all = (void (*)(BIO *a)) _sqo_find("BIO_free_all")); + _C(sqo_BIO_new = (BIO *(*)(BIO_METHOD *type)) _sqo_find("BIO_new")); + _C(sqo_BIO_s_mem = (BIO_METHOD *(*)(void)) _sqo_find("BIO_s_mem")); + _C(sqo_BIO_ctrl = (long (*)(BIO *bp, int cmd, long larg, void *parg)) _sqo_find("BIO_ctrl")); + _C(sqo_BIO_ctrl_pending = (size_t (*)(BIO *)) _sqo_find("BIO_ctrl_pending")); + _C(sqo_BIO_write = (int (*)(BIO *b, const void *data, int len)) _sqo_find("BIO_write")); + _C(sqo_BIO_read = (int (*)(BIO *b, void *data, int len)) _sqo_find("BIO_read")); + _C(sqo_ERR_print_errors_fp = (void (*)(FILE *fp)) _sqo_find("ERR_print_errors_fp")); + _C(sqo_SSL_CTX_free = (void (*)(SSL_CTX *)) _sqo_find("SSL_CTX_free")); + +#if OPENSSL_VERSION_NUMBER >= 0x10000000L + _C(sqo_SSLv23_method = (const SSL_METHOD *(*)(void)) _sqo_find("SSLv23_method")); + _C(sqo_SSL_CTX_new = (SSL_CTX *(*)(const SSL_METHOD *a)) _sqo_find("SSL_CTX_new")); +#else + _C(sqo_SSLv23_method = (SSL_METHOD *(*)(void)) _sqo_find("SSLv23_method")); + _C(sqo_SSL_CTX_new = (SSL_CTX *(*)(SSL_METHOD *a)) _sqo_find("SSL_CTX_new")); +#endif + + _C(sqo_SSL_CTX_set_cipher_list = (int (*)(SSL_CTX *, const char *str)) _sqo_find("SSL_CTX_set_cipher_list")); + _C(sqo_SSL_CTX_set_default_verify_paths = (int (*)(SSL_CTX *ctx)) _sqo_find("SSL_CTX_set_default_verify_paths")); + _C(sqo_SSL_CTX_ctrl = (long (*)(SSL_CTX *ctx, int cmd, long larg, void *parg)) _sqo_find("SSL_CTX_ctrl")); + _C(sqo_SSL_CTX_use_PrivateKey_file = (int (*)(SSL_CTX *ctx, const char *file, int type)) _sqo_find("SSL_CTX_use_PrivateKey_file")); + _C(sqo_SSL_CTX_use_certificate_file = (int (*)(SSL_CTX *ctx, const char *file, int type)) _sqo_find("SSL_CTX_use_certificate_file")); + _C(sqo_SSL_accept = (int (*)(SSL *ssl)) _sqo_find("SSL_accept")); + _C(sqo_SSL_connect = (int (*)(SSL *ssl)) _sqo_find("SSL_connect")); + _C(sqo_SSL_free = (void (*)(SSL *ssl)) _sqo_find("SSL_free")); + _C(sqo_SSL_ctrl = (long (*)(SSL *ssl, int cmd, long larg, void *parg)) _sqo_find("SSL_ctrl")); + _C(sqo_SSL_get_error = (int (*)(const SSL *s, int ret_code)) _sqo_find("SSL_get_error")); + _C(sqo_SSL_get_peer_certificate = (X509 *(*)(const SSL *s)) _sqo_find("SSL_get_peer_certificate")); + _C(sqo_SSL_get_verify_result = (long (*)(const SSL *ssl)) _sqo_find("SSL_get_verify_result")); + _C(sqo_SSL_library_init = (int (*)(void)) _sqo_find("SSL_library_init")); + _C(sqo_SSL_load_error_strings = (void (*)(void)) _sqo_find("SSL_load_error_strings")); + _C(sqo_SSL_new = (SSL *(*)(SSL_CTX *ctx)) _sqo_find("SSL_new")); + _C(sqo_SSL_read = (int (*)(SSL *ssl, void *buf, int num)) _sqo_find("SSL_read")); + _C(sqo_SSL_set_accept_state = (void (*)(SSL *s)) _sqo_find("SSL_set_accept_state")); + _C(sqo_SSL_set_bio = (void (*)(SSL *s, BIO *rbio, BIO *wbio)) _sqo_find("SSL_set_bio")); + _C(sqo_SSL_set_connect_state = (void (*)(SSL *s)) _sqo_find("SSL_set_connect_state")); + _C(sqo_SSL_write = (int (*)(SSL *ssl, const void *buf, int num)) _sqo_find("SSL_write")); + _C(sqo_X509_NAME_get_text_by_NID = (int (*)(X509_NAME *name, int nid, char *buf, int len)) _sqo_find("X509_NAME_get_text_by_NID")); + _C(sqo_X509_get_subject_name = (X509_NAME *(*)(X509 *a)) _sqo_find("X509_get_subject_name")); + _C(sqo_X509_get_ext_d2i = (void *(*)(X509 *x, int nid, int *crit, int *idx)) _sqo_find("X509_get_ext_d2i")); + _C(sqo_X509_free = (void (*)(X509 *)) _sqo_find("X509_free")); + sqo_X509_check_ip_asc = (int (*)(X509 *x, const char *ipasc, unsigned int flags)) _sqo_find("X509_check_ip_asc"); + sqo_X509_check_host = (int (*)(X509 *x, const char *chk, size_t chklen, unsigned int flags, char **peername)) _sqo_find("X509_check_host"); + +#if OPENSSL_VERSION_NUMBER >= 0x10000000L + _C(sqo_sk_new_null = (_STACK *(*)(void)) _sqo_find("sk_new_null")); + _C(sqo_sk_push = (int (*)(_STACK *st, void *data)) _sqo_find("sk_push")); + _C(sqo_sk_free = (void (*)(_STACK *st)) _sqo_find("sk_free")); + _C(sqo_sk_value = (void *(*)(const _STACK *st, int i)) _sqo_find("sk_value")); + _C(sqo_sk_num = (int (*)(const _STACK *st)) _sqo_find("sk_num")); + _C(sqo_sk_pop_free = (void (*)(_STACK *st, void (*func) (void *))) _sqo_find("sk_pop_free")); +#else + _C(sqo_sk_new_null = (STACK *(*)(void)) _sqo_find("sk_new_null")); + _C(sqo_sk_push = (int (*)(STACK *st, char *data)) _sqo_find("sk_push")); + _C(sqo_sk_free = (void (*)(STACK *st)) _sqo_find("sk_free")); + _C(sqo_sk_value = (char *(*)(STACK *st, int i)) _sqo_find("sk_value")); + _C(sqo_sk_num = (int (*)(STACK *st)) _sqo_find("sk_num")); + _C(sqo_sk_pop_free = (void (*)(STACK *st, void (*func) (void *))) _sqo_find("sk_pop_free")); +#endif // OPENSSL_VERSION_NUMBER >= 0x10000000L + return true; +#endif +} + +#endif diff --git a/platforms/unix/plugins/SqueakSSL/sqUnixOpenSSL.c b/platforms/unix/plugins/SqueakSSL/sqUnixOpenSSL.c index 39f38ca4b8..efd40d5873 100644 --- a/platforms/unix/plugins/SqueakSSL/sqUnixOpenSSL.c +++ b/platforms/unix/plugins/SqueakSSL/sqUnixOpenSSL.c @@ -1,13 +1,12 @@ #include "sq.h" #include "SqueakSSL.h" -#include "openssl/ssl.h" -#include "openssl/err.h" -#include "openssl/x509v3.h" +#include "openssl_overlay.h" #include #include #include +#include #include @@ -30,6 +29,8 @@ typedef struct sqSSL { } sqSSL; +static bool wasInitialized = false; + static sqSSL **handleBuf = NULL; static sqInt handleMax = 0; @@ -56,21 +57,20 @@ static sqSSL *sslFromHandle(sqInt handle) { /* sqCopyBioSSL: Copies data from a BIO into an out buffer */ sqInt sqCopyBioSSL(sqSSL *ssl, BIO *bio, char *dstBuf, sqInt dstLen) { - int nbytes = BIO_ctrl_pending(bio); + int nbytes = sqo_BIO_ctrl_pending(bio); if(ssl->loglevel) printf("sqCopyBioSSL: %d bytes pending; buffer size %ld\n", nbytes, (long)dstLen); if(nbytes > dstLen) return -1; - return BIO_read(bio, dstBuf, dstLen); + return sqo_BIO_read(bio, dstBuf, dstLen); } -#ifndef X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS enum sqMatchResult sqVerifyIP(sqSSL* ssl, X509* cert, const char* serverName, const size_t serverNameLength); enum sqMatchResult sqVerifyDNS(sqSSL* ssl, X509* cert, const char* serverName, const size_t serverNameLength); -enum sqMatchResult sqVerifyNameInner(sqSSL* ssl, X509* cert, void* serverName, const size_t serverNameLength, const int matchType); +enum sqMatchResult sqVerifyNameInner(sqSSL* ssl, X509* cert, const void* serverName, const size_t serverNameLength, const int matchType); char* sqVerifyFindStar(char* sANData, size_t sANDataSize); -sqInt sqVerifySAN(sqSSL* ssl, const GENERAL_NAME* sAN, void* data, const size_t dataSizeIn, const int matchType); +sqInt sqVerifySAN(sqSSL* ssl, const GENERAL_NAME* sAN, const void* data, const size_t dataSizeIn, const int matchType); enum sqMatchResult sqVerifyIP(sqSSL* ssl, X509* cert, const char* serverName, const size_t serverNameLength) { struct in6_addr addr = { 0 }; // placeholder, longest of in_addr and in6_addr @@ -95,25 +95,25 @@ enum sqMatchResult sqVerifyDNS(sqSSL* ssl, X509* cert, const char* serverName, c return sqVerifyNameInner(ssl, cert, serverName, serverNameLength, GEN_DNS); } -enum sqMatchResult sqVerifyNameInner(sqSSL* ssl, X509* cert, void* serverName, const size_t serverNameLength, const int matchType) { +enum sqMatchResult sqVerifyNameInner(sqSSL* ssl, X509* cert, const void* serverName, const size_t serverNameLength, const int matchType) { enum sqMatchResult matchFound = NO_MATCH_FOUND; - STACK_OF(GENERAL_NAME)* sANs = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL); + STACK_OF(GENERAL_NAME)* sANs = sqo_X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL); if (!sANs) { if (ssl->loglevel) printf("sqVerifyNameInner: No sAN names\n"); matchFound = NO_SAN_PRESENT; } else { int i = 0; - int sANCount = sk_GENERAL_NAME_num(sANs); + int sANCount = sqo_sk_GENERAL_NAME_num(sANs); for (i = 0; i < sANCount && matchFound != MATCH_FOUND; ++i) { - const GENERAL_NAME* sAN = sk_GENERAL_NAME_value(sANs, i); + const GENERAL_NAME* sAN = sqo_sk_GENERAL_NAME_value(sANs, i); if ((sAN->type == matchType) && sqVerifySAN(ssl, sAN, serverName, serverNameLength, matchType)) { matchFound = MATCH_FOUND; break; } } - sk_GENERAL_NAME_pop_free(sANs, GENERAL_NAME_free); + sqo_sk_GENERAL_NAME_pop_free(sANs, (void(*)(void*))sqo_sk_free); } return matchFound; } @@ -157,9 +157,9 @@ char* sqVerifyFindStar(char* sANData, size_t sANDataSize) { #undef FAIL_STAR } -sqInt sqVerifySAN(sqSSL* ssl, const GENERAL_NAME* sAN, void* data, const size_t dataSizeIn, const int matchType) { - char* sANData = (char *)ASN1_STRING_data(sAN->d.ia5); - size_t sANDataSize = (size_t)ASN1_STRING_length(sAN->d.ia5); +sqInt sqVerifySAN(sqSSL* ssl, const GENERAL_NAME* sAN, const void* data, const size_t dataSizeIn, const int matchType) { + char* sANData = (char *) sqo_ASN1_STRING_data(sAN->d.ia5); + size_t sANDataSize = (size_t) sqo_ASN1_STRING_length(sAN->d.ia5); size_t dataSize = dataSizeIn; if (ssl->loglevel) printf("sqVerifyNameInner: checking sAN %.*s\n", matchType == GEN_DNS ? (int) sANDataSize : 5 , matchType == GEN_DNS ? sANData : "an IP"); @@ -223,44 +223,44 @@ sqInt sqVerifySAN(sqSSL* ssl, const GENERAL_NAME* sAN, void* data, const size_t #undef NOPE #undef YEAH } -#endif -// X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS /* sqSetupSSL: Common SSL setup tasks */ sqInt sqSetupSSL(sqSSL *ssl, int server) { - /* Fixme. Needs to use specified version */ if(ssl->loglevel) printf("sqSetupSSL: setting method\n"); - ssl->method = (SSL_METHOD*) SSLv23_method(); + ssl->method = (SSL_METHOD*) sqo_SSLv23_method(); if(ssl->loglevel) printf("sqSetupSSL: Creating context\n"); - ssl->ctx = SSL_CTX_new(ssl->method); + ssl->ctx = sqo_SSL_CTX_new(ssl->method); if(ssl->loglevel) printf("sqSetupSSL: Disabling SSLv2 and SSLv3\n"); - SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); + sqo_SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); - if(!ssl->ctx) ERR_print_errors_fp(stdout); + if(!ssl->ctx) sqo_ERR_print_errors_fp(stdout); if(ssl->loglevel) printf("sqSetupSSL: setting cipher list\n"); - SSL_CTX_set_cipher_list(ssl->ctx, "!ADH:HIGH:MEDIUM:@STRENGTH"); + sqo_SSL_CTX_set_cipher_list(ssl->ctx, "!ADH:HIGH:MEDIUM:@STRENGTH"); /* if a cert is provided, use it */ if(ssl->certName) { - if(ssl->loglevel) printf("sqSetupSSL: Using cert file %s\n", ssl->certName); - if(SSL_CTX_use_certificate_file(ssl->ctx, ssl->certName, SSL_FILETYPE_PEM)<=0) - ERR_print_errors_fp(stderr); - - if(SSL_CTX_use_PrivateKey_file(ssl->ctx, ssl->certName, SSL_FILETYPE_PEM)<=0) - ERR_print_errors_fp(stderr); + if(ssl->loglevel) { + printf("sqSetupSSL: Using cert file %s\n", ssl->certName); + } + if(sqo_SSL_CTX_use_certificate_file(ssl->ctx, ssl->certName, SSL_FILETYPE_PEM)<=0) { + sqo_ERR_print_errors_fp(stderr); + } + if(sqo_SSL_CTX_use_PrivateKey_file(ssl->ctx, ssl->certName, SSL_FILETYPE_PEM)<=0) { + sqo_ERR_print_errors_fp(stderr); + } } /* Set up trusted CA */ if(ssl->loglevel) printf("sqSetupSSL: No root CA given; using default verify paths\n"); - if(SSL_CTX_set_default_verify_paths(ssl->ctx) <=0) - ERR_print_errors_fp(stderr); + if(sqo_SSL_CTX_set_default_verify_paths(ssl->ctx) <=0) + sqo_ERR_print_errors_fp(stderr); if(ssl->loglevel) printf("sqSetupSSL: Creating SSL\n"); - ssl->ssl = SSL_new(ssl->ctx); + ssl->ssl = sqo_SSL_new(ssl->ctx); if(ssl->loglevel) printf("sqSetupSSL: setting bios\n"); - SSL_set_bio(ssl->ssl, ssl->bioRead, ssl->bioWrite); + sqo_SSL_set_bio(ssl->ssl, ssl->bioRead, ssl->bioWrite); return 1; } /********************************************************************/ @@ -275,14 +275,20 @@ sqInt sqCreateSSL(void) { sqInt handle = 0; sqSSL *ssl = NULL; - SSL_library_init(); - SSL_load_error_strings(); + if (!wasInitialized) { + if (!loadLibrary()) { + return 0; + } + sqo_SSL_library_init(); + sqo_SSL_load_error_strings(); + wasInitialized = true; + } ssl = calloc(1, sizeof(sqSSL)); - ssl->bioRead = BIO_new(BIO_s_mem()); - ssl->bioWrite = BIO_new(BIO_s_mem()); - BIO_set_close(ssl->bioRead, BIO_CLOSE); - BIO_set_close(ssl->bioWrite, BIO_CLOSE); + ssl->bioRead = sqo_BIO_new(sqo_BIO_s_mem()); + ssl->bioWrite = sqo_BIO_new(sqo_BIO_s_mem()); + sqo_BIO_set_close(ssl->bioRead, BIO_CLOSE); + sqo_BIO_set_close(ssl->bioWrite, BIO_CLOSE); /* Find a free handle */ for(handle = 1; handle < handleMax; handle++) @@ -309,14 +315,14 @@ sqInt sqDestroySSL(sqInt handle) { sqSSL *ssl = sslFromHandle(handle); if(ssl == NULL) return 0; - if(ssl->ctx) SSL_CTX_free(ssl->ctx); + if(ssl->ctx) sqo_SSL_CTX_free(ssl->ctx); if(ssl->ssl) { - SSL_free(ssl->ssl); // This will also free bioRead and bioWrite + sqo_SSL_free(ssl->ssl); // This will also free bioRead and bioWrite } else { // SSL_new didn't get called, have to free bioRead and bioWrite manually - BIO_free_all(ssl->bioRead); - BIO_free_all(ssl->bioWrite); + sqo_BIO_free_all(ssl->bioRead); + sqo_BIO_free_all(ssl->bioWrite); } if(ssl->certName) free(ssl->certName); @@ -356,14 +362,14 @@ sqInt sqConnectSSL(sqInt handle, char* srcBuf, sqInt srcLen, char *dstBuf, sqInt if(ssl->loglevel) printf("sqConnectSSL: Setting up SSL\n"); if(!sqSetupSSL(ssl, 0)) return SQSSL_GENERIC_ERROR; if(ssl->loglevel) printf("sqConnectSSL: Setting connect state\n"); - SSL_set_connect_state(ssl->ssl); + sqo_SSL_set_connect_state(ssl->ssl); } if(ssl->loglevel) printf("sqConnectSSL: BIO_write %ld bytes\n", (long)srcLen); if(srcLen > 0) { - int n = BIO_write(ssl->bioRead, srcBuf, srcLen); + int n = sqo_BIO_write(ssl->bioRead, srcBuf, srcLen); if(n < srcLen) { if(ssl->loglevel) printf("sqConnectSSL: BIO too small for input\n"); @@ -378,16 +384,16 @@ sqInt sqConnectSSL(sqInt handle, char* srcBuf, sqInt srcLen, char *dstBuf, sqInt /* if a server name is provided, use it */ if(ssl->serverName) { if(ssl->loglevel) printf("sqSetupSSL: Using server name %s\n", ssl->serverName); - SSL_set_tlsext_host_name(ssl->ssl, ssl->serverName); + sqo_SSL_set_tlsext_host_name(ssl->ssl, ssl->serverName); } if(ssl->loglevel) printf("sqConnectSSL: SSL_connect\n"); - result = SSL_connect(ssl->ssl); + result = sqo_SSL_connect(ssl->ssl); if(result <= 0) { - int error = SSL_get_error(ssl->ssl, result); + int error = sqo_SSL_get_error(ssl->ssl, result); if(error != SSL_ERROR_WANT_READ) { if(ssl->loglevel) printf("sqConnectSSL: SSL_connect failed\n"); - ERR_print_errors_fp(stdout); + sqo_ERR_print_errors_fp(stdout); return SQSSL_GENERIC_ERROR; } if(ssl->loglevel) printf("sqConnectSSL: sqCopyBioSSL\n"); @@ -398,7 +404,7 @@ sqInt sqConnectSSL(sqInt handle, char* srcBuf, sqInt srcLen, char *dstBuf, sqInt ssl->state = SQSSL_CONNECTED; if(ssl->loglevel) printf("sqConnectSSL: SSL_get_peer_certificate\n"); - cert = SSL_get_peer_certificate(ssl->ssl); + cert = sqo_SSL_get_peer_certificate(ssl->ssl); if(ssl->loglevel) printf("sqConnectSSL: cert = %p\n", cert); /* Fail if no cert received. */ if(cert) { @@ -432,19 +438,20 @@ sqInt sqConnectSSL(sqInt handle, char* srcBuf, sqInt srcLen, char *dstBuf, sqInt if (ssl->serverName) { const size_t serverNameLength = strnlen(ssl->serverName, MAX_HOSTNAME_LENGTH); -#ifdef X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS - if(ssl->loglevel) printf("sqConnectSSL: X509_check_host."); - /* Try IP first, expect INVALID_IP_STRING to continue with hostname */ - matched = (enum sqMatchResult) X509_check_ip_asc(cert, ssl->serverName, 0); - if (matched == INVALID_IP_STRING) { - matched = (enum sqMatchResult) X509_check_host(cert, ssl->serverName, serverNameLength, X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS, NULL); - } -#else - matched = sqVerifyIP(ssl, cert, ssl->serverName, serverNameLength); - if (matched == INVALID_IP_STRING) { - matched = sqVerifyDNS(ssl, cert, ssl->serverName, serverNameLength); + //#ifdef X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS + if (sqo_X509_check_ip_asc && sqo_X509_check_host) { + if(ssl->loglevel) printf("sqConnectSSL: X509_check_host."); + /* Try IP first, expect INVALID_IP_STRING to continue with hostname */ + matched = (enum sqMatchResult) sqo_X509_check_ip_asc(cert, ssl->serverName, 0); + if (matched == INVALID_IP_STRING) { + matched = (enum sqMatchResult) sqo_X509_check_host(cert, ssl->serverName, serverNameLength, X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS, NULL); + } + } else { + matched = sqVerifyIP(ssl, cert, ssl->serverName, serverNameLength); + if (matched == INVALID_IP_STRING) { + matched = sqVerifyDNS(ssl, cert, ssl->serverName, serverNameLength); + } } -#endif if (matched == MATCH_FOUND) { if (ssl->loglevel) printf("sqConnectSSL: check hostname OK\n"); ssl->peerName = strndup(ssl->serverName, serverNameLength); @@ -454,16 +461,16 @@ sqInt sqConnectSSL(sqInt handle, char* srcBuf, sqInt srcLen, char *dstBuf, sqInt } // fallback for missing sAN or non-provided serverName if (matched == NO_MATCH_DONE_YET || matched == NO_SAN_PRESENT) { - X509_NAME_get_text_by_NID(X509_get_subject_name(cert), - NID_commonName, peerName, - sizeof(peerName)); + sqo_X509_NAME_get_text_by_NID(sqo_X509_get_subject_name(cert), + NID_commonName, peerName, + sizeof(peerName)); if(ssl->loglevel) printf("sqConnectSSL: peerName = %s\n", peerName); ssl->peerName = strndup(peerName, sizeof(peerName) - 1); } - X509_free(cert); + sqo_X509_free(cert); /* Check the result of verification */ - result = SSL_get_verify_result(ssl->ssl); + result = sqo_SSL_get_verify_result(ssl->ssl); if(ssl->loglevel) printf("sqConnectSSL: SSL_get_verify_result = %d\n", result); /* FIXME: Figure out the actual failure reason */ ssl->certFlags = result ? SQSSL_OTHER_ISSUE : SQSSL_OK; @@ -499,13 +506,13 @@ sqInt sqAcceptSSL(sqInt handle, char* srcBuf, sqInt srcLen, char *dstBuf, sqInt if(ssl->loglevel) printf("sqAcceptSSL: Setting up SSL\n"); if(!sqSetupSSL(ssl, 1)) return SQSSL_GENERIC_ERROR; if(ssl->loglevel) printf("sqAcceptSSL: setting accept state\n"); - SSL_set_accept_state(ssl->ssl); + sqo_SSL_set_accept_state(ssl->ssl); } if(ssl->loglevel) printf("sqAcceptSSL: BIO_write %ld bytes\n", (long)srcLen); if(srcLen > 0) { - int n = BIO_write(ssl->bioRead, srcBuf, srcLen); + int n = sqo_BIO_write(ssl->bioRead, srcBuf, srcLen); if(n < srcLen) { if(ssl->loglevel) printf("sqAcceptSSL: BIO_write wrote less than expected\n"); @@ -518,14 +525,14 @@ sqInt sqAcceptSSL(sqInt handle, char* srcBuf, sqInt srcLen, char *dstBuf, sqInt } if(ssl->loglevel) printf("sqAcceptSSL: SSL_accept\n"); - result = SSL_accept(ssl->ssl); + result = sqo_SSL_accept(ssl->ssl); if(result <= 0) { int count = 0; - int error = SSL_get_error(ssl->ssl, result); + int error = sqo_SSL_get_error(ssl->ssl, result); if(error != SSL_ERROR_WANT_READ) { if(ssl->loglevel) printf("sqAcceptSSL: SSL_accept failed\n"); - ERR_print_errors_fp(stdout); + sqo_ERR_print_errors_fp(stdout); return SQSSL_GENERIC_ERROR; } if(ssl->loglevel) printf("sqAcceptSSL: sqCopyBioSSL\n"); @@ -537,19 +544,19 @@ sqInt sqAcceptSSL(sqInt handle, char* srcBuf, sqInt srcLen, char *dstBuf, sqInt ssl->state = SQSSL_CONNECTED; if(ssl->loglevel) printf("sqAcceptSSL: SSL_get_peer_certificate\n"); - cert = SSL_get_peer_certificate(ssl->ssl); + cert = sqo_SSL_get_peer_certificate(ssl->ssl); if(ssl->loglevel) printf("sqAcceptSSL: cert = %p\n", cert); if(cert) { - X509_NAME_get_text_by_NID(X509_get_subject_name(cert), - NID_commonName, peerName, - sizeof(peerName)); + sqo_X509_NAME_get_text_by_NID(sqo_X509_get_subject_name(cert), + NID_commonName, peerName, + sizeof(peerName)); if(ssl->loglevel) printf("sqAcceptSSL: peerName = %s\n", peerName); ssl->peerName = strndup(peerName, sizeof(peerName) - 1); - X509_free(cert); + sqo_X509_free(cert); /* Check the result of verification */ - result = SSL_get_verify_result(ssl->ssl); + result = sqo_SSL_get_verify_result(ssl->ssl); if(ssl->loglevel) printf("sqAcceptSSL: SSL_get_verify_result = %d\n", result); /* FIXME: Figure out the actual failure reason */ ssl->certFlags = result ? SQSSL_OTHER_ISSUE : SQSSL_OK; @@ -576,7 +583,7 @@ sqInt sqEncryptSSL(sqInt handle, char* srcBuf, sqInt srcLen, char *dstBuf, sqInt if(ssl->loglevel) printf("sqEncryptSSL: Encrypting %ld bytes\n", (long)srcLen); - nbytes = SSL_write(ssl->ssl, srcBuf, srcLen); + nbytes = sqo_SSL_write(ssl->ssl, srcBuf, srcLen); if(nbytes != srcLen) return SQSSL_GENERIC_ERROR; return sqCopyBioSSL(ssl, ssl->bioWrite, dstBuf, dstLen); } @@ -596,11 +603,11 @@ sqInt sqDecryptSSL(sqInt handle, char* srcBuf, sqInt srcLen, char *dstBuf, sqInt if(ssl == NULL || ssl->state != SQSSL_CONNECTED) return SQSSL_INVALID_STATE; - nbytes = BIO_write(ssl->bioRead, srcBuf, srcLen); + nbytes = sqo_BIO_write(ssl->bioRead, srcBuf, srcLen); if(nbytes != srcLen) return SQSSL_GENERIC_ERROR; - nbytes = SSL_read(ssl->ssl, dstBuf, dstLen); + nbytes = sqo_SSL_read(ssl->ssl, dstBuf, dstLen); if(nbytes <= 0) { - int error = SSL_get_error(ssl->ssl, nbytes); + int error = sqo_SSL_get_error(ssl->ssl, nbytes); if(error != SSL_ERROR_WANT_READ && error != SSL_ERROR_ZERO_RETURN) { return SQSSL_GENERIC_ERROR; } From 8e48e6f2a94ecac2010550b68c2ceab6cf7cde91 Mon Sep 17 00:00:00 2001 From: Tobias Pape Date: Tue, 30 Jan 2018 21:15:51 +0100 Subject: [PATCH 2/4] Allow for possibly undefined X509 constant --- platforms/unix/plugins/SqueakSSL/openssl_overlay.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/platforms/unix/plugins/SqueakSSL/openssl_overlay.h b/platforms/unix/plugins/SqueakSSL/openssl_overlay.h index d426b445cc..513714a33a 100644 --- a/platforms/unix/plugins/SqueakSSL/openssl_overlay.h +++ b/platforms/unix/plugins/SqueakSSL/openssl_overlay.h @@ -169,7 +169,9 @@ void (*sqo_sk_pop_free)(STACK *st, void (*func) (void *)); #define sqo_sk_GENERAL_NAME_pop_free(st, free_func) \ sqo_SKM_sk_pop_free(GENERAL_NAME, (st), (free_func)) - +#if !defined(X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS) +#define X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS 0x10 +#endif bool loadLibrary(void) { From 438311cb201cfc01dcb03ddcf034cfb5176b57f4 Mon Sep 17 00:00:00 2001 From: Tobias Pape Date: Wed, 31 Jan 2018 14:27:31 +0100 Subject: [PATCH 3/4] Refactor the overlay, comments where due --- .../unix/plugins/SqueakSSL/openssl_overlay.h | 513 ++++++++++-------- .../unix/plugins/SqueakSSL/sqUnixOpenSSL.c | 7 +- 2 files changed, 292 insertions(+), 228 deletions(-) diff --git a/platforms/unix/plugins/SqueakSSL/openssl_overlay.h b/platforms/unix/plugins/SqueakSSL/openssl_overlay.h index 513714a33a..474000cc47 100644 --- a/platforms/unix/plugins/SqueakSSL/openssl_overlay.h +++ b/platforms/unix/plugins/SqueakSSL/openssl_overlay.h @@ -1,35 +1,239 @@ #ifndef SQ_OPENSSL_OVERLAY_H #define SQ_OPENSSL_OVERLAY_H 1 - +/**************************************************************************** + * PROJECT: SqueakSSL implementation for Linux/Unix + * FILE: openssl_overlay.h + * CONTENT: Overlay OpenSSL for Linux/Unix + * + * AUTHORS: Tobias Pape (topa) + * Hasso Plattner Institute, Postdam, Germany + ***************************************************************************** + * When we dynamically link against OpenSSL, the bundles are not + * portable, as CentOS and friends use other SO_NAMEs than Debian and + * friends. Also, soft-fallback for later features such as host name + * verification is hard. + * + * When we statically link, we might lack behind the OS, the binaries + * are bigger, and the legal situation is less clear. + * + * So we now support not linking at all but rather lookup all necessary + * functions/symbols at runtime. + * + * This can be disabled with SQSSL_OPENSSL_LINKED which effectively + * results in the dynamically-linked behavior. (This is preferable for + * platform builds, eg, debs and rpms) + *****************************************************************************/ #include -#include #include #include #include +/* + * List of all used OpenSSL functions in the following format: + * + * SQO_DECL___(RETURN_TYPE, NAME, ARGS...) + * + * For symbols that appeard first version XYZ (X >=1) use SQO_DECLXYZ, + * for example: + * + * SQO_DECL102 (Available since OpenSSL 1.0.2) + * (NAME will have value NULL in OpenSSL < 1.0.2) + * + * SPECIAL CASE FOR OLD OPENSSL + * For symbols with different types in 0.9.8 / 1.0.0 use: + * + * SQO_DECL098 (OpenSSL <= 0.9.8) + * (NAME will not be defined in > 0.9.8) + * SQO_DECL100 (OpenSSL >= 1.0.0) + * (NAME will not be defined in < 1.0.0) + * + */ +#define SQO_DECLARATIONS \ + /**/ \ + SQO_DECL___(unsigned char *, ASN1_STRING_data, ASN1_STRING *x) \ + SQO_DECL___(int, ASN1_STRING_length, const ASN1_STRING *x) \ + SQO_DECL___(void, BIO_free_all, BIO *a) \ + SQO_DECL___(BIO *, BIO_new, BIO_METHOD *type) \ + SQO_DECL___(BIO_METHOD *, BIO_s_mem, void) \ + SQO_DECL___(size_t, BIO_ctrl_pending, BIO *bp) \ + SQO_DECL___(long, BIO_ctrl, BIO *bp, int cmd, long larg, void *parg) \ + SQO_DECL___(int, BIO_write, BIO *b, const void *data, int len) \ + SQO_DECL___(int, BIO_read, BIO *b, void *data, int len) \ + SQO_DECL___(void, ERR_print_errors_fp, FILE *fp) \ + SQO_DECL___(void, SSL_CTX_free, SSL_CTX *) \ + SQO_DECL___(int, SSL_CTX_set_cipher_list, SSL_CTX *, const char *str) \ + SQO_DECL___(int, SSL_CTX_set_default_verify_paths, SSL_CTX *ctx) \ + SQO_DECL___(long, SSL_CTX_ctrl, SSL_CTX *ctx, int cmd, long larg, void *parg) \ + SQO_DECL___(int, SSL_CTX_use_PrivateKey_file, SSL_CTX *ctx, const char *file, int type) \ + SQO_DECL___(int, SSL_CTX_use_certificate_file, SSL_CTX *ctx, const char *file, int type) \ + SQO_DECL___(int, SSL_accept, SSL *ssl) \ + SQO_DECL___(int, SSL_connect, SSL *ssl) \ + SQO_DECL___(void, SSL_free, SSL *ssl) \ + SQO_DECL___(long, SSL_ctrl, SSL *ssl, int cmd, long larg, void *parg) \ + SQO_DECL___(int, SSL_get_error, const SSL *s, int ret_code) \ + SQO_DECL___(X509 *, SSL_get_peer_certificate, const SSL *s) \ + SQO_DECL___(long, SSL_get_verify_result, const SSL *ssl) \ + SQO_DECL___(int, SSL_library_init, void) \ + SQO_DECL___(void, SSL_load_error_strings, void) \ + SQO_DECL___(SSL *, SSL_new, SSL_CTX *ctx) \ + SQO_DECL___(int, SSL_read, SSL *ssl, void *buf, int num) \ + SQO_DECL___(void, SSL_set_accept_state, SSL *s) \ + SQO_DECL___(void, SSL_set_bio, SSL *s, BIO *rbio, BIO *wbio) \ + SQO_DECL___(void, SSL_set_connect_state, SSL *s) \ + SQO_DECL___(int, SSL_write, SSL *ssl, const void *buf, int num) \ + SQO_DECL___(int, X509_NAME_get_text_by_NID, X509_NAME *name, int nid, char *buf, int len) \ + SQO_DECL___(X509_NAME *, X509_get_subject_name, X509 *a) \ + SQO_DECL___(void *, X509_get_ext_d2i, X509 *x, int nid, int *crit, int *idx) \ + SQO_DECL___(void, X509_free, X509 *ssl) \ + \ + SQO_DECL102(int, X509_check_ip_asc, X509 *x, const char *ipasc, unsigned int flags) \ + SQO_DECL102(int, X509_check_host, X509 *x, const char *chk, size_t chklen, unsigned int flags, char **peername) \ + \ + SQO_DECL100(_STACK *, sk_new_null, void) \ + SQO_DECL100(int, sk_push, _STACK *st, void *data) \ + SQO_DECL100(void, sk_free, _STACK *st) \ + SQO_DECL100(void *, sk_value, const _STACK *st, int i) \ + SQO_DECL100(int, sk_num, const _STACK *st) \ + SQO_DECL100(void, sk_pop_free, _STACK *st, void (*func) (void *)) \ + SQO_DECL100(const SSL_METHOD *, SSLv23_method, void) \ + SQO_DECL100(SSL_CTX *, SSL_CTX_new, const SSL_METHOD *a) \ + \ + SQO_DECL098(STACK *, sk_new_null, void) \ + SQO_DECL098(int, sk_push, STACK *st, char *data) \ + SQO_DECL098(void, sk_free, STACK *st) \ + SQO_DECL098(char *, sk_value, STACK *st, int i) \ + SQO_DECL098(int, sk_num, STACK *st) \ + SQO_DECL098(void, sk_pop_free, STACK *st, void (*func) (void *)) \ + SQO_DECL098(SSL_METHOD *, SSLv23_method, void) \ + SQO_DECL098(SSL_CTX *, SSL_CTX_new, SSL_METHOD *a) \ + /* backstop */ + +/* + * List of re-defined OpenSSL macros + * + * This is necessary to "redirect" the usage of un-prefixed symbols to + * sqo_-prefixed ones. + */ +#define sqo_BIO_set_close(b,c) (int)sqo_BIO_ctrl(b,BIO_CTRL_SET_CLOSE,(c),NULL) +#define sqo_SSL_set_tlsext_host_name(s,name) sqo_SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_HOSTNAME,TLSEXT_NAMETYPE_host_name,(char *)name) +#define sqo_SSL_CTX_set_options(ctx,op) sqo_SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,(op),NULL) +#define sqo_SKM_sk_num(type, st) sqo_sk_num(CHECKED_STACK_OF(type, st)) +#define sqo_SKM_sk_value(type, st,i) ((type *)sqo_sk_value(CHECKED_STACK_OF(type, st), i)) +#define sqo_SKM_sk_free(type, st) sqo_sk_free(CHECKED_STACK_OF(type, st)) +#define sqo_SKM_sk_pop_free(type, st, free_func) sqo_sk_pop_free(CHECKED_STACK_OF(type, st), CHECKED_SK_FREE_FUNC(type, free_func)) +#define sqo_sk_GENERAL_NAME_num(st) sqo_SKM_sk_num(GENERAL_NAME, (st)) +#define sqo_sk_GENERAL_NAME_value(st, i) sqo_SKM_sk_value(GENERAL_NAME, (st), (i)) +#define sqo_sk_GENERAL_NAME_free(st) sqo_SKM_sk_free(GENERAL_NAME, (st)) +#define sqo_sk_GENERAL_NAME_pop_free(st, free_func) sqo_SKM_sk_pop_free(GENERAL_NAME, (st), (free_func)) + +/* + * List of optional OpenSSL constants + * + * This is necessary to allow usage of those constants with newer + * dyamically loaded libraries, but whlist using older versions at + * compile time. + */ +#if defined(X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS) +#define sqo_X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS +#else +#define sqo_X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS 0x10 +#endif + + +/***********************************************************************/ +/***********************************************************************/ +/***********************************************************************/ +/***********************************************************************/ +/***********************************************************************/ +/***********************************************************************/ + +#if OPENSSL_VERSION_NUMBER >= 0x10000000L +#define SQO_DECL098 SQO_DECL_NO +#define SQO_DECL100 SQO_DECL___ +#else +#define SQO_DECL098 SQO_DECL___ +#define SQO_DECL100 SQO_DECL_NO +#endif + +#if OPENSSL_VERSION_NUMBER >= 0x10002000L +#define SQO_DECL102 SQO_DECL___ +#else +#define SQO_DECL102 SQO_DECL_IF +#endif + +/* + * WARNING: Here be dragons! + * + * Only change things beyond this line if you know exactly what + * will happen. + * + * The following stanzas will do this: + * + * * When compiling non-linked (dynmically loaded): + * * find dl-header, define helper marcos for symbol lookup + * * define static handles for dynamic libraries + * * helper function that does actual lookup + * * helper function that unloads libraries on SqueakSSL unload + * + * * Declare all necessary OpenSSL symbols, prefixed with sqo_ + * + * * "loadLibrary" function to be called once by SqueakSSL: + * * When compiling linked (not dynamically loaded): + * * alias all necessary OpenSSL symbols to sqo_ prefixed + * * otherwise, when compiling non-linked (dynamically loaded): + * * lookup every symbol and assing to sqo_ prefixed name + * + * That's it, essentially. + */ +#if !defined(SQSSL_OPENSSL_LINKED) + +#include + +#if !defined(SQO_DL_FLAGS) +# if !defined(__OpenBSD__) +# define SQO_DL_FLAGS RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE +# else +# define SQO_DL_FLAGS RTLD_NOW | RTLD_GLOBAL +# endif +#endif /* !defined(SQO_DL_FLAGS) */ +/* + * Handles for the dlopen'ed dynamic libraries + * + */ static void* dlhandle_self = NULL; static void* dlhandle_crypto = NULL; static void* dlhandle_ssl = NULL; + +/* + * Helpers to make sure the loaded library handles are closed when + * this module is unloaded (w/ care for at lease GCC and llvm/clang) + */ #ifndef __has_attribute #define __has_attribute(x) 0 #endif -#if __has_attribute(constructor) \ +#if __has_attribute(destructor) \ || defined(__GNUC__) -#define SQO_CONSTRUCTOR __attribute__((constructor)) +#define SQO_DESTRUCTOR __attribute__((destructor)) #else -#define SQO_CONSTRUCTOR /**/ +#define SQO_DESTRUCTOR /**/ #endif -void SQO_CONSTRUCTOR fini(void) +void SQO_DESTRUCTOR fini(void) { if (dlhandle_self) { dlclose(dlhandle_self); } if (dlhandle_crypto) { dlclose(dlhandle_crypto); } if (dlhandle_ssl) { dlclose(dlhandle_ssl);} } +/* + * Macro that lookups a symbol in a library and does immediately + * return the address when found. + * + * (whith optional debug output) + */ #if (defined(DEBUG) || defined(DEBUGVM)) && !defined(NDEBUG) #define SQO_HAS_FOUND_SYM(s,n,h) \ do { \ @@ -48,254 +252,115 @@ void SQO_CONSTRUCTOR fini(void) } while (0) #endif -#if !defined(SQO_DL_FLAGS) -#define SQO_DL_FLAGS RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE -#endif - +/* + * Macro that lookups a symbol in a _named_ library. + * Loads library if not yet done. + * Uses SQO_HAS_FOUND_SYM, therefore immediately returns when found. + */ #define SQO_FIND_SYM(sym, name, where, dlname) \ do { \ if (!dlhandle_ ## where) { \ dlhandle_ ## where = dlopen(dlname, SQO_DL_FLAGS); \ - if (!dlhandle_ ## where) { \ - fprintf(stderr, "cannot load from " #dlname "\n"); \ - abort(); \ - } \ } \ if (dlhandle_ ## where) { \ SQO_HAS_FOUND_SYM(sym, name, dlhandle_ ## where); \ } \ } while (0) - + +/* + * Find symbol named "name" in one of the following namespaces + * (in order): + * + * 1. Already loaded dynamic objects + * 2. The running executable itself + * 3. libssl.so (as in OpenSSL) + * 4. libcrypto.so (as in OpenSSL) + */ static inline void* _sqo_find(const char* name) { void* sym = NULL; SQO_HAS_FOUND_SYM(sym, name, RTLD_DEFAULT); - SQO_FIND_SYM(sym, name, self, NULL); - SQO_FIND_SYM(sym, name, ssl, "libssl.so"); + SQO_FIND_SYM(sym, name, self, NULL); + SQO_FIND_SYM(sym, name, ssl, "libssl.so"); SQO_FIND_SYM(sym, name, crypto, "libcrypto.so"); return sym; } +#endif /* !defined(SQSSL_OPENSSL_LINKED) */ -unsigned char *(*sqo_ASN1_STRING_data)(ASN1_STRING *x); -int (*sqo_ASN1_STRING_length)(const ASN1_STRING *x); -void (*sqo_BIO_free_all)(BIO *a); -BIO *(*sqo_BIO_new)(BIO_METHOD *type); -BIO_METHOD *(*sqo_BIO_s_mem)(void); -long (*sqo_BIO_ctrl)(BIO *bp, int cmd, long larg, void *parg); -size_t (*sqo_BIO_ctrl_pending)(BIO *bp); -int (*sqo_BIO_write)(BIO *b, const void *data, int len); -int (*sqo_BIO_read)(BIO *b, void *data, int len); -void (*sqo_ERR_print_errors_fp)(FILE *fp); -void (*sqo_SSL_CTX_free)(SSL_CTX *); - -#if OPENSSL_VERSION_NUMBER >= 0x10000000L -const SSL_METHOD *(*sqo_SSLv23_method)(void); -SSL_CTX *(*sqo_SSL_CTX_new)(const SSL_METHOD *a); -#else -SSL_METHOD *(*sqo_SSLv23_method)(void); -SSL_CTX *(*sqo_SSL_CTX_new)(SSL_METHOD *a); -#endif - -int (*sqo_SSL_CTX_set_cipher_list)(SSL_CTX *, const char *str); -int (*sqo_SSL_CTX_set_default_verify_paths)(SSL_CTX *ctx); -long (*sqo_SSL_CTX_ctrl)(SSL_CTX *ctx, int cmd, long larg, void *parg); -int (*sqo_SSL_CTX_use_PrivateKey_file)(SSL_CTX *ctx, const char *file, int type); -int (*sqo_SSL_CTX_use_certificate_file)(SSL_CTX *ctx, const char *file, int type); -int (*sqo_SSL_accept)(SSL *ssl); -int (*sqo_SSL_connect)(SSL *ssl); -void (*sqo_SSL_free)(SSL *ssl); -long (*sqo_SSL_ctrl)(SSL *ssl, int cmd, long larg, void *parg); -int (*sqo_SSL_get_error)(const SSL *s, int ret_code); -X509 *(*sqo_SSL_get_peer_certificate)(const SSL *s); -long (*sqo_SSL_get_verify_result)(const SSL *ssl); -int (*sqo_SSL_library_init)(void); -void (*sqo_SSL_load_error_strings)(void); -SSL *(*sqo_SSL_new)(SSL_CTX *ctx); -int (*sqo_SSL_read)(SSL *ssl, void *buf, int num); -void (*sqo_SSL_set_accept_state)(SSL *s); -void (*sqo_SSL_set_bio)(SSL *s, BIO *rbio, BIO *wbio); -void (*sqo_SSL_set_connect_state)(SSL *s); -int (*sqo_SSL_write)(SSL *ssl, const void *buf, int num); -int (*sqo_X509_NAME_get_text_by_NID)(X509_NAME *name, int nid, char *buf, int len); -X509_NAME *(*sqo_X509_get_subject_name)(X509 *a); -void *(*sqo_X509_get_ext_d2i)(X509 *x, int nid, int *crit, int *idx); -void (*sqo_X509_free)(X509 *ssl); - -// OPENSSL_VERSION_NUMBER >= 0x10002000L -int (*sqo_X509_check_ip_asc)(X509 *x, const char *ipasc, unsigned int flags); -int (*sqo_X509_check_host)(X509 *x, const char *chk, size_t chklen, unsigned int flags, char **peername); - -#if OPENSSL_VERSION_NUMBER >= 0x10000000L -_STACK *(*sqo_sk_new_null)(void); -int (*sqo_sk_push)(_STACK *st, void *data); -void (*sqo_sk_free)(_STACK *st); -void *(*sqo_sk_value)(const _STACK *st, int i); -int (*sqo_sk_num)(const _STACK *st); -void (*sqo_sk_pop_free)(_STACK *st, void (*func) (void *)); -#else -STACK *(*sqo_sk_new_null)(void); -int (*sqo_sk_push)(STACK *st, char *data); -void (*sqo_sk_free)(STACK *st); -char *(*sqo_sk_value)(STACK *st, int i); -int (*sqo_sk_num)(STACK *st); -void (*sqo_sk_pop_free)(STACK *st, void (*func) (void *)); -#endif // OPENSSL_VERSION_NUMBER >= 0x10000000L - -#define sqo_BIO_set_close(b,c) \ - (int)sqo_BIO_ctrl(b,BIO_CTRL_SET_CLOSE,(c),NULL) - -#define sqo_SSL_set_tlsext_host_name(s,name) \ - sqo_SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_HOSTNAME,TLSEXT_NAMETYPE_host_name,(char *)name) -#define sqo_SSL_CTX_set_options(ctx,op) \ - sqo_SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,(op),NULL) +/* + * + * + * + * DECLARE ALL NECESSARY SYMBOLS AS FOUND IN SQO_DECLARATIONS + * + * + * + * + */ +#define SQO_DECL___(ret, name, ...) ret (*sqo_ ## name)(__VA_ARGS__); +#define SQO_DECL_IF(ret, name, ...) ret (*sqo_ ## name)(__VA_ARGS__); +#define SQO_DECL_NO(ret, name, ...) /**/ -#define sqo_SKM_sk_num(type, st) \ - sqo_sk_num(CHECKED_STACK_OF(type, st)) -#define sqo_SKM_sk_value(type, st,i) \ - ((type *)sqo_sk_value(CHECKED_STACK_OF(type, st), i)) -#define sqo_SKM_sk_free(type, st) \ - sqo_sk_free(CHECKED_STACK_OF(type, st)) -#define sqo_SKM_sk_pop_free(type, st, free_func) \ - sqo_sk_pop_free(CHECKED_STACK_OF(type, st), CHECKED_SK_FREE_FUNC(type, free_func)) -#define sqo_sk_GENERAL_NAME_num(st) \ - sqo_SKM_sk_num(GENERAL_NAME, (st)) -#define sqo_sk_GENERAL_NAME_value(st, i) \ - sqo_SKM_sk_value(GENERAL_NAME, (st), (i)) -#define sqo_sk_GENERAL_NAME_free(st) \ - sqo_SKM_sk_free(GENERAL_NAME, (st)) -#define sqo_sk_GENERAL_NAME_pop_free(st, free_func) \ - sqo_SKM_sk_pop_free(GENERAL_NAME, (st), (free_func)) +/* THIS LINE IS VITAL */ +SQO_DECLARATIONS -#if !defined(X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS) -#define X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS 0x10 -#endif +#undef SQO_DECL___ +#undef SQO_DECL_NO +#undef SQO_DECL_IF +/* + * Function that makes sure that all sqo_ prefixed OpenSSL names are + * actually available. + * + * Returns + * true when all required symbols could be loaded/are linked + * false when at least one required symbol could not be loaded + * + * Call this exaclty once! + */ bool loadLibrary(void) { -#if defined(SQSSL_FORCE_LINK_OPENSSL) - sqo_ASN1_STRING_data = &ASN1_STRING_data; - sqo_ASN1_STRING_length = &ASN1_STRING_length; - sqo_BIO_free_all = &BIO_free_all; - sqo_BIO_new = &BIO_new; - sqo_BIO_s_mem = &BIO_s_mem; - sqo_BIO_ctrl = &BIO_ctrl; - sqo_BIO_ctrl_pending = &BIO_ctrl_pending; - sqo_BIO_write = &BIO_write; - sqo_BIO_read = &BIO_read; - sqo_ERR_print_errors_fp = &ERR_print_errors_fp; - sqo_SSL_CTX_free = &SSL_CTX_free; - sqo_SSLv23_method = &SSLv23_method; - sqo_SSL_CTX_new = &SSL_CTX_new; - sqo_SSL_CTX_set_cipher_list = &SSL_CTX_set_cipher_list; - sqo_SSL_CTX_set_default_verify_paths = &SSL_CTX_set_default_verify_paths; - sqo_SSL_CTX_ctrl = &SSL_CTX_ctrl; - sqo_SSL_CTX_use_PrivateKey_file = &SSL_CTX_use_PrivateKey_file; - sqo_SSL_CTX_use_certificate_file = &SSL_CTX_use_certificate_file; - sqo_SSL_accept = &SSL_accept; - sqo_SSL_connect = &SSL_connect; - sqo_SSL_free = &SSL_free; - sqo_SSL_ctrl = &SSL_ctrl; - sqo_SSL_get_error = &SSL_get_error; - sqo_SSL_get_peer_certificate = &SSL_get_peer_certificate; - sqo_SSL_get_verify_result = &SSL_get_verify_result; - sqo_SSL_library_init = &SSL_library_init; - sqo_SSL_load_error_strings = &SSL_load_error_strings; - sqo_SSL_new = &SSL_new; - sqo_SSL_read = &SSL_read; - sqo_SSL_set_accept_state = &SSL_set_accept_state; - sqo_SSL_set_bio = &SSL_set_bio; - sqo_SSL_set_connect_state = &SSL_set_connect_state; - sqo_SSL_write = &SSL_write; - sqo_X509_NAME_get_text_by_NID = &X509_NAME_get_text_by_NID; - sqo_X509_get_subject_name = &X509_get_subject_name; - sqo_X509_get_ext_d2i = &X509_get_ext_d2i; - sqo_X509_free = &X509_free; -#if OPENSSL_VERSION_NUMBER >= 0x10002000L - sqo_X509_check_ip_asc = &X509_check_ip_asc; - sqo_X509_check_host = &X509_check_host; -#else - sqo_X509_check_ip_asc = NULL; - sqo_X509_check_host = NULL; -#endif - - sqo_sk_new_null = &sk_new_null; - sqo_sk_push = &sk_push; - sqo_sk_free = &sk_free; - sqo_sk_value = &sk_value; - sqo_sk_num = &sk_num; - sqo_sk_pop_free = &sk_pop_free; - return true; -#else +/* + * + * + * + * ASSING ALL NECESSARY SYMBOLS AS FOUND IN SQO_DECLARATIONS + * + * + * + * + */ +#if defined(SQSSL_OPENSSL_LINKED) +# define SQO_DECL___(ret, name, ...) sqo_ ## name = &name; +# define SQO_DECL_NO(ret, name, ...) /**/ +# define SQO_DECL_IF(ret, name, ...) sqo_ ## name = NULL; +#else /* defined(SQSSL_OPENSSL_LINKED) */ +# define SQO_DECL___(ret, name, ...) \ + if (NULL == \ + (sqo_ ## name = (ret (*)(__VA_ARGS__)) _sqo_find(#name))) { \ + return false; \ + } +# define SQO_DECL_IF(ret, name, ...) \ + sqo_ ## name =(ret (*)(__VA_ARGS__)) _sqo_find(#name); +# define SQO_DECL_NO(ret, name, ...) /**/ +#endif /* defined(SQSSL_OPENSSL_LINKED) */ -#define _C(X) if ((X) == NULL) return false - _C(sqo_ASN1_STRING_data = (unsigned char *(*)(ASN1_STRING *x)) _sqo_find("ASN1_STRING_data")); - _C(sqo_ASN1_STRING_length = (int (*)(const ASN1_STRING *x)) _sqo_find("ASN1_STRING_length")); - _C(sqo_BIO_free_all = (void (*)(BIO *a)) _sqo_find("BIO_free_all")); - _C(sqo_BIO_new = (BIO *(*)(BIO_METHOD *type)) _sqo_find("BIO_new")); - _C(sqo_BIO_s_mem = (BIO_METHOD *(*)(void)) _sqo_find("BIO_s_mem")); - _C(sqo_BIO_ctrl = (long (*)(BIO *bp, int cmd, long larg, void *parg)) _sqo_find("BIO_ctrl")); - _C(sqo_BIO_ctrl_pending = (size_t (*)(BIO *)) _sqo_find("BIO_ctrl_pending")); - _C(sqo_BIO_write = (int (*)(BIO *b, const void *data, int len)) _sqo_find("BIO_write")); - _C(sqo_BIO_read = (int (*)(BIO *b, void *data, int len)) _sqo_find("BIO_read")); - _C(sqo_ERR_print_errors_fp = (void (*)(FILE *fp)) _sqo_find("ERR_print_errors_fp")); - _C(sqo_SSL_CTX_free = (void (*)(SSL_CTX *)) _sqo_find("SSL_CTX_free")); +/* THIS LINE IS VITAL */ + SQO_DECLARATIONS -#if OPENSSL_VERSION_NUMBER >= 0x10000000L - _C(sqo_SSLv23_method = (const SSL_METHOD *(*)(void)) _sqo_find("SSLv23_method")); - _C(sqo_SSL_CTX_new = (SSL_CTX *(*)(const SSL_METHOD *a)) _sqo_find("SSL_CTX_new")); -#else - _C(sqo_SSLv23_method = (SSL_METHOD *(*)(void)) _sqo_find("SSLv23_method")); - _C(sqo_SSL_CTX_new = (SSL_CTX *(*)(SSL_METHOD *a)) _sqo_find("SSL_CTX_new")); -#endif - _C(sqo_SSL_CTX_set_cipher_list = (int (*)(SSL_CTX *, const char *str)) _sqo_find("SSL_CTX_set_cipher_list")); - _C(sqo_SSL_CTX_set_default_verify_paths = (int (*)(SSL_CTX *ctx)) _sqo_find("SSL_CTX_set_default_verify_paths")); - _C(sqo_SSL_CTX_ctrl = (long (*)(SSL_CTX *ctx, int cmd, long larg, void *parg)) _sqo_find("SSL_CTX_ctrl")); - _C(sqo_SSL_CTX_use_PrivateKey_file = (int (*)(SSL_CTX *ctx, const char *file, int type)) _sqo_find("SSL_CTX_use_PrivateKey_file")); - _C(sqo_SSL_CTX_use_certificate_file = (int (*)(SSL_CTX *ctx, const char *file, int type)) _sqo_find("SSL_CTX_use_certificate_file")); - _C(sqo_SSL_accept = (int (*)(SSL *ssl)) _sqo_find("SSL_accept")); - _C(sqo_SSL_connect = (int (*)(SSL *ssl)) _sqo_find("SSL_connect")); - _C(sqo_SSL_free = (void (*)(SSL *ssl)) _sqo_find("SSL_free")); - _C(sqo_SSL_ctrl = (long (*)(SSL *ssl, int cmd, long larg, void *parg)) _sqo_find("SSL_ctrl")); - _C(sqo_SSL_get_error = (int (*)(const SSL *s, int ret_code)) _sqo_find("SSL_get_error")); - _C(sqo_SSL_get_peer_certificate = (X509 *(*)(const SSL *s)) _sqo_find("SSL_get_peer_certificate")); - _C(sqo_SSL_get_verify_result = (long (*)(const SSL *ssl)) _sqo_find("SSL_get_verify_result")); - _C(sqo_SSL_library_init = (int (*)(void)) _sqo_find("SSL_library_init")); - _C(sqo_SSL_load_error_strings = (void (*)(void)) _sqo_find("SSL_load_error_strings")); - _C(sqo_SSL_new = (SSL *(*)(SSL_CTX *ctx)) _sqo_find("SSL_new")); - _C(sqo_SSL_read = (int (*)(SSL *ssl, void *buf, int num)) _sqo_find("SSL_read")); - _C(sqo_SSL_set_accept_state = (void (*)(SSL *s)) _sqo_find("SSL_set_accept_state")); - _C(sqo_SSL_set_bio = (void (*)(SSL *s, BIO *rbio, BIO *wbio)) _sqo_find("SSL_set_bio")); - _C(sqo_SSL_set_connect_state = (void (*)(SSL *s)) _sqo_find("SSL_set_connect_state")); - _C(sqo_SSL_write = (int (*)(SSL *ssl, const void *buf, int num)) _sqo_find("SSL_write")); - _C(sqo_X509_NAME_get_text_by_NID = (int (*)(X509_NAME *name, int nid, char *buf, int len)) _sqo_find("X509_NAME_get_text_by_NID")); - _C(sqo_X509_get_subject_name = (X509_NAME *(*)(X509 *a)) _sqo_find("X509_get_subject_name")); - _C(sqo_X509_get_ext_d2i = (void *(*)(X509 *x, int nid, int *crit, int *idx)) _sqo_find("X509_get_ext_d2i")); - _C(sqo_X509_free = (void (*)(X509 *)) _sqo_find("X509_free")); - sqo_X509_check_ip_asc = (int (*)(X509 *x, const char *ipasc, unsigned int flags)) _sqo_find("X509_check_ip_asc"); - sqo_X509_check_host = (int (*)(X509 *x, const char *chk, size_t chklen, unsigned int flags, char **peername)) _sqo_find("X509_check_host"); +#undef SQO_DECL___ +#undef SQO_DECL_NO +#undef SQO_DECL_IF -#if OPENSSL_VERSION_NUMBER >= 0x10000000L - _C(sqo_sk_new_null = (_STACK *(*)(void)) _sqo_find("sk_new_null")); - _C(sqo_sk_push = (int (*)(_STACK *st, void *data)) _sqo_find("sk_push")); - _C(sqo_sk_free = (void (*)(_STACK *st)) _sqo_find("sk_free")); - _C(sqo_sk_value = (void *(*)(const _STACK *st, int i)) _sqo_find("sk_value")); - _C(sqo_sk_num = (int (*)(const _STACK *st)) _sqo_find("sk_num")); - _C(sqo_sk_pop_free = (void (*)(_STACK *st, void (*func) (void *))) _sqo_find("sk_pop_free")); -#else - _C(sqo_sk_new_null = (STACK *(*)(void)) _sqo_find("sk_new_null")); - _C(sqo_sk_push = (int (*)(STACK *st, char *data)) _sqo_find("sk_push")); - _C(sqo_sk_free = (void (*)(STACK *st)) _sqo_find("sk_free")); - _C(sqo_sk_value = (char *(*)(STACK *st, int i)) _sqo_find("sk_value")); - _C(sqo_sk_num = (int (*)(STACK *st)) _sqo_find("sk_num")); - _C(sqo_sk_pop_free = (void (*)(STACK *st, void (*func) (void *))) _sqo_find("sk_pop_free")); -#endif // OPENSSL_VERSION_NUMBER >= 0x10000000L - return true; -#endif + return true; } +#undef SQO_DECLARATIONS +/* !defined(SQ_OPENSSL_OVERLAY_H) */ #endif +/* EOF */ diff --git a/platforms/unix/plugins/SqueakSSL/sqUnixOpenSSL.c b/platforms/unix/plugins/SqueakSSL/sqUnixOpenSSL.c index efd40d5873..ed8d560a34 100644 --- a/platforms/unix/plugins/SqueakSSL/sqUnixOpenSSL.c +++ b/platforms/unix/plugins/SqueakSSL/sqUnixOpenSSL.c @@ -279,8 +279,8 @@ sqInt sqCreateSSL(void) { if (!loadLibrary()) { return 0; } - sqo_SSL_library_init(); - sqo_SSL_load_error_strings(); + sqo_SSL_library_init(); + sqo_SSL_load_error_strings(); wasInitialized = true; } @@ -438,13 +438,12 @@ sqInt sqConnectSSL(sqInt handle, char* srcBuf, sqInt srcLen, char *dstBuf, sqInt if (ssl->serverName) { const size_t serverNameLength = strnlen(ssl->serverName, MAX_HOSTNAME_LENGTH); - //#ifdef X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS if (sqo_X509_check_ip_asc && sqo_X509_check_host) { if(ssl->loglevel) printf("sqConnectSSL: X509_check_host."); /* Try IP first, expect INVALID_IP_STRING to continue with hostname */ matched = (enum sqMatchResult) sqo_X509_check_ip_asc(cert, ssl->serverName, 0); if (matched == INVALID_IP_STRING) { - matched = (enum sqMatchResult) sqo_X509_check_host(cert, ssl->serverName, serverNameLength, X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS, NULL); + matched = (enum sqMatchResult) sqo_X509_check_host(cert, ssl->serverName, serverNameLength, sqo_X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS, NULL); } } else { matched = sqVerifyIP(ssl, cert, ssl->serverName, serverNameLength); From 74e443c1e2c1492ee7677471730182393f5ae996 Mon Sep 17 00:00:00 2001 From: Fabio Niephaus Date: Wed, 31 Jan 2018 14:35:45 +0100 Subject: [PATCH 4/4] Nit picks [ci skip] --- .../unix/plugins/SqueakSSL/openssl_overlay.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/platforms/unix/plugins/SqueakSSL/openssl_overlay.h b/platforms/unix/plugins/SqueakSSL/openssl_overlay.h index 474000cc47..81d1510a20 100644 --- a/platforms/unix/plugins/SqueakSSL/openssl_overlay.h +++ b/platforms/unix/plugins/SqueakSSL/openssl_overlay.h @@ -6,7 +6,7 @@ * CONTENT: Overlay OpenSSL for Linux/Unix * * AUTHORS: Tobias Pape (topa) - * Hasso Plattner Institute, Postdam, Germany + * Hasso Plattner Institute, Potsdam, Germany ***************************************************************************** * When we dynamically link against OpenSSL, the bundles are not * portable, as CentOS and friends use other SO_NAMEs than Debian and @@ -33,7 +33,7 @@ * * SQO_DECL___(RETURN_TYPE, NAME, ARGS...) * - * For symbols that appeard first version XYZ (X >=1) use SQO_DECLXYZ, + * For symbols that appeared first version XYZ (X >=1) use SQO_DECLXYZ, * for example: * * SQO_DECL102 (Available since OpenSSL 1.0.2) @@ -130,7 +130,7 @@ * List of optional OpenSSL constants * * This is necessary to allow usage of those constants with newer - * dyamically loaded libraries, but whlist using older versions at + * dynamically loaded libraries, but whilst using older versions at * compile time. */ #if defined(X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS) @@ -169,8 +169,8 @@ * * The following stanzas will do this: * - * * When compiling non-linked (dynmically loaded): - * * find dl-header, define helper marcos for symbol lookup + * * When compiling non-linked (dynamically loaded): + * * find dl-header, define helper macros for symbol lookup * * define static handles for dynamic libraries * * helper function that does actual lookup * * helper function that unloads libraries on SqueakSSL unload @@ -181,7 +181,7 @@ * * When compiling linked (not dynamically loaded): * * alias all necessary OpenSSL symbols to sqo_ prefixed * * otherwise, when compiling non-linked (dynamically loaded): - * * lookup every symbol and assing to sqo_ prefixed name + * * lookup every symbol and assign to sqo_ prefixed name * * That's it, essentially. */ @@ -232,7 +232,7 @@ void SQO_DESTRUCTOR fini(void) * Macro that lookups a symbol in a library and does immediately * return the address when found. * - * (whith optional debug output) + * (with optional debug output) */ #if (defined(DEBUG) || defined(DEBUGVM)) && !defined(NDEBUG) #define SQO_HAS_FOUND_SYM(s,n,h) \ @@ -319,7 +319,7 @@ SQO_DECLARATIONS * true when all required symbols could be loaded/are linked * false when at least one required symbol could not be loaded * - * Call this exaclty once! + * Call this exactly once! */ bool loadLibrary(void) {