/*
- * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* https://www.openssl.org/source/license.html
*/
-#include <ctype.h>
#include <stdio.h>
#include <time.h>
#include <errno.h>
#include <limits.h>
+#include "internal/ctype.h"
#include "internal/cryptlib.h"
#include <openssl/crypto.h>
-#include <openssl/lhash.h>
#include <openssl/buffer.h>
#include <openssl/evp.h>
#include <openssl/asn1.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/objects.h>
-#include <internal/dane.h>
-#include <internal/x509_int.h>
+#include "internal/dane.h"
+#include "internal/x509_int.h"
#include "x509_lcl.h"
/* CRL score values */
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)
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)
STACK_OF(X509) *sk = NULL;
X509 *x;
int i;
+
for (i = 0; i < sk_X509_num(ctx->other_ctx); i++) {
x = sk_X509_value(ctx->other_ctx, i);
if (X509_NAME_cmp(nm, X509_get_subject_name(x)) == 0) {
sk = sk_X509_new_null();
if (sk == NULL || sk_X509_push(sk, x) == 0) {
sk_X509_pop_free(sk, X509_free);
+ X509err(X509_F_LOOKUP_CERTS_SK, ERR_R_MALLOC_FAILURE);
+ ctx->error = X509_V_ERR_OUT_OF_MEM;
return NULL;
}
X509_up_ref(x);
/* check_purpose() makes the callback as needed */
if (purpose > 0 && !check_purpose(ctx, x, purpose, i, must_be_ca))
return 0;
- /* Check pathlen if not self issued */
- if ((i > 1) && !(x->ex_flags & EXFLAG_SI)
- && (x->ex_pathlen != -1)
- && (plen > (x->ex_pathlen + proxy_path_length + 1))) {
+ /* Check pathlen */
+ if ((i > 1) && (x->ex_pathlen != -1)
+ && (plen > (x->ex_pathlen + proxy_path_length))) {
if (!verify_cb_cert(ctx, x, i, X509_V_ERR_PATH_LENGTH_EXCEEDED))
return 0;
}
- /* Increment path length if not self issued */
- if (!(x->ex_flags & EXFLAG_SI))
+ /* Increment path length if not a self issued intermediate CA */
+ if (i > 0 && (x->ex_flags & EXFLAG_SI) == 0)
plen++;
/*
* If this certificate is a proxy certificate, the next certificate
return 1;
}
+static int has_san_id(X509 *x, int gtype)
+{
+ int i;
+ int ret = 0;
+ GENERAL_NAMES *gs = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
+
+ if (gs == NULL)
+ return 0;
+
+ for (i = 0; i < sk_GENERAL_NAME_num(gs); i++) {
+ GENERAL_NAME *g = sk_GENERAL_NAME_value(gs, i);
+
+ if (g->type == gtype) {
+ ret = 1;
+ break;
+ }
+ }
+ GENERAL_NAMES_free(gs);
+ return ret;
+}
+
static int check_name_constraints(X509_STORE_CTX *ctx)
{
int i;
int rv = NAME_CONSTRAINTS_check(x, nc);
/* If EE certificate check commonName too */
- if (rv == X509_V_OK && i == 0)
+ if (rv == X509_V_OK && i == 0
+ && (ctx->param->hostflags
+ & X509_CHECK_FLAG_NEVER_CHECK_SUBJECT) == 0
+ && ((ctx->param->hostflags
+ & X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT) != 0
+ || !has_san_id(x, GEN_DNS)))
rv = NAME_CONSTRAINTS_check_CN(x, nc);
switch (rv) {
* Digit and date ranges will be verified in the conversion methods.
*/
for (i = 0; i < ctm->length - 1; i++) {
- if (!isdigit(ctm->data[i]))
+ if (!ossl_isdigit(ctm->data[i]))
return 0;
}
if (ctm->data[ctm->length - 1] != 'Z')
int i;
/* Our chain starts with a single untrusted element. */
- OPENSSL_assert(num == 1 && ctx->num_untrusted == num);
+ if (!ossl_assert(num == 1 && ctx->num_untrusted == num)) {
+ X509err(X509_F_BUILD_CHAIN, ERR_R_INTERNAL_ERROR);
+ ctx->error = X509_V_ERR_UNSPECIFIED;
+ return 0;
+ }
#define S_DOUNTRUSTED (1 << 0) /* Search untrusted chain */
#define S_DOTRUSTED (1 << 1) /* Search trusted store */
* certificate among the ones from the trust store.
*/
if ((search & S_DOALTERNATE) != 0) {
- OPENSSL_assert(num > i && i > 0 && ss == 0);
+ if (!ossl_assert(num > i && i > 0 && ss == 0)) {
+ X509err(X509_F_BUILD_CHAIN, ERR_R_INTERNAL_ERROR);
+ X509_free(xtmp);
+ trust = X509_TRUST_REJECTED;
+ ctx->error = X509_V_ERR_UNSPECIFIED;
+ search = 0;
+ continue;
+ }
search &= ~S_DOALTERNATE;
for (; num > i; --num)
X509_free(sk_X509_pop(ctx->chain));
* certificate with ctx->num_untrusted <= num.
*/
if (ok) {
- OPENSSL_assert(ctx->num_untrusted <= num);
+ if (!ossl_assert(ctx->num_untrusted <= num)) {
+ X509err(X509_F_BUILD_CHAIN, ERR_R_INTERNAL_ERROR);
+ trust = X509_TRUST_REJECTED;
+ ctx->error = X509_V_ERR_UNSPECIFIED;
+ search = 0;
+ continue;
+ }
search &= ~S_DOUNTRUSTED;
switch (trust = check_trust(ctx, num)) {
case X509_TRUST_TRUSTED:
*/
if ((search & S_DOUNTRUSTED) != 0) {
num = sk_X509_num(ctx->chain);
- OPENSSL_assert(num == ctx->num_untrusted);
+ if (!ossl_assert(num == ctx->num_untrusted)) {
+ X509err(X509_F_BUILD_CHAIN, ERR_R_INTERNAL_ERROR);
+ trust = X509_TRUST_REJECTED;
+ ctx->error = X509_V_ERR_UNSPECIFIED;
+ search = 0;
+ continue;
+ }
x = sk_X509_value(ctx->chain, num-1);
/*
*/
static int check_sig_level(X509_STORE_CTX *ctx, X509 *cert)
{
- int nid = X509_get_signature_nid(cert);
- int mdnid = NID_undef;
int secbits = -1;
int level = ctx->param->auth_level;
if (level > NUM_AUTH_LEVELS)
level = NUM_AUTH_LEVELS;
- /* Lookup signature algorithm digest */
- if (nid && OBJ_find_sigid_algs(nid, &mdnid, NULL)) {
- const EVP_MD *md;
-
- /* Assume 4 bits of collision resistance for each hash octet */
- if (mdnid != NID_undef && (md = EVP_get_digestbynid(mdnid)) != NULL)
- secbits = EVP_MD_size(md) * 4;
- }
+ if (!X509_get_signature_info(cert, NULL, NULL, &secbits, NULL))
+ return 0;
return secbits >= minbits_table[level - 1];
}