- 使用openssl在socket上建立SSL连接,使用epoll管理连接的socket,并且实现openssl提供的客户端及服务端双向认证;
- 简单的小例子,不足之处请在评论区提出;
- 测试用,方法不完善,仍在改进中,可能会有SSL读写操作处理数据不完全的情况,同时,个人运行时感觉服务端接收数据较慢,原因待排查。
服务端
注意:服务端所开放端口、CA公钥文件、服务端自身的公钥及私钥文件均在代码中定义,如与代码中的不同请注意修改
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/epoll.h>
#include <string.h>
#include <errno.h>
#include <iostream>
#include <unordered_map>
#include <thread>
#include <mutex>
volatile char if_continue = 1;
int main(void){
std::unordered_map<int, SSL*> ssl_sockets; //一个socket对应一个SSL连接
char read_buffer[40]; //socket接收缓冲区
SSL_library_init();
OpenSSL_add_all_algorithms();
SSL_load_error_strings();
SSL_CTX* ssl_ctx = SSL_CTX_new(TLS_server_method());
//设置SSL双向认证
SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
//CA公钥文件
SSL_CTX_load_verify_locations(ssl_ctx, "cacert.pem", NULL);
//服务端公钥文件
int status = SSL_CTX_use_certificate_file(ssl_ctx, "test1.cer", SSL_FILETYPE_PEM);
//服务端私钥文件
status = SSL_CTX_use_PrivateKey_file(ssl_ctx, "test1.pem", SSL_FILETYPE_PEM);
status = SSL_CTX_check_private_key(ssl_ctx);
int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in my_addr;
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(22233); //开放22233端口
my_addr.<