TASSL 服务端 客户端测试代码

openssl s_client -connect kjt.hebei.gov.cn:443

c:\tassl\bin\openssl.exe  s_server -key SS.key -cert SS.pem -www -accept 443 

 

TASSL windows上代码 服务端,需要引入applink.c

/*
 * ++
 * FACILITY:
 *
 *      Simplest SM2 TLSv1.1 Server
 *
 * ABSTRACT:
 *
 *   This is an example of a SSL server with minimum functionality.
 *    The socket APIs are used to handle TCP/IP operations. This SSL
 *    server loads its own certificate and key, but it does not verify
 *  the certificate of the SSL client.
 *
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <iostream>
#if WIN32
#pragma comment(lib,"ws2_32.lib")

#include <memory.h>
#include <errno.h>
#include <WS2tcpip.h> 
#include <winsock2.h>
#include <windows.h>
#include <string.h>
#else
#include <strings.h>

#include <netdb.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/select.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#endif

#include <sys/types.h>

#include "openssl/crypto.h"
#include "openssl/ssl.h"
#include "openssl/err.h"
#include "openssl/evp.h"

#define MAX_BUF_LEN 4096
#define SM2_SERVER_CERT     "./cert/SS.pem"
#define SM2_SERVER_KEY      "./cert/SS.pem"

#define SM2_SERVER_ENC_CERT     "./cert/SE.pem"
#define SM2_SERVER_ENC_KEY      "./cert/SE.pem"

#define SM2_SERVER_CA_CERT  "./cert/CA.pem"

#define SM2_SERVER_CA_PATH  "."
#define SSL_ERROR_WANT_HSM_RESULT 10
#define ON   1
#define OFF  0

#define RETURN_NULL(x) if ((x)==NULL) exit(1)
#define RETURN_ERR(err,s) if ((err)==-1) { perror(s); exit(1); }
#define RETURN_SSL(err) if ((err)==-1) { ERR_print_errors_fp(stderr); exit(1); }
int opt = 1;

#define strcasecmp strcmp

#if WIN32

extern "C" {

#include <openssl/applink.c>
}
#endif

void ShowCerts(SSL* ssl)
{
    X509* cert;
    char* line;

    cert = SSL_get_peer_certificate(ssl);
    if (cert != NULL) {
        printf("数字证书信息:\n");
        line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
        printf("证书: %s\n", line);
        free(line);
        line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
        printf("颁发者: %s\n", line);
        free(line);
        X509_free(cert);
    }
    else
        printf("无证书信息!\n");
}


int verify_callback(int ok, X509_STORE_CTX* ctx)
{
    if (!ok) {
        ok = 1;
    }

    return (ok);
}


int main(int argc, char** argv)
{
    int     err;
    int     verify_client = OFF; /* To verify a client certificate, set ON */

    int     listen_sock;
    int     sock;
    struct sockaddr_in sa_serv;
    struct sockaddr_in sa_cli;
    size_t client_len;
    char* str;
    char buf[MAX_BUF_LEN];
    char tmpbuf[64] = { 0 };

    SSL_CTX* ctx = NULL;
    SSL* ssl = NULL;
    const SSL_METHOD* meth;

    short int       s_port = 443;

    int hsm_tag = 0;
    int aio_tag = 0;

    /*----------------------------------------------------------------*/
    if (argc > 1)
    {
        for (err = 1; err < argc; err++)
        {
            if (!strcasecmp(argv[err], "-H"))
                hsm_tag = 1;
            else if (!strcasecmp(argv[err], "-A"))
                aio_tag = 1;
            else if (!strcasecmp(argv[err], "-P"))
            {
                if (argc >= (err + 2))
                    s_port = atoi(argv[++err]);
                else
                    s_port = 4433;

                if (s_port <= 0) s_port = 4433;
            }
        }
    }
    else
    {
        printf("Usage: %s [-h [-a]] [-p port]\n\t-h: Use HSM\n\t-a: Use HSM With Asynchronism Mode\n\t-p port: service port, default 4433\n", argv[0]);
    }

    printf("Service With HSM=%s AIO=%s Port=%d\n", (hsm_tag ? "YES" : "NO"), (aio_tag ? "YES" : "NO"), s_port);

    /* Load encryption & hashing algorithms for the SSL program */
    SSL_library_init();

    /* Load the error strings for SSL & CRYPTO APIs */
    SSL_load_error_strings();

    /* Create a SSL_METHOD structure (choose a SSL/TLS protocol version) */
    meth = SSLv23_server_method();
    //SSL_set_sm2_group_id_custom(29);
    /*SSL_set_sm2_group_id_custom(59);*/

    /* Create a SSL_CTX structure */
    ctx = SSL_CTX_new(meth);

    if (!ctx)
    {
        ERR_print_errors_fp(stderr);
        exit(1);
    }

    /* Load the server certificate into the SSL_CTX structure */
    if (SSL_CTX_use_certificate_file(ctx, SM2_SERVER_CERT, SSL_FILETYPE_PEM) <= 0)
    {
        ERR_print_errors_fp(stderr);
        exit(1);
    }

    /* Load the private-key corresponding to the server certificate */
    if (SSL_CTX_use_PrivateKey_file(ctx, SM2_SERVER_KEY, SSL_FILETYPE_PEM) <= 0)
    {
        ERR_print_errors_fp(stderr);
        exit(1);
    }

    /* Check if the server certificate and private-key matches */
    if (!SSL_CTX_check_private_key(ctx))
    {
        fprintf(stderr, "Private key does not match the certificate public key\n");
        exit(1);
    }

    /* Load the server encrypt certificate into the SSL_CTX structure */
    if (SSL_CTX_use_enc_certificate_file(ctx, SM2_SERVER_ENC_CERT, SSL_FILETYPE_PEM) <= 0)
    {
        ERR_print_errors_fp(stderr);
        exit(1);
    }

    /* Load the private-key corresponding to the server encrypt certificate */
    if (SSL_CTX_use_enc_PrivateKey_file(ctx, SM2_SERVER_ENC_KEY, SSL_FILETYPE_PEM) <= 0)
    {
        ERR_print_errors_fp(stderr);
        exit(1);
    }

    /* Check if the server encrypt certificate and private-key matches */
    if (!SSL_CTX_check_enc_private_key(ctx))
    {
        fprintf(stderr, "Private key does not match the certificate public key\n");
        exit(1);
    }


    if (verify_client == ON)
    {
        /* Load the RSA CA certificate into the SSL_CTX structure */
        if (!SSL_CTX_load_verify_locations(ctx, SM2_SERVER_CA_CERT, NULL))
        {
            ERR_print_errors_fp(stderr);
            exit(1);
        }

        /* Set to require peer (client) certificate verification */
        SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verify_callback);
        //SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
        //SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, verify_callback);

        /* Set the verification depth to 1 */
        SSL_CTX_set_verify_depth(ctx, 1);

    }
    /* ----------------------------------------------- */
