Add GM double cert support in s_client (#996)

Add dcert and dkey cli args for s_client
This commit is contained in:
J.F
2020-07-25 10:28:49 +08:00
committed by GitHub
parent a15b215389
commit d4420f3876

View File

@@ -525,7 +525,8 @@ typedef enum OPTION_choice {
OPT_4, OPT_6, OPT_HOST, OPT_PORT, OPT_CONNECT, OPT_UNIX, OPT_4, OPT_6, OPT_HOST, OPT_PORT, OPT_CONNECT, OPT_UNIX,
OPT_XMPPHOST, OPT_VERIFY, OPT_XMPPHOST, OPT_VERIFY,
OPT_CERT, OPT_CRL, OPT_CRL_DOWNLOAD, OPT_SESS_OUT, OPT_SESS_IN, OPT_CERT, OPT_CRL, OPT_CRL_DOWNLOAD, OPT_SESS_OUT, OPT_SESS_IN,
OPT_CERTFORM, OPT_CRLFORM, OPT_VERIFY_RET_ERROR, OPT_VERIFY_QUIET, OPT_CERTFORM, OPT_CRLFORM, OPT_DCERTFORM, OPT_DCERT, OPT_DKEYFORM,
OPT_DKEY, OPT_VERIFY_RET_ERROR, OPT_VERIFY_QUIET,
OPT_BRIEF, OPT_PREXIT, OPT_CRLF, OPT_QUIET, OPT_NBIO, OPT_BRIEF, OPT_PREXIT, OPT_CRLF, OPT_QUIET, OPT_NBIO,
OPT_SSL_CLIENT_ENGINE, OPT_RAND, OPT_IGN_EOF, OPT_NO_IGN_EOF, OPT_SSL_CLIENT_ENGINE, OPT_RAND, OPT_IGN_EOF, OPT_NO_IGN_EOF,
OPT_DEBUG, OPT_TLSEXTDEBUG, OPT_STATUS, OPT_WDEBUG, OPT_DEBUG, OPT_TLSEXTDEBUG, OPT_STATUS, OPT_WDEBUG,
@@ -581,6 +582,10 @@ OPTIONS s_client_options[] = {
{"key", OPT_KEY, 's', "Private key file to use, if not in -cert file"}, {"key", OPT_KEY, 's', "Private key file to use, if not in -cert file"},
{"keyform", OPT_KEYFORM, 'E', "Key format (PEM, DER or engine) PEM default"}, {"keyform", OPT_KEYFORM, 'E', "Key format (PEM, DER or engine) PEM default"},
{"pass", OPT_PASS, 's', "Private key file pass phrase source"}, {"pass", OPT_PASS, 's', "Private key file pass phrase source"},
{"dcert", OPT_DCERT, '<', "Second certificate file to use (usually for DSA)"},
{"dcertform", OPT_DCERTFORM, 'F', "Second certificate format (PEM or DER) PEM default"},
{"dkey", OPT_DKEY, 's', "Second private key file to use (usually for DSA)"},
{"dkeyform", OPT_DKEYFORM, 'F', "Second key format (PEM, DER or ENGINE) PEM default"},
{"CApath", OPT_CAPATH, '/', "PEM format directory of CA's"}, {"CApath", OPT_CAPATH, '/', "PEM format directory of CA's"},
{"CAfile", OPT_CAFILE, '<', "PEM format file of CA's"}, {"CAfile", OPT_CAFILE, '<', "PEM format file of CA's"},
{"no-CAfile", OPT_NOCAFILE, '-', {"no-CAfile", OPT_NOCAFILE, '-',
@@ -780,11 +785,11 @@ static void freeandcopy(char **dest, const char *source)
int s_client_main(int argc, char **argv) int s_client_main(int argc, char **argv)
{ {
BIO *sbio; BIO *sbio;
EVP_PKEY *key = NULL; EVP_PKEY *key = NULL, *dkey = NULL;
SSL *con = NULL; SSL *con = NULL;
SSL_CTX *ctx = NULL; SSL_CTX *ctx = NULL;
STACK_OF(X509) *chain = NULL; STACK_OF(X509) *chain = NULL, *dchain = NULL;
X509 *cert = NULL; X509 *cert = NULL, *dcert = NULL;
X509_VERIFY_PARAM *vpm = NULL; X509_VERIFY_PARAM *vpm = NULL;
SSL_EXCERT *exc = NULL; SSL_EXCERT *exc = NULL;
SSL_CONF_CTX *cctx = NULL; SSL_CONF_CTX *cctx = NULL;
@@ -798,10 +803,12 @@ int s_client_main(int argc, char **argv)
char *cbuf = NULL, *sbuf = NULL; char *cbuf = NULL, *sbuf = NULL;
char *mbuf = NULL, *proxystr = NULL, *connectstr = NULL; char *mbuf = NULL, *proxystr = NULL, *connectstr = NULL;
char *cert_file = NULL, *key_file = NULL, *chain_file = NULL; char *cert_file = NULL, *key_file = NULL, *chain_file = NULL;
char *dcert_file = NULL, *dkey_file = NULL, *dchain_file = NULL;
char *chCApath = NULL, *chCAfile = NULL, *host = NULL; char *chCApath = NULL, *chCAfile = NULL, *host = NULL;
char *port = OPENSSL_strdup(PORT); char *port = OPENSSL_strdup(PORT);
char *inrand = NULL; char *inrand = NULL;
char *passarg = NULL, *pass = NULL, *vfyCApath = NULL, *vfyCAfile = NULL; char *passarg = NULL, *pass = NULL, *vfyCApath = NULL, *vfyCAfile = NULL;
char *dpassarg = NULL, *dpass = NULL;
char *sess_in = NULL, *sess_out = NULL, *crl_file = NULL, *p; char *sess_in = NULL, *sess_out = NULL, *crl_file = NULL, *p;
char *xmpphost = NULL; char *xmpphost = NULL;
const char *ehlo = "mail.example.com"; const char *ehlo = "mail.example.com";
@@ -810,6 +817,7 @@ int s_client_main(int argc, char **argv)
int noCApath = 0, noCAfile = 0; int noCApath = 0, noCAfile = 0;
int build_chain = 0, cbuf_len, cbuf_off, cert_format = FORMAT_PEM; int build_chain = 0, cbuf_len, cbuf_off, cert_format = FORMAT_PEM;
int key_format = FORMAT_PEM, crlf = 0, full_log = 1, mbuf_len = 0; int key_format = FORMAT_PEM, crlf = 0, full_log = 1, mbuf_len = 0;
int dcert_format = FORMAT_PEM, dkey_format = FORMAT_PEM;
int prexit = 0; int prexit = 0;
int sdebug = 0; int sdebug = 0;
int reconnect = 0, verify = SSL_VERIFY_NONE, vpmtouched = 0; int reconnect = 0, verify = SSL_VERIFY_NONE, vpmtouched = 0;
@@ -1007,6 +1015,20 @@ int s_client_main(int argc, char **argv)
if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &crl_format)) if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &crl_format))
goto opthelp; goto opthelp;
break; break;
case OPT_DCERTFORM:
if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &dcert_format))
goto opthelp;
break;
case OPT_DCERT:
dcert_file = opt_arg();
break;
case OPT_DKEYFORM:
if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &dkey_format))
goto opthelp;
break;
case OPT_DKEY:
dkey_file = opt_arg();
break;
case OPT_VERIFY_RET_ERROR: case OPT_VERIFY_RET_ERROR:
verify_args.return_error = 1; verify_args.return_error = 1;
break; break;
@@ -1424,7 +1446,7 @@ int s_client_main(int argc, char **argv)
next_proto.data = NULL; next_proto.data = NULL;
#endif #endif
if (!app_passwd(passarg, NULL, &pass, NULL)) { if (!app_passwd(passarg, dpassarg, &pass, &dpass)) {
BIO_printf(bio_err, "Error getting password\n"); BIO_printf(bio_err, "Error getting password\n");
goto end; goto end;
} }
@@ -1485,6 +1507,26 @@ int s_client_main(int argc, char **argv)
BIO_printf(bio_err, "%ld semi-random bytes loaded\n", randamt); BIO_printf(bio_err, "%ld semi-random bytes loaded\n", randamt);
} }
if (dcert_file) {
if (dkey_file == NULL) {
dkey_file = dcert_file;
}
dkey = load_key(dkey_file, dkey_format, 0, dpass, e,
"second certificate private key file");
if (!dkey) {
ERR_print_errors(bio_err);
goto end;
}
dcert = load_cert(dcert_file, dcert_format,
"second server certificate file");
if (!dcert) {
ERR_print_errors(bio_err);
goto end;
}
}
if (bio_c_out == NULL) { if (bio_c_out == NULL) {
if (c_quiet && !c_debug) { if (c_quiet && !c_debug) {
bio_c_out = BIO_new(BIO_s_null()); bio_c_out = BIO_new(BIO_s_null());
@@ -1655,6 +1697,12 @@ int s_client_main(int argc, char **argv)
if (!set_cert_key_stuff(ctx, cert, key, chain, build_chain)) if (!set_cert_key_stuff(ctx, cert, key, chain, build_chain))
goto end; goto end;
if (dcert != NULL) {
if (!set_cert_key_stuff(ctx, dcert, dkey, dchain, build_chain)) {
goto end;
}
}
if (servername != NULL) { if (servername != NULL) {
tlsextcbp.biodebug = bio_err; tlsextcbp.biodebug = bio_err;
SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb); SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
@@ -2512,10 +2560,14 @@ int s_client_main(int argc, char **argv)
#endif #endif
SSL_CTX_free(ctx); SSL_CTX_free(ctx);
X509_free(cert); X509_free(cert);
X509_free(dcert);
sk_X509_CRL_pop_free(crls, X509_CRL_free); sk_X509_CRL_pop_free(crls, X509_CRL_free);
EVP_PKEY_free(key); EVP_PKEY_free(key);
EVP_PKEY_free(dkey);
sk_X509_pop_free(chain, X509_free); sk_X509_pop_free(chain, X509_free);
sk_X509_pop_free(dchain, X509_free);
OPENSSL_free(pass); OPENSSL_free(pass);
OPENSSL_free(dpass);
#ifndef OPENSSL_NO_SRP #ifndef OPENSSL_NO_SRP
OPENSSL_free(srp_arg.srppassin); OPENSSL_free(srp_arg.srppassin);
#endif #endif