return X509_subject_name_cmp(*a,*b);
}
#endif
+/* Return 1 is a certificate is self signed */
+static int cert_self_signed(X509 *x)
+ {
+ X509_check_purpose(x, -1, 0);
+ if (x->ex_flags & EXFLAG_SS)
+ return 1;
+ else
+ return 0;
+ }
/* Given a certificate try and find an exact match in the store */
*/
/* If we are self signed, we break */
- if (ctx->check_issued(ctx, x,x)) break;
-
+ if (cert_self_signed(x))
+ break;
/* If asked see if we can find issuer in trusted store first */
if (ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST)
{
i=sk_X509_num(ctx->chain);
x=sk_X509_value(ctx->chain,i-1);
- if (ctx->check_issued(ctx, x, x))
+ if (cert_self_signed(x))
{
/* we have a self signed certificate */
if (sk_X509_num(ctx->chain) == 1)
if (depth < num) break;
/* If we are self signed, we break */
- if (ctx->check_issued(ctx,x,x)) break;
+ if (cert_self_signed(x))
+ break;
ok = ctx->get_issuer(&xtmp, ctx, x);
/* If explicitly rejected error */
if (i == X509_TRUST_REJECTED)
goto end;
- /* If not explicitly trusted then indicate error */
- if (i != X509_TRUST_TRUSTED)
+ /* If not explicitly trusted then indicate error unless it's
+ * a single self signed certificate in which case we've indicated
+ * an error already and set bad_chain == 1
+ */
+ if (i != X509_TRUST_TRUSTED && !bad_chain)
{
if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss))
{
return ctx->verify_cb(0, ctx);
}
+static int check_hosts(X509 *x, X509_VERIFY_PARAM_ID *id)
+ {
+ int i;
+ int n = sk_OPENSSL_STRING_num(id->hosts);
+ unsigned char *name;
+
+ for (i = 0; i < n; ++i)
+ {
+ name = (unsigned char *)sk_OPENSSL_STRING_value(id->hosts, i);
+ if (X509_check_host(x, name, 0, id->hostflags) > 0)
+ return 1;
+ }
+ return n == 0;
+ }
+
static int check_id(X509_STORE_CTX *ctx)
{
X509_VERIFY_PARAM *vpm = ctx->param;
X509_VERIFY_PARAM_ID *id = vpm->id;
X509 *x = ctx->cert;
- if (id->host && !X509_check_host(x, id->host, id->hostlen, 0))
+ if (id->hosts && !check_hosts(x, id) <= 0)
{
if (!check_id_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH))
return 0;
}
- if (id->email && !X509_check_email(x, id->email, id->emaillen, 0))
+ if (id->email && X509_check_email(x, id->email, id->emaillen, 0) <= 0)
{
if (!check_id_error(ctx, X509_V_ERR_EMAIL_MISMATCH))
return 0;
}
- if (id->ip && !X509_check_ip(x, id->ip, id->iplen, 0))
+ if (id->ip && X509_check_ip(x, id->ip, id->iplen, 0) <= 0)
{
if (!check_id_error(ctx, X509_V_ERR_IP_ADDRESS_MISMATCH))
return 0;
xs=xi;
else
{
- if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN && n == 0)
+ if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN)
{
xs = xi;
goto check_cert;