Add support for certificate stores in CERT structure. This makes it
possible to have different stores per SSL structure or one store in
the parent SSL_CTX. Include distint stores for certificate chain
verification and chain building. New ctrl SSL_CTRL_BUILD_CERT_CHAIN
to build and store a certificate chain in CERT structure: returing
an error if the chain cannot be built: this will allow applications
to test if a chain is correctly configured.

Note: if the CERT based stores are not set then the parent SSL_CTX
store is used to retain compatibility with existing behaviour.
diff --git a/apps/s_server.c b/apps/s_server.c
index 5dd9e8e05..bbe2492 100644
--- a/apps/s_server.c
+++ b/apps/s_server.c
@@ -215,6 +215,9 @@
 				unsigned int *id_len);
 static void init_session_cache_ctx(SSL_CTX *sctx);
 static void free_sessions(void);
+static int ssl_load_stores(SSL_CTX *sctx,
+			const char *vfyCApath, const char *vfyCAfile,
+			const char *chCApath, const char *chCAfile);
 #ifndef OPENSSL_NO_DH
 static DH *load_dh_param(const char *dhfile);
 static DH *get_dh512(void);
@@ -952,6 +955,8 @@
 	int badarg = 0;
 	short port=PORT;
 	char *CApath=NULL,*CAfile=NULL;
+	char *chCApath=NULL,*chCAfile=NULL;
+	char *vfyCApath=NULL,*vfyCAfile=NULL;
 	unsigned char *context = NULL;
 	char *dhfile = NULL;
 #ifndef OPENSSL_NO_ECDH
@@ -961,6 +966,7 @@
 	int ret=1;
 	int off=0;
 	unsigned int cert_flags = 0;
+	int build_chain = 0;
 	int no_tmp_rsa=0,no_dhe=0,no_ecdhe=0,nocert=0;
 	int state=0;
 	const SSL_METHOD *meth=NULL;
@@ -1135,6 +1141,16 @@
 			if (--argc < 1) goto bad;
 			CApath= *(++argv);
 			}
+		else if	(strcmp(*argv,"-chainCApath") == 0)
+			{
+			if (--argc < 1) goto bad;
+			chCApath= *(++argv);
+			}
+		else if	(strcmp(*argv,"-verifyCApath") == 0)
+			{
+			if (--argc < 1) goto bad;
+			vfyCApath= *(++argv);
+			}
 		else if (strcmp(*argv,"-no_cache") == 0)
 			no_cache = 1;
 		else if (strcmp(*argv,"-ext_cache") == 0)
@@ -1162,11 +1178,23 @@
 			if (--argc < 1) goto bad;
 			cipher= *(++argv);
 			}
+		else if	(strcmp(*argv,"-build_chain") == 0)
+			build_chain = 1;
 		else if	(strcmp(*argv,"-CAfile") == 0)
 			{
 			if (--argc < 1) goto bad;
 			CAfile= *(++argv);
 			}
+		else if	(strcmp(*argv,"-chainCAfile") == 0)
+			{
+			if (--argc < 1) goto bad;
+			chCAfile= *(++argv);
+			}
+		else if	(strcmp(*argv,"-verifyCAfile") == 0)
+			{
+			if (--argc < 1) goto bad;
+			vfyCAfile= *(++argv);
+			}
 #ifdef FIONBIO	
 		else if	(strcmp(*argv,"-nbio") == 0)
 			{ s_nbio=1; }
@@ -1672,6 +1700,13 @@
 	if (vpm)
 		SSL_CTX_set1_param(ctx, vpm);
 
+	if (!ssl_load_stores(ctx, vfyCApath, vfyCAfile, chCApath, chCAfile))
+		{
+		BIO_printf(bio_err, "Error loading store locations\n");
+		ERR_print_errors(bio_err);
+		goto end;
+		}
+
 #ifndef OPENSSL_NO_TLSEXT
 	if (s_cert2)
 		{
@@ -1834,19 +1869,19 @@
 		}
 #endif
 	
-	if (!set_cert_key_stuff(ctx, s_cert, s_key, s_chain))
+	if (!set_cert_key_stuff(ctx, s_cert, s_key, s_chain, build_chain))
 		goto end;
 #ifndef OPENSSL_NO_TLSEXT
 	if (s_authz_file != NULL && !SSL_CTX_use_authz_file(ctx, s_authz_file))
 		goto end;
 #endif
 #ifndef OPENSSL_NO_TLSEXT
-	if (ctx2 && !set_cert_key_stuff(ctx2,s_cert2,s_key2, NULL))
+	if (ctx2 && !set_cert_key_stuff(ctx2,s_cert2,s_key2, NULL, build_chain))
 		goto end; 
 #endif
 	if (s_dcert != NULL)
 		{
-		if (!set_cert_key_stuff(ctx, s_dcert, s_dkey, s_dchain))
+		if (!set_cert_key_stuff(ctx, s_dcert, s_dkey, s_dchain, build_chain))
 			goto end;
 		}
 
@@ -3305,7 +3340,36 @@
 		}
 	first = NULL;
 	}
-	
+
+static int ssl_load_stores(SSL_CTX *sctx,
+			const char *vfyCApath, const char *vfyCAfile,
+			const char *chCApath, const char *chCAfile)
+	{
+	X509_STORE *vfy = NULL, *ch = NULL;
+	int rv = 0;
+	if (vfyCApath || vfyCAfile)
+		{
+		vfy = X509_STORE_new();
+		if (!X509_STORE_load_locations(vfy, vfyCAfile, vfyCApath))
+			goto err;
+		SSL_CTX_set1_verify_cert_store(ctx, vfy);
+		}
+	if (chCApath || chCAfile)
+		{
+		ch = X509_STORE_new();
+		if (!X509_STORE_load_locations(ch, chCAfile, chCApath))
+			goto err;
+		/*X509_STORE_set_verify_cb(ch, verify_callback);*/
+		SSL_CTX_set1_chain_cert_store(ctx, ch);
+		}
+	rv = 1;
+	err:
+	if (vfy)
+		X509_STORE_free(vfy);
+	if (ch)
+		X509_STORE_free(ch);
+	return rv;
+	}