X509_VERIFY_PARAM *param = ctx->param;
int depth,i,ok=0;
int num;
- int (*cb)();
+ int (*cb)(int ok,X509_STORE_CTX *ctx);
STACK_OF(X509) *sktmp=NULL;
if (ctx->cert == NULL)
{
#else
int i, ok=0, must_be_ca;
X509 *x;
- int (*cb)();
+ int (*cb)(int ok,X509_STORE_CTX *ctx);
+ int proxy_path_length = 0;
cb=ctx->verify_cb;
+ int allow_proxy_certs = !!(ctx->flags & X509_V_FLAG_ALLOW_PROXY_CERTS);
/* must_be_ca can have 1 of 3 values:
-1: we accept both CA and non-CA certificates, to allow direct
all certificates in the chain except the leaf certificate.
*/
must_be_ca = -1;
+
+ /* A hack to keep people who don't want to modify their software
+ happy */
+ if (getenv("OPENSSL_ALLOW_PROXY_CERTS"))
+ allow_proxy_certs = 1;
+
/* Check all untrusted certificates */
for (i = 0; i < ctx->last_untrusted; i++)
{
ok=cb(0,ctx);
if (!ok) goto end;
}
+ if (!allow_proxy_certs && (x->ex_flags & EXFLAG_PROXY))
+ {
+ ctx->error = X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED;
+ ctx->error_depth = i;
+ ctx->current_cert = x;
+ ok=cb(0,ctx);
+ if (!ok) goto end;
+ }
ret = X509_check_ca(x);
switch(must_be_ca)
{
}
/* Check pathlen */
if ((i > 1) && (x->ex_pathlen != -1)
- && (i > (x->ex_pathlen + 1)))
+ && (i > (x->ex_pathlen + proxy_path_length + 1)))
{
ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED;
ctx->error_depth = i;
ok=cb(0,ctx);
if (!ok) goto end;
}
- /* The next certificate must be a CA */
- must_be_ca = 1;
+ /* If this certificate is a proxy certificate, the next
+ certificate must be another proxy certificate or a EE
+ certificate. If not, the next certificate must be a
+ CA certificate. */
+ if (x->ex_flags & EXFLAG_PROXY)
+ {
+ if (x->ex_pcpathlen != -1 && i > x->ex_pcpathlen)
+ {
+ ctx->error =
+ X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED;
+ ctx->error_depth = i;
+ ctx->current_cert = x;
+ ok=cb(0,ctx);
+ if (!ok) goto end;
+ }
+ proxy_path_length++;
+ must_be_ca = 0;
+ }
+ else
+ must_be_ca = 1;
}
ok = 1;
end:
#else
int i, ok;
X509 *x;
- int (*cb)();
+ int (*cb)(int ok,X509_STORE_CTX *ctx);
cb=ctx->verify_cb;
/* For now just check the last certificate in the chain */
i = sk_X509_num(ctx->chain) - 1;
int ok=0,n;
X509 *xs,*xi;
EVP_PKEY *pkey=NULL;
- int (*cb)();
+ int (*cb)(int ok,X509_STORE_CTX *ctx);
cb=ctx->verify_cb;
goto end;
/* The last error (if any) is still in the error value */
+ ctx->current_issuer=xi;
ctx->current_cert=xs;
ok=(*cb)(1,ctx);
if (!ok) goto end;