使用openssl封装数据包

时间:2016-07-17 12:27:15

标签: c++ ssl openssl

我想开发一个ssl服务器,以便在C ++中使用Openssl创建安全连接。但我收到封装在另一个协议包中的Client Hello消息。示例包:

#include <cstdlib>
#include <iostream>

#include <sys/types.h> 
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h> 

#include <openssl/rand.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <unistd.h>

using namespace std;

int main() {
    /* 
    ------------------ START Initialize Server ------------------
     */

    int serverfd, clientfd;
    struct sockaddr_in vir_serv_addr, cli_addr;

    serverfd = socket(AF_INET, SOCK_STREAM, 0);
    bzero((char *) &vir_serv_addr, sizeof (vir_serv_addr));

    vir_serv_addr.sin_family = AF_INET;
    vir_serv_addr.sin_addr.s_addr = INADDR_ANY;
    vir_serv_addr.sin_port = htons(9999);

    bind(serverfd, (struct sockaddr *) &vir_serv_addr, sizeof (vir_serv_addr));
    listen(serverfd, 5);
    socklen_t client = sizeof (cli_addr);
    clientfd = accept(serverfd, (struct sockaddr*) &cli_addr, (socklen_t*) & client);

    /*
    ------------------- END Initialize Server ------------------- 
     */

    /* 
    ------------------ START SSL ------------------
     */

    SSL_library_init();
    SSL_load_error_strings();
    OpenSSL_add_all_algorithms();

    FILE* certF = fopen("server-cert.pem", "r");
    X509* cert = PEM_read_X509(certF, NULL, NULL, NULL);

    FILE* keyF = fopen("server-key.pem", "r");
    EVP_PKEY* key = PEM_read_PrivateKey(keyF, NULL, NULL, NULL);

    SSL_CTX* context = SSL_CTX_new(TLSv1_server_method());

    SSL_CTX_use_certificate(context, cert);
    SSL_CTX_use_PrivateKey(context, key);
    SSL_CTX_check_private_key(context);

    SSL_CTX_set_ecdh_auto(context, 1);
    SSL_CTX_set_verify_depth(context, 4);
    SSL_CTX_load_verify_locations(context, "ca-cert.pem", "");

    SSL* ssl = SSL_new(context);
    SSL_set_fd(ssl, clientfd);

    int r = SSL_accept(ssl);
    if (r != 1) {
        ERR_print_errors_fp(stderr);
        int err_SSL_get_error = SSL_get_error(ssl, r);

        switch (err_SSL_get_error) {
            case SSL_ERROR_NONE:
                printf("%d", 0);
                break;
            case SSL_ERROR_SSL:
                printf("%d", 1);
                break;
            case SSL_ERROR_WANT_READ:
                printf("%d", 2);
                break;
            case SSL_ERROR_WANT_WRITE:
                printf("%d", 3);
                break;
            default:
                printf("%d", -1);
                break;
        }
    }

    /*
    ------------------- END SSL ------------------- 
     */

    return 0;
}

如何从数据包中提取Client Hello?如何在Openssl accept中使用它?

我的代码:

window.alert(data);
$('#data').val('Sent');

1 个答案:

答案 0 :(得分:1)

如果您不直接在线路上讲TLS,而是将TLS帧封装在其他协议中,则无法使用OpensSL(SSL_set_fd)的文件描述符后端。相反,你必须使用BIO后端(SSL_set_bio)和一些内存BIO。使用内存BIO OpenSSL不会自己从文件描述符读取/写入数据,而是读取/写入某个内存位置。

有关详细信息,请参阅 Directly Read/Write Handshake data with Memory BIO