#if WIN32

    WORD    wVersionRequested;
    WSADATA wsaData;
    int         iLen;
    wVersionRequested = MAKEWORD(2, 2);//create 16bit data
    err = WSAStartup(wVersionRequested, &wsaData);    //load win socket
    if (err != 0)
    {
        std::cout << "Load WinSock Failed!";
        return -1;
    }
#endif

    /* Set up a TCP socket */
    listen_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

    setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&opt, sizeof(opt));
    RETURN_ERR(listen_sock, "socket");
    memset(&sa_serv, '\0', sizeof(sa_serv));
    sa_serv.sin_family = AF_INET; 
    sa_serv.sin_addr.s_addr = INADDR_ANY;
    sa_serv.sin_port = htons(s_port);          /* Server Port number */
    err = bind(listen_sock, (struct sockaddr*) & sa_serv, sizeof(sa_serv));

    RETURN_ERR(err, "bind");

    /* Wait for an incoming TCP connection. */
    err = listen(listen_sock, 5);

    RETURN_ERR(err, "listen");
    client_len = sizeof(sa_cli);
    printf("Service With HSM=%s AIO=%s Port=%d\n", (hsm_tag ? "YES" : "NO"), (aio_tag ? "YES" : "NO"), s_port);

    /* Socket for a TCP/IP connection is created */
    sock = accept(listen_sock, (struct sockaddr*) & sa_cli, (socklen_t*)&client_len);

    RETURN_ERR(sock, "accept");
    closesocket(listen_sock);//close(listen_sock);

    inet_ntop(AF_INET, &sa_cli.sin_addr.s_addr, tmpbuf, sizeof(tmpbuf));
    printf("Connection from %s, port %d\n", tmpbuf, ntohs(sa_cli.sin_port));

    /* ----------------------------------------------- */
    /* TCP connection is ready. */
    /* A SSL structure is created */

    ssl = SSL_new(ctx);

    RETURN_NULL(ssl);

    /* Assign the socket into the SSL structure (SSL and socket without BIO) */
    SSL_set_fd(ssl, sock);

    /* Perform SSL Handshake on the SSL server */
    /*err = SSL_accept(ssl);*/
    SSL_set_accept_state(ssl);
    while (1)
    {
        err = SSL_do_handshake(ssl);
        if (err <= 0)
        {
            if (SSL_get_error(ssl, err) == SSL_ERROR_WANT_HSM_RESULT)
                continue;
            else
            {
                ERR_print_errors_fp(stderr);
                goto err;
            }
        }
        else
            break;
    }

    RETURN_SSL(err);

    /* Informational output (optional) */
    printf("SSL connection using %s\n", SSL_get_cipher(ssl));
    ShowCerts(ssl);


    /*------- DATA EXCHANGE - Receive message and send reply. -------*/
    /* Receive data from the SSL client */
    while (1) {
        memset(buf, 0x00, sizeof(buf));
        err = SSL_read(ssl, buf, sizeof(buf) - 1);
        if (err <= 0) {
            printf("ssl_read fail!\n");
            break;
        }
        break;
    }

    RETURN_SSL(err);

    buf[err] = '\0';

    printf("Received %d chars:'%s'\n", err, buf);

    /* Send data to the SSL client */
    err = SSL_write(ssl,
        "-----This message is from the SSL server-----",
        strlen("-----This message is from the SSL server-----"));

    RETURN_SSL(err);

    /*--------------- SSL closure ---------------*/
    /* Shutdown this side (server) of the connection. */

    err = SSL_shutdown(ssl);

    RETURN_SSL(err);

    /* Terminate communication on a socket */
    closesocket(sock);

