Hi,

Is anyone here interested in helping to evaluate an experimental patch
for wolfSSL support?

Attached please find a WIP patch for wolfSSL support in postgresql-12.
As a shortcut, you may find this merge request helpful:

    https://salsa.debian.org/postgresql/postgresql/-/merge_requests/4

I used Debian stable (buster) with backports enabled and preferred.

The wolfssl.patch in d/patches builds and completes all tests, as long
as libwolfssl-dev version 4.4.0+dfsg-2~bpo10+1 is installed and
patched with the included libwolfssl-dev-rename-types.patch.

You can do so as root with:

    cd /usr/include/wolfssl
    patch -p1 < libwolfssl-dev-rename-types.patch

Patching the library was easier than resolving type conflicts for
twenty-five files. An attempt was made but resulted in failing tests.

The offending types are called 'ValidateDate' and 'Hash'. They do not
seem to be part of the wolfSSL ABI.

The patch operates with the following caveats:

1. DH parameters are not currently loaded from a database-internal PEM
certificate. The function OBJ_find_sigid_algs is not available. The
security implications should be discussed with a cryptographer.

2. The contrib module pgcrypto was not compiled with OpenSSL support
and currently offers only native algorithms. wolfSSL's compatibility
support for OpenSSL's EVP interface is incomplete and offers only a
few algorithms. The module should work directly with wolfCrypt.

3. The error reporting in wolfSSL_set_fd seems to be different from
OpenSSL. I could not locate SSLerr and decided to return BAD_FUNC_ARG.
That is what the routine being mimicked does in wolfSSL. If you see an
SSL connection error, it may be wise to simply remove these two
statements in src/interfaces/libpq/fe-secure-openssl.c:

    ret = BAD_FUNC_ARG;

Unsupported functions or features can probably be replaced with
wolfSSL's or wolfCrypt's native interfaces. The company may be happy
to assist.

The patch includes modifications toward missing goals. Some parts
modify code, for example in util/pgpcrypto, that is not actually called.

Please note that the wolfSSL team prefers the styling of their brand
to be capitalized as recorded in this sentence. Thank you!

Kind regards
Felix Lechner
unchanged:
--- a/configure.in
+++ b/configure.in
@@ -1211,7 +1211,7 @@ fi
 
 if test "$with_gssapi" = yes ; then
   if test "$PORTNAME" != "win32"; then
