C ++ SSL连接:邮件太长

时间:2016-07-04 13:23:50

标签: c++ sockets ssl tcp openssl

我正在开发一个应用程序,其中许多客户端应连接到服务器应用程序并每分钟传输一个大约300字节的字符串。客户端只是RS232和套接字服务器之间的网关。客户端和服务器之间的连接使用openssl进行SSL加密。两者都是用C ++开发的。

传输正在全天候运行,但如果某些数据丢失则并不重要。

首先我尝试使用TCP连接,但是我遇到了麻烦,因为连接断了一些。因此,当我发送信息时,我决定连接并断开每一分钟(也许稍后我将缓存一些数据并且不是每分钟发送一次)。因此我认为与DTLS使用UDP连接会更好。

但我有两个UDP连接问题。

  1. ca每10个字符串都有一个缺少的字符。这不是很关键,但是我的代码可能不是错误吗?

  2. 如果我使用“SSL_CTX_load_verify_locations”验证我的客户端,我有时会收到错误:“SSL connect:message too long”。 我认为通常应该是超过64K的消息?但在连接时我不发送任何数据?如何在连接时发生这种情况?

  3. 你认为UDP对我来说是正确的协议吗?或者我应该使用TCP?

    以下是我的代码中的一些细节:

    服务器:

    server_addr.s4.sin_family = AF_INET;
    server_addr.s4.sin_addr.s_addr = INADDR_ANY;
    server_addr.s4.sin_port = htons(port);
    
    THREAD_setup();
    OpenSSL_add_ssl_algorithms();
    SSL_load_error_strings();
    ctx = SSL_CTX_new(DTLSv1_server_method());
    SSL_CTX_set_cipher_list(ctx, "ALL:NULL:eNULL:aNULL");
    SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
    
    if (!SSL_CTX_use_certificate_file(ctx, SERVERCERT, SSL_FILETYPE_PEM))
        printf("\nERROR: no certificate found!");
    
    if (!SSL_CTX_use_PrivateKey_file(ctx, SERVERKEY, SSL_FILETYPE_PEM))
        printf("\nERROR: no private key found!");
    
    if (!SSL_CTX_check_private_key (ctx))
        printf("\nERROR: invalid private key!");
    
    if(!SSL_CTX_load_verify_locations(ctx, CACERT, NULL))
        cout << "\nERROR: no ca-cert found!\n";
    
    SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, dtls_verify_callback);
    
    SSL_CTX_set_read_ahead(ctx, 1);
    SSL_CTX_set_cookie_generate_cb(ctx, generate_cookie);
    SSL_CTX_set_cookie_verify_cb(ctx, verify_cookie);
    
    fd = socket(server_addr.ss.ss_family, SOCK_DGRAM, 0);
    if (fd < 0) {
        perror("socket");
        exit(-1);
    }
    
    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const void*) &on, (socklen_t) sizeof(on));
    
    bind(fd, (const struct sockaddr *) &server_addr, sizeof(struct sockaddr_in));
    
    while (1)
    {
            memset(&client_addr, 0, sizeof(struct sockaddr_storage));
    
            bio = BIO_new_dgram(fd, BIO_NOCLOSE);
    
            timeout.tv_sec = 5;
            timeout.tv_usec = 0;
            BIO_ctrl(bio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
    
            ssl = SSL_new(ctx);
    
            SSL_set_bio(ssl, bio, bio);
            SSL_set_options(ssl, SSL_OP_COOKIE_EXCHANGE);
    
            while (DTLSv1_listen(ssl, &client_addr) <= 0);
    
            info = (struct pass_info*) malloc (sizeof(struct pass_info));
            memcpy(&info->server_addr, &server_addr, sizeof(struct sockaddr_storage));
            memcpy(&info->client_addr, &client_addr, sizeof(struct sockaddr_storage));
            info->ssl = ssl;
    
            if (pthread_create( &tid, NULL, connection_handle, info) != 0) {
                perror("pthread_create");
                exit(-1);
            }
        }
    
        THREAD_cleanup();
    }
    

    客户端:

    OpenSSL_add_ssl_algorithms();
    SSL_load_error_strings();
    ctx = SSL_CTX_new(DTLSv1_client_method());
    SSL_CTX_set_cipher_list(ctx, "eNULL:!MD5");
    
    if (!SSL_CTX_use_certificate_file(ctx, CLIENTCERT, SSL_FILETYPE_PEM))
        printf("\nERROR: no certificate found!");
    
    if (!SSL_CTX_use_PrivateKey_file(ctx, CLIENTKEY, SSL_FILETYPE_PEM))
        printf("\nERROR: no private key found!");
    
    if (!SSL_CTX_check_private_key (ctx))
        printf("\nERROR: invalid private key!");
    
    if(!SSL_CTX_load_verify_locations(ctx,CACERT,NULL))
        cout << "\nERROR: cannot load CA Cert file for verification!\n";
    
    
    SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,NULL);
    SSL_CTX_set_read_ahead(ctx, 1);
    
    
    ssl = SSL_new(ctx);
    
    bio = BIO_new_dgram(fd, BIO_CLOSE);
    
    connect(fd, (struct sockaddr *) &remote_addr, sizeof(struct sockaddr_in));
    
    BIO_ctrl(bio, BIO_CTRL_DGRAM_SET_CONNECTED, 0, &remote_addr.ss);
    
    SSL_set_bio(ssl, bio, bio);
    
    if (SSL_connect(ssl) < 0) {
        perror("SSL_connect");
        printf("%s\n", ERR_error_string(ERR_get_error(), buf));
        exit(-1);
    }
    
    timeout.tv_sec = 3;
    timeout.tv_usec = 0;
    BIO_ctrl(bio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
    

0 个答案:

没有答案