New option to add CRLs for s_client and s_server.
diff --git a/CHANGES b/CHANGES
index 3f6afc8..a03aa4b 100644
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,9 @@
 
  Changes between 1.0.x and 1.1.0  [xx XXX xxxx]
 
+  *) New options -CRL and -CRLform for s_client and s_server for CRLs.
+     [Steve Henson]
+
   *) Extend OCSP I/O functions so they can be used for simple general purpose
      HTTP as well as OCSP. New wrapper function which can be used to download
      CRLs using the OCSP API.
diff --git a/apps/apps.c b/apps/apps.c
index b36e517..b378836 100644
--- a/apps/apps.c
+++ b/apps/apps.c
@@ -929,6 +929,55 @@
 	return(x);
 	}
 
+X509_CRL *load_crl(char *infile, int format)
+	{
+	X509_CRL *x=NULL;
+	BIO *in=NULL;
+
+	if (format == FORMAT_HTTP)
+		{
+		load_cert_crl_http(infile, bio_err, NULL, &x);
+		return x;
+		}
+
+	in=BIO_new(BIO_s_file());
+	if (in == NULL)
+		{
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+
+	if (infile == NULL)
+		BIO_set_fp(in,stdin,BIO_NOCLOSE);
+	else
+		{
+		if (BIO_read_filename(in,infile) <= 0)
+			{
+			perror(infile);
+			goto end;
+			}
+		}
+	if 	(format == FORMAT_ASN1)
+		x=d2i_X509_CRL_bio(in,NULL);
+	else if (format == FORMAT_PEM)
+		x=PEM_read_bio_X509_CRL(in,NULL,NULL,NULL);
+	else	{
+		BIO_printf(bio_err,"bad input format specified for input crl\n");
+		goto end;
+		}
+	if (x == NULL)
+		{
+		BIO_printf(bio_err,"unable to load CRL\n");
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+	
+end:
+	BIO_free(in);
+	return(x);
+	}
+
+
 EVP_PKEY *load_key(BIO *err, const char *file, int format, int maybe_stdin,
 	const char *pass, ENGINE *e, const char *key_descrip)
 	{
diff --git a/apps/apps.h b/apps/apps.h
index 165e455..e9d21d5 100644
--- a/apps/apps.h
+++ b/apps/apps.h
@@ -245,6 +245,7 @@
 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);
 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,
diff --git a/apps/crl.c b/apps/crl.c
index 888cf7f..fc12734 100644
--- a/apps/crl.c
+++ b/apps/crl.c
@@ -93,7 +93,6 @@
 NULL
 };
 
-static X509_CRL *load_crl(char *file, int format);
 static BIO *bio_out=NULL;
 
 int MAIN(int, char **);
@@ -401,52 +400,3 @@
 	apps_shutdown();
 	OPENSSL_EXIT(ret);
 	}
-
-static X509_CRL *load_crl(char *infile, int format)
-	{
-	X509_CRL *x=NULL;
-	BIO *in=NULL;
-
-	if (format == FORMAT_HTTP)
-		{
-		load_cert_crl_http(infile, bio_err, NULL, &x);
-		return x;
-		}
-
-	in=BIO_new(BIO_s_file());
-	if (in == NULL)
-		{
-		ERR_print_errors(bio_err);
-		goto end;
-		}
-
-	if (infile == NULL)
-		BIO_set_fp(in,stdin,BIO_NOCLOSE);
-	else
-		{
-		if (BIO_read_filename(in,infile) <= 0)
-			{
-			perror(infile);
-			goto end;
-			}
-		}
-	if 	(format == FORMAT_ASN1)
-		x=d2i_X509_CRL_bio(in,NULL);
-	else if (format == FORMAT_PEM)
-		x=PEM_read_bio_X509_CRL(in,NULL,NULL,NULL);
-	else	{
-		BIO_printf(bio_err,"bad input format specified for input crl\n");
-		goto end;
-		}
-	if (x == NULL)
-		{
-		BIO_printf(bio_err,"unable to load CRL\n");
-		ERR_print_errors(bio_err);
-		goto end;
-		}
-	
-end:
-	BIO_free(in);
-	return(x);
-	}
-
diff --git a/apps/s_apps.h b/apps/s_apps.h
index 6aab0a6..0a38241 100644
--- a/apps/s_apps.h
+++ b/apps/s_apps.h
@@ -201,7 +201,9 @@
 			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_load_stores(SSL_CTX *ctx,
 			const char *vfyCApath, const char *vfyCAfile,
-			const char *chCApath, const char *chCAfile);
+			const char *chCApath, const char *chCAfile,
+			STACK_OF(X509_CRL) *crls);
 #endif
