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

PR: 910

Add command line options -certform, -keyform and -pass to s_client and
s_server. This supports the use of alternative passphrase sources, key formats
and keys handled by an ENGINE.

Update docs.
parent 19f39703
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -4,6 +4,11 @@

 Changes between 0.9.7e and 0.9.8  [xx XXX xxxx]

  *) New arguments -certform, -keyform and -pass for s_client and s_server
     to allow alternative format key and certificate files and passphrase
     sources.
     [Steve Henson]

  *) New structure X509_VERIFY_PARAM which combines current verify parameters,
     update associated structures and add various utility functions.

+1 −0
Original line number Diff line number Diff line
@@ -154,6 +154,7 @@ int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx);
#endif
#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);
#endif
int init_client(int *sock, char *server, int port);
int should_retry(int i);
+26 −0
Original line number Diff line number Diff line
@@ -229,6 +229,32 @@ int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file)
	return(1);
	}

int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key)
	{
	if (SSL_CTX_use_certificate(ctx,cert) <= 0)
		{
		BIO_printf(bio_err,"error setting certificate\n");
		ERR_print_errors(bio_err);
		return 0;
		}
	if (SSL_CTX_use_PrivateKey(ctx,key) <= 0)
		{
		BIO_printf(bio_err,"error setting private key\n");
		ERR_print_errors(bio_err);
		return 0;
		}

		
		/* Now we know that a key and cert have been set against
		 * the SSL context */
	if (!SSL_CTX_check_private_key(ctx))
		{
		BIO_printf(bio_err,"Private key does not match the certificate public key\n");
		return 0;
		}
	return 1;
	}

long MS_CALLBACK bio_dump_callback(BIO *bio, int cmd, const char *argp,
	int argi, long argl, long ret)
	{
+55 −2
Original line number Diff line number Diff line
@@ -189,8 +189,11 @@ static void sc_usage(void)

	BIO_printf(bio_err," -verify arg   - turn on peer certificate verification\n");
	BIO_printf(bio_err," -cert arg     - certificate file to use, PEM format assumed\n");
	BIO_printf(bio_err," -key arg      - Private key file to use, PEM format assumed, in cert file if\n");
	BIO_printf(bio_err," -certform arg - certificate format (PEM or DER) PEM default\n");
	BIO_printf(bio_err," -key arg      - Private key file to use, in cert file if\n");
	BIO_printf(bio_err,"                 not specified but cert file is.\n");
	BIO_printf(bio_err," -keyform arg  - key format (PEM or DER) PEM default\n");
	BIO_printf(bio_err," -pass arg     - private key file pass phrase source\n");
	BIO_printf(bio_err," -CApath arg   - PEM format directory of CA's\n");
	BIO_printf(bio_err," -CAfile arg   - PEM format file of CA's\n");
	BIO_printf(bio_err," -reconnect    - Drop and re-make the connection with the same Session-ID\n");
@@ -241,6 +244,10 @@ int MAIN(int argc, char **argv)
	int full_log=1;
	char *host=SSL_HOST_NAME;
	char *cert_file=NULL,*key_file=NULL;
	int cert_format = FORMAT_PEM, key_format = FORMAT_PEM;
	char *passarg = NULL, *pass = NULL;
	X509 *cert = NULL;
	EVP_PKEY *key = NULL;
	char *CApath=NULL,*CAfile=NULL,*cipher=NULL;
	int reconnect=0,badop=0,verify=SSL_VERIFY_NONE,bugs=0;
	int crlf=0;
@@ -329,6 +336,11 @@ int MAIN(int argc, char **argv)
			if (--argc < 1) goto bad;
			cert_file= *(++argv);
			}
		else if	(strcmp(*argv,"-certform") == 0)
			{
			if (--argc < 1) goto bad;
			cert_format = str2fmt(*(++argv));
			}
		else if	(strcmp(*argv,"-crl_check") == 0)
			vflags |= X509_V_FLAG_CRL_CHECK;
		else if	(strcmp(*argv,"-crl_check_all") == 0)
