2010-02-13 95 views
9

Tôi đang viết một chương trình nhỏ với thư viện OpenSSL giả sử thiết lập kết nối với máy chủ SSLv3. Máy chủ này phân phối chứng chỉ tự ký, điều này khiến cho việc bắt tay thất bại với thông báo này: "lỗi bắt tay cảnh báo sslv3, chứng chỉ tự ký trong chuỗi chứng chỉ".OpenSSL Bỏ qua lỗi chứng chỉ tự ký

Có cách nào tôi có thể buộc kết nối tiếp tục không? Tôi đã thử gọi SSL_CTX_set_verify như sau:

SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL); 

Nhưng dường như nó không thay đổi gì cả.

Mọi đề xuất?

+0

'SSL_VERIFY_NONE' vô hiệu hóa xác minh giấy chứng nhận hoàn toàn. Bạn có thể không muốn làm điều này vì điều này khiến bạn dễ bị tấn công MITM. Điều đúng đắn cần làm là thêm chứng chỉ tự ký vào danh sách chứng chỉ đáng tin cậy. (Xem SSL_CTX_load_verify_locations().) –

+0

Nhân tiện, thông báo lỗi không có nghĩa là chứng chỉ của máy chủ được tự ký. Điều đó có nghĩa là bạn không tin tưởng chứng chỉ của CA gốc: ** X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN ​​** _A chứng chỉ tự ký tồn tại trong chuỗi chứng chỉ. Chuỗi chứng chỉ có thể được tạo bằng các chứng chỉ không đáng tin cậy, nhưng không thể tìm thấy CA gốc tại địa phương._ Chứng chỉ CA gốc luôn được ký tự. –

Trả lời

4

Theo mặc định OpenSSL đi chuỗi chứng chỉ và cố gắng xác minh trên mỗi bước, SSL_set_verify() không thay đổi điều đó, xem tha người đàn ông trang. Trích dẫn nó:

Thủ tục xác minh thực tế được thực hiện bằng cách sử dụng một trong hai built-in thủ tục xác minh hoặc sử dụng một ứng dụng khác cung cấp chức năng xác minh thiết lập với SSL_CTX_set_cert_verify_callback (3).

Vì vậy, giải pháp là tạo ra một callback đơn giản và thiết lập một đó, để bạn ghi đè tất cả các giấy chứng nhận chuỗi đi bộ:

static int always_true_callback(X509_STORE_CTX *ctx, void *arg) 
{ 
    return 1; 
} 

SSL_CTX_set_cert_verify_callback(CTX, always_true_callback); 
+2

Chỉ một vài đoạn văn bên dưới văn bản được trích dẫn: 'Nếu không xác định được xác thực, thì gọi lại mặc định sẽ được sử dụng. Giá trị trả về của nó giống hệt preverify_ok, do đó bất kỳ lỗi xác minh nào sẽ dẫn đến việc chấm dứt việc bắt tay TLS/SSL với thông báo cảnh báo, nếu SSL_VERIFY_PEER được đặt.' Câu trả lời của bạn không chính xác, đặt chế độ xác minh thành SSL_VERIFY_NONE là đủ . – Spidey

+1

@Spidey Bạn đã đọc câu hỏi chưa? Nó cho rằng SSL_VERIFY_NONE là * không * đủ. Bạn đã thử nó? FYI hướng dẫn bạn trích dẫn là dành cho 'SSL_CTX_set_verify()'. Nhưng xác minh có thể thất bại là nhiều cách khác ngay cả khi cuộc gọi * set_verify * luôn thành công, đó là lý do tại sao bạn phải đặt lại gọi lại chung chung hơn với 'SSL_CTX_set_cert_verify_callback()'. – jimis

+0

Luôn trả lại '1' sẽ tắt hoàn toàn xác minh chứng chỉ. Điều này giống như thiết lập 'SSL_VERIFY_NONE'. (nghĩa là @Spidey là đúng.) Bạn có thể không muốn làm điều này vì điều này khiến bạn dễ bị tấn công MITM. Điều đúng đắn cần làm là thêm chứng chỉ tự ký vào danh sách chứng chỉ đáng tin cậy. (Xem SSL_CTX_load_verify_locations().) –

0

Bạn đã thử đặt SSL_set_verify chưa?

SSL_set_verify(s, SSL_VERIFY_NONE, NULL); 
+0

Đã thử, không thay đổi – Ramsey

+0

Nhiều mã sẽ tốt hơn vào thời điểm này. – Xorlev

+0