err:

    /* Free the SSL structure */
    if (ssl) SSL_free(ssl);

    /* Free the SSL_CTX structure */
    if (ctx) SSL_CTX_free(ctx);

    return 0;


}

客户端

//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#if  1
#pragma comment(lib,"ws2_32.lib")

#include <memory.h>
#include <errno.h>
#include <WS2tcpip.h> 
#include <winsock2.h>
#include <windows.h>

#else

#include <netdb.h>
#include <unistd.h>
#include <strings.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/select.h>
#include <netinet/in.h>
#include <arpa/inet.h>


#endif //  1


#include "openssl/bio.h"
#include "openssl/err.h"
#include "openssl/rand.h"
#include "openssl/ssl.h"
#include "openssl/x509v3.h"

#define MAX_BUF_LEN 4096
#define CLIENT_S_CERT   "./cert/CS.pem"
#define CLIENT_E_CERT   "./cert/CE.pem"
#define CLIENT_CA_CERT  "./cert/CA.pem"
#define SSL_ERROR_WANT_HSM_RESULT 10


void Init_OpenSSL()
{
    if (!SSL_library_init())
        exit(0);
    SSL_load_error_strings();
}
/*
int seed_prng(int bytes)
{
    if (!RAND_load_file("/dev/random", bytes))
        return 0;
    return 1;
}
*/

