summaryrefslogtreecommitdiff
path: root/lib/algorithms
diff options
context:
space:
mode:
Diffstat (limited to 'lib/algorithms')
-rw-r--r--lib/algorithms/ecc.c47
-rw-r--r--lib/algorithms/groups.c18
-rw-r--r--lib/algorithms/mac.c67
-rw-r--r--lib/algorithms/protocols.c69
-rw-r--r--lib/algorithms/sign.c120
5 files changed, 313 insertions, 8 deletions
diff --git a/lib/algorithms/ecc.c b/lib/algorithms/ecc.c
index f5fb8ac76f..d2c0b3585b 100644
--- a/lib/algorithms/ecc.c
+++ b/lib/algorithms/ecc.c
@@ -353,13 +353,58 @@ gnutls_ecc_curve_t gnutls_ecc_curve_get_id(const char *name)
return ret;
}
+/* This is only called by cfg_apply in priority.c, in blocklisting mode. */
int _gnutls_ecc_curve_mark_disabled(gnutls_ecc_curve_t curve)
{
gnutls_ecc_curve_entry_st *p;
for(p = ecc_curves; p->name != NULL; p++) {
if (p->id == curve) {
- p->supported = 0;
+ p->supported = false;
+ return 0;
+ }
+ }
+
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+}
+
+/* This is only called by cfg_apply in priority.c, in allowlisting mode. */
+void _gnutls_ecc_curve_mark_disabled_all(void)
+{
+ gnutls_ecc_curve_entry_st *p;
+
+ for(p = ecc_curves; p->name != NULL; p++) {
+ p->supported = false;
+ p->supported_revertible = true;
+ }
+}
+
+/**
+ * gnutls_ecc_curve_set_enabled:
+ * @curve: is an ECC curve
+ * @enabled: whether to enable the curve
+ *
+ * Modify the previous system wide setting that marked @curve as
+ * enabled or disabled. This only has effect when the curve is
+ * enabled through the allowlisting mode in the configuration file, or
+ * when the setting is modified with a prior call to this function.
+ *
+ * Returns: 0 on success or negative error code otherwise.
+ *
+ * Since: 3.7.3
+ */
+int
+gnutls_ecc_curve_set_enabled(gnutls_ecc_curve_t curve,
+ unsigned int enabled)
+{
+ gnutls_ecc_curve_entry_st *p;
+
+ for(p = ecc_curves; p->name != NULL; p++) {
+ if (p->id == curve) {
+ if (!p->supported_revertible) {
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+ }
+ p->supported = enabled;
return 0;
}
}
diff --git a/lib/algorithms/groups.c b/lib/algorithms/groups.c
index d4b77beb2a..d8bf95824f 100644
--- a/lib/algorithms/groups.c
+++ b/lib/algorithms/groups.c
@@ -276,6 +276,24 @@ gnutls_group_t gnutls_group_get_id(const char *name)
return ret;
}
+
+/* Similar to gnutls_group_get_id, except that it does not check if
+ * the curve is supported.
+ */
+gnutls_group_t _gnutls_group_get_id(const char *name)
+{
+ gnutls_group_t ret = GNUTLS_GROUP_INVALID;
+
+ GNUTLS_GROUP_LOOP(
+ if (c_strcasecmp(p->name, name) == 0) {
+ ret = p->id;
+ break;
+ }
+ );
+
+ return ret;
+}
+
/**
* gnutls_group_get_name:
* @group: is an element from %gnutls_group_t
diff --git a/lib/algorithms/mac.c b/lib/algorithms/mac.c
index 57dfca95de..a2c66e76bb 100644
--- a/lib/algorithms/mac.c
+++ b/lib/algorithms/mac.c
@@ -291,6 +291,7 @@ gnutls_digest_algorithm_t gnutls_digest_get_id(const char *name)
return ret;
}
+/* This is only called by cfg_apply in priority.c, in blocklisting mode. */
int _gnutls_digest_mark_insecure(gnutls_digest_algorithm_t dig)
{
#ifndef DISABLE_SYSTEM_CONFIG
@@ -307,6 +308,57 @@ int _gnutls_digest_mark_insecure(gnutls_digest_algorithm_t dig)
return GNUTLS_E_INVALID_REQUEST;
}
+/* This is only called by cfg_apply in priority.c, in allowlisting mode. */
+void _gnutls_digest_mark_insecure_all(void)
+{
+#ifndef DISABLE_SYSTEM_CONFIG
+ mac_entry_st *p;
+
+ for(p = hash_algorithms; p->name != NULL; p++) {
+ p->flags |= GNUTLS_MAC_FLAG_PREIMAGE_INSECURE_REVERTIBLE |
+ GNUTLS_MAC_FLAG_PREIMAGE_INSECURE;
+ }
+
+#endif
+}
+
+/**
+ * gnutls_digest_set_secure:
+ * @dig: is a digest algorithm
+ * @secure: whether to mark the digest algorithm secure
+ *
+ * Modify the previous system wide setting that marked @dig as secure
+ * or insecure. This only has effect when the algorithm is enabled
+ * through the allowlisting mode in the configuration file, or when
+ * the setting is modified with a prior call to this function.
+ *
+ * Since: 3.7.3
+ */
+int
+gnutls_digest_set_secure(gnutls_digest_algorithm_t dig,
+ unsigned int secure)
+{
+#ifndef DISABLE_SYSTEM_CONFIG
+ mac_entry_st *p;
+
+ for(p = hash_algorithms; p->name != NULL; p++) {
+ if (p->oid != NULL && p->id == (gnutls_mac_algorithm_t)dig) {
+ if (!(p->flags & GNUTLS_MAC_FLAG_PREIMAGE_INSECURE_REVERTIBLE)) {
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+ }
+ if (secure) {
+ p->flags &= ~GNUTLS_MAC_FLAG_PREIMAGE_INSECURE;
+ } else {
+ p->flags |= GNUTLS_MAC_FLAG_PREIMAGE_INSECURE;
+ }
+ return 0;
+ }
+ }
+
+#endif
+ return GNUTLS_E_INVALID_REQUEST;
+}
+
unsigned _gnutls_digest_is_insecure(gnutls_digest_algorithm_t dig)
{
const mac_entry_st *p;
@@ -320,6 +372,21 @@ unsigned _gnutls_digest_is_insecure(gnutls_digest_algorithm_t dig)
return 1;
}
+bool _gnutls_digest_is_insecure2(gnutls_digest_algorithm_t dig, unsigned flags)
+{
+ const mac_entry_st *p;
+
+ for(p = hash_algorithms; p->name != NULL; p++) {
+ if (p->oid != NULL && p->id == (gnutls_mac_algorithm_t)dig) {
+ return (p->flags & GNUTLS_MAC_FLAG_PREIMAGE_INSECURE &&
+ !(flags & GNUTLS_MAC_FLAG_ALLOW_INSECURE_REVERTIBLE &&
+ p->flags & GNUTLS_MAC_FLAG_PREIMAGE_INSECURE_REVERTIBLE));
+ }
+ }
+
+ return true;
+}
+
/**
* gnutls_mac_get_id:
* @name: is a MAC algorithm name
diff --git a/lib/algorithms/protocols.c b/lib/algorithms/protocols.c
index 4283cd0388..b0f3e0bc30 100644
--- a/lib/algorithms/protocols.c
+++ b/lib/algorithms/protocols.c
@@ -198,6 +198,7 @@ version_is_valid_for_session(gnutls_session_t session,
return 0;
}
+/* This is only called by cfg_apply in priority.c, in blocklisting mode. */
int _gnutls_version_mark_disabled(gnutls_protocol_t version)
{
#ifndef DISABLE_SYSTEM_CONFIG
@@ -205,7 +206,54 @@ int _gnutls_version_mark_disabled(gnutls_protocol_t version)
for (p = sup_versions; p->name != NULL; p++)
if (p->id == version) {
- p->supported = 0;
+ p->supported = false;
+ return 0;
+ }
+
+#endif
+ return GNUTLS_E_INVALID_REQUEST;
+}
+
+/* This is only called by cfg_apply in priority.c, in allowlisting mode. */
+void _gnutls_version_mark_revertible_all(void)
+{
+#ifndef DISABLE_SYSTEM_CONFIG
+ version_entry_st *p;
+
+ for (p = sup_versions; p->name != NULL; p++) {
+ p->supported_revertible = true;
+ }
+
+#endif
+}
+
+/**
+ * gnutls_protocol_set_enabled:
+ * @version: is a (gnutls) version number
+ * @enabled: whether to enable the protocol
+ *
+ * Mark the previous system wide setting that marked @version as
+ * enabled or disabled. This only has effect when the version is
+ * enabled through the allowlisting mode in the configuration file, or
+ * when the setting is modified with a prior call to this function.
+ *
+ * Returns: 0 on success or negative error code otherwise.
+ *
+ * Since: 3.7.3
+ */
+int
+gnutls_protocol_set_enabled(gnutls_protocol_t version,
+ unsigned int enabled)
+{
+#ifndef DISABLE_SYSTEM_CONFIG
+ version_entry_st *p;
+
+ for (p = sup_versions; p->name != NULL; p++)
+ if (p->id == version) {
+ if (!p->supported_revertible) {
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+ }
+ p->supported = enabled;
return 0;
}
@@ -469,6 +517,25 @@ const gnutls_protocol_t *gnutls_protocol_list(void)
return supported_protocols;
}
+/* Return all versions, including non-supported ones.
+ */
+const gnutls_protocol_t *_gnutls_protocol_list(void)
+{
+ const version_entry_st *p;
+ static gnutls_protocol_t protocols[MAX_ALGOS] = { 0 };
+
+ if (protocols[0] == 0) {
+ int i = 0;
+
+ for (p = sup_versions; p->name != NULL; p++) {
+ protocols[i++] = p->id;
+ }
+ protocols[i++] = 0;
+ }
+
+ return protocols;
+}
+
/* Returns a version number given the major and minor numbers.
*/
gnutls_protocol_t _gnutls_version_get(uint8_t major, uint8_t minor)
diff --git a/lib/algorithms/sign.c b/lib/algorithms/sign.c
index 4c5619454f..543bd19bb5 100644
--- a/lib/algorithms/sign.c
+++ b/lib/algorithms/sign.c
@@ -453,15 +453,22 @@ unsigned gnutls_sign_is_secure(gnutls_sign_algorithm_t algorithm)
bool _gnutls_sign_is_secure2(const gnutls_sign_entry_st *se, unsigned int flags)
{
- if (se->hash != GNUTLS_DIG_UNKNOWN && _gnutls_digest_is_insecure(se->hash))
- return gnutls_assert_val(0);
+ if (se->hash != GNUTLS_DIG_UNKNOWN &&
+ _gnutls_digest_is_insecure2(se->hash,
+ flags & GNUTLS_SIGN_FLAG_ALLOW_INSECURE_REVERTIBLE ?
+ GNUTLS_MAC_FLAG_ALLOW_INSECURE_REVERTIBLE :
+ 0)) {
+ return gnutls_assert_val(false);
+ }
- if (flags & GNUTLS_SIGN_FLAG_SECURE_FOR_CERTS)
- return (se->slevel==_SECURE)?1:0;
- else
- return (se->slevel==_SECURE || se->slevel == _INSECURE_FOR_CERTS)?1:0;
+ return (flags & GNUTLS_SIGN_FLAG_SECURE_FOR_CERTS ?
+ se->slevel == _SECURE :
+ (se->slevel == _SECURE || se->slevel == _INSECURE_FOR_CERTS)) ||
+ (flags & GNUTLS_SIGN_FLAG_ALLOW_INSECURE_REVERTIBLE &&
+ se->flags & GNUTLS_SIGN_FLAG_INSECURE_REVERTIBLE);
}
+/* This is only called by cfg_apply in priority.c, in blocklisting mode. */
int _gnutls_sign_mark_insecure(gnutls_sign_algorithm_t sign, hash_security_level_t level)
{
#ifndef DISABLE_SYSTEM_CONFIG
@@ -472,6 +479,7 @@ int _gnutls_sign_mark_insecure(gnutls_sign_algorithm_t sign, hash_security_level
for(p = sign_algorithms; p->name != NULL; p++) {
if (p->id && p->id == sign) {
+ if (p->slevel < level)
p->slevel = level;
return 0;
}
@@ -480,6 +488,106 @@ int _gnutls_sign_mark_insecure(gnutls_sign_algorithm_t sign, hash_security_level
return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
}
+/* This is only called by cfg_apply in priority.c, in allowlisting mode. */
+void _gnutls_sign_mark_insecure_all(hash_security_level_t level)
+{
+#ifndef DISABLE_SYSTEM_CONFIG
+ gnutls_sign_entry_st *p;
+
+ for(p = sign_algorithms; p->name != NULL; p++) {
+ if (p->slevel < level)
+ p->slevel = level;
+ p->flags |= GNUTLS_SIGN_FLAG_INSECURE_REVERTIBLE;
+ }
+#endif
+}
+
+/**
+ * gnutls_sign_set_secure:
+ * @sign: the sign algorithm
+ * @secure: whether to mark the sign algorithm secure
+ *
+ * Modify the previous system wide setting that marked @sign as secure
+ * or insecure. This only has effect when the algorithm is marked as
+ * secure through the allowlisting mode in the configuration file, or
+ * when the setting is modified with a prior call to this function.
+ *
+ * Even when @secure is true, @sign is not marked as secure for the
+ * use in certificates. Use gnutls_sign_set_secure_for_certs() to
+ * mark it secure as well for certificates.
+ *
+ * Since: 3.7.3
+ */
+int
+gnutls_sign_set_secure(gnutls_sign_algorithm_t sign,
+ unsigned int secure)
+{
+#ifndef DISABLE_SYSTEM_CONFIG
+ gnutls_sign_entry_st *p;
+
+ for(p = sign_algorithms; p->name != NULL; p++) {
+ if (p->id && p->id == sign) {
+ if (!(p->flags & GNUTLS_SIGN_FLAG_INSECURE_REVERTIBLE)) {
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+ }
+ if (secure) {
+ if (p->slevel > _INSECURE_FOR_CERTS) {
+ p->slevel = _INSECURE_FOR_CERTS;
+ }
+ } else {
+ p->slevel = _INSECURE;
+ }
+ return 0;
+ }
+ }
+#endif
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+}
+
+/**
+ * gnutls_sign_set_secure_for_certs:
+ * @sign: the sign algorithm
+ * @secure: whether to mark the sign algorithm secure for certificates
+ *
+ * Modify the previous system wide setting that marked @sign as secure
+ * or insecure for the use in certificates. This only has effect when
+ * the algorithm is marked as secure through the allowlisting mode in
+ * the configuration file, or when the setting is modified with a
+ * prior call to this function.
+ *
+ * When @secure is true, @sign is marked as secure for any use unlike
+ * gnutls_sign_set_secure(). Otherwise, it is marked as insecure only
+ * for the use in certificates. Use gnutls_sign_set_secure() to mark
+ * it insecure for any uses.
+ *
+ * Since: 3.7.3
+ */
+int
+gnutls_sign_set_secure_for_certs(gnutls_sign_algorithm_t sign,
+ unsigned int secure)
+{
+#ifndef DISABLE_SYSTEM_CONFIG
+ gnutls_sign_entry_st *p;
+
+ for(p = sign_algorithms; p->name != NULL; p++) {
+ if (p->id && p->id == sign) {
+ if (!(p->flags & GNUTLS_SIGN_FLAG_INSECURE_REVERTIBLE)) {
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+ }
+ if (secure) {
+ p->slevel = _SECURE;
+ } else {
+ if (p->slevel < _INSECURE_FOR_CERTS) {
+ p->slevel = _INSECURE_FOR_CERTS;
+ }
+ }
+ return 0;
+ }
+ }
+#endif
+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+}
+
/**
* gnutls_sign_is_secure2:
* @algorithm: is a sign algorithm