@@ -370,6 +382,16 @@ int MAIN(int argc, char **argv)
#endif
		else if (strcmp(*argv,"-bugs") == 0)
			bugs=1;
		else if	(strcmp(*argv,"-keyform") == 0)
			{
			if (--argc < 1) goto bad;
			key_format = str2fmt(*(++argv));
			}
		else if	(strcmp(*argv,"-pass") == 0)
			{
			if (--argc < 1) goto bad;
			passarg = *(++argv);
			}
		else if	(strcmp(*argv,"-key") == 0)
			{
			if (--argc < 1) goto bad;
@@ -451,6 +473,31 @@ bad:
#ifndef OPENSSL_NO_ENGINE
        e = setup_engine(bio_err, engine_id, 1);
#endif
	if (!app_passwd(bio_err, passarg, NULL, &pass, NULL))
		{
		BIO_printf(bio_err, "Error getting password\n");
		goto end;
		}

	if (key_file == NULL)
		key_file = cert_file;

	key = load_key(bio_err, key_file, key_format, 0, pass, e,
		       "client certificate private key file");
	if (!key)
		{
		ERR_print_errors(bio_err);
		goto end;
		}

	cert = load_cert(bio_err,cert_file,cert_format,
			NULL, e, "client certificate file");

	if (!cert)
		{
		ERR_print_errors(bio_err);
		goto end;
		}

	if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL
		&& !RAND_status())
@@ -499,7 +546,7 @@ bad:
#endif

	SSL_CTX_set_verify(ctx,verify,verify_callback);
	if (!set_cert_stuff(ctx,cert_file,key_file))
	if (!set_cert_key_stuff(ctx,cert,key))
		goto end;

	if ((!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) ||
@@ -932,6 +979,12 @@ end:
	if (con != NULL) SSL_free(con);
	if (con2 != NULL) SSL_free(con2);
	if (ctx != NULL) SSL_CTX_free(ctx);
	if (cert)
		X509_free(cert);
	if (key)
		EVP_PKEY_free(key);
	if (pass)
		OPENSSL_free(pass);
	if (cbuf != NULL) { OPENSSL_cleanse(cbuf,BUFSIZZ); OPENSSL_free(cbuf); }
	if (sbuf != NULL) { OPENSSL_cleanse(sbuf,BUFSIZZ); OPENSSL_free(sbuf); }
	if (mbuf != NULL) { OPENSSL_cleanse(mbuf,BUFSIZZ); OPENSSL_free(mbuf); }
+112 −5
Original line number Diff line number Diff line
@@ -296,12 +296,18 @@ static void sv_usage(void)
	BIO_printf(bio_err," -context arg  - set session ID context\n");
	BIO_printf(bio_err," -verify arg   - turn on peer certificate verification\n");
	BIO_printf(bio_err," -Verify arg   - turn on peer certificate verification, must have a cert.\n");
	BIO_printf(bio_err," -cert arg     - certificate file to use, PEM format assumed\n");
	BIO_printf(bio_err," -cert arg     - certificate file to use\n");
	BIO_printf(bio_err,"                 (default is %s)\n",TEST_CERT);
	BIO_printf(bio_err," -key arg      - Private Key file to use, PEM format assumed, in cert file if\n");
	BIO_printf(bio_err," -certform arg - certificate format (PEM or DER) PEM default\n");
	BIO_printf(bio_err," -key arg      - Private Key file to use, in cert file if\n");
	BIO_printf(bio_err,"                 not specified (default is %s)\n",TEST_CERT);
	BIO_printf(bio_err," -keyform arg  - key format (PEM, DER or ENGINE) PEM default\n");
	BIO_printf(bio_err," -pass arg     - private key file pass phrase source\n");
	BIO_printf(bio_err," -dcert arg    - second certificate file to use (usually for DSA)\n");
	BIO_printf(bio_err," -dcertform x  - second certificate format (PEM or DER) PEM default\n");
	BIO_printf(bio_err," -dkey arg     - second private key file to use (usually for DSA)\n");
	BIO_printf(bio_err," -dkeyform arg - second key format (PEM, DER or ENGINE) PEM default\n");
	BIO_printf(bio_err," -dpass arg    - second private key file pass phrase source\n");
	BIO_printf(bio_err," -dhparam arg  - DH parameter file to use, in cert file if not specified\n");
	BIO_printf(bio_err,"                 or a default set of parameters is used\n");
#ifndef OPENSSL_NO_ECDH
@@ -522,6 +528,12 @@ int MAIN(int argc, char *argv[])
	ENGINE *e=NULL;
#endif
	char *inrand=NULL;
	int s_cert_format = FORMAT_PEM, s_key_format = FORMAT_PEM;
	char *passarg = NULL, *pass = NULL;
	char *dpassarg = NULL, *dpass = NULL;
	int s_dcert_format = FORMAT_PEM, s_dkey_format = FORMAT_PEM;
	X509 *s_cert = NULL, *s_dcert = NULL;
	EVP_PKEY *s_key = NULL, *s_dkey = NULL;

#if !defined(OPENSSL_NO_SSL2) && !defined(OPENSSL_NO_SSL3)
	meth=SSLv23_server_method();
@@ -588,11 +600,26 @@ int MAIN(int argc, char *argv[])
			if (--argc < 1) goto bad;
			s_cert_file= *(++argv);
			}
		else if	(strcmp(*argv,"-certform") == 0)
			{
			if (--argc < 1) goto bad;
			s_cert_format = str2fmt(*(++argv));
			}
		else if	(strcmp(*argv,"-key") == 0)
			{
			if (--argc < 1) goto bad;
			s_key_file= *(++argv);
			}
		else if	(strcmp(*argv,"-keyform") == 0)
			{
			if (--argc < 1) goto bad;
			s_key_format = str2fmt(*(++argv));
			}
		else if	(strcmp(*argv,"-pass") == 0)
			{
			if (--argc < 1) goto bad;
			passarg = *(++argv);
			}
		else if	(strcmp(*argv,"-dhparam") == 0)
			{
			if (--argc < 1) goto bad;
@@ -605,11 +632,26 @@ int MAIN(int argc, char *argv[])
			named_curve = *(++argv);
			}
