pkcs5: Add support for PBES2 encryption schemes other than 3DES

This allows using e.g. AES for PKCS#8 and PKCS#12 files.

Some legacy schemes defined in RFC 2898 are not supported (like RC2).

Fixes #740.
This commit is contained in:
Tobias Brunner
2014-12-05 14:35:50 +01:00
parent 5743f6df2f
commit 7bd5548538
+24 -8
View File
@@ -108,13 +108,13 @@ struct private_pkcs5_t {
* Verify padding of decrypted blob. * Verify padding of decrypted blob.
* Length of blob is adjusted accordingly. * Length of blob is adjusted accordingly.
*/ */
static bool verify_padding(chunk_t *blob) static bool verify_padding(crypter_t *crypter, chunk_t *blob)
{ {
u_int8_t padding, count; u_int8_t padding, count;
padding = count = blob->ptr[blob->len - 1]; padding = count = blob->ptr[blob->len - 1];
if (padding > 8) if (padding > crypter->get_block_size(crypter))
{ {
return FALSE; return FALSE;
} }
@@ -153,7 +153,7 @@ static bool decrypt_generic(private_pkcs5_t *this, chunk_t password,
return FALSE; return FALSE;
} }
memwipe(keymat.ptr, keymat.len); memwipe(keymat.ptr, keymat.len);
if (verify_padding(decrypted)) if (verify_padding(this->crypter, decrypted))
{ {
return TRUE; return TRUE;
} }
@@ -504,6 +504,7 @@ static bool parse_pbes2_params(private_pkcs5_t *this, chunk_t blob, int level0)
{ {
asn1_parser_t *parser; asn1_parser_t *parser;
chunk_t object, params; chunk_t object, params;
size_t keylen;
int objectID; int objectID;
bool success = FALSE; bool success = FALSE;
@@ -533,20 +534,35 @@ static bool parse_pbes2_params(private_pkcs5_t *this, chunk_t blob, int level0)
{ {
int oid = asn1_parse_algorithmIdentifier(object, int oid = asn1_parse_algorithmIdentifier(object,
parser->get_level(parser) + 1, &params); parser->get_level(parser) + 1, &params);
if (oid != OID_3DES_EDE_CBC) this->encr = encryption_algorithm_from_oid(oid, &keylen);
if (this->encr == ENCR_UNDEFINED)
{ /* unsupported encryption scheme */ { /* unsupported encryption scheme */
goto end; goto end;
} }
if (this->keylen <= 0) /* prefer encoded key length */
{ /* default key length for DES-EDE3-CBC-Pad */ this->keylen = this->keylen ?: keylen / 8;
this->keylen = 24; if (!this->keylen)
{ /* set default key length for known algorithms */
switch (this->encr)
{
case ENCR_DES:
this->keylen = 8;
break;
case ENCR_3DES:
this->keylen = 24;
break;
case ENCR_BLOWFISH:
this->keylen = 16;
break;
default:
goto end;
}
} }
if (!asn1_parse_simple_object(&params, ASN1_OCTET_STRING, if (!asn1_parse_simple_object(&params, ASN1_OCTET_STRING,
parser->get_level(parser) + 1, "IV")) parser->get_level(parser) + 1, "IV"))
{ {
goto end; goto end;
} }
this->encr = ENCR_3DES;
this->data.pbes2.iv = chunk_clone(params); this->data.pbes2.iv = chunk_clone(params);
break; break;
} }