From: Sean Khan Date: Mon, 15 Apr 2024 00:07:30 +0000 (-0400) Subject: nginx-util: fix deprecated openssl 3.0 functions X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=0d0afff918e0c1b8b681ee2a85811cb353e3e58b;p=feed%2Fpackages.git nginx-util: fix deprecated openssl 3.0 functions Since upstream openwrt has been using openssl 3.0 for quite some time, figured we could clean up some of the legacy code. This PR updates the code for EC/RSA key generation. nginx-util currently only generates 'ecc' keys, even though the framework is there for rsa as well. In order properly test the changes, I created two binaries: 'nginx-util-ssl' (generates ec keys) 'nginx-util-ssl-rsa' (generates rsa keys) where I would change line:455 in `src/nginx-ssl-util.hpp` `auto pkey = gen_eckey(NID_secp384r1)` to `auto pkey = gen_rsakey(2048)` Example with UCI config ``` config server '_rsa' list listen '443 ssl default_server' list listen '[::]:443 ssl default_server' option server_name '_rsa' list include 'restrict_locally' list include 'conf.d/*.locations' option uci_manage_ssl 'self-signed' option key_type 'rsa' option ssl_certificate '/etc/nginx/conf.d/_rsa.crt' option ssl_certificate_key '/etc/nginx/conf.d/_rsa.key' option ssl_session_cache 'shared:SSL:32k' option ssl_session_timeout '64m' option access_log 'off; # logd openwrt' ``` ➤ /opt/bin/nginx-ssl-util-rsa add_ssl _rsa Adding SSL directives to UCI server: nginx._rsa uci_manage_ssl='self-signed' Created self-signed SSL certificate '/etc/nginx/conf.d/_rsa.crt' with key '/etc/nginx/conf.d/_rsa.key'. [04/14/24 18:37:15](K-6.6.27) root@WRX36 ~ ➤ openssl x509 -in /etc/nginx/conf.d/_rsa.crt -text -noout Certificate: Data: Version: 3 (0x2) Serial Number: 6d:55:a6:cd:52:25:31:fd:3c:78:66:24:82:5f:bb:b6:a6:fe:8f:c7 Signature Algorithm: sha256WithRSAEncryption Issuer: C = ZZ, ST = Somewhere, L = None, CN = OpenWrt, O = OpenWrtBF399B64ACF71BC3 Validity Not Before: Apr 14 22:37:15 2024 GMT Not After : Jul 16 22:37:15 2027 GMT Subject: C = ZZ, ST = Somewhere, L = None, CN = OpenWrt, O = OpenWrtBF399B64ACF71BC3 Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: 00:ac:52:71:af:25:e9:05:0a:a5:d7:86:d3:8d:0b: 66:e0:09:cf:2a:cd:a1:63:57:36:46:61:04:16:fe: 94:84:d0:20:ab:01:15:55:aa:a1:89:c2:85:a9:84: 47:ba:84:d7:1f:a9:0c:c0:f0:67:2f:81:1d:1b:3b: 31:d5:94:6e:a0:f0:e6:ec:26:91:4a:e2:fd:58:4c: ac:b5:9e:a1:cd:7d:91:51:29:81:1d:3e:4a:d9:d1: d5:f1:2f:34:2f:ca:95:dc:42:d5:c4:d3:d6:b2:91: d5:19:61:a2:b5:b1:90:f0:83:88:ef:92:c9:bf:a4: 59:a9:d6:00:6f:1c:0d:70:16:40:cc:cb:c0:de:c4: 8f:00:83:a3:2f:77:ca:18:cd:7b:d4:77:96:47:78: 1b:c1:ff:08:86:93:79:91:8f:a7:95:71:46:06:69: fc:cc:65:64:e7:99:11:cc:82:bb:39:6b:12:27:73: 0e:d1:e7:65:51:9e:ad:dc:b3:ff:3f:ba:b0:72:4f: 22:ad:7e:41:bb:3c:c7:80:30:81:5f:8b:32:f4:7f: 22:48:3f:3d:a9:eb:28:27:12:db:a9:63:c9:7e:e2: ed:36:de:e7:68:31:4e:9c:c0:36:e8:f2:d9:3f:50: 09:50:a3:e8:7a:03:00:4f:8d:e1:10:eb:a1:87:44: be:23 Exponent: 65537 (0x10001) Signature Algorithm: sha256WithRSAEncryption Signature Value: 06:7d:84:00:ac:8f:8b:a6:b6:b7:b5:ed:ee:7f:61:76:6d:ee: 11:53:f6:d1:f8:95:ad:6c:d7:d0:3e:01:ac:bb:d7:7a:8d:59: 80:ec:ba:b2:7b:78:5c:4f:5e:3f:f1:74:ad:d9:8c:a2:6b:08: 9c:bf:b1:42:fd:8d:a6:35:48:4d:a7:2d:92:c9:45:66:77:32: a4:e0:ea:eb:e0:4a:42:f5:dd:ea:a2:c0:0a:66:5a:32:03:1d: e7:87:3a:7f:1e:00:ed:d0:21:01:d5:f9:e2:b1:e6:b7:cb:1c: 67:11:de:69:7f:a2:ce:d0:fc:2d:f2:6c:33:84:4c:3d:f4:f6: 60:6b:2e:31:b7:0c:41:2c:73:31:7e:94:19:a2:2b:6a:56:3f: 07:37:71:97:28:58:91:63:b2:58:97:b2:aa:1e:d5:d9:6d:af: 6f:a0:02:e0:06:39:b0:c9:f5:50:41:b5:58:41:6a:30:72:89: 9a:67:7e:a1:7a:a5:02:b9:2a:f3:f8:93:4f:59:6e:b1:27:54: 86:d1:ec:96:7a:dd:d1:44:6b:1e:3b:17:cf:15:64:ad:83:6b: 63:20:2d:42:c3:28:68:14:de:12:4e:8a:c3:f3:10:c8:4b:4f: c7:d8:2b:a8:45:fb:3a:bd:9d:bd:08:71:08:09:ed:ea:9b:b9: 3b:33:a6:a6 [04/14/24 18:37:27](K-6.6.27) root@WRX36 ~ ➤ /opt/bin/nginx-ssl-util add_ssl _ec Adding SSL directives to UCI server: nginx._ec uci_manage_ssl='self-signed' Created self-signed SSL certificate '/etc/nginx/conf.d/_ec.crt' with key '/etc/nginx/conf.d/_ec.key'. [04/14/24 18:37:43](K-6.6.27) root@WRX36 ~ ➤ openssl x509 -in /etc/nginx/conf.d/_ec.crt -text -noout Certificate: Data: Version: 3 (0x2) Serial Number: 55:32:fe:07:09:79:d1:40:d7:43:2e:45:3d:98:4a:77:65:d0:29:41 Signature Algorithm: ecdsa-with-SHA256 Issuer: C = ZZ, ST = Somewhere, L = None, CN = OpenWrt, O = OpenWrt2EDD40F41960C8C1 Validity Not Before: Apr 14 22:37:43 2024 GMT Not After : Jul 16 22:37:43 2027 GMT Subject: C = ZZ, ST = Somewhere, L = None, CN = OpenWrt, O = OpenWrt2EDD40F41960C8C1 Subject Public Key Info: Public Key Algorithm: id-ecPublicKey Public-Key: (384 bit) pub: 04:97:d2:b2:f0:c9:60:60:89:7e:ea:6f:48:1c:90: 8e:6d:1d:d8:58:46:8c:de:e9:50:e2:74:ea:d8:dd: 8c:d9:ed:f4:4c:b7:41:95:55:98:38:5a:9e:66:83: b9:7c:79:71:9b:ec:18:ed:d9:09:3c:f7:64:32:ae: 59:ad:92:de:d7:c4:15:2e:e5:89:65:f4:29:8a:62: a0:85:21:95:22:3a:38:e3:11:e6:f2:01:f6:50:62: 01:ed:68:0d:d0:0c:d4 ASN1 OID: secp384r1 NIST CURVE: P-384 Signature Algorithm: ecdsa-with-SHA256 Signature Value: 30:65:02:30:78:af:d1:4f:57:b1:97:2b:87:aa:7f:a2:26:39: 19:30:5c:4f:9c:f0:d7:ee:24:8e:a2:39:ec:70:af:16:eb:a6: 72:96:d4:a7:2f:c1:38:f4:65:ed:ed:bf:22:c6:a4:6d:02:31: 00:bc:ec:19:0e:3d:6a:d1:5a:ae:6d:5c:a3:ec:96:60:32:f9: 6a:88:06:92:ed:c1:a7:44:2c:33:7a:22:72:0f:2a:ce:83:f0: f2:04:9e:49:60:ef:83:b4:7f:8b:af:61:c9 ``` Maintainer: Peter Stadler Compile tested: aarch64, qualcommax, Master Branch Run tested: aarch64, Dynalink DL-WRX36, Master Branch Signed-off-by: Sean Khan --- diff --git a/net/nginx-util/Makefile b/net/nginx-util/Makefile index 8b189aeda0..d52ca54231 100644 --- a/net/nginx-util/Makefile +++ b/net/nginx-util/Makefile @@ -1,8 +1,8 @@ include $(TOPDIR)/rules.mk PKG_NAME:=nginx-util -PKG_VERSION:=1.6 -PKG_RELEASE:=21 +PKG_VERSION:=1.7 +PKG_RELEASE:=1 PKG_MAINTAINER:=Peter Stadler include $(INCLUDE_DIR)/package.mk @@ -11,8 +11,6 @@ include $(INCLUDE_DIR)/cmake.mk CMAKE_OPTIONS+= -DUBUS=y CMAKE_OPTIONS+= -DVERSION=$(PKG_VERSION) -TARGET_CFLAGS+= -Wno-error=deprecated-declarations - define Package/nginx-ssl-util/default SECTION:=net CATEGORY:=Network diff --git a/net/nginx-util/src/px5g-openssl.hpp b/net/nginx-util/src/px5g-openssl.hpp index 7c79bad979..3dab5891ca 100644 --- a/net/nginx-util/src/px5g-openssl.hpp +++ b/net/nginx-util/src/px5g-openssl.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -22,7 +23,7 @@ auto checkend(const std::string& crtpath, time_t seconds = 0, bool use_pem = tru auto gen_eckey(int curve) -> EVP_PKEY_ptr; -auto gen_rsakey(int keysize, BN_ULONG exponent = RSA_F4) -> EVP_PKEY_ptr; +auto gen_rsakey(int keysize) -> EVP_PKEY_ptr; void write_key(const EVP_PKEY_ptr& pkey, const std::string& keypath = "", bool use_pem = true); @@ -88,42 +89,45 @@ auto gen_eckey(const int curve) -> EVP_PKEY_ptr } EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); - EC_GROUP_set_point_conversion_form(group, POINT_CONVERSION_UNCOMPRESSED); - auto* eckey = EC_KEY_new(); + EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, nullptr); - if (eckey != nullptr) { - if ((EC_KEY_set_group(eckey, group) == 0) || (EC_KEY_generate_key(eckey) == 0)) { - EC_KEY_free(eckey); - eckey = nullptr; - } + if (!EVP_PKEY_paramgen_init(ctx)) { + throw std::runtime_error("Could not init paramgen"); } - EC_GROUP_free(group); + EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, curve); - if (eckey == nullptr) { - std::string errmsg{"gen_eckey error: cannot build key with curve id "}; - errmsg += std::to_string(curve) + "\n"; + EVP_PKEY* params = nullptr; + EVP_PKEY_paramgen(ctx, ¶ms); + + EVP_PKEY_CTX* key_gen_ctx = EVP_PKEY_CTX_new(params, nullptr); + + if (EVP_PKEY_keygen_init(key_gen_ctx) <= 0) { + std::string errmsg{"gen_eckey error: cannot initialize key generation context\n"}; ERR_print_errors_cb(print_error, &errmsg); throw std::runtime_error(errmsg); } - EVP_PKEY_ptr pkey{EVP_PKEY_new(), ::EVP_PKEY_free}; - - // EVP_PKEY_assign_EC_KEY is a macro casting eckey to char *: - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast) - if (!EVP_PKEY_assign_EC_KEY(pkey.get(), eckey)) { - EC_KEY_free(eckey); - std::string errmsg{"gen_eckey error: cannot assign EC key to EVP\n"}; + EVP_PKEY* pkey = nullptr; + if (!EVP_PKEY_keygen(key_gen_ctx, &pkey)) { + EVP_PKEY_CTX_free(key_gen_ctx); + EC_GROUP_free(group); + std::string errmsg{"gen_eckey error: cannot generate key pair\n"}; ERR_print_errors_cb(print_error, &errmsg); throw std::runtime_error(errmsg); } - return pkey; + EVP_PKEY_CTX_free(ctx); + EC_GROUP_free(group); + + EVP_PKEY_ptr pkey_ptr{pkey, ::EVP_PKEY_free}; + + return pkey_ptr; } -auto gen_rsakey(const int keysize, const BN_ULONG exponent) -> EVP_PKEY_ptr +auto gen_rsakey(const int keysize) -> EVP_PKEY_ptr { if (keysize < rsa_min_modulus_bits || keysize > OPENSSL_RSA_MAX_MODULUS_BITS) { std::string errmsg{"gen_rsakey error: RSA keysize ("}; @@ -131,42 +135,12 @@ auto gen_rsakey(const int keysize, const BN_ULONG exponent) -> EVP_PKEY_ptr errmsg += std::to_string(OPENSSL_RSA_MAX_MODULUS_BITS) + "]"; throw std::runtime_error(errmsg); } - auto* bignum = BN_new(); - - if (bignum == nullptr) { - std::string errmsg{"gen_rsakey error: cannot get big number struct\n"}; - ERR_print_errors_cb(print_error, &errmsg); - throw std::runtime_error(errmsg); - } - - auto* rsa = RSA_new(); - - if (rsa != nullptr) { - if ((BN_set_word(bignum, exponent) == 0) || - (RSA_generate_key_ex(rsa, keysize, bignum, nullptr) == 0)) - { - RSA_free(rsa); - rsa = nullptr; - } - } - - BN_free(bignum); - - if (rsa == nullptr) { - std::string errmsg{"gen_rsakey error: cannot create RSA key with size"}; - errmsg += std::to_string(keysize) + " and exponent "; - errmsg += std::to_string(exponent) + "\n"; - ERR_print_errors_cb(print_error, &errmsg); - throw std::runtime_error(errmsg); - } - EVP_PKEY_ptr pkey{EVP_PKEY_new(), ::EVP_PKEY_free}; + EVP_PKEY_ptr pkey = {EVP_RSA_gen(keysize), EVP_PKEY_free}; - // EVP_PKEY_assign_RSA is a macro casting rsa to char *: - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast) - if (!EVP_PKEY_assign_RSA(pkey.get(), rsa)) { - RSA_free(rsa); - std::string errmsg{"gen_rsakey error: cannot assign RSA key to EVP\n"}; + if (!pkey) { + std::string errmsg{"gen_rsakey error: unable to generate RSA key with size: "}; + errmsg += std::to_string(keysize); ERR_print_errors_cb(print_error, &errmsg); throw std::runtime_error(errmsg); } @@ -179,31 +153,10 @@ void write_key(const EVP_PKEY_ptr& pkey, const std::string& keypath, const bool BIO* bio = nullptr; if (keypath.empty()) { - bio = _BIO_new_fp(stdout, use_pem); + bio = BIO_new_fp(stdout, BIO_NOCLOSE); } - - else { // BIO_new_file(keypath.c_str(), (use_pem ? "w" : "wb") ); - - static constexpr auto mask = 0600; - // auto fd = open(keypath.c_str(), O_WRONLY | O_CREAT | O_TRUNC, mask); - // creat has no cloexec, alt. triggers cppcoreguidelines-pro-type-vararg - // NOLINTNEXTLINE(android-cloexec-creat) - auto fd = creat(keypath.c_str(), mask); // the same without va_args. - - if (fd >= 0) { - auto* fp = fdopen(fd, (use_pem ? "w" : "wb")); - - if (fp != nullptr) { - bio = _BIO_new_fp(fp, use_pem, true); - if (bio == nullptr) { - // NOLINTNEXTLINE(cppcoreguidelines-owning-memory) fp owns fd: - fclose(fp); - } - } - else { - close(fd); - } - } + else { + bio = BIO_new_file(keypath.c_str(), use_pem ? "w" : "wb"); } if (bio == nullptr) { @@ -214,35 +167,28 @@ void write_key(const EVP_PKEY_ptr& pkey, const std::string& keypath, const bool throw std::runtime_error(errmsg); } - int len = 0; - - auto* key = pkey.get(); - switch (EVP_PKEY_base_id(key)) { // use same format as px5g: - case EVP_PKEY_EC: - len = use_pem ? PEM_write_bio_ECPrivateKey(bio, EVP_PKEY_get0_EC_KEY(key), nullptr, - nullptr, 0, nullptr, nullptr) - : i2d_ECPrivateKey_bio(bio, EVP_PKEY_get0_EC_KEY(key)); - break; - case EVP_PKEY_RSA: - len = use_pem ? PEM_write_bio_RSAPrivateKey(bio, EVP_PKEY_get0_RSA(key), nullptr, - nullptr, 0, nullptr, nullptr) - : i2d_RSAPrivateKey_bio(bio, EVP_PKEY_get0_RSA(key)); - break; - default: - len = use_pem - ? PEM_write_bio_PrivateKey(bio, key, nullptr, nullptr, 0, nullptr, nullptr) - : i2d_PrivateKey_bio(bio, key); + if (use_pem) { + if (PEM_write_bio_PrivateKey(bio, pkey.get(), nullptr, nullptr, 0, nullptr, nullptr) != 1) { + BIO_free_all(bio); + std::string errmsg{"write_key error: cannot write EVP pkey to "}; + errmsg += keypath.empty() ? "stdout" : keypath; + errmsg += "\n"; + ERR_print_errors_cb(print_error, &errmsg); + throw std::runtime_error(errmsg); + } + } + else { + if (i2d_PrivateKey_bio(bio, pkey.get()) != 1) { + BIO_free_all(bio); + std::string errmsg{"write_key error: cannot write EVP pkey to "}; + errmsg += keypath.empty() ? "stdout" : keypath; + errmsg += "\n"; + ERR_print_errors_cb(print_error, &errmsg); + throw std::runtime_error(errmsg); + } } BIO_free_all(bio); - - if (len == 0) { - std::string errmsg{"write_key error: cannot write EVP pkey to "}; - errmsg += keypath.empty() ? "stdout" : keypath; - errmsg += "\n"; - ERR_print_errors_cb(print_error, &errmsg); - throw std::runtime_error(errmsg); - } } auto subject2name(const std::string& subject) -> X509_NAME_ptr