2010-09-28 33 views
10

Tôi có một máy chủ sẽ nghe trên HTTPS bằng OpenSSL. Đối với điều này, tôi phải cung cấp chứng chỉ để sử dụng. Tuy nhiên, việc triển khai hiện tại sử dụng tên tệp được cung cấp cho API OpenSSL.Đọc các tệp chứng chỉ từ bộ nhớ thay vì tệp bằng OpenSSL

Tôi muốn thông tin chứng chỉ được đọc từ bộ nhớ, để tôi không phải gửi mở tệp chứng chỉ. Tôi đã cố gắng để google, nhưng tôi đã không đưa ra bất kỳ tùy chọn.

Có thể không? Nếu vậy, làm cách nào để đọc tệp chứng chỉ từ bộ nhớ thay vì tệp bằng OpenSSL?


EDIT: Sau đây đã được chuyển từ các ý kiến ​​cho câu hỏi.

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

"Tôi muốn thông tin xác thực được đọc từ bộ nhớ, để tôi không phải gửi mở chứng chỉ" - Bạn có thể làm rõ điều này không? Không chắc chắn những gì bạn có ý nghĩa ở đây. Mã nào sẽ nhận được chứng nhận ngay từ đầu? –

+0

Tôi có các tệp chứng chỉ với tôi ngay bây giờ. Máy chủ phải sử dụng chúng. Thực hành thông thường là cung cấp OpenSSL với tên tệp của tệp chứng chỉ. OpenSSL sẽ chăm sóc những thứ còn lại trong nội bộ. Nhưng tôi không thể gửi trực tiếp các tập tin chứng chỉ. Tôi sẽ CÓ để mã cứng chúng vào mã nguồn. Đó là yêu cầu. Vì vậy, đã xem xét các tùy chọn mà tôi có chứng chỉ trong bộ nhớ đệm và bằng cách nào đó làm cho OpenSSL sử dụng thông tin chứng chỉ đó. – Karthik

+0

Bạn có thể vui lòng chỉ định những gì bạn đang làm với một số mã mẫu không? Các ngữ cảnh SSL của chứng chỉ có thể được tạo ra từ bộ nhớ nhưng nó sẽ hữu ích nếu bạn chỉ có thể chia sẻ những gì bạn muốn đạt được với một số mã. –

Trả lời

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

Đừng quên & trước cert_datapkey_data - và lưu ý rằng OpenSSL sẽ thay đổi những con trỏ.

11

Các mã sau đây đã làm công việc cho tôi:


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

Bạn không nên quên giải phóng bộ đệm được phân bổ cho phù hợp. – anselm

4

Các đoạn khác sẽ chỉ tải một giấy chứng nhận. Nội dung của các tệp như http://curl.haxx.se/ca/cacert.pem chứa nhiều chứng chỉ khác nhau cần có cách tiếp cận mới. Điều này được điều chỉnh từ openssl 1.0.1p (chủ yếu là openssl-1.0.1p \ crypto \ x509 \ by_file.c, char * buf chứa nội dung của tệp * .pem, ctx là một tăng :: asio :: ssl :: context), thêm lỗi xử lý của riêng bạn:

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

Cảm ơn bạn rất nhiều @ oliver-zendel nó hoàn toàn đã làm công việc :) Tuy nhiên, tôi nhận được một lỗi sau đó, vì vậy tôi di chuyển dòng "BIO_free (cbio);" cuối cùng. Tôi đã sử dụng mã của bạn trong một CURLOPT_SSL_CTX_FUNCTION gọi lại trong curl để đọc tệp PEM với 2 chứng chỉ. – Kervala

+0

Cảm ơn Kervala, tôi đã thay đổi đoạn mã để chắc chắn;) –

+0

Bạn được chào đón :) – Kervala

Các vấn đề liên quan