#endif
		else if	(strcmp(*argv,"-dcertform") == 0)
			{
			if (--argc < 1) goto bad;
			s_dcert_format = str2fmt(*(++argv));
			}
		else if	(strcmp(*argv,"-dcert") == 0)
			{
			if (--argc < 1) goto bad;
			s_dcert_file= *(++argv);
			}
		else if	(strcmp(*argv,"-dkeyform") == 0)
			{
			if (--argc < 1) goto bad;
			s_dkey_format = str2fmt(*(++argv));
			}
		else if	(strcmp(*argv,"-dpass") == 0)
			{
			if (--argc < 1) goto bad;
			dpassarg = *(++argv);
			}
		else if	(strcmp(*argv,"-dkey") == 0)
			{
			if (--argc < 1) goto bad;
@@ -739,6 +781,59 @@ bad:
        e = setup_engine(bio_err, engine_id, 1);
#endif

	if (!app_passwd(bio_err, passarg, dpassarg, &pass, &dpass))
		{
		BIO_printf(bio_err, "Error getting password\n");
		goto end;
		}


	if (s_key_file == NULL)
		s_key_file = s_cert_file;

	s_key = load_key(bio_err, s_key_file, s_key_format, 0, pass, e,
		       "server certificate private key file");
	if (!s_key)
		{
		ERR_print_errors(bio_err);
		goto end;
		}

	s_cert = load_cert(bio_err,s_cert_file,s_cert_format,
			NULL, e, "server certificate file");

	if (!s_cert)
		{
		ERR_print_errors(bio_err);
		goto end;
		}

	if (s_dcert_file)
		{

		if (s_dkey_file == NULL)
			s_dkey_file = s_dcert_file;

		s_dkey = load_key(bio_err, s_dkey_file, s_dkey_format,
				0, dpass, e,
			       "second certificate private key file");
		if (!s_dkey)
			{
			ERR_print_errors(bio_err);
			goto end;
			}

		s_dcert = load_cert(bio_err,s_dcert_file,s_dcert_format,
				NULL, e, "second server certificate file");

		if (!s_dcert)
			{
			ERR_print_errors(bio_err);
			goto end;
			}

		}

	if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL
		&& !RAND_status())
		{
@@ -903,11 +998,11 @@ bad:
		}
#endif
	
	if (!set_cert_stuff(ctx,s_cert_file,s_key_file))
	if (!set_cert_key_stuff(ctx,s_cert,s_key))
		goto end;
	if (s_dcert_file != NULL)
	if (s_dcert != NULL)
		{
		if (!set_cert_stuff(ctx,s_dcert_file,s_dkey_file))
		if (!set_cert_key_stuff(ctx,s_dcert,s_dkey))
			goto end;
		}

@@ -958,6 +1053,18 @@ bad:
	ret=0;
end:
	if (ctx != NULL) SSL_CTX_free(ctx);
	if (s_cert)
		X509_free(s_cert);
	if (s_dcert)
		X509_free(s_dcert);
	if (s_key)
		EVP_PKEY_free(s_key);
	if (s_dkey)
		EVP_PKEY_free(s_dkey);
	if (pass)
		OPENSSL_free(pass);
	if (dpass)
		OPENSSL_free(dpass);
	if (bio_s_out != NULL)
		{
		BIO_free(bio_s_out);
Loading