2010-09-28 18 views
10

Ho un server che ascolta su HTTPS utilizzando OpenSSL. Per questo, devo fornire il certificato da utilizzare. Tuttavia, l'implementazione corrente utilizza un nome file da fornire all'API OpenSSL.Leggere i file dei certificati dalla memoria anziché da un file utilizzando OpenSSL

Desidero che le informazioni del certificato vengano lette dalla memoria, in modo da non dover spedire l'apertura del file del certificato. Ho provato a google, ma non ho trovato nessuna opzione.

È possibile? In tal caso, come faccio a leggere i file dei certificati dalla memoria anziché da un file utilizzando OpenSSL?


EDIT: Il seguente è stato spostato dai commenti alla domanda.

// CURRENT 
void start_server() 
{ 
    const char *fileName = "cert_and_key.pem"; 
    set_server_ssl_file(fileName); 
} 
set_server_ssl_file(const char *fileName) 
{ 
    //initialize context 
    SSL_CTX_use_certificate_file(CTX, pem, SSL_FILETYPE_PEM); 
    SSL_CTX_use_PrivateKey_file(CTX, pem, SSL_FILETYPE_PEM); 
} 

//REQUIRED 
void start_server() 
{ 
    const char *cert = "--BEGIN CERTIFICATE--............"; 
    const char *key = "--BEGIN RSA PRIVATE KEY--......."; 
    set_server_ssl_options(cert, key); 
} 
set_server_ssl_options(const char *cert, const char *key) 
{ 
    //IMPLEMENTATION REQUIRED 
} 
+0

"Voglio che le informazioni del certificato vengano lette dalla memoria, in modo da non dover spedire il file del certificato aperto" - Puoi chiarire questo? Non sei sicuro di cosa intendi qui. Dove sarebbe il codice ottenere il certificato in primo luogo? –

+0

Ho i file del certificato con me ora. Il server deve usarli. La pratica normale è quella di fornire OpenSSL con il nome file del file del certificato. OpenSSL si prenderà cura delle restanti cose internamente. Ma non posso spedire direttamente i file del certificato. Dovrei codificarli nel codice sorgente. Questo è il requisito. Quindi, stavo osservando le opzioni in cui ho il certificato in un buffer di memoria e in qualche modo rendere OpenSSL utilizzare le informazioni del certificato. – Karthik

+0

Puoi specificare cosa stai facendo con un codice di esempio? I contesti SSL certificati possono essere creati dalla memoria, ma sarebbe utile se fosse possibile condividere ciò che si desidera ottenere con un certo codice. –

risposta

4
unsigned char *cert_data = (....); 
int cert_len = (....); 

X509 *cert = d2i_X509(NULL, &cert_data, cert_len); 
SSL_CTX_use_certificate(ctx, cert); 

unsigned char *pkey_data = /* ... */; 
int pkey_len = /* ... */; 

RSA *pkey = d2i_RSAPrivateKey(NULL, &pkey_data, pkey_len); 
SSL_CTX_use_RSAPrivateKey(ctx, pkey); 

Non dimenticare & prima cert_data e pkey_data - e si noti che OpenSSL modifica questi puntatori.

11

Il seguente codice ha fatto il lavoro per me:


SSL_CTX *CTX; 
X509 *cert = NULL; 
RSA *rsa = NULL; 
BIO *cbio, *kbio; 
const char *cert_buffer = ""; 
const char *key_buffer = ""; 

cbio = BIO_new_mem_buf((void*)cert_buffer, -1); 
cert = PEM_read_bio_X509(cbio, NULL, 0, NULL); 
assert(cert != NULL); 
SSL_CTX_use_certificate(CTX, cert); 

kbio = BIO_new_mem_buf((void*)key_buffer, -1); 
rsa = PEM_read_bio_RSAPrivateKey(kbio, NULL, 0, NULL); 
assert(rsa != NULL); 
SSL_CTX_use_RSAPrivateKey(CTX, rsa); 
+1

Non dimenticare di liberare i buffer assegnati di conseguenza. – anselm

4

Gli altri frammenti caricheranno un solo certificato. Il contenuto di file come http://curl.haxx.se/ca/cacert.pem contenenti molti certificati diversi richiede un nuovo approccio. Questo è adattato da openssl 1.0.1p (principalmente openssl-1.0.1p \ crypto \ x509 \ by_file.c, char * buf contiene il contenuto di un file * .pem, ctx è un boost :: asio :: ssl :: context), aggiungi la gestione degli errori da solo:

BIO *cbio = BIO_new_mem_buf((void*)buf, (int)length); 
X509_STORE *cts = SSL_CTX_get_cert_store(ctx.native_handle()); 
if(!cts || !cbio) 
    return false; 
X509_INFO *itmp; 
int i, count = 0, type = X509_FILETYPE_PEM; 
STACK_OF(X509_INFO) *inf = PEM_X509_INFO_read_bio(cbio, NULL, NULL, NULL); 

if (!inf) 
{ 
    BIO_free(cbio);//cleanup 
    return false; 
} 
//itterate over all entries from the pem file, add them to the x509_store one by one 
for (i = 0; i < sk_X509_INFO_num(inf); i++) { 
    itmp = sk_X509_INFO_value(inf, i); 
    if (itmp->x509) { 
      X509_STORE_add_cert(cts, itmp->x509); 
      count++; 
    } 
    if (itmp->crl) { 
      X509_STORE_add_crl(cts, itmp->crl); 
      count++; 
    } 
} 
sk_X509_INFO_pop_free(inf, X509_INFO_free); //cleanup 
BIO_free(cbio);//cleanup 
+0

Grazie mille @ oliver-zendel ha fatto perfettamente il lavoro :) Tuttavia, ho ricevuto un errore più tardi, quindi ho spostato la riga "BIO_free (cbio);" alla fine. Ho usato il tuo codice in una callback CURLOPT_SSL_CTX_FUNCTION in arricciatura per leggere un file PEM con 2 certificati. – Kervala

+0

Grazie Kervala, ho cambiato lo snippet di codice per essere sicuro;) –

+0

Prego :) – Kervala

Problemi correlati