前段时间在自己的异步网络框架handy中添加openssl的支持,因此把相关的资料整理一下,并给出简单的例子
先看同步的openssl使用
客户端的调用次序为:
//初始化SSL库
SSL_load_error_strings ();
SSL_library_init ();
sslContext = SSL_CTX_new (SSLv23_client_method ());
//连接tcp
con->socket = connect (handle, (struct sockaddr *) &server,
sizeof (struct sockaddr));
//初始化一个SSL结构,并与tcp关联
con->sslHandle = SSL_new (sslContext);
SSL_set_fd (con->sslHandle, con->socket);
//调用SSL_connect进行SSL握手
SSL_connect (con->sslHandle);
//通过SSL_read,SSL_write来读写SSL连接里的数据
SSL_write (con->sslHandle, text, len);
SSL_read(con->sslHandle, buf, sizeof buf);
详细可运行的例子参看
https://github.com/yedf/openssl-example/blob/master/sync-ssl-cli.cc
该例子连接www.openssl.com:443,发送一个Http请求,并打印结果中的前256个字符
服务器端调用次序为:
//初始化SSL库
SSL_library_init();
SSL_load_error_strings();
ERR_load_BIO_strings();
SSL_CTX* ctx = SSL_CTX_new (SSLv23_method());
//设置证书与私钥
int r = SSL_CTX_use_certificate_file(ctx, "server.pem", SSL_FILETYPE_PEM);
r = SSL_CTX_use_PrivateKey_file(ctx, "server.pem", SSL_FILETYPE_PEM);
//进行tcp监听与接收连接
int nListenFd = socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC, 0);
r = bind(nListenFd, (struct sockaddr *)&addr, len);
r = listen(nListenFd, 20);
int nAcceptFd = accept(nListenFd, (struct sockaddr *)&addr, (socklen_t *)&len);
//根据tcp socket来初始化SSL
SSL* ssl = SSL_new (ctx);
SSL_set_fd (ssl, nAcceptFd);
//进行SSL握手,下面两个调用可以用SSL_accept(ssl)来替换
SSL_set_accept_state(ssl);
r = SSL_do_handshake(ssl);
//通过SSL_read, SSL_write进行读写
SSL_read(ssl,szBuffer, sizeof(szBuffer));
const char* resp = "HTTP/1.1 200 OK\r\nConnection: Close\r\n\r\n";
SSL_write(ssl, resp, strlen(resp));
详细可运行的例子参看
https://github.com/yedf/openssl-example/blob/master/sync-ssl-svr.cc
该例子监听本地的443端口,并返回一个简单http响应
非阻塞调用
非阻塞调用与同步调用的主要区别在于握手过程并不能够一次性完成,当tcp连接建立之后,调用SSL_set_accept_state/SSL_set_connect_state, 然后在socket可读可写的时候调用SSL_do_handshake直到该调用返回1,一旦SSL握手完成之后,那么把原先socket中的read/write替换成SSL相关函数即可。
详细可运行的例子参看
https://github.com/yedf/openssl-example/blob/master/async-ssl-svr.cc
https://github.com/yedf/openssl-example/blob/master/async-ssl-cli.cc
handy已经对openssl进行了封装,并且给出了例子,详见
https://github.com/yedf/handy-ssl