tests/rsa-psk-cb
tests/rsa-rsa-oaep
tests/rsa-rsa-pss
+tests/rsaes-pkcs1-v1_5
tests/safe-renegotiation/Makefile
tests/safe-renegotiation/Makefile.in
tests/safe-renegotiation/srn*
Copyright (C) 2013-2019 Nikos Mavrogiannopoulos
See the end for copying conditions.
+* Version 3.8.5 (unreleased ????-??-??)
+
+** libgnutls: Due to majority of usages and implementations of
+ RSA decryption with PKCS#1 v1.5 padding being incorrect,
+ leaving them vulnerable to Marvin attack, the RSAES-PKCS1-v1_5
+ is being deprecated (encryption and decryption) and will be
+ disabled in the future. A new option `allow-rsa-pkcs1-encrypt`
+ has been added into the system-wide library configuration which
+ allows to enable/disable the RSAES-PKCS1-v1_5. Currently, the
+ RSAES-PKCS1-v1_5 is enabled by default.
+
+** API and ABI modifications:
+No changes since last version.
+
* Version 3.8.4 (released 2024-03-18)
** libgnutls: RSA-OAEP encryption scheme is now supported
* Overriding the parameter verification profile::
* Overriding the default priority string::
* Enabling/Disabling system/acceleration protocols::
+* Enabling/Disabling RSAES-PKCS1-v1_5
@end menu
@node Application-specific priority strings
@subsection Enabling KTLS
When GnuTLS is build with -–enable-ktls configuration, KTLS is disabled by default.
This can be enabled by setting @code{ktls = true} in @code{[global]} section.
+
+
+@node Enabling/Disabling RSAES-PKCS1-v1_5
+@section Enabling/Disabling RSAES-PKCS1-v1_5
+
+This option can be used to enable/disable RSA PKCS1 v1.5 encryption and decryption
+in GnuTLS. The RSAES-PKCS1-v1_5 is enabled by default.
+
+Below example shows how to explicitely disable the RSAES-PKCS1-v1_5.
+@example
+[overrides]
+allow-rsa-pkcs1-encrypt = false
+
+@end example
GNUTLS_E_NO_COMMON_KEY_SHARE),
ERROR_ENTRY(N_("The early data were rejected."),
GNUTLS_E_EARLY_DATA_REJECTED),
+ ERROR_ENTRY(N_("The encryption algorithm is not supported."),
+ GNUTLS_E_UNSUPPORTED_ENCRYPTION_ALGORITHM),
{ NULL, NULL, 0 }
};
}
/* PK */
- ret = gnutls_pk_self_test(0, GNUTLS_PK_RSA);
- if (ret < 0) {
- return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
+ if (_gnutls_config_is_rsa_pkcs1_encrypt_allowed()) {
+ ret = gnutls_pk_self_test(0, GNUTLS_PK_RSA);
+ if (ret < 0) {
+ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR);
+ }
}
ret = gnutls_pk_self_test(0, GNUTLS_PK_DSA);
extern unsigned int _gnutls_global_version;
bool _gnutls_config_is_ktls_enabled(void);
+bool _gnutls_config_is_rsa_pkcs1_encrypt_allowed(void);
#endif /* GNUTLS_LIB_GNUTLS_INT_H */
#define GNUTLS_E_TOO_MANY_HANDSHAKE_PACKETS -81
#define GNUTLS_E_RECEIVED_DISALLOWED_NAME -82 /* GNUTLS_A_ILLEGAL_PARAMETER */
#define GNUTLS_E_CERTIFICATE_REQUIRED -112 /* GNUTLS_A_CERTIFICATE_REQUIRED */
+#define GNUTLS_E_UNSUPPORTED_ENCRYPTION_ALGORITHM -113
/* returned if you need to generate temporary RSA
* parameters. These are needed for export cipher suites.
struct rsa_public_key pub;
nettle_random_func *random_func;
+ if (!_gnutls_config_is_rsa_pkcs1_encrypt_allowed()) {
+ ret = gnutls_assert_val(
+ GNUTLS_E_UNSUPPORTED_ENCRYPTION_ALGORITHM);
+ goto cleanup;
+ }
+
/* RSA encryption with PKCS#1 v1.5 padding is not approved */
not_approved = true;
size_t length;
nettle_random_func *random_func;
+ if (!_gnutls_config_is_rsa_pkcs1_encrypt_allowed()) {
+ ret = gnutls_assert_val(
+ GNUTLS_E_UNSUPPORTED_ENCRYPTION_ALGORITHM);
+ goto cleanup;
+ }
+
/* RSA decryption with PKCS#1 v1.5 padding is not approved */
not_approved = true;
switch (algo) {
case GNUTLS_PK_RSA:
+ if (!_gnutls_config_is_rsa_pkcs1_encrypt_allowed()) {
+ ret = gnutls_assert_val(
+ GNUTLS_E_UNSUPPORTED_ENCRYPTION_ALGORITHM);
+ goto fail;
+ }
+
/* RSA decryption with PKCS#1 v1.5 padding is not approved */
not_approved = true;
struct cfg {
bool allowlisting;
bool ktls_enabled;
+ bool allow_rsa_pkcs1_encrypt;
name_val_array_t priority_strings;
char *priority_string;
dst->allowlisting = src->allowlisting;
dst->ktls_enabled = src->ktls_enabled;
+ dst->allow_rsa_pkcs1_encrypt = src->allow_rsa_pkcs1_encrypt;
dst->force_ext_master_secret = src->force_ext_master_secret;
dst->force_ext_master_secret_set = src->force_ext_master_secret_set;
memcpy(dst->ciphers, src->ciphers, sizeof(src->ciphers));
_gnutls_default_priority_string = cfg->default_priority_string;
}
+ /* enable RSA-PKCS1-V1_5 by default */
+ cfg->allow_rsa_pkcs1_encrypt = true;
+
if (cfg->allowlisting) {
/* also updates `flags` of global `hash_algorithms[]` */
ret = cfg_hashes_set_array(cfg, ctx->hashes, ctx->hashes_size);
return 0;
goto exit;
}
+ } else if (c_strcasecmp(name, "allow-rsa-pkcs1-encrypt") == 0) {
+ p = clear_spaces(value, str);
+ if (c_strcasecmp(p, "true") == 0) {
+ cfg->allow_rsa_pkcs1_encrypt = true;
+ } else if (c_strcasecmp(p, "false") == 0) {
+ cfg->allow_rsa_pkcs1_encrypt = false;
+ } else {
+ _gnutls_debug_log(
+ "cfg: unknown RSA PKCS1 encryption mode %s\n",
+ p);
+ if (fail_on_invalid_config)
+ return 0;
+ goto exit;
+ }
} else {
_gnutls_debug_log("unknown parameter %s\n", name);
if (fail_on_invalid_config)
return system_wide_config.ktls_enabled;
}
+bool _gnutls_config_is_rsa_pkcs1_encrypt_allowed(void)
+{
+ return system_wide_config.allow_rsa_pkcs1_encrypt;
+}
+
/*
* high-level interface for overriding configuration files
*/
protocol-set-allowlist.sh
indirect_tests += system-override-curves-allowlist
indirect_tests += protocol-set-allowlist
+
+dist_check_SCRIPTS += system-override-allow-rsa-pkcs1-encrypt.sh
+indirect_tests += rsaes-pkcs1-v1_5
+rsaes_pkcs1_v1_5_SOURCES = rsaes-pkcs1-v1_5.c
+rsaes_pkcs1_v1_5_LDADD = $(COMMON_GNUTLS_LDADD)
endif
dist_check_SCRIPTS += gnutls-cli-self-signed.sh gnutls-cli-invalid-crl.sh gnutls-cli-rawpk.sh
--- /dev/null
+/*
+ * Copyright (C) 2024 Red Hat, Inc.
+ *
+ * Author: Zoltan Fridrich
+ *
+ * This file is part of GnuTLS.
+ *
+ * GnuTLS is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuTLS is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <gnutls/abstract.h>
+#include <gnutls/gnutls.h>
+
+static const char pem[] =
+ "-----BEGIN RSA PRIVATE KEY-----\n"
+ "MIICXAIBAAKBgQC7ZkP18sXXtozMxd/1iDuxyUtqDqGtIFBACIChT1yj0Phsz+Y8\n"
+ "9+wEdhMXi2SJIlvA3VN8O+18BLuAuSi+jpvGjqClEsv1Vx6i57u3M0mf47tKrmpN\n"
+ "aP/JEeIyjc49gAuNde/YAIGPKAQDoCKNYQQH+rY3fSEHSdIJYWmYkKNYqQIDAQAB\n"
+ "AoGADpmARG5CQxS+AesNkGmpauepiCz1JBF/JwnyiX6vEzUh0Ypd39SZztwrDxvF\n"
+ "PJjQaKVljml1zkJpIDVsqvHdyVdse8M+Qn6hw4x2p5rogdvhhIL1mdWo7jWeVJTF\n"
+ "RKB7zLdMPs3ySdtcIQaF9nUAQ2KJEvldkO3m/bRJFEp54k0CQQDYy+RlTmwRD6hy\n"
+ "7UtMjR0H3CSZJeQ8svMCxHLmOluG9H1UKk55ZBYfRTsXniqUkJBZ5wuV1L+pR9EK\n"
+ "ca89a+1VAkEA3UmBelwEv2u9cAU1QjKjmwju1JgXbrjEohK+3B5y0ESEXPAwNQT9\n"
+ "TrDM1m9AyxYTWLxX93dI5QwNFJtmbtjeBQJARSCWXhsoaDRG8QZrCSjBxfzTCqZD\n"
+ "ZXtl807ymCipgJm60LiAt0JLr4LiucAsMZz6+j+quQbSakbFCACB8SLV1QJBAKZQ\n"
+ "YKf+EPNtnmta/rRKKvySsi3GQZZN+Dt3q0r094XgeTsAqrqujVNfPhTMeP4qEVBX\n"
+ "/iVX2cmMTSh3w3z8MaECQEp0XJWDVKOwcTW6Ajp9SowtmiZ3YDYo1LF9igb4iaLv\n"
+ "sWZGfbnU3ryjvkb6YuFjgtzbZDZHWQCo8/cOtOBmPdk=\n"
+ "-----END RSA PRIVATE KEY-----\n";
+
+const gnutls_datum_t privkey_datum = { (void *)pem, sizeof(pem) };
+const gnutls_datum_t in_message = { (void *)"hello", 5 };
+
+int main(void)
+{
+ int ret = EXIT_FAILURE;
+ gnutls_datum_t crypt = { NULL, 0 };
+ gnutls_datum_t out_message = { NULL, 0 };
+ gnutls_pubkey_t pubkey = NULL;
+ gnutls_privkey_t privkey = NULL;
+
+ gnutls_global_init();
+ assert(gnutls_privkey_init(&privkey) >= 0);
+ assert(gnutls_pubkey_init(&pubkey) >= 0);
+ assert(gnutls_privkey_import_x509_raw(privkey, &privkey_datum,
+ GNUTLS_X509_FMT_PEM, NULL,
+ 0) >= 0);
+ assert(gnutls_pubkey_import_privkey(pubkey, privkey, 0, 0) >= 0);
+
+ if (gnutls_pubkey_encrypt_data(pubkey, 0, &in_message, &crypt) < 0 ||
+ gnutls_privkey_decrypt_data(privkey, 0, &crypt, &out_message) < 0)
+ goto cleanup;
+
+ assert(in_message.size == out_message.size);
+ assert(memcmp(out_message.data, in_message.data, in_message.size) == 0);
+ ret = EXIT_SUCCESS;
+cleanup:
+ gnutls_free(crypt.data);
+ gnutls_free(out_message.data);
+ gnutls_privkey_deinit(privkey);
+ gnutls_pubkey_deinit(pubkey);
+ gnutls_global_deinit();
+ return ret;
+}
--- /dev/null
+#!/bin/sh
+
+# Copyright (C) 2024 Red Hat, Inc.
+#
+# Author: Zoltan Fridrich
+#
+# This file is part of GnuTLS.
+#
+# GnuTLS is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# GnuTLS is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>
+
+: ${srcdir=.}
+TEST=${srcdir}/rsaes-pkcs1-v1_5
+CONF=${srcdir}/config.$$.tmp
+export GNUTLS_SYSTEM_PRIORITY_FILE=${CONF}
+export GNUTLS_SYSTEM_PRIORITY_FAIL_ON_INVALID=1
+
+if test "${WINDIR}" != ""; then
+ exit 77
+fi
+
+if test "${GNUTLS_FORCE_FIPS_MODE}" = 1; then
+ exit 77
+fi
+
+cat <<_EOF_ > ${CONF}
+[overrides]
+allow-rsa-pkcs1-encrypt = true
+_EOF_
+
+${TEST} && fail "RSAES-PKCS1-v1_5 expected to succeed"
+
+cat <<_EOF_ > ${CONF}
+[overrides]
+allow-rsa-pkcs1-encrypt = false
+_EOF_
+
+${TEST} || fail "RSAES-PKCS1-v1_5 expected to fail"
+
+unset GNUTLS_SYSTEM_PRIORITY_FILE
+unset GNUTLS_SYSTEM_PRIORITY_FAIL_ON_INVALID
+exit 0