]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/resolve/resolved-dns-dnssec.c
openssl: supress warnings about functions deprecated by openssl 3.0
[thirdparty/systemd.git] / src / resolve / resolved-dns-dnssec.c
index 9bcce83dcf8995b613b9ed0cfd8fcea62e3d3423..738259481d9eecf90b78ad86e2966defb6e2f9bc 100644 (file)
 #include "sort-util.h"
 #include "string-table.h"
 
+#if PREFER_OPENSSL
+#  pragma GCC diagnostic push
+#    pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(RSA*, RSA_free, NULL);
+DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EC_KEY*, EC_KEY_free, NULL);
+#  pragma GCC diagnostic pop
+#endif
+
 #define VERIFY_RRS_MAX 256
 #define MAX_KEY_SIZE (32*1024)
 
@@ -88,13 +96,15 @@ static int dnssec_rsa_verify_raw(
                 const void *data, size_t data_size,
                 const void *exponent, size_t exponent_size,
                 const void *modulus, size_t modulus_size) {
+        int r;
 
 #if PREFER_OPENSSL
+#  pragma GCC diagnostic push
+#    pragma GCC diagnostic ignored "-Wdeprecated-declarations"
         _cleanup_(RSA_freep) RSA *rpubkey = NULL;
         _cleanup_(EVP_PKEY_freep) EVP_PKEY *epubkey = NULL;
         _cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx = NULL;
         _cleanup_(BN_freep) BIGNUM *e = NULL, *m = NULL;
-        int r;
 
         assert(hash_algorithm);
 
@@ -110,8 +120,9 @@ static int dnssec_rsa_verify_raw(
         if (!rpubkey)
                 return -ENOMEM;
 
-        if (RSA_set0_key(rpubkey, BN_dup(m), BN_dup(e), NULL) <= 0)
+        if (RSA_set0_key(rpubkey, m, e, NULL) <= 0)
                 return -EIO;
+        e = m = NULL;
 
         assert((size_t) RSA_size(rpubkey) == signature_size);
 
@@ -140,13 +151,11 @@ static int dnssec_rsa_verify_raw(
                 return log_debug_errno(SYNTHETIC_ERRNO(EIO),
                                        "Signature verification failed: 0x%lx", ERR_get_error());
 
-        return r;
-
+#  pragma GCC diagnostic pop
 #else
         gcry_sexp_t public_key_sexp = NULL, data_sexp = NULL, signature_sexp = NULL;
         gcry_mpi_t n = NULL, e = NULL, s = NULL;
         gcry_error_t ge;
-        int r;
 
         assert(hash_algorithm);
 
@@ -222,9 +231,8 @@ finish:
                 gcry_sexp_release(signature_sexp);
         if (data_sexp)
                 gcry_sexp_release(data_sexp);
-
-        return r;
 #endif
+        return r;
 }
 
 static int dnssec_rsa_verify(
@@ -290,15 +298,17 @@ static int dnssec_ecdsa_verify_raw(
                 const void *signature_s, size_t signature_s_size,
                 const void *data, size_t data_size,
                 const void *key, size_t key_size) {
+        int k;
 
 #if PREFER_OPENSSL
+#  pragma GCC diagnostic push
+#    pragma GCC diagnostic ignored "-Wdeprecated-declarations"
         _cleanup_(EC_GROUP_freep) EC_GROUP *ec_group = NULL;
         _cleanup_(EC_POINT_freep) EC_POINT *p = NULL;
         _cleanup_(EC_KEY_freep) EC_KEY *eckey = NULL;
         _cleanup_(BN_CTX_freep) BN_CTX *bctx = NULL;
         _cleanup_(BN_freep) BIGNUM *r = NULL, *s = NULL;
         _cleanup_(ECDSA_SIG_freep) ECDSA_SIG *sig = NULL;
-        int k;
 
         assert(hash_algorithm);
 
@@ -344,21 +354,20 @@ static int dnssec_ecdsa_verify_raw(
         if (!sig)
                 return -ENOMEM;
 
-        if (ECDSA_SIG_set0(sig, BN_dup(r), BN_dup(s)) <= 0)
+        if (ECDSA_SIG_set0(sig, r, s) <= 0)
                 return -EIO;
+        r = s = NULL;
 
         k = ECDSA_do_verify(data, data_size, sig, eckey);
         if (k < 0)
                 return log_debug_errno(SYNTHETIC_ERRNO(EIO),
                                        "Signature verification failed: 0x%lx", ERR_get_error());
 
-        return k;
-
+#  pragma GCC diagnostic pop
 #else
         gcry_sexp_t public_key_sexp = NULL, data_sexp = NULL, signature_sexp = NULL;
         gcry_mpi_t q = NULL, r = NULL, s = NULL;
         gcry_error_t ge;
-        int k;
 
         assert(hash_algorithm);
 
@@ -433,9 +442,8 @@ finish:
                 gcry_sexp_release(signature_sexp);
         if (data_sexp)
                 gcry_sexp_release(data_sexp);
-
-        return k;
 #endif
+        return k;
 }
 
 static int dnssec_ecdsa_verify(
@@ -1461,27 +1469,22 @@ int dnssec_verify_dnskey_by_ds_search(DnsResourceRecord *dnskey, DnsAnswer *vali
         return 0;
 }
 
-static int nsec3_hash_to_gcrypt_md(uint8_t algorithm) {
+static hash_md_t nsec3_hash_to_hash_md(uint8_t algorithm) {
 
-        /* Translates a DNSSEC NSEC3 hash algorithm into a gcrypt digest identifier */
+        /* Translates a DNSSEC NSEC3 hash algorithm into an openssl/gcrypt digest identifier */
 
         switch (algorithm) {
 
         case NSEC3_ALGORITHM_SHA1:
-                return GCRY_MD_SHA1;
+                return OPENSSL_OR_GCRYPT(EVP_sha1(), GCRY_MD_SHA1);
 
         default:
-                return -EOPNOTSUPP;
+                return OPENSSL_OR_GCRYPT(NULL, -EOPNOTSUPP);
         }
 }
 
 int dnssec_nsec3_hash(DnsResourceRecord *nsec3, const char *name, void *ret) {
         uint8_t wire_format[DNS_WIRE_FORMAT_HOSTNAME_MAX];
-        _cleanup_(gcry_md_closep) gcry_md_hd_t md = NULL;
-        gcry_error_t err;
-        size_t hash_size;
-        int algorithm;
-        void *result;
         int r;
 
         assert(nsec3);
@@ -1496,13 +1499,55 @@ int dnssec_nsec3_hash(DnsResourceRecord *nsec3, const char *name, void *ret) {
                                        "Ignoring NSEC3 RR %s with excessive number of iterations.",
                                        dns_resource_record_to_string(nsec3));
 
-        algorithm = nsec3_hash_to_gcrypt_md(nsec3->nsec3.algorithm);
+        hash_md_t algorithm = nsec3_hash_to_hash_md(nsec3->nsec3.algorithm);
+#if PREFER_OPENSSL
+        if (!algorithm)
+                return -EOPNOTSUPP;
+
+        size_t hash_size = EVP_MD_size(algorithm);
+        assert(hash_size > 0);
+
+        if (nsec3->nsec3.next_hashed_name_size != hash_size)
+                return -EINVAL;
+
+        _cleanup_(EVP_MD_CTX_freep) EVP_MD_CTX *ctx = EVP_MD_CTX_new();
+        if (!ctx)
+                return -ENOMEM;
+
+        if (EVP_DigestInit_ex(ctx, algorithm, NULL) <= 0)
+                return -EIO;
+
+        r = dns_name_to_wire_format(name, wire_format, sizeof(wire_format), true);
+        if (r < 0)
+                return r;
+
+        if (EVP_DigestUpdate(ctx, wire_format, r) <= 0)
+                return -EIO;
+        if (EVP_DigestUpdate(ctx, nsec3->nsec3.salt, nsec3->nsec3.salt_size) <= 0)
+                return -EIO;
+
+        uint8_t result[EVP_MAX_MD_SIZE];
+        if (EVP_DigestFinal_ex(ctx, result, NULL) <= 0)
+                return -EIO;
+
+        for (unsigned k = 0; k < nsec3->nsec3.iterations; k++) {
+                if (EVP_DigestInit_ex(ctx, algorithm, NULL) <= 0)
+                        return -EIO;
+                if (EVP_DigestUpdate(ctx, result, hash_size) <= 0)
+                        return -EIO;
+                if (EVP_DigestUpdate(ctx, nsec3->nsec3.salt, nsec3->nsec3.salt_size) <= 0)
+                        return -EIO;
+
+                if (EVP_DigestFinal_ex(ctx, result, NULL) <= 0)
+                        return -EIO;
+        }
+#else
         if (algorithm < 0)
                 return algorithm;
 
         initialize_libgcrypt(false);
 
-        hash_size = gcry_md_get_algo_dlen(algorithm);
+        unsigned hash_size = gcry_md_get_algo_dlen(algorithm);
         assert(hash_size > 0);
 
         if (nsec3->nsec3.next_hashed_name_size != hash_size)
@@ -1512,14 +1557,15 @@ int dnssec_nsec3_hash(DnsResourceRecord *nsec3, const char *name, void *ret) {
         if (r < 0)
                 return r;
 
-        err = gcry_md_open(&md, algorithm, 0);
+        _cleanup_(gcry_md_closep) gcry_md_hd_t md = NULL;
+        gcry_error_t err = gcry_md_open(&md, algorithm, 0);
         if (gcry_err_code(err) != GPG_ERR_NO_ERROR || !md)
                 return -EIO;
 
         gcry_md_write(md, wire_format, r);
         gcry_md_write(md, nsec3->nsec3.salt, nsec3->nsec3.salt_size);
 
-        result = gcry_md_read(md, 0);
+        void *result = gcry_md_read(md, 0);
         if (!result)
                 return -EIO;
 
@@ -1535,6 +1581,7 @@ int dnssec_nsec3_hash(DnsResourceRecord *nsec3, const char *name, void *ret) {
                 if (!result)
                         return -EIO;
         }
+#endif
 
         memcpy(ret, result, hash_size);
         return (int) hash_size;
@@ -1554,8 +1601,14 @@ static int nsec3_is_good(DnsResourceRecord *rr, DnsResourceRecord *nsec3) {
                 return 0;
 
         /* Ignore NSEC3 RRs whose algorithm we don't know */
-        if (nsec3_hash_to_gcrypt_md(rr->nsec3.algorithm) < 0)
+#if PREFER_OPENSSL
+        if (!nsec3_hash_to_hash_md(rr->nsec3.algorithm))
                 return 0;
+#else
+        if (nsec3_hash_to_hash_md(rr->nsec3.algorithm) < 0)
+                return 0;
+#endif
+
         /* Ignore NSEC3 RRs with an excessive number of required iterations */
         if (rr->nsec3.iterations > NSEC3_ITERATIONS_MAX)
                 return 0;