Add code to download CRLs based on CRLDP extension.
Just a sample, real world applications would have to be cleverer.
This commit is contained in:
		
							
								
								
									
										4
									
								
								CHANGES
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								CHANGES
									
									
									
									
									
								
							@@ -4,6 +4,10 @@
 | 
			
		||||
 | 
			
		||||
 Changes between 1.0.x and 1.1.0  [xx XXX xxxx]
 | 
			
		||||
 | 
			
		||||
  *) New option -crl_download in several openssl utilities to download CRLs
 | 
			
		||||
     from CRLDP extension in certificates.
 | 
			
		||||
     [Steve Henson]
 | 
			
		||||
 | 
			
		||||
  *) Integrate hostname, email address and IP address checking with certificate
 | 
			
		||||
     verification. New verify options supporting checking in opensl utility.
 | 
			
		||||
     [Steve Henson]
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										79
									
								
								apps/apps.c
									
									
									
									
									
								
							
							
						
						
									
										79
									
								
								apps/apps.c
									
									
									
									
									
								
							@@ -929,7 +929,7 @@ end:
 | 
			
		||||
	return(x);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
X509_CRL *load_crl(char *infile, int format)
 | 
			
		||||
X509_CRL *load_crl(const char *infile, int format)
 | 
			
		||||
	{
 | 
			
		||||
	X509_CRL *x=NULL;
 | 
			
		||||
	BIO *in=NULL;
 | 
			
		||||
@@ -2974,6 +2974,83 @@ void print_cert_checks(BIO *bio, X509 *x,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
/* Get first http URL from a DIST_POINT structure */
 | 
			
		||||
 | 
			
		||||
static const char *get_dp_url(DIST_POINT *dp)
 | 
			
		||||
	{
 | 
			
		||||
	GENERAL_NAMES *gens;
 | 
			
		||||
	GENERAL_NAME *gen;
 | 
			
		||||
	int i, gtype;
 | 
			
		||||
	ASN1_STRING *uri;
 | 
			
		||||
	if (!dp->distpoint || dp->distpoint->type != 0)
 | 
			
		||||
		return NULL;
 | 
			
		||||
	gens = dp->distpoint->name.fullname;
 | 
			
		||||
	for (i = 0; i < sk_GENERAL_NAME_num(gens); i++)
 | 
			
		||||
		{
 | 
			
		||||
		gen = sk_GENERAL_NAME_value(gens, i);
 | 
			
		||||
		uri = GENERAL_NAME_get0_value(gen, >ype);
 | 
			
		||||
		if (gtype == GEN_URI && ASN1_STRING_length(uri) > 6)
 | 
			
		||||
			{
 | 
			
		||||
			char *uptr = (char *)ASN1_STRING_data(uri);
 | 
			
		||||
			if (!strncmp(uptr, "http://", 7))
 | 
			
		||||
				return uptr;
 | 
			
		||||
			}
 | 
			
		||||
		}		
 | 
			
		||||
	return NULL;
 | 
			
		||||
	}
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
/* Look through a CRLDP structure and attempt to find an http URL to downloads
 | 
			
		||||
 * a CRL from.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static X509_CRL *load_crl_crldp(STACK_OF(DIST_POINT) *crldp)
 | 
			
		||||
	{
 | 
			
		||||
	int i;
 | 
			
		||||
	const char *urlptr = NULL;
 | 
			
		||||
	for (i = 0; i < sk_DIST_POINT_num(crldp); i++)
 | 
			
		||||
		{
 | 
			
		||||
		DIST_POINT *dp = sk_DIST_POINT_value(crldp, i);
 | 
			
		||||
		urlptr = get_dp_url(dp);
 | 
			
		||||
		if (urlptr)
 | 
			
		||||
			return load_crl(urlptr, FORMAT_HTTP);
 | 
			
		||||
		}
 | 
			
		||||
	return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
/* Example of downloading CRLs from CRLDP: not usable for real world
 | 
			
		||||
 * as it always downloads, doesn't support non-blocking I/O and doesn't
 | 
			
		||||
 * cache anything.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static STACK_OF(X509_CRL) *crls_http_cb(X509_STORE_CTX *ctx, X509_NAME *nm)
 | 
			
		||||
	{
 | 
			
		||||
	X509 *x;
 | 
			
		||||
	STACK_OF(X509_CRL) *crls = NULL;
 | 
			
		||||
	X509_CRL *crl;
 | 
			
		||||
	STACK_OF(DIST_POINT) *crldp;
 | 
			
		||||
	x = X509_STORE_CTX_get_current_cert(ctx);
 | 
			
		||||
	crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, NULL, NULL);
 | 
			
		||||
	crl = load_crl_crldp(crldp);
 | 
			
		||||
	sk_DIST_POINT_pop_free(crldp, DIST_POINT_free);
 | 
			
		||||
	if (!crl)
 | 
			
		||||
		return NULL;
 | 
			
		||||
	crls = sk_X509_CRL_new_null();
 | 
			
		||||
	sk_X509_CRL_push(crls, crl);
 | 
			
		||||
	/* Try to download delta CRL */
 | 
			
		||||
	crldp = X509_get_ext_d2i(x, NID_freshest_crl, NULL, NULL);
 | 
			
		||||
	crl = load_crl_crldp(crldp);
 | 
			
		||||
	sk_DIST_POINT_pop_free(crldp, DIST_POINT_free);
 | 
			
		||||
	if (crl)
 | 
			
		||||
		sk_X509_CRL_push(crls, crl);
 | 
			
		||||
	return crls;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
void store_setup_crl_download(X509_STORE *st)
 | 
			
		||||
	{
 | 
			
		||||
	X509_STORE_set_lookup_crls_cb(st, crls_http_cb);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Platform-specific sections
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
@@ -245,7 +245,7 @@ int app_passwd(BIO *err, char *arg1, char *arg2, char **pass1, char **pass2);
 | 
			
		||||
int add_oid_section(BIO *err, CONF *conf);
 | 
			
		||||
X509 *load_cert(BIO *err, const char *file, int format,
 | 
			
		||||
	const char *pass, ENGINE *e, const char *cert_descrip);
 | 
			
		||||
X509_CRL *load_crl(char *infile, int format);
 | 
			
		||||
X509_CRL *load_crl(const char *infile, int format);
 | 
			
		||||
int load_cert_crl_http(const char *url, BIO *err,
 | 
			
		||||
					X509 **pcert, X509_CRL **pcrl);
 | 
			
		||||
EVP_PKEY *load_key(BIO *err, const char *file, int format, int maybe_stdin,
 | 
			
		||||
@@ -343,6 +343,8 @@ void print_cert_checks(BIO *bio, X509 *x,
 | 
			
		||||
				const unsigned char *checkemail,
 | 
			
		||||
				const char *checkip);
 | 
			
		||||
 | 
			
		||||
void store_setup_crl_download(X509_STORE *st);
 | 
			
		||||
 | 
			
		||||
#define FORMAT_UNDEF    0
 | 
			
		||||
#define FORMAT_ASN1     1
 | 
			
		||||
#define FORMAT_TEXT     2
 | 
			
		||||
 
 | 
			
		||||
@@ -197,9 +197,9 @@ int args_ssl(char ***pargs, int *pargc, SSL_CONF_CTX *cctx,
 | 
			
		||||
			int *badarg, BIO *err, STACK_OF(OPENSSL_STRING) **pstr);
 | 
			
		||||
int args_ssl_call(SSL_CTX *ctx, BIO *err, SSL_CONF_CTX *cctx,
 | 
			
		||||
				STACK_OF(OPENSSL_STRING) *str, int no_ecdhe);
 | 
			
		||||
int ssl_ctx_add_crls(SSL_CTX *ctx, STACK_OF(X509_CRL) *crls);
 | 
			
		||||
int ssl_ctx_add_crls(SSL_CTX *ctx, STACK_OF(X509_CRL) *crls, int crl_download);
 | 
			
		||||
int ssl_load_stores(SSL_CTX *ctx,
 | 
			
		||||
			const char *vfyCApath, const char *vfyCAfile,
 | 
			
		||||
			const char *chCApath, const char *chCAfile,
 | 
			
		||||
			STACK_OF(X509_CRL) *crls);
 | 
			
		||||
			STACK_OF(X509_CRL) *crls, int crl_download);
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										24
									
								
								apps/s_cb.c
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								apps/s_cb.c
									
									
									
									
									
								
							@@ -1660,32 +1660,28 @@ static int add_crls_store(X509_STORE *st, STACK_OF(X509_CRL) *crls)
 | 
			
		||||
	{
 | 
			
		||||
	X509_CRL *crl;
 | 
			
		||||
	int i;
 | 
			
		||||
	if (crls)
 | 
			
		||||
	for (i = 0; i < sk_X509_CRL_num(crls); i++)
 | 
			
		||||
		{
 | 
			
		||||
		for (i = 0; i < sk_X509_CRL_num(crls); i++)
 | 
			
		||||
			{
 | 
			
		||||
			crl = sk_X509_CRL_value(crls, i);
 | 
			
		||||
			X509_STORE_add_crl(st, crl);
 | 
			
		||||
			}
 | 
			
		||||
		crl = sk_X509_CRL_value(crls, i);
 | 
			
		||||
		X509_STORE_add_crl(st, crl);
 | 
			
		||||
		}
 | 
			
		||||
	return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
int ssl_ctx_add_crls(SSL_CTX *ctx, STACK_OF(X509_CRL) *crls)
 | 
			
		||||
int ssl_ctx_add_crls(SSL_CTX *ctx, STACK_OF(X509_CRL) *crls, int crl_download)
 | 
			
		||||
	{
 | 
			
		||||
	X509_STORE *st;
 | 
			
		||||
	if (crls)
 | 
			
		||||
		{
 | 
			
		||||
		st = SSL_CTX_get_cert_store(ctx);
 | 
			
		||||
		add_crls_store(st, crls);
 | 
			
		||||
		}
 | 
			
		||||
	st = SSL_CTX_get_cert_store(ctx);
 | 
			
		||||
	add_crls_store(st, crls);
 | 
			
		||||
	if (crl_download)
 | 
			
		||||
		store_setup_crl_download(st);
 | 
			
		||||
	return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
int ssl_load_stores(SSL_CTX *ctx,
 | 
			
		||||
			const char *vfyCApath, const char *vfyCAfile,
 | 
			
		||||
			const char *chCApath, const char *chCAfile,
 | 
			
		||||
			STACK_OF(X509_CRL) *crls)
 | 
			
		||||
			STACK_OF(X509_CRL) *crls, int crl_download)
 | 
			
		||||
	{
 | 
			
		||||
	X509_STORE *vfy = NULL, *ch = NULL;
 | 
			
		||||
	int rv = 0;
 | 
			
		||||
@@ -1696,6 +1692,8 @@ int ssl_load_stores(SSL_CTX *ctx,
 | 
			
		||||
			goto err;
 | 
			
		||||
		add_crls_store(vfy, crls);
 | 
			
		||||
		SSL_CTX_set1_verify_cert_store(ctx, vfy);
 | 
			
		||||
		if (crl_download)
 | 
			
		||||
			store_setup_crl_download(vfy);
 | 
			
		||||
		}
 | 
			
		||||
	if (chCApath || chCAfile)
 | 
			
		||||
		{
 | 
			
		||||
 
 | 
			
		||||
@@ -635,6 +635,7 @@ int MAIN(int argc, char **argv)
 | 
			
		||||
 | 
			
		||||
	char *crl_file = NULL;
 | 
			
		||||
	int crl_format = FORMAT_PEM;
 | 
			
		||||
	int crl_download = 0;
 | 
			
		||||
	STACK_OF(X509_CRL) *crls = NULL;
 | 
			
		||||
 | 
			
		||||
	meth=SSLv23_client_method();
 | 
			
		||||
@@ -711,6 +712,8 @@ int MAIN(int argc, char **argv)
 | 
			
		||||
			if (--argc < 1) goto bad;
 | 
			
		||||
			crl_file= *(++argv);
 | 
			
		||||
			}
 | 
			
		||||
		else if	(strcmp(*argv,"-crl_download") == 0)
 | 
			
		||||
			crl_download = 1;
 | 
			
		||||
		else if	(strcmp(*argv,"-sess_out") == 0)
 | 
			
		||||
			{
 | 
			
		||||
			if (--argc < 1) goto bad;
 | 
			
		||||
@@ -1192,7 +1195,8 @@ bad:
 | 
			
		||||
		goto end;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	if (!ssl_load_stores(ctx, vfyCApath, vfyCAfile, chCApath, chCAfile, crls))
 | 
			
		||||
	if (!ssl_load_stores(ctx, vfyCApath, vfyCAfile, chCApath, chCAfile,
 | 
			
		||||
						crls, crl_download))
 | 
			
		||||
		{
 | 
			
		||||
		BIO_printf(bio_err, "Error loading store locations\n");
 | 
			
		||||
		ERR_print_errors(bio_err);
 | 
			
		||||
@@ -1254,7 +1258,7 @@ bad:
 | 
			
		||||
		/* goto end; */
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	ssl_ctx_add_crls(ctx, crls);
 | 
			
		||||
	ssl_ctx_add_crls(ctx, crls, crl_download);
 | 
			
		||||
 | 
			
		||||
	if (!set_cert_key_stuff(ctx,cert,key, NULL, build_chain))
 | 
			
		||||
		goto end;
 | 
			
		||||
 
 | 
			
		||||
@@ -1715,12 +1715,12 @@ bad:
 | 
			
		||||
	if (vpm)
 | 
			
		||||
		SSL_CTX_set1_param(ctx, vpm);
 | 
			
		||||
 | 
			
		||||
	ssl_ctx_add_crls(ctx, crls);
 | 
			
		||||
	ssl_ctx_add_crls(ctx, crls, 0);
 | 
			
		||||
 | 
			
		||||
	if (!args_ssl_call(ctx, bio_err, cctx, ssl_args, no_ecdhe))
 | 
			
		||||
		goto end;
 | 
			
		||||
 | 
			
		||||
	if (!ssl_load_stores(ctx, vfyCApath, vfyCAfile, chCApath, chCAfile, crls))
 | 
			
		||||
	if (!ssl_load_stores(ctx, vfyCApath, vfyCAfile, chCApath, chCAfile, crls, 0))
 | 
			
		||||
		{
 | 
			
		||||
		BIO_printf(bio_err, "Error loading store locations\n");
 | 
			
		||||
		ERR_print_errors(bio_err);
 | 
			
		||||
@@ -1783,7 +1783,7 @@ bad:
 | 
			
		||||
		if (vpm)
 | 
			
		||||
			SSL_CTX_set1_param(ctx2, vpm);
 | 
			
		||||
 | 
			
		||||
		ssl_ctx_add_crls(ctx2, crls);
 | 
			
		||||
		ssl_ctx_add_crls(ctx2, crls, 0);
 | 
			
		||||
 | 
			
		||||
		if (!args_ssl_call(ctx2, bio_err, cctx, ssl_args, no_ecdhe))
 | 
			
		||||
			goto end;
 | 
			
		||||
 
 | 
			
		||||
@@ -88,6 +88,7 @@ int MAIN(int argc, char **argv)
 | 
			
		||||
	X509_STORE *cert_ctx=NULL;
 | 
			
		||||
	X509_LOOKUP *lookup=NULL;
 | 
			
		||||
	X509_VERIFY_PARAM *vpm = NULL;
 | 
			
		||||
	int crl_download = 0;
 | 
			
		||||
#ifndef OPENSSL_NO_ENGINE
 | 
			
		||||
	char *engine=NULL;
 | 
			
		||||
#endif
 | 
			
		||||
@@ -145,6 +146,8 @@ int MAIN(int argc, char **argv)
 | 
			
		||||
				if (argc-- < 1) goto end;
 | 
			
		||||
				crlfile= *(++argv);
 | 
			
		||||
				}
 | 
			
		||||
			else if (strcmp(*argv,"-crl_download") == 0)
 | 
			
		||||
				crl_download = 1;
 | 
			
		||||
#ifndef OPENSSL_NO_ENGINE
 | 
			
		||||
			else if (strcmp(*argv,"-engine") == 0)
 | 
			
		||||
				{
 | 
			
		||||
@@ -222,6 +225,9 @@ int MAIN(int argc, char **argv)
 | 
			
		||||
			goto end;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	if (crl_download)
 | 
			
		||||
		store_setup_crl_download(cert_ctx);
 | 
			
		||||
 | 
			
		||||
	if (argc < 1) check(cert_ctx, NULL, untrusted, trusted, crls, e);
 | 
			
		||||
	else
 | 
			
		||||
		for (i=0; i<argc; i++)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user