diff --git a/apps/s_cb.c b/apps/s_cb.c
index 0759c8a..e0289d4 100644
--- a/apps/s_cb.c
+++ b/apps/s_cb.c
@@ -293,7 +293,6 @@
 		ERR_print_errors(bio_err);
 		return 0;
 		}
-		
 	return 1;
 	}
 
@@ -1670,9 +1669,36 @@
 	return 1;
 	}
 
+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++)
+			{
+			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)
+	{
+	X509_STORE *st;
+	if (crls)
+		{
+		st = SSL_CTX_get_cert_store(ctx);
+		add_crls_store(st, crls);
+		}
+	return 1;
+	}
+
 int ssl_load_stores(SSL_CTX *ctx,
 			const char *vfyCApath, const char *vfyCAfile,
-			const char *chCApath, const char *chCAfile)
+			const char *chCApath, const char *chCAfile,
+			STACK_OF(X509_CRL) *crls)
 	{
 	X509_STORE *vfy = NULL, *ch = NULL;
 	int rv = 0;
@@ -1681,6 +1707,7 @@
 		vfy = X509_STORE_new();
 		if (!X509_STORE_load_locations(vfy, vfyCAfile, vfyCApath))
 			goto err;
+		add_crls_store(vfy, crls);
 		SSL_CTX_set1_verify_cert_store(ctx, vfy);
 		}
 	if (chCApath || chCAfile)
diff --git a/apps/s_client.c b/apps/s_client.c
index aebdeac..1a8f8ac 100644
--- a/apps/s_client.c
+++ b/apps/s_client.c
@@ -639,6 +639,10 @@
 	SSL_CONF_CTX *cctx = NULL;
 	STACK_OF(OPENSSL_STRING) *ssl_args = NULL;
 
+	char *crl_file = NULL;
+	int crl_format = FORMAT_PEM;
+	STACK_OF(X509_CRL) *crls = NULL;
+
 	meth=SSLv23_client_method();
 
 	apps_startup();
@@ -708,6 +712,11 @@
 			if (--argc < 1) goto bad;
 			cert_file= *(++argv);
 			}
+		else if	(strcmp(*argv,"-CRL") == 0)
+			{
+			if (--argc < 1) goto bad;
+			crl_file= *(++argv);
+			}
 		else if	(strcmp(*argv,"-sess_out") == 0)
 			{
 			if (--argc < 1) goto bad;
@@ -723,6 +732,11 @@
 			if (--argc < 1) goto bad;
 			cert_format = str2fmt(*(++argv));
 			}
+		else if	(strcmp(*argv,"-CRLform") == 0)
+			{
+			if (--argc < 1) goto bad;
+			crl_format = str2fmt(*(++argv));
+			}
 		else if (args_verify(&argv, &argc, &badarg, bio_err, &vpm))
 			{
 			if (badarg)
@@ -1128,6 +1142,26 @@
 			}
 		}
 
+	if (crl_file)
+		{
+		X509_CRL *crl;
+		crl = load_crl(crl_file, crl_format);
+		if (!crl)
+			{
+			BIO_puts(bio_err, "Error loading CRL\n");
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+		crls = sk_X509_CRL_new_null();
+		if (!crls || !sk_X509_CRL_push(crls, crl))
+			{
+			BIO_puts(bio_err, "Error adding CRL\n");
+			ERR_print_errors(bio_err);
+			X509_CRL_free(crl);
+			goto end;
+			}
+		}
+
 	if (!load_excert(&exc, bio_err))
 		goto end;
 
@@ -1179,7 +1213,7 @@
 		goto end;
 		}
 
-	if (!ssl_load_stores(ctx, vfyCApath, vfyCAfile, chCApath, chCAfile))
+	if (!ssl_load_stores(ctx, vfyCApath, vfyCAfile, chCApath, chCAfile, crls))
 		{
 		BIO_printf(bio_err, "Error loading store locations\n");
 		ERR_print_errors(bio_err);
@@ -1241,6 +1275,8 @@
 		/* goto end; */
 		}
 
