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_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
|
||||||
|
|||||||
Reference in New Issue
Block a user