]> tinc-vpn.org Git - tinc/commitdiff
Fix compatibility with LibreSSL.
authorGuus Sliepen <guus@tinc-vpn.org>
Fri, 27 Feb 2026 10:13:36 +0000 (11:13 +0100)
committerGuus Sliepen <guus@tinc-vpn.org>
Sun, 1 Mar 2026 14:12:55 +0000 (15:12 +0100)
m4/openssl.m4
src/net_setup.c
src/protocol_auth.c
src/tincd.c

index 12b92aa99d2aaa9251c8cab0a10e1f7e1be1e762..0133d6e1a15f44632fdb86a832818f97879360ce 100644 (file)
@@ -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 <openssl/rsa.h>])
+
   AC_DEFINE(HAVE_OPENSSL, 1, [enable OpenSSL support])
 ])
index 7bde753bf4ce9107a25995f21aa5cba408207651..04021a2b36a966695d41dd43e3a9b9f593933332 100644 (file)
@@ -24,7 +24,9 @@
 
 #include <openssl/err.h>
 #include <openssl/evp.h>
+#ifdef HAVE_OPENSSL_PARAM_BUILD_H
 #include <openssl/param_build.h>
+#endif
 #include <openssl/pem.h>
 #include <openssl/rand.h>
 
@@ -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;
        }
 
index 063823c883f6427281fad2335036ec0e835c491b..3824fa18dd020dd53aadf4e8ed7c657da7fffdc6 100644 (file)
@@ -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",
index 2f0c219bbce97418107773d3021b575038ad5a77..287e37467d2a0dcacb3553a192733f3952c1a326 100644 (file)
@@ -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");