Cảm ơn bạn đã trả lời. Tôi đã thử tất cả các đề xuất của bạn và vẫn không có may mắn. Tôi đã dán các phần chính của chương trình tại đây: http://pastebin.com/m78497bf3 – Ramsey

2

Bạn đã cố gắng đưa ra ứng dụng của bạn chứng chỉ CA của máy chủ để ứng dụng của bạn có thể xác minh chuỗi chứng chỉ?

+0

Đúng, mặc dù trong trường hợp này máy chủ sử dụng tự chứng chỉ đã ký, những gì OP phải làm cho ứng dụng của mình tin cậy không phải là chứng chỉ CA mà là chứng chỉ của máy chủ. –

+0

Tệ của tôi, OP là sai. Chứng chỉ máy chủ không được tự ký. Thông báo lỗi được bao gồm trong câu hỏi cho thấy lỗi là 'X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN' có nghĩa là chứng chỉ tự ký được đề cập không phải là chứng chỉ của máy chủ mà là chứng chỉ của CA gốc. –

0

Bạn có thể thử chuyển số gọi lại của riêng mình tới SSL_set_verify() và sau đó thực hiện xác minh của riêng bạn. Nó ít hơn lý tưởng vì tôi nghĩ bạn cần thực hiện tất cả xác minh và sau đó cho phép bỏ qua lỗi tự ký, nhưng bạn có thể tìm ra mã xác minh tiêu chuẩn nào từ nguồn OpenSSL và sau đó chỉ cần kéo nó vào callback xác minh của riêng bạn và cho phép các mã lỗi cụ thể ...

+0

Nếu bạn muốn chấp nhận chứng chỉ tự ký, thì các bước xác minh còn lại là vô nghĩa. – caf

+0

caf - có khả năng, có ... –

2

Kiểm tra những OpenSSL Ví dụ: http://www.rtfm.com/openssl-examples/

các wclient.c kết nối với bất kỳ trang https, ví dụ:

wclient -h www.yahoo.com -p 443 

Nếu bạn chạy nó với cài đặt mặc định, bạn sẽ gặp phải lỗi chứng chỉ (bạn có thể sử dụng cờ -i để bỏ qua kiểm tra chứng chỉ).

Để xác minh các chứng chỉ, bạn sẽ cần phải tải về chứng chỉ CA (Verisign, Thawte, Equifax, vv), vì vậy google tập tin này CAcert.pem, tải về và đổi tên nó để root.pem và bạn sẽ có thể kết nối với máy chủ web và xác thực chứng chỉ của máy chủ.

+0

Ngoài ra, nếu bạn muốn in chứng chỉ, chèn dòng này (trong wclient.c) sau khi check_cert (ssl, host): X509_print_fp (stdout, SSL_get_peer_certificate (ssl)); –

+0

Đúng, mặc dù trong trường hợp này máy chủ sử dụng chứng chỉ tự ký, những gì OP phải làm cho niềm tin ứng dụng của mình không phải là chứng chỉ CA mà là chứng chỉ của máy chủ. –

+0

Tệ của tôi, OP là sai. Chứng chỉ máy chủ không được tự ký. Thông báo lỗi được bao gồm trong câu hỏi cho thấy lỗi là 'X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN' có nghĩa là chứng chỉ tự ký được đề cập không phải là chứng chỉ của máy chủ mà là chứng chỉ của CA gốc. –

0

Mã khách hàng mẫu của tôi (link) hoạt động tốt với chứng chỉ máy chủ tự ký. Tôi có đoạn code dưới đây sau khi SSL_connect và có toàn quyền kiểm soát tự ký giấy chứng nhận chấp nhận trong khách hàng của tôi

SSL_CTX* ctx = SSL_CTX_new(SSLv3_method()); 

// TCP connection and SSL handshake ... 

/* Check the certificate */ 

rc = SSL_get_verify_result(ssl); 
if(rc != X509_V_OK) { 
    if (rc == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT || rc == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN) { 
    fprintf(stderr, "self signed certificate\n"); 
    } 
    else { 
    fprintf(stderr, "Certificate verification error: %ld\n", SSL_get_verify_result(ssl)); 
    SSL_CTX_free(ctx); 
    return 0; 
    } 
} 
+0

Điều này khiến bạn dễ bị tấn công MITM! Bất kỳ chứng chỉ tự ký nào đều được chấp nhận nếu bạn làm điều này. Các lỗi bạn bỏ qua không được nâng lên nếu chứng chỉ được tin cậy. Điều đúng đắn cần làm là thêm chứng chỉ tự ký vào danh sách chứng chỉ đáng tin cậy. (Xem SSL_CTX_load_verify_locations().) –

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