(This is on 1.0.2 beta 1 as found on openssl.org/source) I'm getting a double free error when building a CMS EnvelopedData with RSA OAEP. Here's how I'm setting things up (error checking left out for brevity):
int flags = CMS_BINARY | CMS_USE_KEYID | CMS_PARTIAL | CMS_KEY_PARAM; CMS_ContentInfo* edata = CMS_encrypt(NULL, NULL, cipher, flags); CMS_RecipientInfo* r_info = CMS_add1_recipient_cert(edata, r_cert, flags); EVP_PKEY_CTX* wrap_ctx = CMS_RecipientInfo_get0_pkey_ctx(r_info); EVP_PKEY_CTX_set_rsa_padding(wrap_ctx, RSA_PKCS1_OAEP_PADDING); EVP_PKEY_CTX_set_rsa_oaep_md(wrap_ctx, EVP_sha256()); EVP_PKEY_CTX_set_rsa_mgf1_md(wrap_ctx, EVP_sha256()); EVP_PKEY_CTX_set0_rsa_oaep_label(wrap_ctx, my_label, my_label_l); CMS_final(edata, in, NULL, flags); Valgrind says: ==13434== Invalid free() / delete / delete[] ==13434== at 0x4024B3A: free (vg_replace_malloc.c:366) ==13434== by 0x8087BE4: CRYPTO_free (mem.c:397) ==13434== by 0x80B27AC: pkey_rsa_cleanup (rsa_pmeth.c:175) ==13434== by 0x80615E7: EVP_PKEY_CTX_free (pmeth_lib.c:374) ==13434== by 0x8082DED: cms_RecipientInfo_ktri_encrypt (cms_env.c:433) ==13434== by 0x8083930: CMS_RecipientInfo_encrypt (cms_env.c:896) ==13434== by 0x8083BC5: cms_EnvelopedData_init_bio (cms_env.c:1013) ==13434== by 0x807D885: CMS_dataInit (cms_lib.c:141) ==13434== by 0x8080358: CMS_final (cms_smime.c:807) ==13434== by 0x804A5C4: <snip> ==13434== Address 0xbeb16466 is on thread 1's stack Might be a case of PEBKAC, I mostly guessed how this was supposed to work based on [1], so I might be doing retarded things. [1] https://github.com/openssl/openssl/commit/f2edf3181e30413c99864e7106125be7da905678 Some more code if anyone wants to try: #define OSSL_FAIL { ERR_print_errors_fp(stderr); goto end; } OpenSSL_add_all_algorithms(); ERR_load_crypto_strings(); BIO* in = NULL; BIO* tmp_out = NULL; CMS_ContentInfo* edata = NULL; const EVP_CIPHER* cipher = EVP_aes_256_cbc(); /* Retrieve recipient certificate */ FILE* r_cert_file = fopen(recip_cert_path, "rb"); if (!r_cert_file) { printf("Could not open certificate at %s.\n", recip_cert_path); goto end; } if (!PEM_read_X509(r_cert_file, &r_cert, NULL, NULL)) OSSL_FAIL; fclose(r_cert_file); in = BIO_new_file(in_path, "rb"); if (!in) OSSL_FAIL; int flags = CMS_BINARY | CMS_USE_KEYID | CMS_PARTIAL | CMS_KEY_PARAM; edata = CMS_encrypt(NULL, NULL, cipher, flags); if (!edata) OSSL_FAIL; CMS_RecipientInfo* r_info = CMS_add1_recipient_cert(edata, r_cert, flags); if (!r_info) OSSL_FAIL; unsigned char oaep_label[] = "BLORG"; size_t oaep_label_l = sizeof(oaep_label); EVP_PKEY_CTX* wrap_ctx = CMS_RecipientInfo_get0_pkey_ctx(r_info); if (!wrap_ctx) { printf("oh noes! no wrap ctx :(\n"); goto end; } if (EVP_PKEY_CTX_set_rsa_padding(wrap_ctx, RSA_PKCS1_OAEP_PADDING)<1) OSSL_FAIL; if (EVP_PKEY_CTX_set_rsa_oaep_md(wrap_ctx, EVP_sha256())<1) OSSL_FAIL; if (EVP_PKEY_CTX_set_rsa_mgf1_md(wrap_ctx, EVP_sha256())<1) OSSL_FAIL; if (EVP_PKEY_CTX_set0_rsa_oaep_label(wrap_ctx, oaep_label, oaep_label_l)<1) OSSL_FAIL; if (! CMS_final(edata, in, NULL, flags) ) OSSL_FAIL; /* Out */ char* env_out = malloc(strlen(in_path) + sizeof(".ENV.CMS")); strncpy(env_out, in_path, strlen(out_path)+1); strcat(env_out, ".ENV.CMS"); BIO* tmp_out = BIO_new_file(env_out, "wb"); if (!tmp_out) OSSL_FAIL; if (!i2d_CMS_bio(tmp_out, edata)) OSSL_FAIL; if (BIO_flush(tmp_out)<1) OSSL_FAIL; free(env_out); end: if (edata) CMS_ContentInfo_free(edata); if (r_cert) X509_free(r_cert); if (in) BIO_free(in); if (tmp_out) BIO_free(tmp_out); ERR_free_strings(); EVP_cleanup(); PS: Many thanks to Tom and Steve for their previous help on nested CMS structures :) ended up parsing the ASN.1 string myself, which was 1) not difficult 2) very instructive. ______________________________________________________________________ OpenSSL Project http://www.openssl.org User Support Mailing List openssl-users@openssl.org Automated List Manager majord...@openssl.org