diff options
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/x509/x509_vfy.c | 4 | ||||
-rw-r--r-- | crypto/x509v3/v3_ncons.c | 31 |
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; |