我正在使用openssl(v.1.0.1k)编写库,以根据颁发者证书和撤销列表验证证书。我的第一步是验证CLR来自发行人。我已经验证证书和CLR是否已正确生成并使用以下命令行进行验证:
openssl crl -issuer -inform PEM -in root.crl.pem -noout -CAfile master_ca.crt
verify OK ...
然而!我无法使用X509_CRL_verify()将CRL验证工作。它始终报告:"期待:证书"
来自ERR_get_error()的输出:
140239350716336:error:0906D06C:lib(9):func(109):reason(108):pem_lib.c:703:Expecting: CERTIFICATE
140239350716336:error:0D0C50A1:lib(13):func(197):reason(161):a_verify.c:200:
我想知道它是否有问题,因为我的证书是一个受信任的"证书。我必须使用PEM_read_bio_x509_AUX()来加载证书而不是正常的PEM_read_bio_x509()。在验证可信证书之前,我还需要做些什么吗?
这是验证码:
int verifyCRL( X509_CRL* crl, EVP_PKEY* issuer )
{
int rv = 0;
if ( issuer != NULL )
{
if ( X509_CRL_verify( crl,issuer ) == 1 )
{
log_msg( 5, "CRL verify.. OK" );
rv = 1;
}
else
{
log_msg( 0, "CRL verify.. FAILED" );
print_ssl_errors();
}
}
这是发行人证书:
-----BEGIN TRUSTED CERTIFICATE-----
MIIDHjCCAoegAwIBAgIJAIEOyY6V3s6CMA0GCSqGSIb3DQEBDQUAMIGfMQswCQYD
VQQGEwJVUzELMAkGA1UECAwCVVQxFzAVBgNVBAcMDlBsZWFzYW50IEdyb3ZlMSUw
IwYDVQQKDBxNYXN0ZXIgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MRIwEAYDVQQLDAlN
YXN0ZXIgQ0ExETAPBgNVBAMMCHRlc3QuY29tMRwwGgYJKoZIhvcNAQkBFg1mcmVk
QHRlc3QuY29tMB4XDTE1MTIxMTIyNTU0MloXDTI1MTIwODIyNTU0MlowgZ8xCzAJ
BgNVBAYTAlVTMQswCQYDVQQIDAJVVDEXMBUGA1UEBwwOUGxlYXNhbnQgR3JvdmUx
JTAjBgNVBAoMHE1hc3RlciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxEjAQBgNVBAsM
CU1hc3RlciBDQTERMA8GA1UEAwwIdGVzdC5jb20xHDAaBgkqhkiG9w0BCQEWDWZy
ZWRAdGVzdC5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALWSHVFCRRSn
mvT8XZHa4kUjMBncZ9RGkoDNt6QgvtaQmEqmywvwMBMk4v1iXE9by/0JfMng0LU7
cBwIOYpUGO2pliPHbniY7sERTSB/JcViPtpPmtaKFob1+rUT0bXr0rQYdIeNPHAy
UySkxauUzGWJ4e6tSDPqPGEUR8SRufi5AgMBAAGjYDBeMAkGA1UdIwQCMAAwDAYD
VR0TBAUwAwEB/zALBgNVHQ8EBAMCAf4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cHM6
Ly9saWNlbnNpbmcudGVzdC5jb20vc2VydmVyLmNybDANBgkqhkiG9w0BAQ0FAAOB
gQBbtP+kUklffVQPyfofvYLp1K4U4YH7QRSMEc0BvFHSwulhv7kXOvHVYQIw/+fC
5LiCLSEpim2h2Lszx5oDcEIcPgDp/n2dhrCXJKIZ+cia/xXdobpm8vIHlb3cc4dh
3L+gn0ZzJm6kbkLOcYv1bVsXa+bKiWrR21TKiE5jTxy52w==
-----END TRUSTED CERTIFICATE-----
CRL:
-----BEGIN X509 CRL-----
MIIBjjCB+AIBATANBgkqhkiG9w0BAQ0FADCBnzELMAkGA1UEBhMCVVMxCzAJBgNV
BAgMAlVUMRcwFQYDVQQHDA5QbGVhc2FudCBHcm92ZTElMCMGA1UECgwcTWFzdGVy
IENlcnRpZmljYXRlIEF1dGhvcml0eTESMBAGA1UECwwJTWFzdGVyIENBMREwDwYD
VQQDDAh0ZXN0LmNvbTEcMBoGCSqGSIb3DQEJARYNZnJlZEB0ZXN0LmNvbRcNMTUx
MjExMjI1NTQyWhcNMTcxMjEwMjI1NTQyWjAUMBICAQIXDTE1MTIxMTIyNTU0Mlqg
DjAMMAoGA1UdFAQDAgECMA0GCSqGSIb3DQEBDQUAA4GBABu22UFiB1aW87egynsc
TZycZMgXUjXJhJq2825e274PX77pd00/yUYezom1X6HYuwRHTJj6/25QPm25lrXL
cy84aeLJgJMcKR79oHe0252Bo1y6a2VKgMet3/m58u2opNVOM4pPYh5FSPd2UgWw
//D3L6/+3wwQrDMj8kEbaJZi
-----END X509 CRL-----
OH,是的,我已经初始化了openssl堆栈:
SSL_load_error_strings();
SSL_library_init();libraries
OpenSSL_add_all_algorithms();
谢谢!
答案 0 :(得分:0)
经过几天的openssl代码挖掘后,我发现了一个似乎有效的答案。如果我将CA证书添加到x509商店,然后从X509_get_by_subject()中提取发行者,我可以获取公钥并使用它来验证CRL。以下是生成的“工作”代码:
int verifyCRL( X509_CRL* crl, X509* ca )
{
int rv = 0;
X509_STORE *store;
X509_STORE_CTX ctx;
X509_OBJECT xobj;
EVP_PKEY* pkey = NULL;
log_msg( 5, "Verifying CRL issuer" );
if ( issuer != NULL )
{
store = X509_STORE_new();
X509_STORE_add_crl(store, crl );
X509_STORE_add_cert(store, ca );
X509_STORE_CTX_init(&ctx, store, NULL, NULL);
// get the issuer
X509_STORE_get_by_subject(&ctx, X509_LU_X509, X509_CRL_get_issuer(crl), &xobj);
pkey = X509_get_pubkey(xobj.data.x509);
X509_OBJECT_free_contents(&xobj);
if ( pkey != NULL )
{
if ( X509_CRL_verify( crl,pkey ) == 1 )
{
log_msg( 0, "CRL verify OK" );
rv = 1;
}
else
{
log_msg( 0, "CRL verify issuer failed!" );
}
}
else
log_msg( 0, "Error, could not find CRL issuer public key" );
X509_STORE_CTX_cleanup(&ctx);
X509_STORE_free(store);
}
else
{
log_msg( 0, "Error! CRL issuer not provided" );
}
return rv;
}
我不确定为什么这是必要的,但它似乎提取了验证CRL签名所需的正确公钥。
答案 1 :(得分:0)
在验证证书之前,您应该OpenSSL_add_all_algorithms();
。这是我用不同方式验证证书的代码,第一种方法是使用从根证书获取的公钥,另一种是用根证书验证证书。
int CertificateChecker::X509_Verify(const unsigned char* certRoot, unsigned long rootCertLen, const unsigned char* cert , unsigned long certLen)
{
int ret = -1;
X509 *usrCert = NULL;
X509 *rootCert = NULL;
//rootCert = d2i_X509(NULL, (const unsigned char**)&certRoot, rootCertLen); //for cert with der format
BIO* bio = BIO_new_mem_buf((void*)certRoot, -1);
rootCert = PEM_read_bio_X509(bio, NULL, 0, NULL);
BIO_free(bio);
if( NULL == rootCert){
printf("root cert d2i_X509 failed\n");
return -1;
}
//usrCert = d2i_X509(NULL, (const unsigned char**)&cert,certLen);
bio = BIO_new_mem_buf((void*)cert, -1);
usrCert = PEM_read_bio_X509(bio, NULL, 0, NULL);
BIO_free(bio);
if(usrCert == NULL){
printf(" usr Cert d2i_X509 failed\n");
return -1;
}
OpenSSL_add_all_algorithms();
//start. verify the Certificate with public key.
EVP_PKEY * pubkey = X509_get_pubkey(rootCert);
//verify. result less than or 0 means not verified or some error.
ret = X509_verify(usrCert, pubkey);
//free the public key.
EVP_PKEY_free(pubkey);
//end. verify the Certification with public key.
//start. verify the Certificate with root certificate.
X509_STORE_CTX *ctx = NULL;
X509_STORE *certStore = NULL;
certStore = X509_STORE_new();
X509_STORE_add_cert(certStore, rootCert);
ctx = X509_STORE_CTX_new();
if (1 == X509_STORE_CTX_init(ctx,certStore,usrCert,NULL))
{
ret = X509_verify_cert(ctx);
long nCode = X509_STORE_CTX_get_error(ctx);
const char * pChError = X509_verify_cert_error_string(nCode);
printf("\r\n err info: %s \r\n", pChError);
}
X509_STORE_CTX_cleanup(ctx);
X509_STORE_CTX_free(ctx);
X509_STORE_free(certStore);
//end. verify the Certificate with root certificate.
X509_free(usrCert);
X509_free(rootCert);
return ret;
}