From: Tobias Brunner Date: Wed, 18 Oct 2023 15:01:52 +0000 (+0200) Subject: openssl: Add support for unprotected PKCS#12 containers X-Git-Tag: 5.9.12rc1~7^2~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7bb6aed5abd004af5cb98f35756a71cc065fe559;p=thirdparty%2Fstrongswan.git openssl: Add support for unprotected PKCS#12 containers --- diff --git a/src/libstrongswan/plugins/openssl/openssl_pkcs12.c b/src/libstrongswan/plugins/openssl/openssl_pkcs12.c index 3c74ac1991..51745f5240 100644 --- a/src/libstrongswan/plugins/openssl/openssl_pkcs12.c +++ b/src/libstrongswan/plugins/openssl/openssl_pkcs12.c @@ -139,6 +139,29 @@ static bool add_key(private_pkcs12_t *this, EVP_PKEY *private) return key != NULL; } +/** + * Decrypt PKCS#12 file using the given password and unpack credentials + */ +static status_t decrypt_and_unpack_pw(private_pkcs12_t *this, char *password) +{ + STACK_OF(X509) *cas = NULL; + EVP_PKEY *private; + X509 *cert; + + if (PKCS12_parse(this->p12, password, &private, &cert, &cas)) + { + /* if at least one is successful, we accept it */ + if ((int)add_key(this, private) | + (int)add_cert(this, cert) | + (int)add_cas(this, cas)) + { + return SUCCESS; + } + return FAILED; + } + return PARSE_ERROR; +} + /** * Decrypt PKCS#12 file and unpack credentials */ @@ -146,13 +169,21 @@ static bool decrypt_and_unpack(private_pkcs12_t *this) { enumerator_t *enumerator; shared_key_t *shared; - STACK_OF(X509) *cas = NULL; - EVP_PKEY *private; - X509 *cert; chunk_t key; char *password; bool success = FALSE; + /* try without password first */ + switch (decrypt_and_unpack_pw(this, NULL)) + { + case PARSE_ERROR: + break; + case SUCCESS: + return TRUE; + default: + return FALSE; + } + enumerator = lib->credmgr->create_shared_enumerator(lib->credmgr, SHARED_PRIVATE_KEY_PASS, NULL, NULL); while (enumerator->enumerate(enumerator, &shared, NULL, NULL)) @@ -160,17 +191,25 @@ static bool decrypt_and_unpack(private_pkcs12_t *this) key = shared->get_key(shared); if (!key.ptr || asprintf(&password, "%.*s", (int)key.len, key.ptr) < 0) { - password = NULL; + password = strdup(""); } - if (PKCS12_parse(this->p12, password, &private, &cert, &cas)) + switch (decrypt_and_unpack_pw(this, password)) { - success = add_key(this, private); - success &= add_cert(this, cert); - success &= add_cas(this, cas); - free(password); - break; + case PARSE_ERROR: + /* password was incorrect, try another */ + memwipe(password, strlen(password)); + free(password); + continue; + case SUCCESS: + success = TRUE; + break; + default: + /* password was correct but we were unable to unpack anything */ + break; } + memwipe(password, strlen(password)); free(password); + break; } enumerator->destroy(enumerator); return success;