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:
@@ -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, ¶ms);
|
parser->get_level(parser) + 1, ¶ms);
|
||||||
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(¶ms, ASN1_OCTET_STRING,
|
if (!asn1_parse_simple_object(¶ms, 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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user