int main_cli(int argc, char** argv)
{
    setvbuf(stdout, NULL, _IONBF, 0);
    BIO* conn = NULL;
    SSL* ssl = NULL;
    SSL_CTX* ctx = NULL;
    int usecert = 1;
    int retval;
    int aio_tag = 0;
    char sendbuf[MAX_BUF_LEN];
    int i = 0;
    const SSL_METHOD* meth;

    /*Detect arguments*/
    if (argc < 2)
    {
        printf("Usage : %s host:port [use_cert] [aio]\n", argv[0]);
        exit(0);
    }

    if (argc >= 3)
        usecert = atoi(argv[2]);

    if (argc >= 4)
        aio_tag = atoi(argv[3]);

    Init_OpenSSL();


    meth = CNTLS_client_method();
    ctx = SSL_CTX_new(meth);
    if (ctx == NULL)
    {
        printf("Error of Create SSL CTX!\n");
        goto err;
    }

    if (usecert)
    {
        if (SSL_CTX_use_certificate_file(ctx, CLIENT_S_CERT, SSL_FILETYPE_PEM) <= 0)
        {
            ERR_print_errors_fp(stderr);
            goto err;
        }

        if (SSL_CTX_use_PrivateKey_file(ctx, CLIENT_S_CERT, SSL_FILETYPE_PEM) <= 0)
        {
            ERR_print_errors_fp(stderr);
            goto err;
        }

        if (SSL_CTX_use_enc_certificate_file(ctx, CLIENT_E_CERT, SSL_FILETYPE_PEM) <= 0)
        {
            ERR_print_errors_fp(stderr);
            goto err;
        }
        if (SSL_CTX_use_enc_PrivateKey_file(ctx, CLIENT_E_CERT, SSL_FILETYPE_PEM) <= 0)
        {
            ERR_print_errors_fp(stderr);
            goto err;
        }

        if (!SSL_CTX_check_private_key(ctx))
        {
            printf("Private key does not match the certificate public key/n");
            goto err;
        }

        if (!SSL_CTX_check_enc_private_key(ctx))
        {
            printf("Private key does not match the certificate public key/n");
            goto err;
        }

        if (!SSL_CTX_load_verify_locations(ctx, CLIENT_CA_CERT, NULL))
        {
            ERR_print_errors_fp(stderr);
            exit(1);
        }

    }


    /*Now Connect host:port*/
    conn = BIO_new_connect(argv[1]);
    if (!conn)
    {
        printf("Error Of Create Connection BIO\n");
        goto err;
    }

    if (BIO_do_connect(conn) <= 0)
    {
        printf("Error Of Connect to %s\n", argv[1]);
        goto err;
    }

    if (!SSL_CTX_set_cipher_list(ctx, "ECDHE-SM4-SM3")) {
        printf("set cipher list fail!\n");
        exit(0);
    }

    ssl = SSL_new(ctx);
    if (ssl == NULL)
    {
        printf("SSL New Error\n");
        goto err;
    }

    SSL_set_bio(ssl, conn, conn);

    /*if (SSL_connect(ssl) <= 0)
    {
        printf("Error Of SSL connect server\n");
        goto err;
    }*/

    SSL_set_connect_state(ssl);
    //SSL_set_sm2_group_id_custom(29);
    while (1)
    {
        retval = SSL_do_handshake(ssl);
        if (retval > 0)
            break;
        else
        {
            if (SSL_get_error(ssl, retval) == SSL_ERROR_WANT_HSM_RESULT)
                continue;
            else
            {
                printf("Error Of SSL do handshake\n");
                goto err;
            }
        }
    }

    for (i = 0; i < MAX_BUF_LEN; i++) { 

        sprintf(sendbuf + i, "%d", i % 10);
    }

    while (1) {

        if (SSL_write(ssl, "hello i am from client ", strlen("hello i am from client ")) <= 0)
        {
            printf("ssl_write fail!\n");
            break;
        }
        break;
    }
    {
        char rbuf[2048];

        memset(rbuf, 0x0, sizeof(rbuf));
        if (SSL_read(ssl, rbuf, 2048) > 0)
            printf("SSL recv: %s.\n", rbuf);
        else
            printf("None recv buf.\n");

        SSL_shutdown(ssl);
    }

err:
    if (ssl) SSL_free(ssl);
    if (ctx) SSL_CTX_free(ctx);

    return 0;
}

 

posted @ 2020-04-23 16:43  Bigben  阅读(1252)  评论(0编辑  收藏  举报