+	ssl_ctx_add_crls(ctx, crls);
+
 	if (!set_cert_key_stuff(ctx,cert,key, NULL, build_chain))
 		goto end;
 
@@ -1983,6 +2019,8 @@
 	if (ctx != NULL) SSL_CTX_free(ctx);
 	if (cert)
 		X509_free(cert);
+	if (crls)
+		sk_X509_CRL_pop_free(crls, X509_CRL_free);
 	if (key)
 		EVP_PKEY_free(key);
 	if (pass)
diff --git a/apps/s_server.c b/apps/s_server.c
index 6813fb7..b9f6f30 100644
--- a/apps/s_server.c
+++ b/apps/s_server.c
@@ -999,6 +999,10 @@
 	SSL_CONF_CTX *cctx = NULL;
 	STACK_OF(OPENSSL_STRING) *ssl_args = NULL;
 
+	char *crl_file = NULL;
+	int crl_format = FORMAT_PEM;
+	STACK_OF(X509_CRL) *crls = NULL;
+
 	meth=SSLv23_server_method();
 
 	local_argc=argc;
@@ -1077,6 +1081,11 @@
 			if (--argc < 1) goto bad;
 			s_cert_file= *(++argv);
 			}
+		else if	(strcmp(*argv,"-CRL") == 0)
+			{
+			if (--argc < 1) goto bad;
+			crl_file= *(++argv);
+			}
 #ifndef OPENSSL_NO_TLSEXT
 		else if	(strcmp(*argv,"-authz") == 0)
 			{
@@ -1167,6 +1176,11 @@
 			no_cache = 1;
 		else if (strcmp(*argv,"-ext_cache") == 0)
 			ext_cache = 1;
+		else if	(strcmp(*argv,"-CRLform") == 0)
+			{
+			if (--argc < 1) goto bad;
+			crl_format = str2fmt(*(++argv));
+			}
 		else if (args_verify(&argv, &argc, &badarg, bio_err, &vpm))
 			{
 			if (badarg)
@@ -1567,6 +1581,26 @@
 		}
 #endif
 
+	if (crl_file)
+		{
+		X509_CRL *crl;
+		crl = load_crl(crl_file, crl_format);
+		if (!crl)
+			{
+			BIO_puts(bio_err, "Error loading CRL\n");
+			ERR_print_errors(bio_err);
+			goto end;
+			}
+		crls = sk_X509_CRL_new_null();
+		if (!crls || !sk_X509_CRL_push(crls, crl))
+			{
+			BIO_puts(bio_err, "Error adding CRL\n");
+			ERR_print_errors(bio_err);
+			X509_CRL_free(crl);
+			goto end;
+			}
+		}
+
 
 	if (s_dcert_file)
 		{
@@ -1702,10 +1736,12 @@
 	if (vpm)
 		SSL_CTX_set1_param(ctx, vpm);
 
+	ssl_ctx_add_crls(ctx, crls);
+
 	if (!args_ssl_call(ctx, bio_err, cctx, ssl_args, no_ecdhe))
 		goto end;
 
-	if (!ssl_load_stores(ctx, vfyCApath, vfyCAfile, chCApath, chCAfile))
+	if (!ssl_load_stores(ctx, vfyCApath, vfyCAfile, chCApath, chCAfile, crls))
 		{
 		BIO_printf(bio_err, "Error loading store locations\n");
 		ERR_print_errors(bio_err);
@@ -1768,6 +1804,8 @@
 		if (vpm)
 			SSL_CTX_set1_param(ctx2, vpm);
 
+		ssl_ctx_add_crls(ctx2, crls);
+
 		if (!args_ssl_call(ctx2, bio_err, cctx, ssl_args, no_ecdhe))
 			goto end;
 		}
@@ -1973,6 +2011,8 @@
 	if (ctx != NULL) SSL_CTX_free(ctx);
 	if (s_cert)
 		X509_free(s_cert);
+	if (crls)
+		sk_X509_CRL_pop_free(crls, X509_CRL_free);
 	if (s_dcert)
 		X509_free(s_dcert);
 	if (s_key)