Commit 11262391 authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

Initial chain verify code: not tested probably not working

at present. However nothing enables it yet so this doesn't
matter :-)
parent 6d3724d3
Loading
Loading
Loading
Loading
+15 −2
Original line number Diff line number Diff line
@@ -4,8 +4,21 @@

 Changes between 0.9.4 and 0.9.5  [xx XXX 1999]

  *) Support for the authority information access extension. Not
     very well tested yet.
  *) Very preliminary certificate chain verify code. Currently just tests
     the untrusted certificates for consistency with the verify purpose
     (which is set when the X509_STORE_CTX structure is set up) and checks
     the pathlength. Totally untested at present: needs some extra
     functionality in the verify program first. There is a
     NO_CHAIN_VERIFY compilation option to keep the old behaviour: this is
     because when it is finally working it will reject chains with
     invalid extensions whereas before it made no checks at all.

     Also added X509_STORE_CTX_new() and X509_STORE_CTX_free() functions
     which should be used for version portability: especially since the
     verify structure is likely to change more often now.
     [Steve Henson]

  *) Support for the authority information access extension.
     [Steve Henson]

  *) Modify RSA and DSA PEM read routines to transparently handle
+13 −0
Original line number Diff line number Diff line
@@ -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;
+6 −0
Original line number Diff line number Diff line
@@ -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:
+58 −0
Original line number Diff line number Diff line
@@ -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)

+9 −0
Original line number Diff line number Diff line
@@ -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
}