static int null_callback(int ok,X509_STORE_CTX *e);
static int check_chain_purpose(X509_STORE_CTX *ctx);
+static int check_trust(X509_STORE_CTX *ctx);
static int internal_verify(X509_STORE_CTX *ctx);
const char *X509_version="X.509" OPENSSL_VERSION_PTEXT;
if(!ok) goto end;
+ /* The chain extensions are OK: check trust */
+
+ if(ctx->trust_purpose > 0) ok = check_trust(ctx);
+
+ if(!ok) goto end;
+
/* We may as well copy down any DSA parameters that are required */
X509_get_pubkey_parameters(NULL,ctx->chain);
#endif
}
+static int check_trust(X509_STORE_CTX *ctx)
+{
+#ifdef NO_CHAIN_VERIFY
+ return 1;
+#else
+ int i, ok;
+ X509 *x;
+ int (*cb)();
+ cb=ctx->ctx->verify_cb;
+ if (cb == NULL) cb=null_callback;
+/* For now just check the last certificate in the chain */
+ i = sk_X509_num(ctx->chain) - 1;
+ x = sk_X509_value(ctx->chain, i);
+ ok = X509_check_trust(x, ctx->trust_purpose, 0);
+ if(ok == X509_TRUST_TRUSTED) return 1;
+ ctx->error_depth = sk_X509_num(ctx->chain) - 1;
+ ctx->current_cert = x;
+ if(ok == X509_TRUST_REJECTED) ctx->error = X509_V_ERR_CERT_REJECTED;
+ else ctx->error = X509_V_ERR_CERT_UNTRUSTED;
+ ok = cb(0, ctx);
+ return(ok);
+#endif
+}
+
static int internal_verify(X509_STORE_CTX *ctx)
{
int i,ok=0,n;
ctx->untrusted=sk;
}
-void X509_STORE_CTX_chain_purpose(X509_STORE_CTX *ctx, int purpose)
+int X509_STORE_CTX_chain_purpose(X509_STORE_CTX *ctx, int purpose)
{
- ctx->chain_purpose = purpose;
+ return X509_set_purpose_and_trust(purpose,
+ &ctx->chain_purpose, &ctx->trust_purpose);
}
void X509_STORE_CTX_trust_purpose(X509_STORE_CTX *ctx, int purpose)
ctx->trust_purpose = purpose;
}
+int X509_set_purpose_and_trust(int id, int *purp, int *trust)
+{
+ X509_PURPOSE *ptmp;
+ int idx;
+ idx = X509_PURPOSE_get_by_id(id);
+ if(idx == -1) {
+ X509err(X509_F_X509_SET_PURPOSE_AND_TRUST,
+ X509_R_UNKNOWN_TRUST_ID);
+ return 0;
+ }
+ ptmp = X509_PURPOSE_iget(idx);
+ if(purp) *purp = id;
+ if(trust) *trust = ptmp->trust_id;
+ return 1;
+}
+
IMPLEMENT_STACK_OF(X509)
IMPLEMENT_ASN1_SET_OF(X509)