我花了一些时间搜索互联网寻找更好的方法来分析和调试我的问题,但我似乎无法找到解决方案.所以我想我会问.
简单地说.我正在尝试创建一个非阻塞的ssl转发代理.代理的服务器部分使用自签名服务器证书,我使用自己的CA证书签名.如果重要,我正在使用libev.我首先成功创建了一个非加密代理(它盲目地转发了网络流量),现在我正在尝试添加SSL.:)
我在让客户端连接到代理时遇到问题.我已经尝试过wget和ssl的s_client作为测试客户端,因为我想要进行一些自动化测试.
ssl服务器设置(此代码在EV_READ事件中从libev观察器侦听套接字accept_handler()调用):
/* setup client side ssl state (we are a SERVER) */
ctx = SSL_CTX_new(SSLv23_server_mode());
SSL_CTX_set_options(ctx, SSL_OP_NO_SSLV2 | SSL_OP_ALL);
SSL_CTX_set_info_callback(ctx, client_info_cb);
SSL_CTX_set_cipher_list(ctx, "ALL:!SSLv2:-aNULL");
//SSL_CTX_load_verify_locations(ctx, CA_CERTIFICATE, NULL);
//SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(CA_CERTIFICATE));
SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
SSL_CTX_set_verify_depth(ctx, 0);
SSL *client_ssl = SSN_new(ctx);
SSL_set_mode(client_ssl, SSL_MODE_ENABLE_PARTIAL_WRITE);
SSL_set_accept_state(client_ssl);
SSL_set_fd(client_ssl, client_fd);
/* initialize client handshake watchers */
ev_io_init(&ev_r_ch, client_handshake, client_fd, EV_READ);
ev_io_init(&ev_w_ch, client_handshake, client_fd, EV_WRITE);
... other watcher inits and set watcher data portions ...
/* start the read */
ev_io_start(loop, &ev_r_ch);
Run Code Online (Sandbox Code Playgroud)
libev循环设置为:
loop = ev_default_loop(EVFLAG_AUTO);
Run Code Online (Sandbox Code Playgroud)
我有定时器等检查关机标志以及其他内务活动.
我的client_handshake()main函数本质上看起来像这样:
int t = SSL_accept(client_ssl);
if (t == 1) { // SSL_ERROR_NONE
end_client_handshake(...);
} else {
int err = SSL_get_error(client_ssl, t);
if (err == SSL_ERROR_WANT_READ) {
ev_io_stop(loop, &ev_w_ch);
ev_io_start(loop, &ev_r_ch);
}
else if (err == SSL_ERROR_WANT_WRITE) {
ev_io_stop(loop, &ev_r_ch);
ev_io_start(loop, &ev_w_ch);
}
else ...
}
Run Code Online (Sandbox Code Playgroud)
在client_info_cb()中,我在进行时打印出内部SSL状态,并从我的print()函数中获取以下内容:
client_info_cb: 8193: SSLv3 read client hello A
client_info_cb: 8193: SSLv3 write server hello A
client_info_cb: 8193: SSLv3 write certificate A
client_info_cb: 8193: SSLv3 write server done A
client_info_cb: 8193: SSLv3 flush data
client_info_cb: 8194: SSLv3 read client certificate A
client_info_cb: 8194: SSLv3 read client certificate A
Run Code Online (Sandbox Code Playgroud)
这就是它挂起的地方.如果我检测到SSL_ERROR_WANT_READ(这是SSL_get_error()在上面的第二个"读取客户端证书A"消息之后返回),我尝试将client_handshake()函数修改为围绕SSL_accept()循环(1){}.
这没什么,只是让我进入一个无限循环(),不断调用SSL_accept().
我假设SSL状态机需要一些它无法获得的额外信息.我起初以为我需要继续从套接字读取,但这不起作用.
另外,我很困惑为什么我的代理尝试读取客户端证书,因为我明确指出我不想验证上面的客户端证书(SSL_VERIFY_NONE); 除非我误解了这个功能的目的.
如果有人对此有任何见解,我将不胜感激.或者也许是调试此问题的更好方法.strace()对此没用,我没有从wget或s_client中得到任何好的返回/错误消息.
我尝试在SSL的状态机中设置alert_callbacks和msg_callbacks,但这并没有给我提供比信息回调更多的信息.
在这一点上,我不确定它是套接字问题,还是SSL问题,或者是什么.
edit1:我想指出,在accept_handler()中,我首先通过ssl连接到服务器,以便在完成accept()之前验证我正在代理的主机的证书.如果我颠倒了操作的顺序,并且在连接()之前先接受(),它就可以工作.
edit2:我试着查看s_client和代理之间的tcpdump输出.在client_info_cb中引用的写入服务器数据和刷新数据之后,客户端发送"客户端密钥交换","更改密码规范"和"加密的完成消息".但是ssl状态机正在寻找客户端证书???
--> Client Key Exchange
write to 0x9547a78 [0x9592e90] (523 bytes => 523 (0x20B))
0000 - 16 03 01 02 06 10 00 02-02 02 00 be 51 c7 3d 77 ............Q.=w
0010 - 5a b3 9e 28 81 f4 4e b5-63 ce ce 0b 19 f3 85 64 Z..(..N.c......d
0020 - 29 0e e8 22 83 b8 60 a6-54 e3 7a 62 b3 37 d8 04 ).."..`.T.zb.7..
0030 - 6c f1 8e ff 50 44 ed cc-7b 08 61 0c 16 88 f4 61 l...PD..{.a....a
0040 - 7b 8d f2 1e 04 1d 74 3d-cc ee a4 93 d3 bb 90 ee {.....t=........
<snip>
--> Change Cipher Spec
write to 0x9547a78 [0x9592e90] (6 bytes => 6 (0x6))
0000 - 14 03 01 00 01 01
--> Finished Message ......
write to 0x9547a78 [0x9592e90] (53 bytes => 53 (0x35))
0000 - 16 03 01 00 30 9a 88 8b-14 d6 d1 f1 f7 d8 0d ac ....0...........
0010 - 38 cd 54 78 26 85 7b 11-c8 e9 db 8d a2 0c 6a a8 8.Tx&.{.......j.
0020 - d4 e7 d4 ad 5d 7a 6d 47-eb f9 5f 2c f6 ca 6a 1f ....]zmG.._,..j.
0030 - 17 a6 58 25 41 ..X%A
Run Code Online (Sandbox Code Playgroud)
也许您可能遇到一些会话缓存问题(默认情况下启用它并且“编辑1”指向它),\xc2\xbfare 您试图从服务器向客户端提供欺骗性证书?也许内部缓存是按证书名称存储的,并且它尝试恢复服务器会话......
\n\nSSL_CTX_set_session_cache_mode
尝试使用选项关闭缓存SSL_SESS_CACHE_OFF
。
关于“编辑2”,客户端密钥交换阶段不谈论发送客户端的证书,它发送用于所选密码系统的秘密(或什么也不发送)(如果所选密码不发送,它可以发送空客户端交换)不需要秘密)。阅读此处了解相关内容。
\n 归档时间: |
|
查看次数: |
1529 次 |
最近记录: |