aboutsummaryrefslogtreecommitdiff
path: root/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'crypto')
-rw-r--r--crypto/x509/x509_vfy.c4
-rw-r--r--crypto/x509v3/v3_ncons.c31
2 files changed, 33 insertions, 2 deletions
diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c
index fd297e2..d4a5f3a 100644
--- a/crypto/x509/x509_vfy.c
+++ b/crypto/x509/x509_vfy.c
@@ -217,7 +217,6 @@ static int verify_chain(X509_STORE_CTX *ctx)
if ((ok = build_chain(ctx)) == 0 ||
(ok = check_chain_extensions(ctx)) == 0 ||
(ok = check_auth_level(ctx)) == 0 ||
- (ok = check_name_constraints(ctx)) == 0 ||
(ok = check_id(ctx)) == 0 || 1)
X509_get_pubkey_parameters(NULL, ctx->chain);
if (ok == 0 || (ok = ctx->check_revocation(ctx)) == 0)
@@ -235,6 +234,9 @@ static int verify_chain(X509_STORE_CTX *ctx)
if (!ok)
return ok;
+ if ((ok = check_name_constraints(ctx)) == 0)
+ return ok;
+
#ifndef OPENSSL_NO_RFC3779
/* RFC 3779 path validation, now that CRL check has been done */
if ((ok = X509v3_asid_validate_path(ctx)) == 0)
diff --git a/crypto/x509v3/v3_ncons.c b/crypto/x509v3/v3_ncons.c
index 7731bac..561128e 100644
--- a/crypto/x509v3/v3_ncons.c
+++ b/crypto/x509v3/v3_ncons.c
@@ -9,6 +9,7 @@
#include "e_os.h" /* for strncasecmp */
#include "internal/cryptlib.h"
+#include <limits.h>
#include <stdio.h>
#include "internal/asn1_int.h"
#include <openssl/asn1t.h>
@@ -166,6 +167,22 @@ static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip)
return 1;
}
+#define NAME_CHECK_MAX (1 << 20)
+
+static int add_lengths(int *out, int a, int b)
+{
+ /* sk_FOO_num(NULL) returns -1 but is effectively 0 when iterating. */
+ if (a < 0)
+ a = 0;
+ if (b < 0)
+ b = 0;
+
+ if (a > INT_MAX - b)
+ return 0;
+ *out = a + b;
+ return 1;
+}
+
/*-
* Check a certificate conforms to a specified set of constraints.
* Return values:
@@ -180,11 +197,23 @@ static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip)
int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc)
{
- int r, i;
+ int r, i, name_count, constraint_count;
X509_NAME *nm;
nm = X509_get_subject_name(x);
+ /*
+ * Guard against certificates with an excessive number of names or
+ * constraints causing a computationally expensive name constraints check.
+ */
+ if (!add_lengths(&name_count, X509_NAME_entry_count(nm),
+ sk_GENERAL_NAME_num(x->altname))
+ || !add_lengths(&constraint_count,
+ sk_GENERAL_SUBTREE_num(nc->permittedSubtrees),
+ sk_GENERAL_SUBTREE_num(nc->excludedSubtrees))
+ || (name_count > 0 && constraint_count > NAME_CHECK_MAX / name_count))
+ return X509_V_ERR_UNSPECIFIED;
+
if (X509_NAME_entry_count(nm) > 0) {
GENERAL_NAME gntmp;
gntmp.type = GEN_DIRNAME;