背景
我需要以编程方式验证x509证书中的extendedKeyUsage
。我的目标是确保TLS Web Server Authentication, TLS Web Client Authentication
中仅存在extendedKeyUsage
。我在MacOS上使用OpenSSL 1.0.2p
lib。
以下是我用于检索extendedKeyUsage字段的代码:
#include <openssl/x509v3.h>
#include <openssl/bn.h>
#include <openssl/asn1.h>
#include <openssl/x509.h>
#include <openssl/x509_vfy.h>
#include <openssl/pem.h>
#include <openssl/bio.h>
int verifyDeviceCertExtendedKeyUsage(){
OpenSSL_add_all_algorithms();
auto readBytes = MyApp::FileUtil::readAllBytes("path/to/pem");
BIO *bio_mem = BIO_new(BIO_s_mem());
BIO_puts(bio_mem, readBytes.data());
X509 *x509 = PEM_read_bio_X509(bio_mem, NULL, NULL, NULL);
ASN1_BIT_STRING *usage = static_cast<ASN1_BIT_STRING*>(X509_get_ext_d2i(x509, NID_ext_key_usage, NULL, NULL));
if (usage && (usage->length > 0)){
_CERTUTIL_LOG->debug("in verifyDeviceCertExtendedKeyUsage, usage->data[0]: {0:x}", (int)usage->data[0]);
}
}
此外,摘录自openssl x509 -text -noout -in path/to/pem
的输出:
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
问题
每次我运行代码时,usage->data[0]
的值都不同,这表明我的代码正在引起未定义的行为。
注意:我使用类似的代码通过将keyUsage
中的NID_ext_key_usage
替换为NID_key_usage
来成功检索X509_get_ext_d2i()
字段。
如果我的代码返回了正确的值,我将通过与openssl/x509v3.h
中的以下内容进行比较来验证它:
# define XKU_SSL_SERVER 0x1
# define XKU_SSL_CLIENT 0x2
问题
我的代码有问题吗?
如何可靠地获取extendedKeyUsage
字段并进行验证?
更新
我找到了一种方法,但是让我比较字符串不方便:
BIO *bio_mem = BIO_new(BIO_s_mem());
BIO_puts(bio_mem, readBytes.data());
X509 *x509 = PEM_read_bio_X509(bio_mem, NULL, NULL, NULL);
auto extIndex = X509_get_ext_by_NID(x509, NID_ext_key_usage, -1);
if(extIndex < 0){
BIO_free(bio_mem);
X509_free(x509);
return ERR;
}
X509_EXTENSION *ext = X509_get_ext(x509, extIndex);
EXTENDED_KEY_USAGE *eku = static_cast<EXTENDED_KEY_USAGE*>(X509V3_EXT_d2i(ext));
for(int i = 0 ; i < sk_ASN1_OBJECT_num(eku) ; i++){
char buffer[100] = {0}; // <--- init all elements with 0, compiler specific behavior?
OBJ_obj2txt(buffer, sizeof(buffer), sk_ASN1_OBJECT_value(eku, i), 1);
if(strcmp(buffer, "1.3.6.1.5.5.7.3.1") == 0 && strcmp(buffer, "1.3.6.1.5.5.7.3.1") == 0){
BIO_free(bio_mem);
X509_free(x509);
return SUCCESS;
}
}
答案 0 :(得分:0)
在openssl 1.1中,一旦有了X509指针,就很容易。您只需要使用以下方法:X509_get_extension_flags和X509_get_extended_key_usage
if ((X509_get_extension_flags(x509) & EXFLAG_XKUSAGE) == EXFLAG_XKUSAGE)
{
auto const certificate_key_usage = X509_get_extended_key_usage(x509);
if ((certificate_key_usage & (XKU_SSL_SERVER | XKU_SSL_CLIENT)) == (XKU_SSL_SERVER | XKU_SSL_CLIENT))
{
// has both TLS Web Server Authentication and TLS Web Client Authentication
}
else
{
// doesn't have both TLS Web Server Authentication and TLS Web Client Authentication
}
}
对于旧版的openssl,您应该能够定义以下内容才能使上述代码正常工作:
#if OPENSSL_VERSION_NUMBER < 0x10100000L
#define X509_get_extension_flags(x) (x->ex_flags)
#define X509_get_extended_key_usage(x) (x->ex_xkusage)
#endif