pkcs5: Add support for PBES2 encryption schemes other than 3DES
authorTobias Brunner <tobias@strongswan.org>
Fri, 17 Oct 2014 08:16:19 +0000 (10:16 +0200)
committerTobias Brunner <tobias@strongswan.org>
Fri, 5 Dec 2014 13:35:50 +0000 (14:35 +0100)
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.

src/libstrongswan/crypto/pkcs5.c

index 3b4df0e..478926f 100644 (file)
@@ -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, &params);
-                               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(&params, ASN1_OCTET_STRING,
                                                                        parser->get_level(parser) + 1, "IV"))
                                {
                                        goto end;
                                }
-                               this->encr = ENCR_3DES;
                                this->data.pbes2.iv = chunk_clone(params);
                                break;
                        }