tls建立流程范例
1、SSL初始化: bool init(string certFile, string privFile) { SSL_load_error_strings (); int r = SSL_library_init (); if (r == 0) { return false; } ssl_ctx = SSL_CTX_new (SSLv23_method ()); if (ssl_ctx == NULL) { printf("SSL_library_init failed \n"); return false; } err_bio = BIO_new_fd(2, BIO_NOCLOSE); r = SSL_CTX_use_certificate_file(ssl_ctx, certFile.c_str(), SSL_FILETYPE_PEM); if (r <= 0) { printf("SSL_CTX_use_certificate_file %s failed \n", certFile.c_str()); return false; } r = SSL_CTX_use_PrivateKey_file(ssl_ctx, privFile.c_str(), SSL_FILETYPE_PEM); if (r <= 0) { printf("SSL_CTX_use_PrivateKey_file %s failed \n", privFile.c_str()); return false; } r = SSL_CTX_check_private_key(ssl_ctx); if (r == 0) { printf("SSL_CTX_check_private_key failed \n"); return false; } printf("SSL inited success\n"); return true; } 2、握手协商: int SSLHandshake() { // 在未建立ssl连接之前,应将读写事件添加至epoll中 if (!tcp_connected) { struct pollfd pfd; pfd.fd = fd; pfd.events = POLLOUT | POLLERR; int r = poll(&pfd, 1, 0); if (r == 1 && pfd.revents == POLLOUT) { printf("tcp connected fd:%d\n", fd); tcp_connected = true; //注册读写事件 SetEvent(FD_SEND|FD_RECV|FD_CLOSE|FD_ERROR); } else { printf("poll fd:%d return %d revents %d\n", fd, r, pfd.revents); return -1; } } //如果ssl为null,使用已建立连接的socket初始化ssl if (ssl == NULL) { ssl = SSL_new(ssl_ctx); if (ssl == NULL) { printf("SSL_new failed, fd:%d \n", fd); return -1; } int r = SSL_set_fd(ssl, fd); if (r == 0) { printf("SSL_set_fd failed fd:%d \n", fd); } printf("SSL_set_accept_state for fd:%d \n", fd); SSL_set_accept_state(ssl); } int r = SSL_do_handshake(ssl); //若返回值为1,则SSL握手已完成 if (r == 1) { ssl_connected = true; printf("SSL_do_handshake connected success fd:%d\n", fd); return 0; } //处理握手完成后,应该将相应事件移除 int err = SSL_get_error(ssl, r); if (err == SSL_ERROR_WANT_WRITE) { //移除读事件 SetEvent(FD_SEND|FD_CLOSE|FD_ERROR); printf("SSL_get_error return want write set events, fd:%d \n", fd); return -2; } else if (err == SSL_ERROR_WANT_READ) { //移除写事件 SetEvent(FD_RECV|FD_CLOSE|FD_ERROR); printf("SSL_get_error return want read set events, fd:%d \n", fd); return -2; } else { printf("SSL_get_error return %d error %d errno %d msg %s fd:%d \n" , r, err, errno, strerror(errno), fd); return -1; } }