From: Tobias Brunner Date: Fri, 17 Oct 2014 08:16:19 +0000 (+0200) Subject: pkcs5: Add support for PBES2 encryption schemes other than 3DES X-Git-Tag: 5.2.2rc1~33 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7bd55485386bc32f0b24fb39bc41d4a43ba3f03c;p=thirdparty%2Fstrongswan.git 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. --- diff --git a/src/libstrongswan/crypto/pkcs5.c b/src/libstrongswan/crypto/pkcs5.c index 3b4df0e8a7..478926f2fa 100644 --- a/src/libstrongswan/crypto/pkcs5.c +++ b/src/libstrongswan/crypto/pkcs5.c @@ -108,13 +108,13 @@ struct private_pkcs5_t { * Verify padding of decrypted blob. * 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; padding = count = blob->ptr[blob->len - 1]; - if (padding > 8) + if (padding > crypter->get_block_size(crypter)) { return FALSE; } @@ -153,7 +153,7 @@ static bool decrypt_generic(private_pkcs5_t *this, chunk_t password, return FALSE; } memwipe(keymat.ptr, keymat.len); - if (verify_padding(decrypted)) + if (verify_padding(this->crypter, decrypted)) { return TRUE; } @@ -504,6 +504,7 @@ static bool parse_pbes2_params(private_pkcs5_t *this, chunk_t blob, int level0) { asn1_parser_t *parser; chunk_t object, params; + size_t keylen; int objectID; 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, 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 */ goto end; } - if (this->keylen <= 0) - { /* default key length for DES-EDE3-CBC-Pad */ - this->keylen = 24; + /* prefer encoded key length */ + this->keylen = this->keylen ?: keylen / 8; + 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, parser->get_level(parser) + 1, "IV")) { goto end; } - this->encr = ENCR_3DES; this->data.pbes2.iv = chunk_clone(params); break; }