Tongsuo-Project / Tongsuo

铜锁/Tongsuo is a Modern Cryptographic Primitives and Protocols Library
https://www.tongsuo.net
Apache License 2.0
1.16k stars 186 forks source link

客户端代码使用ECDHE-SM2-WITH-SM4-SM3报错 #605

Open wynnfeng opened 6 months ago

wynnfeng commented 6 months ago

我在参考https://www.yuque.com/tsdoc/ts/hedgqf使用ECDHE-SM2-WITH-SM4-SM3,

if(SSL_CTX_set_cipher_list(ssl_ctx, "ECDHE-SM2-WITH-SM4-SM3") <= 0)
        goto exit;

报错如下:

[root@anolis ~]# ./client
TCP connection to server successful
SSL connection to server failed

40A7E7BD6C7F0000:error:0A000418:SSL routines:ssl3_read_bytes:tlsv1 alert unknown ca:ssl/record/rec_layer_s3.c:1586:SSL alert number 48

请问是什么原因呢?

使用的铜锁版本为:tongsuo-8.4.1-2.an23.x86_64

wynnfeng commented 6 months ago

具体的client.c代码如下:

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <openssl/ssl.h>
#include <openssl/err.h>

int main(int argc, char **argv)
{
    struct sockaddr_in addr;
    const SSL_METHOD *method;
    SSL_CTX *ssl_ctx = NULL;
    SSL *ssl = NULL;
    int fd = -1;
    char *txbuf = NULL;
    size_t txcap = 0;
    int txlen;
    char rxbuf[128];
    size_t rxcap = sizeof(rxbuf);
    int rxlen;
    char *server_ip = "127.0.0.1";
    char *server_port = "443";

    if (argc == 2) {
        server_ip = argv[1];
        server_port = strstr(argv[1], ":");
        if (server_port != NULL)
            *server_port++ = '\0';
        else
            server_port = "443";
    }

    method = NTLS_client_method();
    ssl_ctx = SSL_CTX_new(method);
    if (ssl_ctx == NULL) {
        perror("Unable to create SSL context");
        ERR_print_errors_fp(stderr);
        exit(EXIT_FAILURE);
    }

    SSL_CTX_enable_ntls(ssl_ctx);
    if(SSL_CTX_set_cipher_list(ssl_ctx, "ECDHE-SM2-WITH-SM4-SM3") <= 0)
        goto exit;
    if (!SSL_CTX_use_sign_certificate_file(ssl_ctx, "certs/client/sm2_sign.crt",
                                           SSL_FILETYPE_PEM)
        || !SSL_CTX_use_sign_PrivateKey_file(ssl_ctx, "certs/client/sm2_sign.key",
                                             SSL_FILETYPE_PEM)
            || !SSL_CTX_use_enc_certificate_file(ssl_ctx, "certs/client/sm2_enc.crt",
                                              SSL_FILETYPE_PEM)
            || !SSL_CTX_use_enc_PrivateKey_file(ssl_ctx, "certs/client/sm2_enc.key",
                                             SSL_FILETYPE_PEM)) {
        ERR_print_errors_fp(stderr);
        exit(EXIT_FAILURE);
    }
    SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_NONE, NULL);

    fd = socket(AF_INET, SOCK_STREAM, 0);
    if (fd < 0) {
        perror("Unable to create socket");
        exit(EXIT_FAILURE);
    }

    addr.sin_family = AF_INET;
    inet_pton(AF_INET, server_ip, &addr.sin_addr.s_addr);
    addr.sin_port = htons(atoi(server_port));

    if (connect(fd, (struct sockaddr*) &addr, sizeof(addr)) != 0) {
        perror("Unable to TCP connect to server");
        goto exit;
    } else {
        printf("TCP connection to server successful\n");
    }

    /* Create client SSL structure using dedicated client socket */
    ssl = SSL_new(ssl_ctx);
    SSL_set_fd(ssl, fd);

    if (SSL_connect(ssl) == 1) {
        printf("TLCP connection to server successful\n\n");

        /* Loop to send input from keyboard */
        while (1) {
            /* Get a line of input */
            txlen = getline(&txbuf, &txcap, stdin);
            /* Exit loop on error */
            if (txlen < 0 || txbuf == NULL) {
                break;
            }
            /* Exit loop if just a carriage return */
            if (txbuf[0] == '\n') {
                break;
            }
            /* Send it to the server */
            if (SSL_write(ssl, txbuf, txlen) <= 0) {
                printf("Server closed connection\n");
                ERR_print_errors_fp(stderr);
                break;
            }

            /* Wait for the echo */
            rxlen = SSL_read(ssl, rxbuf, rxcap);
            if (rxlen <= 0) {
                printf("Server closed connection\n");
                ERR_print_errors_fp(stderr);
                break;
            } else {
                /* Show it */
                rxbuf[rxlen] = 0;
                printf("Received: %s", rxbuf);
            }
        }
        printf("Client exiting...\n");
    } else {

        printf("SSL connection to server failed\n\n");

        ERR_print_errors_fp(stderr);
    }
exit:
    if (ssl != NULL) {
        SSL_shutdown(ssl);
        SSL_free(ssl);
    }
    SSL_CTX_free(ssl_ctx);

    if (fd != -1)
        close(fd);
        if (txbuf != NULL && txcap > 0)
        free(txbuf);

    return 0;
}
// gcc client.c  -I/opt/tongsuo/include/ -L/opt/tongsuo/lib64/ -lssl -lcrypto -Wl,-rpath=/opt/tongsuo/lib64 -o client