提交 d9bfe4f9 编写于 作者: R Richard Levitte

Added restrictions on the use of proxy certificates, as they may pose

a security threat on unexpecting applications.  Document and test.
上级 dc0ed30c
......@@ -783,6 +783,12 @@
*) Undo Cygwin change.
[Ulf Möller]
*) Added support for proxy certificates according to RFC 3820.
Because they may be a security thread to unaware applications,
they must be explicitely allowed in run-time. See
docs/HOWTO/proxy_certificates.txt for further information.
[Richard Levitte]
Changes between 0.9.7e and 0.9.7f [22 Mar 2005]
*) Use (SSL_RANDOM_VALUE - 4) bytes of pseudo random data when generating
......
......@@ -128,6 +128,8 @@ const char *X509_verify_cert_error_string(long n)
return ("path length constraint exceeded");
case X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED:
return("proxy path length constraint exceeded");
case X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED:
return("proxy cerificates not allowed, please set the appropriate flag");
case X509_V_ERR_INVALID_PURPOSE:
return ("unsupported certificate purpose");
case X509_V_ERR_CERT_UNTRUSTED:
......
......@@ -391,6 +391,7 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
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
......@@ -401,6 +402,12 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
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++)
{
......@@ -415,6 +422,14 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
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)
{
......
......@@ -292,7 +292,7 @@ void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth);
#define X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY 6
#define X509_V_ERR_CERT_SIGNATURE_FAILURE 7
#define X509_V_ERR_CRL_SIGNATURE_FAILURE 8
#define X509_V_ERR_CERT_NOT_YET_VALID 9
#define X509_V_ERR_CERT_NOT_YET_VALID 9
#define X509_V_ERR_CERT_HAS_EXPIRED 10
#define X509_V_ERR_CRL_NOT_YET_VALID 11
#define X509_V_ERR_CRL_HAS_EXPIRED 12
......@@ -325,10 +325,11 @@ void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth);
#define X509_V_ERR_INVALID_NON_CA 37
#define X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED 38
#define X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE 39
#define X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED 40
#define X509_V_ERR_INVALID_EXTENSION 40
#define X509_V_ERR_INVALID_POLICY_EXTENSION 41
#define X509_V_ERR_NO_EXPLICIT_POLICY 42
#define X509_V_ERR_INVALID_EXTENSION 41
#define X509_V_ERR_INVALID_POLICY_EXTENSION 42
#define X509_V_ERR_NO_EXPLICIT_POLICY 43
/* The application is not happy */
......@@ -348,14 +349,16 @@ void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth);
#define X509_V_FLAG_IGNORE_CRITICAL 0x10
/* Disable workarounds for broken certificates */
#define X509_V_FLAG_X509_STRICT 0x20
/* Enable proxy certificate validation */
#define X509_V_FLAG_ALLOW_PROXY_CERTS 0x40
/* Enable policy checking */
#define X509_V_FLAG_POLICY_CHECK 0x40
#define X509_V_FLAG_POLICY_CHECK 0x80
/* Policy variable require-explicit-policy */
#define X509_V_FLAG_EXPLICIT_POLICY 0x80
#define X509_V_FLAG_EXPLICIT_POLICY 0x100
/* Policy variable inhibit-any-policy */
#define X509_V_FLAG_INHIBIT_ANY 0x100
#define X509_V_FLAG_INHIBIT_ANY 0x200
/* Policy variable inhibit-policy-mapping */
#define X509_V_FLAG_INHIBIT_MAP 0x200
#define X509_V_FLAG_INHIBIT_MAP 0x400
/* Notify callback that policy is OK */
#define X509_V_FLAG_NOTIFY_POLICY 0x800
......
......@@ -338,7 +338,9 @@ static void x509v3_cache_extensions(X509 *x)
}
/* Handle proxy certificates */
if((pci=X509_get_ext_d2i(x, NID_proxyCertInfo, NULL, NULL))) {
if (x->ex_flags & EXFLAG_CA) {
if (x->ex_flags & EXFLAG_CA
|| X509_get_ext_by_NID(x, NID_subject_alt_name, 0) >= 0
|| X509_get_ext_by_NID(x, NID_issuer_alt_name, 0) >= 0) {
x->ex_flags |= EXFLAG_INVALID;
}
if (pci->pcPathLengthConstraint) {
......
......@@ -22,7 +22,48 @@ name of the owner of the EE certificate.
See http://www.ietf.org/rfc/rfc3820.txt for more information.
2. How to create proxy cerificates
2. A warning about proxy certificates
Noone seems to have tested proxy certificates with security in mind.
Basically, to this date, it seems that proxy certificates have only
been used in a world that's highly aware of them. What would happen
if an unsuspecting application is to validate a chain of certificates
that contains proxy certificates? It would usually consider the leaf
to be the certificate to check for authorisation data, and since proxy
certificates are controlled by the EE certificate owner alone, it's
would be normal to consider what the EE certificate owner could do
with them.
subjectAltName and issuerAltName are forbidden in proxy certificates,
and this is enforced in OpenSSL. The subject must be the same as the
issuer, with one commonName added on.
Possible threats are, as far as has been imagined so far:
- impersonation through commonName (think server certificates).
- use of additional extensions, possibly non-standard ones used in
certain environments, that would grant extra or different
authorisation rights.
For this reason, OpenSSL requires that the use of proxy certificates
be explicitely allowed. Currently, this can be done using the
following methods:
- if the application calls X509_verify_cert() itself, it can do the
following prior to that call (ctx is the pointer passed in the call
to X509_verify_cert()):
X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_ALLOW_PROXY_CERTS);
- in all other cases, proxy certificate validation can be enabled
before starting the application by setting the envirnoment variable
OPENSSL_ALLOW_PROXY with some non-empty value.
There are thoughts to allow proxy certificates with a line in the
default openssl.cnf, but that's still in the future.
3. How to create proxy cerificates
It's quite easy to create proxy certificates, by taking advantage of
the lack of checks of the 'openssl x509' application (*ahem*). But
......@@ -111,7 +152,7 @@ section for it):
-extfile openssl.cnf -extensions v3_proxy2
3. How to have your application interpret the policy?
4. How to have your application interpret the policy?
The basic way to interpret proxy policies is to prepare some default
rights, then do a check of the proxy certificate against the a chain
......@@ -258,6 +299,7 @@ This is some cookbook code for you to fill in:
X509_STORE_CTX_set_verify_cb(ctx, verify_callback);
X509_STORE_CTX_set_ex_data(ctx, get_proxy_auth_ex_data_idx(), &rights);
X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_ALLOW_PROXY_CERTS);
ok = X509_verify_cert(ctx);
if (ok == 1)
......
......@@ -88,6 +88,10 @@ PKCS#12: Personal Information Exchange Syntax Standard, version 1.0.
(Format: TXT=143173 bytes) (Obsoletes RFC2437) (Status:
INFORMATIONAL)
3820 Internet X.509 Public Key Infrastructure (PKI) Proxy Certificate
Profile. S. Tuecke, V. Welch, D. Engert, L. Pearlman, M. Thompson.
June 2004. (Format: TXT=86374 bytes) (Status: PROPOSED STANDARD)
Related:
--------
......
......@@ -190,6 +190,7 @@ struct app_verify_arg
{
char *string;
int app_verify;
int allow_proxy_certs;
char *proxy_auth;
char *proxy_cond;
};
......@@ -223,6 +224,7 @@ static void sv_usage(void)
fprintf(stderr,"\n");
fprintf(stderr," -server_auth - check server certificate\n");
fprintf(stderr," -client_auth - do client authentication\n");
fprintf(stderr," -proxy - allow proxy certificates\n");
fprintf(stderr," -proxy_auth <val> - set proxy policy rights\n");
fprintf(stderr," -proxy_cond <val> - experssion to test proxy policy rights\n");
fprintf(stderr," -v - more output\n");
......@@ -383,7 +385,7 @@ int main(int argc, char *argv[])
int client_auth=0;
int server_auth=0,i;
struct app_verify_arg app_verify_arg =
{ APP_CALLBACK_STRING, 0, NULL, NULL };
{ APP_CALLBACK_STRING, 0, 0, NULL, NULL };
char *server_cert=TEST_SERVER_CERT;
char *server_key=NULL;
char *client_cert=TEST_CLIENT_CERT;
......@@ -580,6 +582,10 @@ int main(int argc, char *argv[])
{
app_verify_arg.app_verify = 1;
}
else if (strcmp(*argv,"-proxy") == 0)
{
app_verify_arg.allow_proxy_certs = 1;
}
else
{
fprintf(stderr,"unknown option %s\n",*argv);
......@@ -1606,17 +1612,22 @@ static int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx)
fprintf(stderr,"depth=%d %s\n",
ctx->error_depth,buf);
else
{
fprintf(stderr,"depth=%d error=%d %s\n",
ctx->error_depth,ctx->error,buf);
}
}
if (ok == 0)
{
fprintf(stderr,"Error string: %s\n",
X509_verify_cert_error_string(ctx->error));
switch (ctx->error)
{
case X509_V_ERR_CERT_NOT_YET_VALID:
case X509_V_ERR_CERT_HAS_EXPIRED:
case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
fprintf(stderr," ... ignored.\n");
ok=1;
}
}
......@@ -2018,6 +2029,10 @@ static int MS_CALLBACK app_verify_callback(X509_STORE_CTX *ctx, void *arg)
X509_STORE_CTX_set_ex_data(ctx,
get_proxy_auth_ex_data_idx(),letters);
}
if (cb_arg->allow_proxy_certs)
{
X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_ALLOW_PROXY_CERTS);
}
#ifndef OPENSSL_NO_X509_VERIFY
# ifdef OPENSSL_FIPS
......
......@@ -4,7 +4,7 @@ echo 'Testing a lot of proxy conditions.'
echo 'Some of them may turn out being invalid, which is fine.'
for auth in A B C BC; do
for cond in A B C 'A|B&!C'; do
sh ./testssl $1 $2 $3 "-proxy_auth $auth -proxy_cond $cond"
sh ./testssl $1 $2 $3 "-proxy -proxy_auth $auth -proxy_cond $cond"
if [ $? = 3 ]; then exit 1; fi
done
done
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册