tls建立流程范例

时间:2019-10-22
本文章向大家介绍tls建立流程范例,主要包括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;
    }
}

原文地址:https://www.cnblogs.com/share-ideas/p/11718904.html