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.
This commit is contained in:
parent
19f39703f7
commit
826a42a088
7 changed files with 238 additions and 7 deletions
5
CHANGES
5
CHANGES
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
apps/s_cb.c
26
apps/s_cb.c
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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); }
|
||||
|
|
117
apps/s_server.c
117
apps/s_server.c
|
@ -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);
|
||||
|
|
|
@ -11,7 +11,10 @@ B<openssl> B<s_client>
|
|||
[B<-connect host:port>]
|
||||
[B<-verify depth>]
|
||||
[B<-cert filename>]
|
||||
[B<-certform DER|PEM>]
|
||||
[B<-key filename>]
|
||||
[B<-keyform DER|PEM>]
|
||||
[B<-pass arg>]
|
||||
[B<-CApath directory>]
|
||||
[B<-CAfile filename>]
|
||||
[B<-reconnect>]
|
||||
|
@ -57,11 +60,24 @@ then an attempt is made to connect to the local host on port 4433.
|
|||
The certificate to use, if one is requested by the server. The default is
|
||||
not to use a certificate.
|
||||
|
||||
=item B<-certform format>
|
||||
|
||||
The certificate format to use: DER or PEM. PEM is the default.
|
||||
|
||||
=item B<-key keyfile>
|
||||
|
||||
The private key to use. If not specified then the certificate file will
|
||||
be used.
|
||||
|
||||
=item B<-keyform format>
|
||||
|
||||
The private format to use: DER or PEM. PEM is the default.
|
||||
|
||||
=item B<-pass arg>
|
||||
|
||||
the private key password source. For more information about the format of B<arg>
|
||||
see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
|
||||
|
||||
=item B<-verify depth>
|
||||
|
||||
The verify depth to use. This specifies the maximum length of the
|
||||
|
|
|
@ -13,9 +13,15 @@ B<openssl> B<s_server>
|
|||
[B<-verify depth>]
|
||||
[B<-Verify depth>]
|
||||
[B<-cert filename>]
|
||||
[B<-certform DER|PEM>]
|
||||
[B<-key keyfile>]
|
||||
[B<-keyform DER|PEM>]
|
||||
[B<-pass arg>]
|
||||
[B<-dcert filename>]
|
||||
[B<-dcertform DER|PEM>]
|
||||
[B<-dkey keyfile>]
|
||||
[B<-dkeyform DER|PEM>]
|
||||
[B<-dpass arg>]
|
||||
[B<-dhparam filename>]
|
||||
[B<-nbio>]
|
||||
[B<-nbio_test>]
|
||||
|
@ -70,11 +76,24 @@ certificate and some require a certificate with a certain public key type:
|
|||
for example the DSS cipher suites require a certificate containing a DSS
|
||||
(DSA) key. If not specified then the filename "server.pem" will be used.
|
||||
|
||||
=item B<-certform format>
|
||||
|
||||
The certificate format to use: DER or PEM. PEM is the default.
|
||||
|
||||
=item B<-key keyfile>
|
||||
|
||||
The private key to use. If not specified then the certificate file will
|
||||
be used.
|
||||
|
||||
=item B<-keyform format>
|
||||
|
||||
The private format to use: DER or PEM. PEM is the default.
|
||||
|
||||
=item B<-pass arg>
|
||||
|
||||
the private key password source. For more information about the format of B<arg>
|
||||
see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
|
||||
|
||||
=item B<-dcert filename>, B<-dkey keyname>
|
||||
|
||||
specify an additional certificate and private key, these behave in the
|
||||
|
@ -86,6 +105,10 @@ and some a DSS (DSA) key. By using RSA and DSS certificates and keys
|
|||
a server can support clients which only support RSA or DSS cipher suites
|
||||
by using an appropriate certificate.
|
||||
|
||||
=item B<-dcertform format>, B<-dkeyform format>, B<-dpass arg>
|
||||
|
||||
addtional certificate and private key format and passphrase respectively.
|
||||
|
||||
=item B<-nocert>
|
||||
|
||||
if this option is set then no certificate is used. This restricts the
|
||||
|
|
Loading…
Reference in a new issue