From: Guus Sliepen Date: Fri, 27 Feb 2026 10:13:36 +0000 (+0100) Subject: Fix compatibility with LibreSSL. X-Git-Tag: release-1.0.37~1 X-Git-Url: https://www.tinc-vpn.org/git/?a=commitdiff_plain;h=eb0fd6db7cb3a27a209a2f44559d59cb11542dcb;p=tinc Fix compatibility with LibreSSL. --- diff --git a/m4/openssl.m4 b/m4/openssl.m4 index 12b92aa9..0133d6e1 100644 --- a/m4/openssl.m4 +++ b/m4/openssl.m4 @@ -35,15 +35,19 @@ AC_DEFUN([tinc_OPENSSL], LDFLAGS="$LDFLAGS -L$withval"] ) - AC_CHECK_HEADERS([openssl/evp.h openssl/rsa.h openssl/rand.h openssl/err.h openssl/sha.h openssl/pem.h openssl/param_build.h], + AC_CHECK_HEADERS([openssl/evp.h openssl/rsa.h openssl/rand.h openssl/err.h openssl/sha.h openssl/pem.h], [], [AC_MSG_ERROR([LibreSSL/OpenSSL header files not found.]); break] ) + AC_CHECK_HEADERS([openssl/param_build.h]) + AC_CHECK_LIB(crypto, OPENSSL_init_crypto, [LIBS="-lcrypto $LIBS"], [AC_MSG_ERROR([LibreSSL/OpenSSL libraries not found.])] ) + AC_CHECK_DECLS([EVP_RSA_gen], [], [], [#include ]) + AC_DEFINE(HAVE_OPENSSL, 1, [enable OpenSSL support]) ]) diff --git a/src/net_setup.c b/src/net_setup.c index 7bde753b..04021a2b 100644 --- a/src/net_setup.c +++ b/src/net_setup.c @@ -24,7 +24,9 @@ #include #include +#ifdef HAVE_OPENSSL_PARAM_BUILD_H #include +#endif #include #include @@ -51,10 +53,9 @@ devops_t devops; bool read_rsa_public_key(connection_t *c) { FILE *fp; char *pubname; - char *hcfname; char *key; - if(!c->rsa_key) { + if(c->rsa_key) { EVP_PKEY_free(c->rsa_key); c->rsa_key = NULL; } @@ -64,10 +65,6 @@ bool read_rsa_public_key(connection_t *c) { if(get_config_string(lookup_config(c->config_tree, "PublicKey"), &key)) { BIGNUM *n = NULL; BIGNUM *e = NULL; - OSSL_PARAM_BLD *bld = NULL; - OSSL_PARAM *param = NULL; - EVP_PKEY_CTX *ctx = NULL; - int result; logger(LOG_WARNING, "Obsolete PublicKey statement for %s!", c->name); @@ -80,6 +77,12 @@ bool read_rsa_public_key(connection_t *c) { free(key); BN_hex2bn(&e, "FFFF"); +#ifdef HAVE_OPENSSL_PARAM_BUILD_H + OSSL_PARAM_BLD *bld = NULL; + OSSL_PARAM *param = NULL; + EVP_PKEY_CTX *ctx = NULL; + int result; + bld = OSSL_PARAM_BLD_new(); if(!bld) { @@ -106,12 +109,50 @@ bool read_rsa_public_key(connection_t *c) { return false; } +#else + c->rsa_key = EVP_PKEY_new(); + RSA *rsa_key = RSA_new(); + + if(!c->rsa_key || !rsa_key || !n || !e || RSA_set0_key(rsa_key, n, e, NULL) != 1) { + RSA_free(rsa_key); + BN_free(e); + BN_free(n); + logger(LOG_ERR, "RSA_set0_key() failed with PublicKey for %s!", c->name); + return false; + } + + EVP_PKEY_set1_RSA(c->rsa_key, rsa_key); +#endif + return true; } - /* Else, check for PublicKeyFile statement and read it */ + /* Else, check for PublicKeyFile statement, or else check the host config file */ + + if(!get_config_string(lookup_config(c->config_tree, "PublicKeyFile"), &pubname)) { + xasprintf(&pubname, "%s/hosts/%s", confbase, c->name); + } + - if(get_config_string(lookup_config(c->config_tree, "PublicKeyFile"), &pubname)) { + fp = fopen(pubname, "r"); + + if(!fp) { + logger(LOG_ERR, "Error reading RSA public key file `%s': %s", pubname, strerror(errno)); + free(pubname); + return false; + } + +#ifndef LIBRESSL_VERSION_NUMBER + c->rsa_key = PEM_read_PUBKEY(fp, &c->rsa_key, NULL, NULL); +#else + RSA *rsa_key = RSA_new(); + + if(!rsa_key) { + abort(); + } + + if(!PEM_read_RSAPublicKey(fp, &rsa_key, NULL, NULL)) { + fclose(fp); fp = fopen(pubname, "r"); if(!fp) { @@ -120,40 +161,25 @@ bool read_rsa_public_key(connection_t *c) { return false; } - c->rsa_key = PEM_read_PUBKEY(fp, &c->rsa_key, NULL, NULL); - fclose(fp); - - if(c->rsa_key) { - free(pubname); - return true; /* Woohoo. */ - } - - logger(LOG_ERR, "Reading RSA public key file `%s' failed: %s", pubname, strerror(errno)); - free(pubname); - return false; + PEM_read_RSA_PUBKEY(fp, &rsa_key, NULL, NULL); } - /* Else, check if a harnessed public key is in the config file */ - - xasprintf(&hcfname, "%s/hosts/%s", confbase, c->name); - fp = fopen(hcfname, "r"); - - if(!fp) { - logger(LOG_ERR, "Error reading RSA public key file `%s': %s", hcfname, strerror(errno)); - free(hcfname); - return false; + if(rsa_key) { + c->rsa_key = EVP_PKEY_new(); + EVP_PKEY_set1_RSA(c->rsa_key, rsa_key); } - c->rsa_key = PEM_read_PUBKEY(fp, &c->rsa_key, NULL, NULL); +#endif + fclose(fp); if(c->rsa_key) { - free(hcfname); + free(pubname); return true; } - logger(LOG_ERR, "No public key for %s specified!", c->name); - + logger(LOG_ERR, "Reading RSA public key from `%s' failed: %s", pubname, strerror(errno)); + free(pubname); return false; } @@ -166,10 +192,6 @@ static bool read_rsa_private_key(void) { BIGNUM *n = NULL; BIGNUM *e = NULL; BIGNUM *d = NULL; - OSSL_PARAM_BLD *bld = NULL; - OSSL_PARAM *param = NULL; - EVP_PKEY_CTX *ctx = NULL; - int result; logger(LOG_WARNING, "Obsolete PrivateKey statement for myself!"); @@ -196,6 +218,12 @@ static bool read_rsa_private_key(void) { free(key); BN_hex2bn(&e, "FFFF"); +#ifdef HAVE_OPENSSL_PARAM_BUILD_H + OSSL_PARAM_BLD *bld = NULL; + OSSL_PARAM *param = NULL; + EVP_PKEY_CTX *ctx = NULL; + int result; + bld = OSSL_PARAM_BLD_new(); if(!bld) { @@ -223,6 +251,21 @@ static bool read_rsa_private_key(void) { return false; } +#else + myself->connection->rsa_key = EVP_PKEY_new(); + RSA *rsa_key = RSA_new(); + + if(!myself->connection->rsa_key || !rsa_key || !n || !e || !d || RSA_set0_key(rsa_key, n, e, d) != 1) { + RSA_free(rsa_key); + BN_free(d); + BN_free(e); + BN_free(n); + logger(LOG_ERR, "RSA_set0_key() failed with PrivateKey for myself!"); + } + + EVP_PKEY_set1_RSA(myself->connection->rsa_key, rsa_key); +#endif + return true; } diff --git a/src/protocol_auth.c b/src/protocol_auth.c index 063823c8..3824fa18 100644 --- a/src/protocol_auth.c +++ b/src/protocol_auth.c @@ -147,7 +147,7 @@ bool send_metakey(connection_t *c) { bool x; int result; - int len = EVP_PKEY_get_size(c->rsa_key); + int len = EVP_PKEY_size(c->rsa_key); size_t outlen = len; /* Allocate buffers for the meta key */ @@ -262,7 +262,7 @@ bool metakey_h(connection_t *c) { return false; } - len = EVP_PKEY_get_size(myself->connection->rsa_key); + len = EVP_PKEY_size(myself->connection->rsa_key); outlen = len; /* Check if the length of the meta key is all right */ @@ -375,7 +375,7 @@ bool metakey_h(connection_t *c) { bool send_challenge(connection_t *c) { /* CHECKME: what is most reasonable value for len? */ - int len = EVP_PKEY_get_size(c->rsa_key); + int len = EVP_PKEY_size(c->rsa_key); /* Allocate buffers for the challenge */ @@ -411,7 +411,7 @@ bool challenge_h(connection_t *c) { return false; } - len = EVP_PKEY_get_size(myself->connection->rsa_key); + len = EVP_PKEY_size(myself->connection->rsa_key); /* Check if the length of the challenge is all right */ @@ -456,7 +456,7 @@ bool send_chal_reply(connection_t *c) { } if(!EVP_DigestInit(ctx, c->indigest) - || !EVP_DigestUpdate(ctx, c->mychallenge, EVP_PKEY_get_size(myself->connection->rsa_key)) + || !EVP_DigestUpdate(ctx, c->mychallenge, EVP_PKEY_size(myself->connection->rsa_key)) || !EVP_DigestFinal(ctx, (unsigned char *)hash, NULL)) { EVP_MD_CTX_destroy(ctx); logger(LOG_ERR, "Error during calculation of response for %s (%s): %s", @@ -511,7 +511,7 @@ bool chal_reply_h(connection_t *c) { } if(!EVP_DigestInit(ctx, c->outdigest) - || !EVP_DigestUpdate(ctx, c->hischallenge, EVP_PKEY_get_size(c->rsa_key)) + || !EVP_DigestUpdate(ctx, c->hischallenge, EVP_PKEY_size(c->rsa_key)) || !EVP_DigestFinal(ctx, (unsigned char *)myhash, NULL)) { EVP_MD_CTX_destroy(ctx); logger(LOG_ERR, "Error during calculation of response from %s (%s): %s", diff --git a/src/tincd.c b/src/tincd.c index 2f0c219b..287e3746 100644 --- a/src/tincd.c +++ b/src/tincd.c @@ -369,7 +369,31 @@ static bool keygen(int bits) { fprintf(stderr, "Generating %d bits keys...\n", bits); +#if HAVE_DECL_EVP_RSA_GEN rsa_key = EVP_RSA_gen(bits); +#else + BIGNUM *e = NULL; + + if(BN_hex2bn(&e, "10001") == 0 || !e) { + abort(); + } + + rsa_key = EVP_PKEY_new(); + RSA *tmp_key = RSA_new(); + + if(!rsa_key || !tmp_key) { + abort(); + } + + int result = RSA_generate_key_ex(tmp_key, bits, e, NULL); + + if(!result) { + fprintf(stderr, "Error during key generation!\n"); + return false; + } + + EVP_PKEY_set1_RSA(rsa_key, tmp_key); +#endif if(!rsa_key) { fprintf(stderr, "Error during key generation!\n");