aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/x509
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>1999-11-24 01:31:49 +0000
committerDr. Stephen Henson <steve@openssl.org>1999-11-24 01:31:49 +0000
commit1126239111a89c52d301c3439d20dc0fd61649c2 (patch)
tree6fd2adc2e9e9569b892123538f5a59d4ead28e73 /crypto/x509
parent6d3724d3b0e0b2dff99feb815d46ef41e65db0d2 (diff)
downloadopenssl-1126239111a89c52d301c3439d20dc0fd61649c2.tar.gz
Initial chain verify code: not tested probably not working
at present. However nothing enables it yet so this doesn't matter :-)
Diffstat (limited to 'crypto/x509')
-rw-r--r--crypto/x509/x509_lu.c13
-rw-r--r--crypto/x509/x509_txt.c6
-rw-r--r--crypto/x509/x509_vfy.c58
-rw-r--r--crypto/x509/x509_vfy.h9
4 files changed, 86 insertions, 0 deletions
diff --git a/crypto/x509/x509_lu.c b/crypto/x509/x509_lu.c
index 18bfecb11e..82e7fa50a7 100644
--- a/crypto/x509/x509_lu.c
+++ b/crypto/x509/x509_lu.c
@@ -381,6 +381,17 @@ X509_OBJECT *X509_OBJECT_retrieve_by_subject(LHASH *h, int type,
return(tmp);
}
+X509_STORE_CTX *X509_STORE_CTX_new(void)
+{
+ return (X509_STORE_CTX *)Malloc(sizeof(X509_STORE_CTX));
+}
+
+void X509_STORE_CTX_free(X509_STORE_CTX *ctx)
+{
+ X509_STORE_CTX_cleanup(ctx);
+ Free(ctx);
+}
+
void X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
STACK_OF(X509) *chain)
{
@@ -389,6 +400,8 @@ void X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
ctx->cert=x509;
ctx->untrusted=chain;
ctx->last_untrusted=0;
+ ctx->chain_purpose=0;
+ ctx->trust_purpose=0;
ctx->valid=0;
ctx->chain=NULL;
ctx->depth=9;
diff --git a/crypto/x509/x509_txt.c b/crypto/x509/x509_txt.c
index 60c48f1248..b6f61c5e57 100644
--- a/crypto/x509/x509_txt.c
+++ b/crypto/x509/x509_txt.c
@@ -120,6 +120,12 @@ const char *X509_verify_cert_error_string(long n)
return("certificate chain too long");
case X509_V_ERR_CERT_REVOKED:
return("certificate revoked");
+ case X509_V_ERR_INVALID_CA:
+ return ("invalid CA certificate");
+ case X509_V_ERR_PATH_LENGTH_EXCEEDED:
+ return ("path length constraint exceeded");
+ case X509_V_ERR_INVALID_PURPOSE:
+ return ("unsupported certificate purpose");
case X509_V_ERR_APPLICATION_VERIFICATION:
return("application verification failure");
default:
diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c
index 97984cade4..3d1b38a019 100644
--- a/crypto/x509/x509_vfy.c
+++ b/crypto/x509/x509_vfy.c
@@ -67,9 +67,11 @@
#include <openssl/evp.h>
#include <openssl/asn1.h>
#include <openssl/x509.h>
+#include <openssl/x509v3.h>
#include <openssl/objects.h>
static int null_callback(int ok,X509_STORE_CTX *e);
+static int check_chain_purpose(X509_STORE_CTX *ctx);
static int internal_verify(X509_STORE_CTX *ctx);
const char *X509_version="X.509" OPENSSL_VERSION_PTEXT;
@@ -290,6 +292,11 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
if (!ok) goto end;
}
+ /* We have the chain complete: now we need to check its purpose */
+ if(ctx->chain_purpose > 0) ok = check_chain_purpose(ctx);
+
+ if(!ok) goto end;
+
/* We may as well copy down any DSA parameters that are required */
X509_get_pubkey_parameters(NULL,ctx->chain);
@@ -308,6 +315,47 @@ end:
return(ok);
}
+/* Check a certificate chains extensions for consistency
+ * with the supplied purpose
+ */
+
+static int check_chain_purpose(X509_STORE_CTX *ctx)
+{
+#ifdef NO_CHAIN_VERIFY
+ return 1;
+#else
+ int i, ok=0;
+ X509 *x;
+ int (*cb)();
+ cb=ctx->ctx->verify_cb;
+ if (cb == NULL) cb=null_callback;
+ /* Check all untrusted certificates */
+ for(i = 0; i < ctx->last_untrusted; i++) {
+ x = sk_X509_value(ctx->chain, i);
+ if(!X509_check_purpose(x, ctx->chain_purpose, i)) {
+ if(i) ctx->error = X509_V_ERR_INVALID_CA;
+ else ctx->error = X509_V_ERR_INVALID_PURPOSE;
+ ctx->error_depth = i;
+ ctx->current_cert = x;
+ ok=cb(0,ctx);
+ if(!ok) goto end;
+ }
+ /* Check pathlen */
+ if((i > 1) && (x->ex_pathlen != -1)
+ && (i > (x->ex_pathlen + 1))) {
+ ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED;
+ ctx->error_depth = i;
+ ctx->current_cert = x;
+ ok=cb(0,ctx);
+ if(!ok) goto end;
+ }
+ }
+ ok = 1;
+ end:
+ return(ok);
+#endif
+}
+
static int internal_verify(X509_STORE_CTX *ctx)
{
int i,ok=0,n;
@@ -648,6 +696,16 @@ void X509_STORE_CTX_set_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
ctx->untrusted=sk;
}
+void X509_STORE_CTX_chain_purpose(X509_STORE_CTX *ctx, int purpose)
+ {
+ ctx->chain_purpose = purpose;
+ }
+
+void X509_STORE_CTX_trust_purpose(X509_STORE_CTX *ctx, int purpose)
+ {
+ ctx->trust_purpose = purpose;
+ }
+
IMPLEMENT_STACK_OF(X509)
IMPLEMENT_ASN1_SET_OF(X509)
diff --git a/crypto/x509/x509_vfy.h b/crypto/x509/x509_vfy.h
index 9891a6944d..47c0b4028c 100644
--- a/crypto/x509/x509_vfy.h
+++ b/crypto/x509/x509_vfy.h
@@ -202,6 +202,8 @@ struct x509_store_state_st /* X509_STORE_CTX */
/* The following are set by the caller */
X509 *cert; /* The cert to check */
STACK_OF(X509) *untrusted; /* chain of X509s - untrusted - passed in */
+ int chain_purpose; /* purpose to check untrusted certificates */
+ int trust_purpose; /* trust setting to check */
/* The following is built up */
int depth; /* how far to go looking up certs */
@@ -258,6 +260,9 @@ struct x509_store_state_st /* X509_STORE_CTX */
#define X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE 21
#define X509_V_ERR_CERT_CHAIN_TOO_LONG 22
#define X509_V_ERR_CERT_REVOKED 23
+#define X509_V_ERR_INVALID_CA 24
+#define X509_V_ERR_PATH_LENGTH_EXCEEDED 25
+#define X509_V_ERR_INVALID_PURPOSE 26
/* The application is not happy */
#define X509_V_ERR_APPLICATION_VERIFICATION 50
@@ -285,6 +290,8 @@ void X509_OBJECT_free_contents(X509_OBJECT *a);
X509_STORE *X509_STORE_new(void );
void X509_STORE_free(X509_STORE *v);
+X509_STORE_CTX *X509_STORE_CTX_new(void);
+void X509_STORE_CTX_free(X509_STORE_CTX *ctx);
void X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store,
X509 *x509, STACK_OF(X509) *chain);
void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx);
@@ -340,6 +347,8 @@ X509 * X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx);
STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx);
void X509_STORE_CTX_set_cert(X509_STORE_CTX *c,X509 *x);
void X509_STORE_CTX_set_chain(X509_STORE_CTX *c,STACK_OF(X509) *sk);
+void X509_STORE_CTX_chain_purpose(X509_STORE_CTX *ctx, int purpose);
+void X509_STORE_CTX_trust_purpose(X509_STORE_CTX *ctx, int purpose);
#ifdef __cplusplus
}