mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-05-06 16:36:16 +08:00
Add GM double cert support in s_client (#996)
Add dcert and dkey cli args for s_client
This commit is contained in:
@@ -525,7 +525,8 @@ typedef enum OPTION_choice {
|
||||
OPT_4, OPT_6, OPT_HOST, OPT_PORT, OPT_CONNECT, OPT_UNIX,
|
||||
OPT_XMPPHOST, OPT_VERIFY,
|
||||
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_SSL_CLIENT_ENGINE, OPT_RAND, OPT_IGN_EOF, OPT_NO_IGN_EOF,
|
||||
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"},
|
||||
{"keyform", OPT_KEYFORM, 'E', "Key format (PEM, DER or engine) PEM default"},
|
||||
{"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"},
|
||||
{"CAfile", OPT_CAFILE, '<', "PEM format file of CA's"},
|
||||
{"no-CAfile", OPT_NOCAFILE, '-',
|
||||
@@ -780,11 +785,11 @@ static void freeandcopy(char **dest, const char *source)
|
||||
int s_client_main(int argc, char **argv)
|
||||
{
|
||||
BIO *sbio;
|
||||
EVP_PKEY *key = NULL;
|
||||
EVP_PKEY *key = NULL, *dkey = NULL;
|
||||
SSL *con = NULL;
|
||||
SSL_CTX *ctx = NULL;
|
||||
STACK_OF(X509) *chain = NULL;
|
||||
X509 *cert = NULL;
|
||||
STACK_OF(X509) *chain = NULL, *dchain = NULL;
|
||||
X509 *cert = NULL, *dcert = NULL;
|
||||
X509_VERIFY_PARAM *vpm = NULL;
|
||||
SSL_EXCERT *exc = NULL;
|
||||
SSL_CONF_CTX *cctx = NULL;
|
||||
@@ -798,10 +803,12 @@ int s_client_main(int argc, char **argv)
|
||||
char *cbuf = NULL, *sbuf = NULL;
|
||||
char *mbuf = NULL, *proxystr = NULL, *connectstr = 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 *port = OPENSSL_strdup(PORT);
|
||||
char *inrand = 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 *xmpphost = NULL;
|
||||
const char *ehlo = "mail.example.com";
|
||||
@@ -810,6 +817,7 @@ int s_client_main(int argc, char **argv)
|
||||
int noCApath = 0, noCAfile = 0;
|
||||
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 dcert_format = FORMAT_PEM, dkey_format = FORMAT_PEM;
|
||||
int prexit = 0;
|
||||
int sdebug = 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))
|
||||
goto opthelp;
|
||||
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:
|
||||
verify_args.return_error = 1;
|
||||
break;
|
||||
@@ -1424,7 +1446,7 @@ int s_client_main(int argc, char **argv)
|
||||
next_proto.data = NULL;
|
||||
#endif
|
||||
|
||||
if (!app_passwd(passarg, NULL, &pass, NULL)) {
|
||||
if (!app_passwd(passarg, dpassarg, &pass, &dpass)) {
|
||||
BIO_printf(bio_err, "Error getting password\n");
|
||||
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);
|
||||
}
|
||||
|
||||
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 (c_quiet && !c_debug) {
|
||||
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))
|
||||
goto end;
|
||||
|
||||
if (dcert != NULL) {
|
||||
if (!set_cert_key_stuff(ctx, dcert, dkey, dchain, build_chain)) {
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (servername != NULL) {
|
||||
tlsextcbp.biodebug = bio_err;
|
||||
SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
|
||||
@@ -2512,10 +2560,14 @@ int s_client_main(int argc, char **argv)
|
||||
#endif
|
||||
SSL_CTX_free(ctx);
|
||||
X509_free(cert);
|
||||
X509_free(dcert);
|
||||
sk_X509_CRL_pop_free(crls, X509_CRL_free);
|
||||
EVP_PKEY_free(key);
|
||||
EVP_PKEY_free(dkey);
|
||||
sk_X509_pop_free(chain, X509_free);
|
||||
sk_X509_pop_free(dchain, X509_free);
|
||||
OPENSSL_free(pass);
|
||||
OPENSSL_free(dpass);
|
||||
#ifndef OPENSSL_NO_SRP
|
||||
OPENSSL_free(srp_arg.srppassin);
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user