Tôi đang gặp khó khăn với vấn đề chứng chỉ ứng dụng khách và hy vọng ai đó ở đây có thể giúp tôi. Tôi đang phát triển một cặp máy khách/máy chủ bằng cách sử dụng asio tăng nhưng tôi sẽ cố gắng không cụ thể. Tôi đang sử dụng các cửa sổ và sử dụng openssl 1.0.1eỨng dụng khách OpenSSL không gửi chứng chỉ ứng dụng khách
Về cơ bản, tôi muốn có xác thực ứng dụng khách bằng cách sử dụng chứng chỉ ứng dụng khách. Máy chủ sẽ chỉ chấp nhận các máy khách có chứng chỉ được ký bởi CA của riêng tôi. Vì vậy, tôi đã thiết lập một CA tự ký. Điều này đã phát hành thêm hai chứng chỉ. Một cho khách hàng và một cho máy chủ. Cả hai được ký bởi CA. Tôi đã làm điều đó khá nhiều lần và tôi tự tin rằng tôi đã nhận được nó.
Phía máy chủ của tôi cũng hoạt động tốt. Nó yêu cầu chứng chỉ ứng dụng khách và nếu tôi đang sử dụng s_client và cung cấp cho các chứng chỉ đó hoạt động. Ngoài ra nếu tôi đang sử dụng một trình duyệt và đã cài đặt CA gốc của tôi là đáng tin cậy và sau đó nhập các chứng chỉ ứng dụng khách.
Điều duy nhất mà tôi không thể làm việc là ứng dụng khách libssl. Nó luôn thất bại trong khi bắt tay và như xa như tôi có thể nhìn thấy nó sẽ không gửi các certficate khách hàng:
$ openssl.exe s_server -servername localhost -bugs -CAfile myca.crt -cert server.crt
-cert2 server.crt -key private/server.key -key2 private/server.key -accept 8887 -www
-state -Verify 5
verify depth is 5, must return a certificate
Setting secondary ctx parameters
Using default temp DH parameters
Using default temp ECDH parameters
ACCEPT
SSL_accept:before/accept initialization
SSL_accept:SSLv3 read client hello A
SSL_accept:SSLv3 write server hello A
SSL_accept:SSLv3 write certificate A
SSL_accept:SSLv3 write key exchange A
SSL_accept:SSLv3 write certificate request A
SSL_accept:SSLv3 flush data
SSL3 alert read:warning:no certificate
SSL3 alert write:fatal:handshake failure
SSL_accept:error in SSLv3 read client certificate B
SSL_accept:error in SSLv3 read client certificate B
2675716:error:140890C7:SSL routines:SSL3_GET_CLIENT_CERTIFICATE:peer did not return a
certificate:s3_srvr.c:3193:
ACCEPT
Tôi đang sử dụng s_server này như một công cụ gỡ lỗi nhưng đối với máy chủ thật của tôi điều tương tự xảy ra. s_client sẽ hoạt động tốt với cùng chứng chỉ. Ngoài ra, nếu tôi vô hiệu hóa "-Xác minh" trong máy chủ kết nối hoạt động. Vì vậy, nó thực sự có vẻ như chỉ là khách hàng từ chối gửi nó certficate. Điều gì có thể là lý do cho điều đó?
Kể từ khi tôi đang sử dụng tăng ASIO như một SSL bao bọc mã trông như thế này:
m_ssl_context.set_verify_mode(asio::ssl::context::verify_peer);
m_ssl_context.load_verify_file("myca.crt");
m_ssl_context.use_certificate_file("testclient.crt", asio::ssl::context::pem);
m_ssl_context.use_private_key_file("testclient.key", asio::ssl::context::pem);
Tôi cũng đã cố gắng để vượt qua ASIO và truy cập vào bối cảnh SSL trực tiếp bằng cách nói:
SSL_CTX *ctx = m_ssl_context.impl();
SSL *ssl = m_ssl_socket.impl()->ssl;
int res = 0;
res = SSL_CTX_use_certificate_chain_file(ctx, "myca.crt");
if (res <= 0) {
// handle error
}
res = SSL_CTX_use_certificate_file(ctx, "testclient.crt", SSL_FILETYPE_PEM);
if (res <= 0) {
// handle error
}
res = SSL_CTX_use_PrivateKey_file(ctx, "testclient.key", SSL_FILETYPE_PEM);
if (res <= 0) {
// handle error
}
Tôi không thể thấy bất kỳ sự khác biệt nào về hành vi. Nó nên được đề cập rằng tôi đang sử dụng một asio rất cũ 1,43 asio mà tôi không thể cập nhật nhưng tôi cho rằng tất cả các cuộc gọi có liên quan đi nhiều hay ít trực tiếp đến OpenSSL và máy chủ hoạt động tốt với phiên bản đó nên tôi nghĩ rằng tôi có thể loại trừ.
Nếu tôi bắt đầu ép khách hàng và máy chủ đến các phiên bản cụ thể, thông báo lỗi thay đổi nhưng nó không bao giờ hoạt động và vẫn luôn hoạt động với kiểm tra s_client. Hiện nay nó được thiết lập để TLSv1
Nếu tôi chuyển nó đến TLSv1 ví dụ có nhiều trò chuyện giữa client và server và cuối cùng tôi nhận được lỗi:
...
SSL_accept:SSLv3 read client key exchange A
<<< TLS 1.0 ChangeCipherSpec [length 0001]
01
<<< TLS 1.0 Handshake [length 0010], Finished
14 00 00 0c f4 71 28 4d ab e3 dd f2 46 e8 8b ed
>>> TLS 1.0 Alert [length 0002], fatal unexpected_message
02 0a
SSL3 alert write:fatal:unexpected_message
SSL_accept:failed in SSLv3 read certificate verify B
2675716:error:140880AE:SSL routines:SSL3_GET_CERT_VERIFY:missing verify
message:s3_srvr.c:2951:
2675716:error:140940E5:SSL routines:SSL3_READ_BYTES:ssl handshake failure:s3_pkt.c:989:
ACCEPT
Tôi đã tìm thấy một mục lỗi cũ đăng tải trên danh sách gửi thư openssl đã được quy định cho điều này. Rõ ràng là một CRLF sai trong cái bắt tay đã được sửa cách đây hai năm. Hay có nó?
Tôi đã gỡ lỗi này trong gần một tuần và tôi thực sự bị kẹt. Có ai có một gợi ý về những gì để thử? Tôi ra khỏi ý tưởng ...
Chúc mừng, Stephan
PS: Đây là những gì các s_server debug ra ở trên sẽ là với s_client và certficate cùng:
$ openssl s_client -CAfile ca.crt -cert testclient.crt -key private/testclient.key -verify 2 -connect myhost:8887
ACCEPT
SSL_accept:before/accept initialization
SSL_accept:SSLv3 read client hello A
SSL_accept:SSLv3 write server hello A
SSL_accept:SSLv3 write certificate A
SSL_accept:SSLv3 write key exchange A
SSL_accept:SSLv3 write certificate request A
SSL_accept:SSLv3 flush data
depth=1 C = DE, // further info
verify return:1
depth=0 C = DE, // further info
verify return:1
SSL_accept:SSLv3 read client certificate A
SSL_accept:SSLv3 read client key exchange A
SSL_accept:SSLv3 read certificate verify A
SSL_accept:SSLv3 read finished A
SSL_accept:SSLv3 write session ticket A
SSL_accept:SSLv3 write change cipher spec A
SSL_accept:SSLv3 write finished A
SSL_accept:SSLv3 flush data
ACCEPT
... bắt tay hoàn thành và dữ liệu được chuyển giao.
Rất tiếc, tôi đã thử tất cả các kết hợp mà tôi có thể đưa ra. Bao gồm cái này. Không có kết quả. Có vẻ như khách hàng sẽ không tin tưởng vào chứng chỉ ứng dụng khách của chính mình và không gửi nó. Nếu tôi sử dụng kết hợp này, khách hàng sẽ không gửi chứng chỉ nào cả, Nếu tôi sử dụng tệp chuỗi, có vẻ như nó sẽ gửi CA gốc thay vì của riêng mình. –
Nếu nó gửi CA gốc, đó là vì bạn đang gọi SSL_CTX_use_certificate_chain_file() chỉ với chứng chỉ CA trong đó. Bạn có thể thử truyền tệp chỉ chứa chứng chỉ ứng dụng khách của bạn tới SSL_CTX_use_certificate_chain_file() không? –
Xin cảm ơn tất cả mọi người! Nhiều đánh giá cao! @Remi: khi tôi làm điều này, khách hàng không gửi bất kỳ chứng chỉ nào. Đó là trường hợp đầu tiên tôi đã mô tả. Mà bằng cách này cũng là trường hợp nếu tập tin chuỗi chỉ chứa các cert cert. Tôi biết, điều đó không hợp lý nhưng tôi vẫn muốn thử. –