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

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.
parent 5818a07a
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -4,6 +4,19 @@

 Changes between 1.0.1 and 1.1.0  [xx XXX xxxx]

  *) 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.

     [Steve Henson]

  *) New function ssl_set_client_disabled to set a ciphersuite disabled
     mask based on the current session, check mask when sending client
     hello and checking the requested ciphersuite.
+1 −1
Original line number Diff line number Diff line
@@ -155,7 +155,7 @@ int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx);
#ifdef HEADER_SSL_H
int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file);
int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key,
							STACK_OF(X509) *chain);
					STACK_OF(X509) *chain, int build_chain);
# ifndef OPENSSL_NO_TLSEXT
int set_cert_key_and_authz(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key,
                           unsigned char *authz, size_t authz_length);
+28 −4
Original line number Diff line number Diff line
@@ -251,7 +251,7 @@ int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file)
	}

int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key,
		       STACK_OF(X509) *chain)
		       STACK_OF(X509) *chain, int build_chain)
	{
	if (cert == NULL)
		return 1;
@@ -282,6 +282,13 @@ int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key,
		ERR_print_errors(bio_err);
		return 0;
		}
	if (!chain && build_chain && !SSL_CTX_build_cert_chain(ctx, 0))
		{
		BIO_printf(bio_err,"error building certificate chain\n");
		ERR_print_errors(bio_err);
		return 0;
		}
		
	return 1;
	}

@@ -1123,6 +1130,7 @@ struct ssl_excert_st
	X509 *cert;
	EVP_PKEY *key;
	STACK_OF(X509) *chain;
	int build_chain;
	struct ssl_excert_st *next, *prev;
	};

@@ -1150,7 +1158,16 @@ static int set_cert_cb(SSL *ssl, void *arg)
			{
			SSL_use_certificate(ssl, exc->cert);
			SSL_use_PrivateKey(ssl, exc->key);
			if (exc->chain)
			/* NB: we wouldn't normally do this as it is
			 * not efficient building chains on each connection
			 * better to cache the chain in advance.
			 */
			if (exc->build_chain)
				{
				if (!SSL_build_cert_chain(ssl, 0))
					return 0;
				}
			else if (exc->chain)
				SSL_set1_chain(ssl, exc->chain);
			}
		exc = exc->prev;
@@ -1176,6 +1193,7 @@ static int ssl_excert_prepend(SSL_EXCERT **pexc)
	exc->key = NULL;
	exc->chain = NULL;
	exc->prev = NULL;
	exc->build_chain = 0;

	exc->next = *pexc;
	*pexc = exc;
@@ -1260,6 +1278,7 @@ int args_excert(char ***pargs, int *pargc,
	{
	char *arg = **pargs, *argn = (*pargs)[1];
	SSL_EXCERT *exc = *pexc;
	int narg = 2;
	if (!exc)
		{
		if (ssl_excert_prepend(&exc))
@@ -1316,6 +1335,11 @@ int args_excert(char ***pargs, int *pargc,
			}
		exc->chainfile = argn;
		}
	else if (strcmp(arg,"-xchain_build") == 0)
		{
		narg = 1;
		exc->build_chain = 1;
		}
	else if (strcmp(arg,"-xcertform") == 0)
		{
		if (!argn)
@@ -1337,10 +1361,10 @@ int args_excert(char ***pargs, int *pargc,
	else
		return 0;

	(*pargs) += 2;
	(*pargs) += narg;

	if (pargc)
		*pargc -= 2;
		*pargc -= narg;

	*pexc = exc;

+6 −2
Original line number Diff line number Diff line
@@ -559,6 +559,7 @@ int MAIN(int argc, char **argv)
	{
	unsigned int off=0, clr=0;
	unsigned int cert_flags=0;
	int build_chain = 0;
	SSL *con=NULL;
#ifndef OPENSSL_NO_KRB5
	KSSL_CTX *kctx;
@@ -877,6 +878,8 @@ int MAIN(int argc, char **argv)
			if (--argc < 1) goto bad;
			CApath= *(++argv);
			}
		else if	(strcmp(*argv,"-build_chain") == 0)
			build_chain = 1;
		else if	(strcmp(*argv,"-CAfile") == 0)
			{
			if (--argc < 1) goto bad;
@@ -1212,8 +1215,6 @@ bad:
#endif

	SSL_CTX_set_verify(ctx,verify,verify_callback);
	if (!set_cert_key_stuff(ctx,cert,key, NULL))
		goto end;

	if ((!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) ||
		(!SSL_CTX_set_default_verify_paths(ctx)))
@@ -1223,6 +1224,9 @@ bad:
		/* goto end; */
		}

	if (!set_cert_key_stuff(ctx,cert,key, NULL, build_chain))
		goto end;

#ifndef OPENSSL_NO_TLSEXT
	if (curves != NULL)
		if(!SSL_CTX_set1_curves_list(ctx,curves)) {
+68 −4
Original line number Diff line number Diff line
@@ -215,6 +215,9 @@ static int generate_session_id(const SSL *ssl, unsigned char *id,
				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 MAIN(int argc, char *argv[])
	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 MAIN(int argc, char *argv[])
	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 @@ int MAIN(int argc, char *argv[])
			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 @@ int MAIN(int argc, char *argv[])
			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 @@ bad:
	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 @@ bad:
		}
#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;
		}

@@ -3306,6 +3341,35 @@ static void free_sessions(void)
	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;
	}



Loading