-    AC_SEARCH_LIBS(gss_init_sec_context, [gssapi_krb5 gss 'gssapi -lkrb5 -lcrypto'], [],
+    AC_SEARCH_LIBS(gss_init_sec_context, [gssapi_krb5 gss 'gssapi -lkrb5 -lwolfssl'], [],
                    [AC_MSG_ERROR([could not find function 'gss_init_sec_context' required for GSSAPI])])
   else
     LIBS="$LIBS -lgssapi32"
@@ -1221,29 +1221,35 @@ fi
 if test "$with_openssl" = yes ; then
   dnl Order matters!
   if test "$PORTNAME" != "win32"; then
-     AC_CHECK_LIB(crypto, CRYPTO_new_ex_data, [], [AC_MSG_ERROR([library 'crypto' is required for OpenSSL])])
-     AC_CHECK_LIB(ssl,    SSL_new, [], [AC_MSG_ERROR([library 'ssl' is required for OpenSSL])])
+     AC_CHECK_LIB(wolfssl, wolfSSL_new, [], [AC_MSG_ERROR([library 'wolfssl' is required for OpenSSL])])
   else
-     AC_SEARCH_LIBS(CRYPTO_new_ex_data, [eay32 crypto], [], [AC_MSG_ERROR([library 'eay32' or 'crypto' is required for OpenSSL])])
-     AC_SEARCH_LIBS(SSL_new, [ssleay32 ssl], [], [AC_MSG_ERROR([library 'ssleay32' or 'ssl' is required for OpenSSL])])
+     AC_SEARCH_LIBS(wolfSSL_new, [wolfssl], [], [AC_MSG_ERROR([library 'wolfssl' is required for OpenSSL])])
   fi
-  AC_CHECK_FUNCS([SSL_get_current_compression X509_get_signature_nid])
+  # support for NIDs is incomplete; lack OBJ_find_sigid_algs
+  #AC_DEFINE(HAVE_X509_GET_SIGNATURE_NID, 1, [Define to 1 if you have X509_get_signature_nid()])
+
   # Functions introduced in OpenSSL 1.1.0. We used to check for
   # OPENSSL_VERSION_NUMBER, but that didn't work with 1.1.0, because LibreSSL
   # defines OPENSSL_VERSION_NUMBER to claim version 2.0.0, even though it
   # doesn't have these OpenSSL 1.1.0 functions. So check for individual
   # functions.
-  AC_CHECK_FUNCS([OPENSSL_init_ssl BIO_get_data BIO_meth_new ASN1_STRING_get0_data])
+  AC_DEFINE(HAVE_BIO_GET_DATA, 1, [Define to 1 if you have BIO_get_data()])
+
+  # support for BIO_meth_new incomplete; lack BIO_meth_get_*
+  #AC_DEFINE(HAVE_BIO_METH_NEW, 1, [Define to 1 if you have BIO_meth_new()])
+  AC_DEFINE(HAVE_ASN1_STRING_GET0_DATA, 1, [Define to 1 if you have ASN1_STRING_get0_data()])
   # OpenSSL versions before 1.1.0 required setting callback functions, for
   # thread-safety. In 1.1.0, it's no longer required, and CRYPTO_lock()
   # function was removed.
-  AC_CHECK_FUNCS([CRYPTO_lock])
+  # wolfSSL has CRYPTO_lock but does not need it; lacks CRYPTO_get_locking_callback
+  # AC_DEFINE(HAVE_CRYPTO_LOCK, 1, [Define to 1 if you have CRYPTO_lock()])
   # SSL_clear_options is a macro in OpenSSL from 0.9.8 to 1.0.2, and
   # a function from 1.1.0 onwards so we cannot use AC_CHECK_FUNCS.
   AC_CACHE_CHECK([for SSL_clear_options], ac_cv_func_ssl_clear_options,
   [AC_LINK_IFELSE([AC_LANG_PROGRAM([
-  #include <openssl/ssl.h>
-  #include <openssl/bio.h>
+  #include <wolfssl/options.h>
+  #include <wolfssl/openssl/ssl.h>
+  #include <wolfssl/openssl/bio.h>
   SSL *ssl;
   ],
   [return SSL_clear_options(ssl, 0);])],
@@ -1428,8 +1434,8 @@ if test "$with_gssapi" = yes ; then
 fi
 
 if test "$with_openssl" = yes ; then
-  AC_CHECK_HEADER(openssl/ssl.h, [], [AC_MSG_ERROR([header file <openssl/ssl.h> is required for OpenSSL])])
-  AC_CHECK_HEADER(openssl/err.h, [], [AC_MSG_ERROR([header file <openssl/err.h> is required for OpenSSL])])
+  AC_CHECK_HEADER(wolfssl/openssl/ssl.h, [], [AC_MSG_ERROR([header file <openssl/ssl.h> is required for OpenSSL])])
+  AC_CHECK_HEADER(wolfssl/openssl/err.h, [], [AC_MSG_ERROR([header file <openssl/err.h> is required for OpenSSL])])
 fi
 
 if test "$with_pam" = yes ; then
--- a/src/include/common/sha2.h
+++ b/src/include/common/sha2.h
@@ -51,7 +51,9 @@
 #define _PG_SHA2_H_
 
 #ifdef USE_OPENSSL
-#include <openssl/sha.h>
+#include <wolfssl/options.h>
+#include <wolfssl/openssl/ssl.h>
+#include <wolfssl/openssl/sha.h>
 #endif
 
 /*** SHA224/256/384/512 Various Length Definitions ***********************/
--- a/src/common/sha2_openssl.c
+++ b/src/common/sha2_openssl.c
@@ -20,7 +20,8 @@
 #include "postgres_fe.h"
 #endif
 
-#include <openssl/sha.h>
+#include <wolfssl/options.h>
+#include <wolfssl/openssl/sha.h>
 
 #include "common/sha2.h"
 
--- a/src/port/pg_strong_random.c
+++ b/src/port/pg_strong_random.c
@@ -25,7 +25,8 @@
 #include <sys/time.h>
 
 #ifdef USE_OPENSSL
-#include <openssl/rand.h>
+#include <wolfssl/options.h>
+#include <wolfssl/openssl/rand.h>
 #endif
 #ifdef WIN32
 #include <wincrypt.h>
--- a/src/include/libpq/libpq-be.h
+++ b/src/include/libpq/libpq-be.h
@@ -20,8 +20,9 @@
 
 #include <sys/time.h>
 #ifdef USE_OPENSSL
-#include <openssl/ssl.h>
-#include <openssl/err.h>
+#include <wolfssl/options.h>
+#include <wolfssl/openssl/ssl.h>
+#include <wolfssl/openssl/err.h>
 #endif
 #ifdef HAVE_NETINET_TCP_H
 #include <netinet/tcp.h>
--- a/src/backend/libpq/be-secure-openssl.c
+++ b/src/backend/libpq/be-secure-openssl.c
@@ -29,11 +29,13 @@
 #include <arpa/inet.h>
 #endif
 
-#include <openssl/ssl.h>
-#include <openssl/dh.h>
-#include <openssl/conf.h>
+#include <wolfssl/options.h>
+#include <wolfssl/openssl/ssl.h>
+#include <wolfssl/openssl/dh.h>
+#include <wolfssl/openssl/conf.h>
+#include <wolfssl/openssl/bio.h>
 #ifndef OPENSSL_NO_ECDH
-#include <openssl/ec.h>
+#include <wolfssl/openssl/ec.h>
 #endif
 
 #include "libpq/libpq.h"
@@ -50,7 +52,6 @@ static int	my_sock_write(BIO *h, const c
 static BIO_METHOD *my_BIO_s_socket(void);
 static int	my_SSL_set_fd(Port *port, int fd);
 
-static DH  *load_dh_file(char *filename, bool isServerStart);
 static DH  *load_dh_buffer(const char *, size_t);
 static int	ssl_external_passwd_cb(char *buf, int size, int rwflag, void *userdata);
 static int	dummy_ssl_passwd_cb(char *buf, int size, int rwflag, void *userdata);
@@ -741,7 +742,7 @@ my_BIO_s_socket(void)
 #ifdef HAVE_BIO_METH_NEW
 		int			my_bio_index;
 
-		my_bio_index = BIO_get_new_index();
+		my_bio_index = -1;
 		if (my_bio_index == -1)
 			return NULL;
 		my_bio_methods = BIO_meth_new(my_bio_index, "PostgreSQL backend socket");
@@ -765,8 +766,8 @@ my_BIO_s_socket(void)
 		if (!my_bio_methods)
 			return NULL;
 		memcpy(my_bio_methods, biom, sizeof(BIO_METHOD));
-		my_bio_methods->bread = my_sock_read;
-		my_bio_methods->bwrite = my_sock_write;
+		my_bio_methods->readCb = my_sock_read;
+		my_bio_methods->writeCb = my_sock_write;
 #endif
 	}
 	return my_bio_methods;
@@ -783,14 +784,12 @@ my_SSL_set_fd(Port *port, int fd)
 	bio_method = my_BIO_s_socket();
 	if (bio_method == NULL)
 	{
-		SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
 		goto err;
 	}
 	bio = BIO_new(bio_method);
 
 	if (bio == NULL)
 	{
-		SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
 		goto err;
 	}
 	BIO_set_data(bio, port);
@@ -826,8 +825,8 @@ load_dh_file(char *filename, bool isServ
 		return NULL;
 	}
 
-	dh = PEM_read_DHparams(fp, NULL, NULL, NULL);
 	FreeFile(fp);
+	return NULL;
 
 	if (dh == NULL)
 	{
--- a/src/backend/postmaster/fork_process.c
+++ b/src/backend/postmaster/fork_process.c
@@ -18,7 +18,8 @@
 #include <sys/time.h>
 #include <unistd.h>
 #ifdef USE_OPENSSL
-#include <openssl/rand.h>
+#include <wolfssl/options.h>
+#include <wolfssl/openssl/rand.h>
 #endif
 
 #ifndef WIN32
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -72,8 +72,9 @@ typedef struct
 #endif							/* ENABLE_SSPI */
 
 #ifdef USE_OPENSSL
-#include <openssl/ssl.h>
-#include <openssl/err.h>
+#include <wolfssl/options.h>
+#include <wolfssl/openssl/ssl.h>
+#include <wolfssl/openssl/err.h>
 
 #ifndef OPENSSL_NO_ENGINE
 #define USE_SSL_ENGINE
--- a/src/interfaces/libpq/fe-secure-openssl.c
+++ b/src/interfaces/libpq/fe-secure-openssl.c
@@ -54,12 +54,13 @@
 #endif
 #endif
 
-#include <openssl/ssl.h>
-#include <openssl/conf.h>
+#include <wolfssl/options.h>
+#include <wolfssl/openssl/ssl.h>
+#include <wolfssl/openssl/conf.h>
 #ifdef USE_SSL_ENGINE
-#include <openssl/engine.h>
+#include <wolfssl/openssl/engine.h>
 #endif
-#include <openssl/x509v3.h>
+#include <wolfssl/openssl/x509v3.h>
 
 static int	verify_cb(int ok, X509_STORE_CTX *ctx);
 static int	openssl_verify_peer_name_matches_certificate_name(PGconn *conn,
@@ -1557,8 +1558,8 @@ my_BIO_s_socket(void)
 		if (!my_bio_methods)
 			return NULL;
 		memcpy(my_bio_methods, biom, sizeof(BIO_METHOD));
-		my_bio_methods->bread = my_sock_read;
-		my_bio_methods->bwrite = my_sock_write;
+		my_bio_methods->readCb = my_sock_read;
+		my_bio_methods->writeCb = my_sock_write;
 #endif
 	}
 	return my_bio_methods;
@@ -1575,13 +1576,13 @@ my_SSL_set_fd(PGconn *conn, int fd)
 	bio_method = my_BIO_s_socket();
 	if (bio_method == NULL)
 	{
-		SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
+		ret = BAD_FUNC_ARG;
 		goto err;
 	}
 	bio = BIO_new(bio_method);
 	if (bio == NULL)
 	{
-		SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
+		ret = BAD_FUNC_ARG;
 		goto err;
 	}
 	BIO_set_data(bio, conn);
--- a/contrib/pgcrypto/openssl.c
+++ b/contrib/pgcrypto/openssl.c
@@ -33,9 +33,10 @@
 
 #include "px.h"
 
-#include <openssl/evp.h>
-#include <openssl/err.h>
-#include <openssl/rand.h>
+#include <wolfssl/options.h>
+#include <wolfssl/openssl/evp.h>
+#include <wolfssl/openssl/err.h>
+#include <wolfssl/openssl/rand.h>
 
 #include "utils/memutils.h"
 #include "utils/resowner.h"
@@ -633,16 +634,10 @@ ossl_aes_cbc_init(PX_Cipher *c, const ui
  */
 
 static PX_Alias ossl_aliases[] = {
-	{"bf", "bf-cbc"},
-	{"blowfish", "bf-cbc"},
-	{"blowfish-cbc", "bf-cbc"},
-	{"blowfish-ecb", "bf-ecb"},
-	{"blowfish-cfb", "bf-cfb"},
 	{"des", "des-cbc"},
 	{"3des", "des3-cbc"},
 	{"3des-ecb", "des3-ecb"},
 	{"3des-cbc", "des3-cbc"},
-	{"cast5", "cast5-cbc"},
 	{"aes", "aes-cbc"},
 	{"rijndael", "aes-cbc"},
 	{"rijndael-cbc", "aes-cbc"},
@@ -650,24 +645,6 @@ static PX_Alias ossl_aliases[] = {
 	{NULL}
 };
 
-static const struct ossl_cipher ossl_bf_cbc = {
-	bf_init,
-	EVP_bf_cbc,
-	64 / 8, 448 / 8
-};
-
-static const struct ossl_cipher ossl_bf_ecb = {
-	bf_init,
-	EVP_bf_ecb,
-	64 / 8, 448 / 8
-};
-
-static const struct ossl_cipher ossl_bf_cfb = {
-	bf_init,
-	EVP_bf_cfb,
-	64 / 8, 448 / 8
-};
-
 static const struct ossl_cipher ossl_des_ecb = {
 	ossl_des_init,
 	EVP_des_ecb,
@@ -692,18 +669,6 @@ static const struct ossl_cipher ossl_des
 	64 / 8, 192 / 8
 };
 
-static const struct ossl_cipher ossl_cast_ecb = {
-	ossl_cast_init,
-	EVP_cast5_ecb,
-	64 / 8, 128 / 8
-};
-
-static const struct ossl_cipher ossl_cast_cbc = {
-	ossl_cast_init,
-	EVP_cast5_cbc,
-	64 / 8, 128 / 8
-};
-
 static const struct ossl_cipher ossl_aes_ecb = {
 	ossl_aes_ecb_init,
 	NULL,						/* EVP_aes_XXX_ecb(), determined in init
@@ -728,15 +693,10 @@ struct ossl_cipher_lookup
 };
 
 static const struct ossl_cipher_lookup ossl_cipher_types[] = {
-	{"bf-cbc", &ossl_bf_cbc},
-	{"bf-ecb", &ossl_bf_ecb},
-	{"bf-cfb", &ossl_bf_cfb},
 	{"des-ecb", &ossl_des_ecb},
 	{"des-cbc", &ossl_des_cbc},
 	{"des3-ecb", &ossl_des3_ecb},
 	{"des3-cbc", &ossl_des3_cbc},
-	{"cast5-ecb", &ossl_cast_ecb},
-	{"cast5-cbc", &ossl_cast_cbc},
 	{"aes-ecb", &ossl_aes_ecb},
 	{"aes-cbc", &ossl_aes_cbc},
 	{NULL}
--- a/contrib/pgcrypto/pgp-mpi-openssl.c
+++ b/contrib/pgcrypto/pgp-mpi-openssl.c
@@ -30,7 +30,8 @@
  */
 #include "postgres.h"
 
-#include <openssl/bn.h>
+#include <wolfssl/options.h>
+#include <wolfssl/openssl/bn.h>
 
 #include "px.h"
 #include "pgp.h"
--- a/contrib/sslinfo/sslinfo.c
+++ b/contrib/sslinfo/sslinfo.c
@@ -9,9 +9,10 @@
 
 #include "postgres.h"
 
-#include <openssl/x509.h>
-#include <openssl/x509v3.h>
-#include <openssl/asn1.h>
+#include <wolfssl/options.h>
+#include <wolfssl/openssl/x509.h>
+#include <wolfssl/openssl/x509v3.h>
+#include <wolfssl/openssl/asn1.h>
 
 #include "access/htup_details.h"
 #include "funcapi.h"
--- a/contrib/pgcrypto/Makefile
+++ b/contrib/pgcrypto/Makefile
@@ -10,8 +10,8 @@ OSSL_TESTS = sha2 des 3des cast5
 ZLIB_TST = pgp-compression
 ZLIB_OFF_TST = pgp-zlib-DISABLED
 
-CF_SRCS = $(if $(subst no,,$(with_openssl)), $(OSSL_SRCS), $(INT_SRCS))
-CF_TESTS = $(if $(subst no,,$(with_openssl)), $(OSSL_TESTS), $(INT_TESTS))
+CF_SRCS = $(INT_SRCS)
+CF_TESTS = $(INT_TESTS)
 CF_PGP_TESTS = $(if $(subst no,,$(with_zlib)), $(ZLIB_TST), $(ZLIB_OFF_TST))
 
 SRCS		= pgcrypto.c px.c px-hmac.c px-crypt.c \

Attachment: series
Description: Binary data

Attachment: README.wolfSSL
Description: Binary data

diff -rup /usr/include/wolfssl/ssl.h wolfssl/ssl.h
--- /usr/include/wolfssl/ssl.h	2020-06-26 07:09:46.827611150 -0700
+++ wolfssl/ssl.h	2020-06-26 06:24:16.376046803 -0700
@@ -920,7 +920,7 @@ WOLFSSL_API int  wolfSSL_BIO_new_bio_pai
 
 WOLFSSL_API int wolfSSL_RSA_padding_add_PKCS1_PSS(WOLFSSL_RSA *rsa, unsigned char *EM,
                                                   const unsigned char *mHash,
-                                                  const WOLFSSL_EVP_MD *Hash, int saltLen);
+                                                  const WOLFSSL_EVP_MD *WolfSSLHash, int saltLen);
 WOLFSSL_API int wolfSSL_RSA_verify_PKCS1_PSS(WOLFSSL_RSA *rsa, const unsigned char *mHash,
                                           const WOLFSSL_EVP_MD *hashAlg,
                                           const unsigned char *EM, int saltLen);
diff -rup /usr/include/wolfssl/wolfcrypt/asn.h wolfssl/wolfcrypt/asn.h
--- /usr/include/wolfssl/wolfcrypt/asn.h	2020-06-26 07:09:46.895610573 -0700
+++ wolfssl/wolfcrypt/asn.h	2020-06-26 06:21:36.862159331 -0700
@@ -1115,7 +1115,7 @@ WOLFSSL_LOCAL int GetAsnTimeString(void*
 WOLFSSL_LOCAL int ExtractDate(const unsigned char* date, unsigned char format,
                                                  wolfssl_tm* certTime, int* idx);
 WOLFSSL_LOCAL int DateGreaterThan(const struct tm* a, const struct tm* b);
-WOLFSSL_LOCAL int ValidateDate(const byte* date, byte format, int dateType);
+WOLFSSL_LOCAL int WolfSSLValidateDate(const byte* date, byte format, int dateType);
 WOLFSSL_LOCAL int wc_OBJ_sn2nid(const char *sn);
 
 /* ASN.1 helper functions */
diff -rup /usr/include/wolfssl/wolfcrypt/hmac.h wolfssl/wolfcrypt/hmac.h
--- /usr/include/wolfssl/wolfcrypt/hmac.h	2020-06-26 07:09:46.927610303 -0700
+++ wolfssl/wolfcrypt/hmac.h	2020-06-26 07:19:42.843225264 -0700
@@ -131,11 +131,11 @@ typedef union {
 #ifdef WOLFSSL_SHA3
     wc_Sha3 sha3;
 #endif
-} Hash;
+} WolfSSLHash;
 
 /* Hmac digest */
 struct Hmac {
-    Hash    hash;
+    WolfSSLHash    hash;
     word32  ipad[WC_HMAC_BLOCK_SIZE  / sizeof(word32)];  /* same block size all*/
     word32  opad[WC_HMAC_BLOCK_SIZE  / sizeof(word32)];
     word32  innerHash[WC_MAX_DIGEST_SIZE / sizeof(word32)];
Only in wolfssl/wolfcrypt: hmac.h~
diff -rup /usr/include/wolfssl/wolfcrypt/wc_port.h wolfssl/wolfcrypt/wc_port.h
--- /usr/include/wolfssl/wolfcrypt/wc_port.h	2020-06-26 07:09:46.927610303 -0700
+++ wolfssl/wolfcrypt/wc_port.h	2020-06-26 06:21:24.974018611 -0700
@@ -683,7 +683,7 @@ WOLFSSL_API int wolfCrypt_Cleanup(void);
 #endif
 #if !defined(XVALIDATE_DATE) && !defined(HAVE_VALIDATE_DATE)
     #define USE_WOLF_VALIDDATE
-    #define XVALIDATE_DATE(d, f, t) ValidateDate((d), (f), (t))
+    #define XVALIDATE_DATE(d, f, t) WolfSSLValidateDate((d), (f), (t))
 #endif
 
 /* wolf struct tm and time_t */

Reply via email to