The following bug  has been reproduced on RedHat Enterprise Linux with OpenSSL 
1.0.1e.

When upgrading from 0.9.8e to 1.0.1e we noticed that a call to PKCS12_parse() 
would sometimes fail with the following:

3073869560:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad 
decrypt:evp_enc.c:535:
3073869560:error:23077074:PKCS12 routines:PKCS12_pbe_crypt:pkcs12 cipherfinal 
error:p12_decr.c:97:
3073869560:error:2306A075:PKCS12 routines:PKCS12_item_decrypt_d2i:pkcs12 pbe 
crypt error:p12_decr.c:123:
3073869560:error:23076072:PKCS12 routines:PKCS12_parse:parse 
error:p12_kiss.c:129:

We determined that the cause was an existing PBE registration within our 
application via EVP_PBE_alg_add():

EVP_PBE_alg_add(NID_pbe_WithSHA1And40BitRC2_CBC, EVP_rc2_40_cbc(), EVP_sha1(), 
PKCS12_PBE_keyivgen);

Under OpenSSL 1.0.0 and beyond, this causes a PBE to be added with a cipher NID 
of RC2-CBC instead of RC2-40-CBC. A change to this API uses an incorrect cipher 
NID returned by EVP_CIPHER_type(). The decryption of PKCS12 components that are 
encrypted with RC2-40-CBC  fails because RC2-CBC is used instead.

Enclosed is a modified version of demos/pkcs12/pkread.c. When linked against 
OpenSSL 1.x.x the code will fail to decrypt a PKCS12 file encrypted with 
RC2-40-CBC. The same code works fine when linked against 0.9.8*. The code can 
be made to work with 1.x.x by removing the call to EVP_PBE_alg_add(), allowing 
the builtin version of this PBE (with the correct cipher NID) to be used.

Thank you.

Doug Gibbons | Consulting Engineer | Avaya Inc. | 1300 W. 120th Ave | B3-C61 | 
Westminster, CO 80234 | 303-538-3538 | 
ldgibb...@avaya.com<mailto:ldgibb...@avaya.com>



/* pkread.c */

#include <stdio.h>
#include <stdlib.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/pkcs12.h>

/* Simple PKCS#12 file reader */

int main(int argc, char **argv)
{
        FILE *fp;
        EVP_PKEY *pkey;
        X509 *cert;
        STACK_OF(X509) *ca = NULL;
        PKCS12 *p12;
        int i;
        if (argc != 4) {
                fprintf(stderr, "Usage: pkread p12file password opfile\n");
                exit (1);
        }
        OpenSSL_add_all_algorithms();
        ERR_load_crypto_strings();
#if 1
        /* With OpenSSL 1.x.x next line creates PBE with incorrect cipher NID */
        EVP_PBE_alg_add(NID_pbe_WithSHA1And40BitRC2_CBC, EVP_rc2_40_cbc(),
                EVP_sha1(), PKCS12_PBE_keyivgen);
#endif
        if (!(fp = fopen(argv[1], "rb"))) {
                fprintf(stderr, "Error opening file %s\n", argv[1]);
                exit(1);
        }
        p12 = d2i_PKCS12_fp(fp, NULL);
        fclose (fp);
        if (!p12) {
                fprintf(stderr, "Error reading PKCS#12 file\n");
                ERR_print_errors_fp(stderr);
                exit (1);
        }
        if (!PKCS12_parse(p12, argv[2], &pkey, &cert, &ca)) {
                fprintf(stderr, "Error parsing PKCS#12 file\n");
                ERR_print_errors_fp(stderr);
                exit (1);
        }
        PKCS12_free(p12);
        if (!(fp = fopen(argv[3], "w"))) {
                fprintf(stderr, "Error opening file %s\n", argv[1]);
                exit(1);
        }
        if (pkey) {
                fprintf(fp, "***Private Key***\n");
                PEM_write_PrivateKey(fp, pkey, NULL, NULL, 0, NULL, NULL);
        }
        if (cert) {
                fprintf(fp, "***User Certificate***\n");
                PEM_write_X509_AUX(fp, cert);
        }
        if (ca && sk_X509_num(ca)) {
                fprintf(fp, "***Other Certificates***\n");
                for (i = 0; i < sk_X509_num(ca); i++) 
                    PEM_write_X509_AUX(fp, sk_X509_value(ca, i));
        }
        fclose(fp);
        return 0;
}

Reply via email to