OpenSSL 3.0中OSSL_DECODER_CTX生成的EVP_KEY需手动释放吗?代码是否泄漏?
关于OpenSSL 3.0中EVP_PKEY的释放问题
问题1解答:由OSSL_DECODER_CTX_new_for_pkey创建的EVP_KEY需要手动释放
当使用OSSL_DECODER_CTX_new_for_pkey时,函数会将解码生成的EVP_PKEY实例赋值给你传入的指针(代码中的&pkey)。这个EVP_PKEY的所有权完全属于调用者,解码器上下文(OSSL_DECODER_CTX)在被释放时不会自动清理这个密钥对象,因此必须手动调用EVP_PKEY_free来释放它占用的内存。
问题2解答:示例代码存在内存泄漏,需要额外调用EVP_PKEY_free(pkey)
你提供的代码中,虽然释放了BIO和OSSL_DECODER_CTX,但未处理pkey的内存释放:
- 如果
OSSL_DECODER_from_bio解码成功,pkey会被分配内存,此时不调用EVP_PKEY_free(pkey)会导致内存泄漏。 - 即使解码失败,
pkey保持NULL,调用EVP_PKEY_free(NULL)也是安全的(OpenSSL的这类free函数都兼容空指针),所以在代码末尾加上这一步不会有问题。
修正后的代码片段(保留原逻辑,补充释放步骤):
EVP_PKEY *pkey = NULL; BIO *public_key_file = BIO_new_file("public.pem", "r"); OSSL_DECODER_CTX *dctx = OSSL_DECODER_CTX_new_for_pkey( &pkey, "PEM", NULL, "EC", OSSL_KEYMGMT_SELECT_PUBLIC_KEY | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS, NULL, NULL ); OSSL_DECODER_from_bio(dctx, public_key_file); // ... BIO_free(public_key_file); OSSL_DECODER_CTX_free(dctx); EVP_PKEY_free(pkey); // 补充密钥释放步骤
补充说明
OpenSSL的API设计惯例中,这类通过输出参数返回的对象,除非文档明确说明由上下文或其他对象托管生命周期,否则都需要调用对应的free函数手动释放。即使官方文档未特别提及OSSL_DECODER_CTX_new_for_pkey返回密钥的释放规则,也遵循这一通用惯例。
内容的提问来源于stack exchange,提问作者OrangeDog
相关产品推荐
相关产品推荐

