2010-09-28 6 views
10

Mam serwer, który będzie nasłuchiwał na HTTPS przy użyciu OpenSSL. W tym celu muszę dostarczyć certyfikat do użycia. Jednak obecna implementacja wykorzystuje nazwę pliku do dostarczenia do OpenSSL API.Odczytaj pliki certyfikatów z pamięci zamiast z pliku przy użyciu OpenSSL

Chcę, aby informacje o certyfikatach były odczytywane z pamięci, tak aby nie musiałem wysyłać otwarcia pliku certyfikatu. Próbowałem google, ale nie wymyśliłem żadnych opcji.

Czy jest to możliwe? Jeśli tak, jak mogę odczytać pliki certyfikatów z pamięci zamiast z pliku przy użyciu OpenSSL?


EDIT: Następujący tekst został przeniesiony z uwagi na to pytanie.

// 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

"Chcę, aby informacje o certy były odczytywane z pamięci, tak, że nie muszę wysyłać otwarcia pliku certyfikatu" - Czy możesz to wyjaśnić? Nie jestem pewien, co masz na myśli. Gdzie kod otrzymywałby certyfikat w pierwszej kolejności? –

+0

Mam teraz pliki certyfikatów ze mną. Serwer musi z nich korzystać. Normalną praktyką jest udostępnienie OpenSSL nazwy pliku certyfikatu. OpenSSL zajmie się resztą rzeczy wewnętrznie. Ale nie mogę wysyłać plików certyfikatów bezpośrednio. Mógłbym MNIE mocno zakodować je w kodzie źródłowym. To jest wymaganie. Tak więc, przyglądałem się opcjom, w których mam certyfikat w buforze pamięci i w jakiś sposób sprawić, że OpenSSL używa tych informacji o certyfikacie. – Karthik

+0

Czy możesz podać, co robisz z przykładowym kodem? Konteksty SSL certyfikatu można tworzyć z pamięci, ale byłoby to pomocne, gdybyś mógł po prostu udostępnić to, co chcesz osiągnąć za pomocą jakiegoś kodu. –

Odpowiedz

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); 

Nie zapomnij & przed cert_data i pkey_data - i zauważ, że OpenSSL modyfikuje te wskaźniki.

11

Poniższy kod nie praca dla mnie:


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

Nie należy zapominać o zwolnieniu przydzielonych buforów odpowiednio. – anselm

4

Pozostałe fragmenty będzie ładować tylko jeden certyfikat. Zawartość plików takich jak http://curl.haxx.se/ca/cacert.pem, które zawierają wiele różnych certyfikatów, wymaga nowego podejścia. Jest to dostosowane z openssl 1.0.1p (przeważnie openssl-1.0.1p \ crypto \ x509 \ by_file.c, char * buf zawiera treść pliku * .pem, ctx to boost :: asio :: ssl :: context), dodaj obsługę błędów na własną rękę:

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

Bardzo dziękuję @ oliver-zendel to doskonale wykonało zadanie :) Jednak później otrzymałem błąd, więc przeniosłem linię "BIO_free (cbio);" na końcu. Użyłem twojego kodu w wywołaniu zwrotnym CURLOPT_SSL_CTX_FUNCTION w curl, aby odczytać plik PEM z 2 certyfikatami. – Kervala

+0

Dzięki Kervala, zmieniłem fragment kodu, aby się upewnić;) –

+0

Nie ma za co :) – Kervala

Powiązane problemy