c++ - 使用 OpenSSL 将 CRL 号码扩展添加到 CRL
问题描述
对于某些客户端测试,我需要“即时”生成证书和吊销列表。我可以使用 OpenSSL 控制台命令和配置文件设置带有 CRL 号码扩展的吊销列表。但是我无法在代码中完成这项工作。
这是我的相关功能:
X509* g_certificate[MAX_CERTIFICATE_COUNT];
EVP_PKEY* g_certificateKeyPair[MAX_CERTIFICATE_COUNT];
X509_CRL* g_crl;
UINT16 GenerateCrl(UINT16 issuerCertificateIndex, UINT16 crlNumber, INT32 lastUpdate, INT32 nextUpdate)
{
ASN1_TIME* lastUpdateTime = ASN1_TIME_new();
ASN1_TIME* nextUpdateTime = ASN1_TIME_new();
char crlNumberString[32];
int result = 1;
if (g_crl != NULL) X509_CRL_free(g_crl);
g_crl = X509_CRL_new();
result &= X509_CRL_set_version(g_crl, 1);
result &= X509_CRL_set_issuer_name(g_crl, X509_get_subject_name(g_certificate[issuerCertificateIndex]));
// there are multiple X509 certificate objects stored in memory, which I use to setup certificate chains
ASN1_TIME_set(lastUpdateTime, time(NULL) + lastUpdate);
ASN1_TIME_set(nextUpdateTime, time(NULL) + nextUpdate);
result &= X509_CRL_set1_lastUpdate(g_crl, lastUpdateTime);
result &= X509_CRL_set1_nextUpdate(g_crl, nextUpdateTime);
ASN1_TIME_free(lastUpdateTime);
ASN1_TIME_free(nextUpdateTime);
_itoa_s((int)crlNumber, crlNumberString, 10);
// my CRLs need to have the authority key identifier and CRL number extensions
result &= SetCrlExtension(issuerCertificateIndex, NID_authority_key_identifier, "keyid:always"); // this does add the auth key id extension
result &= SetCrlExtension(issuerCertificateIndex, NID_crl_number, crlNumberString); // this does not add CRL number the extension
result &= X509_CRL_sign(g_crl, g_certificateKeyPair[issuerCertificateIndex], EVP_sha256());
return result;
}
INT16 SetCrlExtension(UINT16 issuerCertificateIndex, INT16 extensionNid, const char* extensionData)
{
X509V3_CTX ctx;
X509_EXTENSION* extension;
lhash_st_CONF_VALUE conf; // actually I have no idea what this is for, probably it is not required here
int result = 1;
X509V3_set_ctx(&ctx, g_certificate[issuerCertificateIndex], NULL, NULL, g_crl, 0);
extension = X509V3_EXT_conf_nid(&conf, &ctx, extensionNid, (char*)extensionData);
result &= X509_CRL_add_ext(g_crl, extension, -1);
return result;
}
void SaveCrlAsPem(const char* fileName)
{
FILE* f;
fopen_s(&f, fileName, "wb");
PEM_write_X509_CRL(f, g_crl);
if (f != NULL) fclose(f);
}
所以例如
GenerateCrl(1, 1234, -3600, 36000);
SaveCrlAsPem("crl.pem");
应该导致具有所述扩展名的 CRL。但它只包含授权密钥标识符扩展。其他一切都很好。我也以基本相同的方式添加证书扩展,并且没有任何问题。
那么如何获得附加到我的 CRL 的 CRL 编号?
解决方案
您提到您可以CRL number
从 OpenSSL 命令行设置扩展。那么您可能应该查看特定命令的源代码。
我没有使用 CRL,但我相信您正在使用该ca
命令。NID_crl_number
在其源代码中寻找apps/ca.c
(来自 OpenSSL 1.1.1g)显示以下代码:
/* Add any extensions asked for */
if (crl_ext != NULL || crlnumberfile != NULL) {
X509V3_CTX crlctx;
X509V3_set_ctx(&crlctx, x509, NULL, NULL, crl, 0);
X509V3_set_nconf(&crlctx, conf);
if (crl_ext != NULL)
if (!X509V3_EXT_CRL_add_nconf(conf, &crlctx, crl_ext, crl))
goto end;
if (crlnumberfile != NULL) {
tmpser = BN_to_ASN1_INTEGER(crlnumber, NULL);
if (!tmpser)
goto end;
X509_CRL_add1_ext_i2d(crl, NID_crl_number, tmpser, 0, 0);
ASN1_INTEGER_free(tmpser);
crl_v2 = 1;
if (!BN_add_word(crlnumber, 1))
goto end;
}
}
所以,看来你可以使用X509V3_EXT_CRL_add_nconf
orX509_CRL_add1_ext_i2d
来达到目的。请参考apps/ca.c
您使用的 OpenSSL 版本。
另一种解决方案:也许不是最好的方法,但是如果可以接受,您可能可以从代码启动与进程相同的 OpenSSL 命令并处理它们的输出。
推荐阅读
- php - SQL add sub-index column on query?
- c++ - How to store a list in a map in c++?
- php - 有没有办法将 wordpress 连接与 mysql 工作台远程数据库连接连接起来?
- ruby-on-rails - 在 ActiveRecord 集合中包含关联模型的属性
- java - LRU java, java.lang.IndexOutOfBoundsException
- c# - 是否可以从 Azure 托管的应用程序访问本地 AD 实例?
- python - Selecting a random value in a pandas data frame by column
- c# - C# MongoDB InsertBatch 丢失
- azure - azure-functions-core-tools on Mac OS
- php - Nested mysql while loop not returning expected results