/CRLCertVerify.cpp Secret
Last active
June 20, 2017 08:56
Simple class to verify certificate chain with CRLs using openssl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <CRLCertVerify.h> | |
#define LOG_SSL_WARNING(custommsg) \ | |
ERR_load_crypto_strings(); \ | |
unsigned long errQueue = 0; \ | |
stringstream error; \ | |
error << custommsg; \ | |
while ((errQueue = ERR_get_error())) \ | |
error << " - " << ERR_reason_error_string(errQueue)<<"["<<errQueue<<"]"; \ | |
cout << error.str(); | |
CertificateStore::CertificateStore() | |
{ | |
//create store and store ctx | |
_store = X509_STORE_new(); | |
_storeCtx = X509_STORE_CTX_new(); | |
} | |
CertificateStore::~CertificateStore() | |
{ | |
X509_STORE_free(_store); | |
X509_STORE_CTX_free(_storeCtx); | |
} | |
void CertificateStore::setCRLVerificationFlag(bool crlCheckAll) | |
{ | |
//verify complete chain or only one certificate | |
X509_STORE_set_flags(_store, crlCheckAll ? (X509_V_FLAG_CRL_CHECK_ALL | X509_V_FLAG_CRL_CHECK) : X509_V_FLAG_CRL_CHECK); | |
} | |
void CertificateStore::addLookupHashDir(const char* path) | |
{ | |
/*Adding CRL directory for lookup. During CRL verify, openssl will check for CRLs from this path. | |
CRL files should be present in this dir as <issuer_hash>.rN | |
More details : https://www.openssl.org/docs/man1.1.0/crypto/X509_LOOKUP_file.html | |
If you have specic CRL files to add you can loaded them using "X509_load_crl_file" API as well*/ | |
X509_LOOKUP* lookup = X509_STORE_add_lookup(_store, X509_LOOKUP_hash_dir()); | |
if (lookup == NULL) | |
{ | |
cout << "CRL path initialization error: X509 lookup initialization failed."; | |
throw CRL_LOOKUP_FAILURE; | |
} | |
if(not X509_LOOKUP_add_dir(lookup, path, X509_FILETYPE_PEM)) | |
{ | |
cout << "CRL path initialization error: path addition failed."; | |
throw CRL_LOOKUP_FAILURE; | |
} | |
} | |
void CertificateStore::addCertToStore(X509* cert) | |
{ | |
/*Add certificate to the store*/ | |
if (not X509_STORE_add_cert(_store, cert)) | |
{ | |
LOG_SSL_WARNING("Failed to add certificate to store."); | |
throw OPERATION_FAILED; | |
} | |
} | |
int CertificateStore::verifyCert(X509* cert, string& msg) | |
{ | |
/*Initialize store_ctx with global store, add the last EE certificate to the store ctx. | |
NOTE: store ctx cab be used only once to verify chain. */ | |
X509_STORE_CTX_init(_storeCtx, _store, NULL, NULL); | |
X509_STORE_CTX_set_cert(_storeCtx, cert); | |
X509_verify_cert(_storeCtx); | |
int sslRet = X509_STORE_CTX_get_error(_storeCtx); | |
if (sslRet != X509_V_OK) | |
{ | |
const char* err = X509_verify_cert_error_string(sslRet); | |
if (err) | |
msg = string(err); | |
} | |
return sslRet; | |
} | |
X509* CertificateStore::getCurrentCertDetails(long& serialNum, string& issuer) | |
{ | |
/*get the certificate details for which verify failed*/ | |
X509* cert = X509_STORE_CTX_get_current_cert(_storeCtx); | |
serialNum = ASN1_INTEGER_get(X509_get_serialNumber(cert)); | |
char* issuerId = X509_NAME_oneline(X509_get_issuer_name(cert), NULL, 0); | |
if (issuerId) | |
issuer = string(issuerId); | |
return cert; | |
} | |
int main() | |
{ | |
string msg; | |
X509* rca_cert = NULL; | |
X509* ica_cert = NULL; | |
X509* ee = NULL; | |
CertificateStore store; | |
store.setCRLVerificationFlag(true); | |
store.addLookupHashDir("/path/to/crls"); | |
//get certificates in X509* format and add them to trusted store. | |
store.addCertToStore(rca_cert); | |
store.addCertToStore(ica_cert); | |
//verify the required certificate. if required ica_cert can also be verified using below. | |
//BUt it may not be required indeed, as we verify whole chain. | |
int ret = store.verifyCert(ee, msg); | |
if (ret == X509_V_ERR_CERT_REVOKED) | |
{ | |
long sr; | |
string issuer; | |
store.getCurrentCertDetails(sr, issuer); | |
cout << "Certificate " << std::hex << sr << " issued by "<<issuer<<" is revoked". | |
} | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <openssl/pem.h> | |
#include <openssl/x509.h> | |
#include <openssl/asn1.h> | |
#include <openssl/err.h> | |
class CertificateStore | |
{ | |
public: | |
CertificateStore(); | |
~CertificateStore(); | |
void setCRLVerificationFlag(bool crlCheckAll); | |
void addLookupHashDir(const char* path); | |
void addCertToStore(X509* cert); | |
int verifyCert(X509* cert, string& msg); | |
X509* getCurrentCertDetails(long& serialNum, string& issuer); | |
private: | |
X509_STORE* _store; | |
X509_STORE_CTX *_storeCtx; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment