2010-05-03 10 views
6

Ich habe Zertifikate im DER- und PEM-Format. Mein Ziel ist es, die Felder Aussteller und Subjekt abzurufen und das Zertifikat mit dem öffentlichen Schlüssel CA zu überprüfen und gleichzeitig CA-Zertifikat mit dem öffentlichen Schlüssel zu verifizieren. Ich kann alle Details von Aussteller und Betreff abrufen, aber das Zertifikat nicht überprüfen.
Die API verwendet:x509 Zertifikatsverifizierung in C

x509 = d2i_X509_fp (fp, &x509); //READING DER Format 
x509 = PEM_read_X509 (fp, &x509, NULL, NULL); //READING PEM Format 
//to retrieve the Subject: 
X509_NAME_oneline(X509_get_subject_name(x509), subject, sizeof (subject)); 
//to retrieve the Issuer: 
X509_NAME_oneline(X509_get_issuer_name(x509), issuer, sizeof (issuer)); 

//To store the CA public key (in unsigned char *key) that will be used to verify the 
//certificate (in my case always sha1WithRSAEncryption): 
RSA *x = X509_get_pubkey(x509)->pkey.rsa; 
bn = x->n; 
//extracts the bytes from public key & convert into unsigned char buffer 
buf_len = (size_t) BN_num_bytes (bn); 
stored_CA_pubKey = (unsigned char *)malloc (buf_len); 
i_n = BN_bn2bin (bn, (unsigned char *)stored_CA_pubKey); 
if (i_n != buf_len) 
    LOG(ERROR," : key error\n"); 
if (key[0] & 0x80) 
    LOG(DEBUG, "00\n"); 

stored_CA_pubKeyLen = EVP_PKEY_size(X509_get_pubkey(x509)); 

Für Überprüfung ging ich durch verschiedene Ansätze, aber ich bin nicht in der Lage zu überprüfen:

a)

i_x509_verify = X509_verify(cert_x509, ca_pubkey); 

b)

/* verify the signature */ 
int iRet1, iRet2, iReason; 
iRet1 = EVP_VerifyInit(&md_ctx, EVP_sha1()); 
iRet2 = EVP_VerifyUpdate(&md_ctx, cert_code, cert_code_len); 
rv = EVP_VerifyFinal(&md_ctx, (const unsigned char *)stored_CA_pubKey, 
    stored_CA_pubKeyLen, cert_pubkey); 

HINWEIS : cert_code und stored_CA_pubKey sind vorzeichenlose Zeichenpuffer.

Antwort

11

Ich verwende folgenden Code für die Überprüfung eines Zertifikats

init certstore:

X509_STORE* m_store = X509_STORE_new(); 
X509_LOOKUP* m_lookup = X509_STORE_add_lookup(m_store,X509_LOOKUP_file());  
X509_STORE_load_locations(m_store, "CAFile.pem", NULL); 
X509_STORE_set_default_paths(m_store); 
X509_LOOKUP_load_file(m_lookup,"CAFile.pem",X509_FILETYPE_PEM) 
// alternative lookup by hashdir 
// X509_LOOKUP* m_lookup=X509_STORE_add_lookup(m_store,X509_LOOKUP_hash_dir()); 

VerifyCert:

X509_STORE_CTX *storeCtx = X509_STORE_CTX_new(); 
X509_STORE_CTX_init(storeCtx,m_store,cert,NULL); 
X509_STORE_CTX_set_flags(storeCtx, X509_V_FLAG_CB_ISSUER_CHECK); 
if (X509_verify_cert(storeCtx) == 1) 
{ 
    printf("success"); 
} 
else 
{ 
    printf("Verificatione rror: %s",X509_verify_cert_error_string(storeCtx->error)); 
} 
X509_STORE_CTX_free(storeCtx); 

Sie auch zur Reinigung benötigen m_store

if(m_store != NULL) 
{ 
    X509_STORE_free(m_store); 
    m_store = NULL; 
} 
+0

in init cert store 2 Zeile llookup wird verwendet, aber in der 5. Zeile deklariert ... wie funktioniert dieser Code ..? Bitte geben Sie den vollständigen Code – Balamurugan

+0

thx Balamurugan, kopierte ich nur die relevanten Teile des Codes, wäre der vollständige Code zu komplex. :) Die zweite Init der Suche ist eine Alternative, wo die CA-Dateien in einem Hash-Verzeichnis gespeichert sind. – pHagi

+0

Sie sollten 'X509_STORE_CTX_get_error (storeCtx)' anstelle von 'storeCtx-> error'; Letzteres ist aufgrund von ABI-Änderungen fragiler. –

0
X509_STORE* m_store = NULL; 

X509_LOOKUP *m_lookup = NULL; 
X509_STORE_CTX *storeCtx = NULL; 
m_store = X509_STORE_new(); 
if(NULL == m_store) goto exit; 
m_lookup = X509_STORE_add_lookup(m_store, X509_LOOKUP_file()); 
if(NULL == m_lookup) goto exit; 
X509_STORE_load_locations(m_store, CA_CERT_PATH, NULL); 
X509_STORE_set_default_paths(m_store); 
X509_LOOKUP_load_file(m_lookup,CA_CERT_PATH, X509_FILETYPE_ASN1); 
m_lookup = X509_STORE_add_lookup(m_store, X509_LOOKUP_hash_dir()); 
if(NULL == m_lookup) goto exit; 
storeCtx = X509_STORE_CTX_new(); 
if(NULL == storeCtx) goto exit; 
X509_STORE_CTX_init(storeCtx,m_store,cer_x509,NULL); 
X509_STORE_CTX_set_flags(storeCtx, /*X509_V_FLAG_CHECK_SS_SIGNATURE*/0x4000); 
if (X509_verify_cert(storeCtx) == 1) 
{ 
printf("success\n"); 
} 
else 
{ 
printf("Verification error: %s\n",X509_verify_cert_error_string(storeCtx->error)); 
} 
exit: 
    if(NULL != storeCtx) X509_STORE_CTX_free(storeCtx); 
    if(m_store != NULL) 
    { 
     X509_STORE_free(m_store); 
     m_store = NULL; 
    } 

Danach mache ich auch bin ich nicht in der Lage Selbst Zertifikat

Verwandte Themen