From 64a110955017371c92093c11584e3a436e6a76f3 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 7 May 2021 15:03:20 +0100 Subject: [PATCH] Move cert/sslkey/cert_password into a 'struct cert_info' This paves the way for having more than one of them. Signed-off-by: David Woodhouse --- auth.c | 6 ++-- gnutls.c | 72 +++++++++++++++++++++--------------------- gnutls_tpm.c | 4 +-- gnutls_tpm2_esys.c | 8 ++--- library.c | 20 ++++++------ main.c | 14 ++++---- openconnect-internal.h | 12 +++++-- openssl-pkcs11.c | 32 +++++++++---------- openssl.c | 58 +++++++++++++++++----------------- ssl.c | 18 +++++------ 10 files changed, 125 insertions(+), 119 deletions(-) diff --git a/auth.c b/auth.c index 4a63a017..89fe3cde 100644 --- a/auth.c +++ b/auth.c @@ -1292,7 +1292,7 @@ int cstp_obtain_cookie(struct openconnect_info *vpninfo) const char *method = "POST"; char *orig_host = NULL, *orig_path = NULL, *form_path = NULL; int orig_port = 0; - int cert_rq, cert_sent = !vpninfo->cert; + int cert_rq, cert_sent = !vpninfo->certinfo[0].cert; int newgroup_attempts = 5; if (!vpninfo->xmlpost) @@ -1386,10 +1386,10 @@ newgroup: free_auth_form(form); form = NULL; - if (!cert_sent && vpninfo->cert) { + if (!cert_sent && vpninfo->certinfo[0].cert) { /* Try again on a fresh connection. */ cert_sent = 1; - } else if (cert_sent && vpninfo->cert) { + } else if (cert_sent && vpninfo->certinfo[0].cert) { /* Try again with in the request */ vpn_progress(vpninfo, PRG_ERR, _("Server requested SSL client certificate after one was provided\n")); diff --git a/gnutls.c b/gnutls.c index 256baea0..2888eb3d 100644 --- a/gnutls.c +++ b/gnutls.c @@ -509,7 +509,7 @@ static int load_pkcs12_certificate(struct openconnect_info *vpninfo, return NOT_PKCS12; } - pass = vpninfo->cert_password; + pass = vpninfo->certinfo[0].password; while ((err = gnutls_pkcs12_verify_mac(p12, pass)) == GNUTLS_E_MAC_VERIFY_FAILED) { if (!pass) { /* OpenSSL's PKCS12_parse() code will try both NULL and "" automatically, @@ -523,7 +523,7 @@ static int load_pkcs12_certificate(struct openconnect_info *vpninfo, vpn_progress(vpninfo, PRG_ERR, _("Failed to decrypt PKCS#12 certificate file\n")); free_pass(&pass); - vpninfo->cert_password = NULL; + vpninfo->certinfo[0].password = NULL; err = request_passphrase(vpninfo, "openconnect_pkcs12", &pass, _("Enter PKCS#12 pass phrase:")); if (err) { @@ -541,7 +541,7 @@ static int load_pkcs12_certificate(struct openconnect_info *vpninfo, /* If the first attempt, and we didn't know for sure it was PKCS#12 anyway, bail out and try loading it as something different. */ - if (pass == vpninfo->cert_password) { + if (pass == vpninfo->certinfo[0].password) { /* Make it non-fatal... */ level = PRG_DEBUG; ret = NOT_PKCS12; @@ -555,7 +555,7 @@ static int load_pkcs12_certificate(struct openconnect_info *vpninfo, err = gnutls_pkcs12_simple_parse(p12, pass, key, chain, chain_len, extra_certs, extra_certs_len, crl, 0); free_pass(&pass); - vpninfo->cert_password = NULL; + vpninfo->certinfo[0].password = NULL; gnutls_pkcs12_deinit(p12); if (err) { @@ -845,8 +845,8 @@ static int import_openssl_pem(struct openconnect_info *vpninfo, if (!key_data) goto out_enc_key; - pass = vpninfo->cert_password; - vpninfo->cert_password = NULL; + pass = vpninfo->certinfo[0].password; + vpninfo->certinfo[0].password = NULL; while (1) { memcpy(key_data, b64_data.data, b64_data.size); @@ -970,10 +970,10 @@ static int load_certificate(struct openconnect_info *vpninfo, struct gtls_cert_i void *dummy_hash_data = &load_certificate; #endif #if defined(HAVE_P11KIT) || defined(HAVE_GNUTLS_SYSTEM_KEYS) - char *cert_url = (char *)vpninfo->cert; + char *cert_url = (char *)vpninfo->certinfo[0].cert; #endif #ifdef HAVE_P11KIT - char *key_url = (char *)vpninfo->sslkey; + char *key_url = (char *)vpninfo->certinfo[0].key; gnutls_pkcs11_privkey_t p11key = NULL; #endif char *pem_header; @@ -992,12 +992,12 @@ static int load_certificate(struct openconnect_info *vpninfo, struct gtls_cert_i fdata.data = NULL; - key_is_p11 = !strncmp(vpninfo->sslkey, "pkcs11:", 7); - cert_is_p11 = !strncmp(vpninfo->cert, "pkcs11:", 7); + key_is_p11 = !strncmp(vpninfo->certinfo[0].key, "pkcs11:", 7); + cert_is_p11 = !strncmp(vpninfo->certinfo[0].cert, "pkcs11:", 7); /* GnuTLS returns true for pkcs11:, tpmkey:, system:, and custom URLs. */ - key_is_sys = !key_is_p11 && gnutls_url_is_supported(vpninfo->sslkey); - cert_is_sys = !cert_is_p11 && gnutls_url_is_supported(vpninfo->cert); + key_is_sys = !key_is_p11 && gnutls_url_is_supported(vpninfo->certinfo[0].key); + cert_is_sys = !cert_is_p11 && gnutls_url_is_supported(vpninfo->certinfo[0].cert); #ifndef HAVE_GNUTLS_SYSTEM_KEYS if (key_is_sys || cert_is_sys) { @@ -1037,7 +1037,7 @@ static int load_certificate(struct openconnect_info *vpninfo, struct gtls_cert_i if (key_is_p11 && !p11_kit_uri_parse(key_url, P11_KIT_URI_FOR_ANY, uri)) { - if (vpninfo->sslkey == vpninfo->cert || + if (vpninfo->certinfo[0].key == vpninfo->certinfo[0].cert || !p11_kit_uri_get_attribute(uri, CKA_CLASS)) { class = CKO_PRIVATE_KEY; p11_kit_uri_set_attribute(uri, &attr); @@ -1084,10 +1084,10 @@ static int load_certificate(struct openconnect_info *vpninfo, struct gtls_cert_i /* OK, not a PKCS#11 certificate so it must be coming from a file... */ vpn_progress(vpninfo, PRG_DEBUG, - _("Using certificate file %s\n"), vpninfo->cert); + _("Using certificate file %s\n"), vpninfo->certinfo[0].cert); /* Load file contents */ - ret = load_datum(vpninfo, &fdata, vpninfo->cert); + ret = load_datum(vpninfo, &fdata, vpninfo->certinfo[0].cert); if (ret) return ret; @@ -1158,7 +1158,7 @@ static int load_certificate(struct openconnect_info *vpninfo, struct gtls_cert_i #ifdef HAVE_GNUTLS_SYSTEM_KEYS if (key_is_sys) { vpn_progress(vpninfo, PRG_DEBUG, - _("Using system key %s\n"), vpninfo->sslkey); + _("Using system key %s\n"), vpninfo->certinfo[0].key); err = gnutls_privkey_init(&gci->pkey); if (err) { @@ -1171,11 +1171,11 @@ static int load_certificate(struct openconnect_info *vpninfo, struct gtls_cert_i gnutls_privkey_set_pin_function(gci->pkey, gnutls_pin_callback, vpninfo); - err = gnutls_privkey_import_url(gci->pkey, vpninfo->sslkey, 0); + err = gnutls_privkey_import_url(gci->pkey, vpninfo->certinfo[0].key, 0); if (err) { vpn_progress(vpninfo, PRG_ERR, _("Error importing system key %s: %s\n"), - vpninfo->sslkey, gnutls_strerror(err)); + vpninfo->certinfo[0].key, gnutls_strerror(err)); ret = -EIO; goto out; } @@ -1207,7 +1207,7 @@ static int load_certificate(struct openconnect_info *vpninfo, struct gtls_cert_i can work out what token the *cert* was found in and try that before we give up... */ if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE && - vpninfo->cert == vpninfo->sslkey) { + vpninfo->certinfo[0].cert == vpninfo->certinfo[0].key) { gnutls_pkcs11_obj_t crt; P11KitUri *uri; CK_TOKEN_INFO *token; @@ -1333,14 +1333,14 @@ static int load_certificate(struct openconnect_info *vpninfo, struct gtls_cert_i /* OK, not a PKCS#11 key so it must be coming from a file... load the file into memory, unless it's the same as the cert file and we already loaded that. */ - if (!fdata.data || vpninfo->sslkey != vpninfo->cert) { + if (!fdata.data || vpninfo->certinfo[0].key != vpninfo->certinfo[0].cert) { gnutls_free(fdata.data); fdata.data = NULL; vpn_progress(vpninfo, PRG_DEBUG, - _("Using private key file %s\n"), vpninfo->sslkey); + _("Using private key file %s\n"), vpninfo->certinfo[0].key); - ret = load_datum(vpninfo, &fdata, vpninfo->sslkey); + ret = load_datum(vpninfo, &fdata, vpninfo->certinfo[0].key); if (ret) goto out; } @@ -1425,7 +1425,7 @@ static int load_certificate(struct openconnect_info *vpninfo, struct gtls_cert_i } } else if (strstr((char *)fdata.data, "-----BEGIN ENCRYPTED PRIVATE KEY-----")) { /* Encrypted PKCS#8 */ - char *pass = vpninfo->cert_password; + char *pass = vpninfo->certinfo[0].password; while ((err = gnutls_x509_privkey_import_pkcs8(gci->key, &fdata, GNUTLS_X509_FMT_PEM, @@ -1437,7 +1437,7 @@ static int load_certificate(struct openconnect_info *vpninfo, struct gtls_cert_i ret = -EINVAL; goto out; } - vpninfo->cert_password = NULL; + vpninfo->certinfo[0].password = NULL; if (pass) { vpn_progress(vpninfo, PRG_ERR, _("Failed to decrypt PKCS#8 certificate file\n")); @@ -1451,14 +1451,14 @@ static int load_certificate(struct openconnect_info *vpninfo, struct gtls_cert_i } } free_pass(&pass); - vpninfo->cert_password = NULL; + vpninfo->certinfo[0].password = NULL; } else if (!gnutls_x509_privkey_import(gci->key, &fdata, GNUTLS_X509_FMT_DER) || !gnutls_x509_privkey_import_pkcs8(gci->key, &fdata, GNUTLS_X509_FMT_DER, NULL, GNUTLS_PKCS_PLAIN)) { /* Unencrypted DER (PKCS#1 or PKCS#8) */ } else { /* Last chance: try encrypted PKCS#8 DER. And give up if it's not that */ - char *pass = vpninfo->cert_password; + char *pass = vpninfo->certinfo[0].password; while ((err = gnutls_x509_privkey_import_pkcs8(gci->key, &fdata, GNUTLS_X509_FMT_DER, @@ -1466,11 +1466,11 @@ static int load_certificate(struct openconnect_info *vpninfo, struct gtls_cert_i if (err != GNUTLS_E_DECRYPTION_FAILED) { vpn_progress(vpninfo, PRG_ERR, _("Failed to determine type of private key %s\n"), - vpninfo->sslkey); + vpninfo->certinfo[0].key); ret = -EINVAL; goto out; } - vpninfo->cert_password = NULL; + vpninfo->certinfo[0].password = NULL; if (pass) { vpn_progress(vpninfo, PRG_ERR, _("Failed to decrypt PKCS#8 certificate file\n")); @@ -1484,7 +1484,7 @@ static int load_certificate(struct openconnect_info *vpninfo, struct gtls_cert_i } } free_pass(&pass); - vpninfo->cert_password = NULL; + vpninfo->certinfo[0].password = NULL; } /* Now attempt to make sure we use the *correct* certificate, to match @@ -1835,9 +1835,9 @@ static int load_certificate(struct openconnect_info *vpninfo, struct gtls_cert_i #ifdef HAVE_P11KIT /* This exists in the HAVE_GNUTLS_SYSTEM_KEYS case but will never change so it's OK not to add to the #ifdef mess here. */ - if (cert_url != vpninfo->cert) + if (cert_url != vpninfo->certinfo[0].cert) free(cert_url); - if (key_url != vpninfo->sslkey) + if (key_url != vpninfo->certinfo[0].key) free(key_url); #endif return ret; @@ -2223,7 +2223,7 @@ int openconnect_open_https(struct openconnect_info *vpninfo) } } - if (vpninfo->cert) { + if (vpninfo->certinfo[0].cert) { err = load_primary_certificate(vpninfo); if (err) { vpn_progress(vpninfo, PRG_ERR, @@ -2550,10 +2550,10 @@ static int gnutls_pin_callback(void *priv, int attempt, const char *uri, (*cache)->token = strdup(uri); } - if (!attempt && vpninfo->cert_password) { - snprintf(pin, pin_max, "%s", vpninfo->cert_password); - (*cache)->pin = vpninfo->cert_password; - vpninfo->cert_password = NULL; + if (!attempt && vpninfo->certinfo[0].password) { + snprintf(pin, pin_max, "%s", vpninfo->certinfo[0].password); + (*cache)->pin = vpninfo->certinfo[0].password; + vpninfo->certinfo[0].password = NULL; return 0; } diff --git a/gnutls_tpm.c b/gnutls_tpm.c index 2bed077f..278e1fb4 100644 --- a/gnutls_tpm.c +++ b/gnutls_tpm.c @@ -163,8 +163,8 @@ int load_tpm1_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata, goto out_srk; } - pass = vpninfo->cert_password; - vpninfo->cert_password = NULL; + pass = vpninfo->certinfo[0].password; + vpninfo->certinfo[0].password = NULL; while (1) { static const char nullpass[20]; diff --git a/gnutls_tpm2_esys.c b/gnutls_tpm2_esys.c index c5eabd82..25819843 100644 --- a/gnutls_tpm2_esys.c +++ b/gnutls_tpm2_esys.c @@ -356,12 +356,12 @@ static int auth_tpm2_key(struct openconnect_info *vpninfo, ESYS_CONTEXT *ctx, ES { TSS2_RC r; - if (vpninfo->tpm2->need_userauth || vpninfo->cert_password) { + if (vpninfo->tpm2->need_userauth || vpninfo->certinfo[0].password) { char *pass = NULL; - if (vpninfo->cert_password) { - pass = vpninfo->cert_password; - vpninfo->cert_password = NULL; + if (vpninfo->certinfo[0].password) { + pass = vpninfo->certinfo[0].password; + vpninfo->certinfo[0].password = NULL; } else { int err = request_passphrase(vpninfo, "openconnect_tpm2_key", &pass, _("Enter TPM2 key password:")); diff --git a/library.c b/library.c index 18afe89d..c8ec44df 100644 --- a/library.c +++ b/library.c @@ -584,7 +584,7 @@ void openconnect_vpninfo_free(struct openconnect_info *vpninfo) free(vpninfo->proxy); free(vpninfo->proxy_user); free_pass(&vpninfo->proxy_pass); - free_pass(&vpninfo->cert_password); + free_pass(&vpninfo->certinfo[0].password); free(vpninfo->vpnc_script); free(vpninfo->cafile); free(vpninfo->ifname); @@ -630,9 +630,9 @@ void openconnect_vpninfo_free(struct openconnect_info *vpninfo) /* These are const in openconnect itself, but for consistency of the library API we do take ownership of the strings we're given, and thus we have to free them too. */ - if (vpninfo->cert != vpninfo->sslkey) - free((void *)vpninfo->sslkey); - free((void *)vpninfo->cert); + if (vpninfo->certinfo[0].cert != vpninfo->certinfo[0].key) + free((void *)vpninfo->certinfo[0].key); + free((void *)vpninfo->certinfo[0].cert); if (vpninfo->peer_cert) { #if defined(OPENCONNECT_OPENSSL) X509_free(vpninfo->peer_cert); @@ -873,15 +873,15 @@ int openconnect_set_client_cert(struct openconnect_info *vpninfo, UTF8CHECK(sslkey); /* Avoid freeing it twice if it's the same */ - if (vpninfo->sslkey == vpninfo->cert) - vpninfo->sslkey = NULL; + if (vpninfo->certinfo[0].key == vpninfo->certinfo[0].cert) + vpninfo->certinfo[0].key = NULL; - STRDUP(vpninfo->cert, cert); + STRDUP(vpninfo->certinfo[0].cert, cert); if (sslkey) { - STRDUP(vpninfo->sslkey, sslkey); + STRDUP(vpninfo->certinfo[0].key, sslkey); } else { - vpninfo->sslkey = vpninfo->cert; + vpninfo->certinfo[0].key = vpninfo->certinfo[0].cert; } return 0; @@ -963,7 +963,7 @@ void openconnect_set_cert_expiry_warning(struct openconnect_info *vpninfo, int openconnect_set_key_password(struct openconnect_info *vpninfo, const char *pass) { - STRDUP(vpninfo->cert_password, pass); + STRDUP(vpninfo->certinfo[0].password, pass); return 0; } diff --git a/main.c b/main.c index dc44d238..504030c5 100644 --- a/main.c +++ b/main.c @@ -994,7 +994,7 @@ static char *xstrdup(const char *arg) * For this we use the keep_config_arg() macro below. * 3. It may be freed during normal operation, so we have to use strdup() * or convert_arg_to_utf8() even when it's an option from argv[]. - * (e.g. vpninfo->cert_password). + * (e.g. vpninfo->certinfo[0].password). * For this we use the dup_config_arg() macro below. */ @@ -1811,13 +1811,13 @@ int main(int argc, char **argv) vpninfo->cookie = dup_config_arg(); break; case 'c': - vpninfo->cert = dup_config_arg(); + vpninfo->certinfo[0].cert = dup_config_arg(); break; case 'e': vpninfo->cert_expire_warning = 86400 * atoi(config_arg); break; case 'k': - vpninfo->sslkey = dup_config_arg(); + vpninfo->certinfo[0].key = dup_config_arg(); break; case 'd': vpninfo->req_compr = COMPR_ALL; @@ -1852,7 +1852,7 @@ int main(int argc, char **argv) } break; case 'p': - vpninfo->cert_password = dup_config_arg(); + vpninfo->certinfo[0].password = dup_config_arg(); break; case 'P': proxy = keep_config_arg(); @@ -2022,8 +2022,8 @@ int main(int argc, char **argv) usage(); } - if (!vpninfo->sslkey) - vpninfo->sslkey = vpninfo->cert; + if (!vpninfo->certinfo[0].key) + vpninfo->certinfo[0].key = vpninfo->certinfo[0].cert; if (vpninfo->dump_http_traffic && verbose < PRG_DEBUG) verbose = PRG_DEBUG; @@ -2060,7 +2060,7 @@ int main(int argc, char **argv) exit(1); } - if (vpninfo->sslkey && do_passphrase_from_fsid) + if (vpninfo->certinfo[0].key && do_passphrase_from_fsid) openconnect_passphrase_from_fsid(vpninfo); if (config_lookup_host(vpninfo, argv[optind])) diff --git a/openconnect-internal.h b/openconnect-internal.h index 0a0d8a9e..aa682c9f 100644 --- a/openconnect-internal.h +++ b/openconnect-internal.h @@ -411,6 +411,12 @@ struct oc_pcsc_ctx; struct oc_tpm1_ctx; struct oc_tpm2_ctx; +struct cert_info { + char *cert; + char *key; + char *password; +}; + struct openconnect_info { const struct vpn_proto *proto; @@ -483,9 +489,9 @@ struct openconnect_info { int port; char *urlpath; int cert_expire_warning; - char *cert; - char *sslkey; - char *cert_password; + + struct cert_info certinfo[1]; + char *cafile; unsigned no_system_trust; const char *xmlconfig; diff --git a/openssl-pkcs11.c b/openssl-pkcs11.c index 171d65a8..d0cd165f 100644 --- a/openssl-pkcs11.c +++ b/openssl-pkcs11.c @@ -191,9 +191,9 @@ static int request_pin(struct openconnect_info *vpninfo, struct pin_cache *cache if (!vpninfo || !vpninfo->process_auth_form) return -EINVAL; - if (vpninfo->cert_password) { - cache->pin = vpninfo->cert_password; - vpninfo->cert_password = NULL; + if (vpninfo->certinfo[0].password) { + cache->pin = vpninfo->certinfo[0].password; + vpninfo->certinfo[0].password = NULL; return 0; } memset(&f, 0, sizeof(f)); @@ -340,11 +340,11 @@ int load_pkcs11_certificate(struct openconnect_info *vpninfo) if (!ctx) return -EIO; - if (parse_pkcs11_uri(vpninfo->cert, &match_tok, &cert_id, - &cert_id_len, &cert_label, &vpninfo->cert_password) < 0) { + if (parse_pkcs11_uri(vpninfo->certinfo[0].cert, &match_tok, &cert_id, + &cert_id_len, &cert_label, &vpninfo->certinfo[0].password) < 0) { vpn_progress(vpninfo, PRG_ERR, _("Failed to parse PKCS#11 URI '%s'\n"), - vpninfo->cert); + vpninfo->certinfo[0].cert); return -EINVAL; } @@ -395,7 +395,7 @@ int load_pkcs11_certificate(struct openconnect_info *vpninfo) ret = -EINVAL; vpn_progress(vpninfo, PRG_ERR, _("Failed to find PKCS#11 cert '%s'\n"), - vpninfo->cert); + vpninfo->certinfo[0].cert); got_cert: if (cert) { /* This happens if the cert is too large for the fixed buffer @@ -408,7 +408,7 @@ int load_pkcs11_certificate(struct openconnect_info *vpninfo) } vpn_progress(vpninfo, PRG_DEBUG, - _("Using PKCS#11 certificate %s\n"), vpninfo->cert); + _("Using PKCS#11 certificate %s\n"), vpninfo->certinfo[0].cert); vpninfo->cert_x509 = X509_dup(cert->x509); if (!SSL_CTX_use_certificate(vpninfo->https_ctx, vpninfo->cert_x509)) { @@ -421,7 +421,7 @@ int load_pkcs11_certificate(struct openconnect_info *vpninfo) /* If the key is in PKCS#11 too (which is likely), then keep the slot around. We might want to know which slot the certificate was found in, so we can log into it to find the key. */ - if (!strncmp(vpninfo->sslkey, "pkcs11:", 7)) { + if (!strncmp(vpninfo->certinfo[0].key, "pkcs11:", 7)) { vpninfo->pkcs11_slot_list = slot_list; vpninfo->pkcs11_slot_count = slot_count; vpninfo->pkcs11_cert_slot = slot; @@ -563,11 +563,11 @@ int load_pkcs11_key(struct openconnect_info *vpninfo) if (!ctx) return -EIO; - if (parse_pkcs11_uri(vpninfo->sslkey, &match_tok, &key_id, - &key_id_len, &key_label, &vpninfo->cert_password) < 0) { + if (parse_pkcs11_uri(vpninfo->certinfo[0].key, &match_tok, &key_id, + &key_id_len, &key_label, &vpninfo->certinfo[0].password) < 0) { vpn_progress(vpninfo, PRG_ERR, _("Failed to parse PKCS#11 URI '%s'\n"), - vpninfo->sslkey); + vpninfo->certinfo[0].key); return -EINVAL; } @@ -609,7 +609,7 @@ int load_pkcs11_key(struct openconnect_info *vpninfo) the cert was found in and the key wasn't separately specified, then try that slot. */ if (matching_slots != 1 && vpninfo->pkcs11_cert_slot && - vpninfo->sslkey == vpninfo->cert) { + vpninfo->certinfo[0].key == vpninfo->certinfo[0].cert) { /* Use the slot the cert was found in, if one specifier was given for both */ matching_slots = 1; login_slot = vpninfo->pkcs11_cert_slot; @@ -628,7 +628,7 @@ int load_pkcs11_key(struct openconnect_info *vpninfo) /* We still haven't found it. If we weren't explicitly given a URI for the key and we're inferring the location of the key from the cert, then drop the label and try matching the CKA_ID of the cert. */ - if (vpninfo->cert == vpninfo->sslkey && vpninfo->pkcs11_cert_id && + if (vpninfo->certinfo[0].cert == vpninfo->certinfo[0].key && vpninfo->pkcs11_cert_id && (key_label || !key_id)) { key = slot_find_key(vpninfo, ctx, slot, NULL, vpninfo->pkcs11_cert_id, vpninfo->pkcs11_cert_id_len); @@ -640,12 +640,12 @@ int load_pkcs11_key(struct openconnect_info *vpninfo) ret = -EINVAL; vpn_progress(vpninfo, PRG_ERR, _("Failed to find PKCS#11 key '%s'\n"), - vpninfo->sslkey); + vpninfo->certinfo[0].key); got_key: if (key) { vpn_progress(vpninfo, PRG_DEBUG, - _("Using PKCS#11 key %s\n"), vpninfo->sslkey); + _("Using PKCS#11 key %s\n"), vpninfo->certinfo[0].key); pkey = PKCS11_get_private_key(key); if (!pkey) { diff --git a/openssl.c b/openssl.c index aef7c4f9..7c6afd16 100644 --- a/openssl.c +++ b/openssl.c @@ -504,9 +504,9 @@ static int pem_pw_cb(char *buf, int len, int w, void *v) char *pass = NULL; int plen; - if (vpninfo->cert_password) { - pass = vpninfo->cert_password; - vpninfo->cert_password = NULL; + if (vpninfo->certinfo[0].password) { + pass = vpninfo->certinfo[0].password; + vpninfo->certinfo[0].password = NULL; } else if (request_passphrase(vpninfo, "openconnect_pem", &pass, _("Enter PEM pass phrase:"))) return -1; @@ -568,8 +568,8 @@ static int load_pkcs12_certificate(struct openconnect_info *vpninfo, PKCS12 *p12 int ret = 0; char *pass; - pass = vpninfo->cert_password; - vpninfo->cert_password = NULL; + pass = vpninfo->certinfo[0].password; + vpninfo->certinfo[0].password = NULL; retrypass: /* We do this every time round the loop, to work around a bug in OpenSSL < 1.0.0-beta2 -- where the stack at *ca will be freed @@ -667,20 +667,20 @@ static int load_tpm_certificate(struct openconnect_info *vpninfo, return -EINVAL; } - if (vpninfo->cert_password) { - if (!ENGINE_ctrl_cmd(e, "PIN", strlen(vpninfo->cert_password), - vpninfo->cert_password, NULL, 0)) { + if (vpninfo->certinfo[0].password) { + if (!ENGINE_ctrl_cmd(e, "PIN", strlen(vpninfo->certinfo[0].password), + vpninfo->certinfo[0].password, NULL, 0)) { vpn_progress(vpninfo, PRG_ERR, _("Failed to set TPM SRK password\n")); openconnect_report_ssl_errors(vpninfo); } - free_pass(&vpninfo->cert_password); + free_pass(&vpninfo->certinfo[0].password); } /* Provide our own UI method to handle the PIN callback. */ meth = create_openssl_ui(); - key = ENGINE_load_private_key(e, vpninfo->sslkey, meth, vpninfo); + key = ENGINE_load_private_key(e, vpninfo->certinfo[0].key, meth, vpninfo); if (meth) UI_destroy_method(meth); if (!key) { @@ -736,14 +736,14 @@ static int load_tpm_certificate(struct openconnect_info *vpninfo, static int load_cert_chain_file(struct openconnect_info *vpninfo) { BIO *b; - FILE *f = openconnect_fopen_utf8(vpninfo, vpninfo->cert, "rb"); + FILE *f = openconnect_fopen_utf8(vpninfo, vpninfo->certinfo[0].cert, "rb"); STACK_OF(X509) *extra_certs = NULL; char buf[200]; if (!f) { vpn_progress(vpninfo, PRG_ERR, _("Failed to open certificate file %s: %s\n"), - vpninfo->cert, strerror(errno)); + vpninfo->certinfo[0].cert, strerror(errno)); return -ENOENT; } @@ -874,7 +874,7 @@ static int load_certificate(struct openconnect_info *vpninfo) char buf[256]; int ret; - if (!strncmp(vpninfo->cert, "pkcs11:", 7)) { + if (!strncmp(vpninfo->certinfo[0].cert, "pkcs11:", 7)) { int ret = load_pkcs11_certificate(vpninfo); if (ret) return ret; @@ -882,16 +882,16 @@ static int load_certificate(struct openconnect_info *vpninfo) } vpn_progress(vpninfo, PRG_DEBUG, - _("Using certificate file %s\n"), vpninfo->cert); + _("Using certificate file %s\n"), vpninfo->certinfo[0].cert); - if (strncmp(vpninfo->cert, "keystore:", 9)) { + if (strncmp(vpninfo->certinfo[0].cert, "keystore:", 9)) { PKCS12 *p12; - f = openconnect_fopen_utf8(vpninfo, vpninfo->cert, "rb"); + f = openconnect_fopen_utf8(vpninfo, vpninfo->certinfo[0].cert, "rb"); if (!f) { vpn_progress(vpninfo, PRG_ERR, _("Failed to open certificate file %s: %s\n"), - vpninfo->cert, strerror(errno)); + vpninfo->certinfo[0].cert, strerror(errno)); return -ENOENT; } p12 = d2i_PKCS12_fp(f, NULL); @@ -905,8 +905,8 @@ static int load_certificate(struct openconnect_info *vpninfo) /* It's PEM or TPM now, and either way we need to load the plain cert: */ #ifdef ANDROID_KEYSTORE - if (!strncmp(vpninfo->cert, "keystore:", 9)) { - BIO *b = BIO_from_keystore(vpninfo, vpninfo->cert); + if (!strncmp(vpninfo->certinfo[0].cert, "keystore:", 9)) { + BIO *b = BIO_from_keystore(vpninfo, vpninfo->certinfo[0].cert); if (!b) return -EINVAL; vpninfo->cert_x509 = PEM_read_bio_X509_AUX(b, NULL, pem_pw_cb, vpninfo); @@ -935,11 +935,11 @@ static int load_certificate(struct openconnect_info *vpninfo) got_cert: #ifdef ANDROID_KEYSTORE - if (!strncmp(vpninfo->sslkey, "keystore:", 9)) { + if (!strncmp(vpninfo->certinfo[0].key, "keystore:", 9)) { BIO *b; again_android: - b = BIO_from_keystore(vpninfo, vpninfo->sslkey); + b = BIO_from_keystore(vpninfo, vpninfo->certinfo[0].key); if (!b) return -EINVAL; key = PEM_read_bio_PrivateKey(b, NULL, pem_pw_cb, vpninfo); @@ -961,14 +961,14 @@ static int load_certificate(struct openconnect_info *vpninfo) return 0; } #endif /* ANDROID_KEYSTORE */ - if (!strncmp(vpninfo->sslkey, "pkcs11:", 7)) + if (!strncmp(vpninfo->certinfo[0].key, "pkcs11:", 7)) return load_pkcs11_key(vpninfo); - f = openconnect_fopen_utf8(vpninfo, vpninfo->sslkey, "rb"); + f = openconnect_fopen_utf8(vpninfo, vpninfo->certinfo[0].key, "rb"); if (!f) { vpn_progress(vpninfo, PRG_ERR, _("Failed to open private key file %s: %s\n"), - vpninfo->sslkey, strerror(errno)); + vpninfo->certinfo[0].key, strerror(errno)); return -ENOENT; } @@ -1044,7 +1044,7 @@ static int load_certificate(struct openconnect_info *vpninfo) if (p8) { PKCS8_PRIV_KEY_INFO *p8inf; - char *pass = vpninfo->cert_password; + char *pass = vpninfo->certinfo[0].password; fclose(f); @@ -1073,13 +1073,13 @@ static int load_certificate(struct openconnect_info *vpninfo) } free_pass(&pass); - vpninfo->cert_password = NULL; + vpninfo->certinfo[0].password = NULL; X509_SIG_free(p8); return -EINVAL; } free_pass(&pass); - vpninfo->cert_password = NULL; + vpninfo->certinfo[0].password = NULL; key = EVP_PKCS82PKEY(p8inf); @@ -1106,7 +1106,7 @@ static int load_certificate(struct openconnect_info *vpninfo) fclose(f); vpn_progress(vpninfo, PRG_ERR, _("Failed to identify private key type in '%s'\n"), - vpninfo->sslkey); + vpninfo->certinfo[0].key); return -EINVAL; } @@ -1814,7 +1814,7 @@ int openconnect_open_https(struct openconnect_info *vpninfo) } #endif - if (vpninfo->cert) { + if (vpninfo->certinfo[0].cert) { err = load_certificate(vpninfo); if (!err && !SSL_CTX_check_private_key(vpninfo->https_ctx)) { vpn_progress(vpninfo, PRG_ERR, diff --git a/ssl.c b/ssl.c index 97f20630..f1feccf7 100644 --- a/ssl.c +++ b/ssl.c @@ -559,17 +559,17 @@ int __attribute__ ((format(printf, 4, 5))) int openconnect_passphrase_from_fsid(struct openconnect_info *vpninfo) { struct statvfs buf; - char *sslkey = openconnect_utf8_to_legacy(vpninfo, vpninfo->sslkey); + char *sslkey = openconnect_utf8_to_legacy(vpninfo, vpninfo->certinfo[0].key); int err = 0; if (statvfs(sslkey, &buf)) { err = -errno; vpn_progress(vpninfo, PRG_ERR, _("statvfs: %s\n"), strerror(errno)); - } else if (asprintf(&vpninfo->cert_password, "%lx", buf.f_fsid) == -1) + } else if (asprintf(&vpninfo->certinfo[0].password, "%lx", buf.f_fsid) == -1) err = -ENOMEM; - if (sslkey != vpninfo->sslkey) + if (sslkey != vpninfo->certinfo[0].key) free(sslkey); return err; } @@ -600,11 +600,11 @@ int openconnect_passphrase_from_fsid(struct openconnect_info *vpninfo) if (!func) goto notsupp; - fd = openconnect_open_utf8(vpninfo, vpninfo->sslkey, O_RDONLY); + fd = openconnect_open_utf8(vpninfo, vpninfo->certinfo[0].key, O_RDONLY); if (fd == -1) { vpn_progress(vpninfo, PRG_ERR, _("Failed to open private key file '%s': %s\n"), - vpninfo->sslkey, strerror(errno)); + vpninfo->certinfo[0].key, strerror(errno)); return -ENOENT; } @@ -615,7 +615,7 @@ int openconnect_passphrase_from_fsid(struct openconnect_info *vpninfo) if (!success) return -EIO; - if (asprintf(&vpninfo->cert_password, "%lx", serial) == -1) + if (asprintf(&vpninfo->certinfo[0].password, "%lx", serial) == -1) return -ENOMEM; return 0; @@ -623,7 +623,7 @@ int openconnect_passphrase_from_fsid(struct openconnect_info *vpninfo) #elif defined(HAVE_STATFS) int openconnect_passphrase_from_fsid(struct openconnect_info *vpninfo) { - char *sslkey = openconnect_utf8_to_legacy(vpninfo, vpninfo->sslkey); + char *sslkey = openconnect_utf8_to_legacy(vpninfo, vpninfo->certinfo[0].key); struct statfs buf; unsigned *fsid = (unsigned *)&buf.f_fsid; unsigned long long fsid64; @@ -637,11 +637,11 @@ int openconnect_passphrase_from_fsid(struct openconnect_info *vpninfo) } else { fsid64 = ((unsigned long long)fsid[0] << 32) | fsid[1]; - if (asprintf(&vpninfo->cert_password, "%llx", fsid64) == -1) + if (asprintf(&vpninfo->certinfo[0].password, "%llx", fsid64) == -1) err = -ENOMEM; } - if (sslkey != vpninfo->sslkey) + if (sslkey != vpninfo->certinfo[0].key) free(sslkey); return err; -- 2.50.1