openssl: Add support for unprotected PKCS#12 containers
This commit is contained in:
@@ -139,6 +139,29 @@ static bool add_key(private_pkcs12_t *this, EVP_PKEY *private)
|
|||||||
return key != NULL;
|
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
|
* Decrypt PKCS#12 file and unpack credentials
|
||||||
*/
|
*/
|
||||||
@@ -146,13 +169,21 @@ static bool decrypt_and_unpack(private_pkcs12_t *this)
|
|||||||
{
|
{
|
||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
shared_key_t *shared;
|
shared_key_t *shared;
|
||||||
STACK_OF(X509) *cas = NULL;
|
|
||||||
EVP_PKEY *private;
|
|
||||||
X509 *cert;
|
|
||||||
chunk_t key;
|
chunk_t key;
|
||||||
char *password;
|
char *password;
|
||||||
bool success = FALSE;
|
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,
|
enumerator = lib->credmgr->create_shared_enumerator(lib->credmgr,
|
||||||
SHARED_PRIVATE_KEY_PASS, NULL, NULL);
|
SHARED_PRIVATE_KEY_PASS, NULL, NULL);
|
||||||
while (enumerator->enumerate(enumerator, &shared, 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);
|
key = shared->get_key(shared);
|
||||||
if (!key.ptr || asprintf(&password, "%.*s", (int)key.len, key.ptr) < 0)
|
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);
|
case PARSE_ERROR:
|
||||||
success &= add_cert(this, cert);
|
/* password was incorrect, try another */
|
||||||
success &= add_cas(this, cas);
|
memwipe(password, strlen(password));
|
||||||
free(password);
|
free(password);
|
||||||
break;
|
continue;
|
||||||
|
case SUCCESS:
|
||||||
|
success = TRUE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* password was correct but we were unable to unpack anything */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
memwipe(password, strlen(password));
|
||||||
free(password);
|
free(password);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
return success;
|
return success;
|
||||||
|
|||||||
Reference in New Issue
Block a user