如何从BIO加载含1至N个证书的PEM到STACK_OF(X509*)?
你说得没错,OpenSSL确实没有提供一个像PEM_read_bio_X509那样直接从BIO读取并返回STACK_OF(X509*)的函数。不过别担心,有两种常用的方法可以实现这个需求,我给你详细说说:
方法一:手动循环读取单个证书并构建栈
这是最直接也最常用的方式——循环调用PEM_read_bio_X509读取每个证书,直到遇到EOF,然后把每个读取到的X509对象推入栈中。需要注意处理内存分配错误和读取过程中的异常情况:
#include <openssl/x509.h> #include <openssl/pem.h> STACK_OF(X509)* load_certs_from_bio(BIO *bio) { // 创建空的X509栈 STACK_OF(X509)* cert_stack = sk_X509_new_null(); if (!cert_stack) { fprintf(stderr, "Failed to create X509 stack\n"); return NULL; } X509* cert = NULL; // 循环读取每个PEM证书 while ((cert = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) { // 将证书推入栈中 if (!sk_X509_push(cert_stack, cert)) { fprintf(stderr, "Failed to push certificate to stack\n"); // 清理已获取的证书和栈 X509_free(cert); sk_X509_pop_free(cert_stack, X509_free); return NULL; } } // 检查循环终止的原因:是正常EOF还是读取错误 unsigned long err = ERR_get_error(); if (ERR_GET_REASON(err) != PEM_R_NO_START_LINE) { fprintf(stderr, "Error reading certificates: %s\n", ERR_error_string(err, NULL)); sk_X509_pop_free(cert_stack, X509_free); return NULL; } // 成功读取所有证书,返回栈 return cert_stack; }
使用完栈之后,记得用sk_X509_pop_free(cert_stack, X509_free)来释放栈和所有证书对象,避免内存泄漏。
方法二:利用X509_STORE间接加载(适合需要验证场景)
如果你最终需要把这些证书用于证书验证,可以借助X509_STORE来间接加载:
#include <openssl/x509_vfy.h> X509_STORE* load_certs_to_store_from_bio(BIO *bio) { X509_STORE* store = X509_STORE_new(); if (!store) { fprintf(stderr, "Failed to create X509 store\n"); return NULL; } X509* cert = NULL; while ((cert = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) { if (!X509_STORE_add_cert(store, cert)) { fprintf(stderr, "Failed to add certificate to store\n"); X509_free(cert); X509_STORE_free(store); return NULL; } // X509_STORE_add_cert会接管证书的内存,不需要手动free cert = NULL; } unsigned long err = ERR_get_error(); if (ERR_GET_REASON(err) != PEM_R_NO_START_LINE) { fprintf(stderr, "Error reading certificates: %s\n", ERR_error_string(err, NULL)); X509_STORE_free(store); return NULL; } return store; }
这种方法的好处是X509_STORE会自动管理证书的内存,不需要你手动维护栈的释放逻辑,适合后续要做证书链验证的场景。
内容的提问来源于stack exchange,提问作者Antoxyde
相关产品推荐
相关产品推荐

