ssl调研

来源:互联网 发布:qq飞车针尖数据 编辑:程序博客网 时间:2024/05/17 08:17

SSL传输数据时,是根据记录进行传输的socket(tcp)是面向流的协议。原因估计是要加密与解密。

比如:一端SSL_write(ssl,buf, size)之后再SSL_write(ssl, buf, size)

另一端SSL_read(ssl,buf, size-n)之后再SSL_read(ssl, buf, 2*size),此时buf中只有n个数据。

这是与socket不同的一点。

 

SSL的错误处理与socket错误处理方式不同,SSL 调用返回值描述中没有关于设置errno。

SSL协议是在socket之上的的协议,有SSL自己的握手与关闭过程

客户端,在connect成功返回后,若要加密传输,可先通知服务端要进行加密传输,需要先发送给服务端一段选择数据,之后则处理scoket描述符调用SSL_connect进行握手。

服务端,在accept成功返回后,先接收一段选择数据,如要加密传输,则要处理socket描述符之后调用SSL_accept进行握手

 

SSL io目前发现两个,SSL_read和SSL_write

SSL_read:基于SSL/TLS记录,记录有个最大值(man中是16KB)。仅当一个记录完全接收完后,SSL_read才能处理。SSL_read读数据是按记录(最大16kb)进行读取,如果底层io是blocking,SSL_read会在完成读或发生错误是返回。除非发生重新协商。调用SSL_get_error()查看错误原因

         SSL_write:按记录进行写,如果写的数据size比最大记录(16kb)大,就会将数据分成多个记录写入,直到写完size个数据后返回。如果底层io是blocking的,SSL_write会在完成写或出错时返回,除非发生重新协商。调用SSL_get_error()查看错误。

 

Libev支持:

         Libev库中的事件是监视socket描述符进行的,当socket描述符对应的连接缓冲区有数据时,事件被触发,而SSL是在socket(tcp)之上的的一层协议,在使用的时候与socket是有区别的,SSL就像是在socket(tcp) 之上作的一层应用,这层应用有自己的IO函数(SSL_read,SSL_write),同样的是,SSL层还有自己的缓冲区。SSL使用libev的问题就出在SSL缓冲区这一块,比如出现这种情况:socket(tcp)缓冲区中有4KB字节,此时触发libev事件,调用回调函数,回调函数中的IO使用的是SSL_read,通过SSL_read读,size参数是2KB,所以只读取了2KB字节就返回,此时socket缓冲区中可能已经没有了数据,即4KB字节的数据全被SSL读到自己的缓冲区中了,这样,没有通过SSL_read读出的剩下2KB字节就无法触发libev事件,这样回调函数就无法被调用,剩下的2KB字节就无法读出。

 

SSL_read读取数据过程(通过libev事件验证得到的)

如果SSL缓冲区中有数据,就从SSL缓冲区中读取,如果SSL缓冲区没有数据,就从socket缓冲区中读取(以个记录为单位进行读)。另外,SSL缓冲区中的数据都是同一个记录的数据,每一次SSL层从socket缓冲区读数据时,无论socket缓冲区有多少数据,SSL层每次只读一个记录的数据(最大是16KB),这样,当有大量数据是,SSL层会频繁的进行系统调用进入内核读数据,会影响性能,但还没有找到方法改变SSL层缓冲区限制。

对于libev的支持方面,如果每次SSL_read都按leosync协议的记录(先读一个头,在从头中获取之后数据的大小)进行读取,SSL_read是可以使用的,但是还是会有性能的影响,因为一个事件的发生,可能会频繁的进入内核读取数据。

SSL_write的写过程与都过程类似,如果写的数据大小 < 16KB这按一个记录进行写,如果 > 16KB,则分成多个记录进行写。

        

 

 

SSL错误处理

SSL_get_error(SSL*, int)函数是专门处理SSL I/O操作错误的函数,SSL_get_error监视当前线程的OpenSSL错误队列,SSL_get_error必须使用在当同一线程的SSLI/O操作上,并且I/O操作与SSL_get_error之间没有其他的OpenSSL函数调用。其中SSL I/O的返回值是SSL_get_error函数的第二个参数。如果出现的是linux文件系统的IO错误,则SSL_get_error会返回SSL_ERROR_SYSCALL,通过errno查看错误原因。

 

 

在支持加密传输的程序中,

 

SSL_CTX_set_mode

SSL_connect

SSL_set_connect_state

SSL_accept

SSL_set_accept_state

SSL_shutdown

SSL_set_shutdown

SSL_get_error

 

SSL_library_init

SSL_CTX_new

SSL_new

SSL_set_fd

SSL错误处理


 

 

Leosync 加密传输

 

Client部分

Connect过程

Client在需要传输数据时才进行必要tcp连接,

LsTarget::comm->lsNetServer::getCommand->lsNetServer::getCommandPoint

->lsNetServer::getCommandPointLocked->lsNetPoint::connect

->lsCommandPoint::connectLocked

这些方法的参数中要增加iscryto 参数选项。

 

客户端与服务器完成tcp连接时,客户端要通过tcp通知服务器是否需要加密传输。客户端和服务端都要处理加密选项的处理。

 

Client在传输数据的过程

 

0 0