SSL3_get_client_certificate:验证失败

时间:2017-09-28 11:11:35

标签: c ssl server openssl ssl-certificate

我使用TLS/SSL api在c中开发了openssl-1.0.2k服务器。为了验证客户端,我提供了CAfile并设置了以下选项。

SSL_CTX_load_verify_locations(ctx, "rootCAChain.chain", NULL );
SSL_CTX_set_client_CA_list( ctx, SSL_load_client_CA_file( "rootCAChain.chain" ) );
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL );
SSL_CTX_set_verify_depth(ctx, 2);

其中,rootCAChain.chain是两个PEM证书(根CA和中间CA)的列表。

我使用s_client应用程序使用以下命令测试我的服务器;

openssl s_client -connect 127.0.0.1:8888 -cert client.crt -key client.key  -CAfile rootCAChain.chain -msg -verify 2 -verify_return_error

问题SSL_accept来电期间的握手失败。我在错误队列中输入了错误,

err = SSL_accept(ssl);
if( err != 1 ) 
{
    ERR_error_string_n( ERR_get_error(), buf, sizeof(buf) );
    printf( buf );
    exit( 1 );
}

输出:

error:14089086:SSL routines:ssl3_get_client_certificate:certificate verify failed

我在客户端和服务器上拥有相同的证书副本以及CA.这是个问题吗? 另一方面,证书是可以的,因为我使用s_server进行了测试。完整代码如下。

 #define _CRT_SECURE_NO_DEPRECATE

 #include <windows.h>
 #include <winsock.h>
 #include <stdio.h>

 #include <openssl/crypto.h>
 #include <openssl/x509.h>
 #include <openssl/pem.h>
 #include <openssl/ssl.h>
 #include <openssl/err.h>

#pragma comment (lib,"uuid.lib")
#pragma comment (lib,"libeay32.lib")
#pragma comment (lib,"ssleay32.lib")
#pragma comment (lib,"Ws2_32.lib")
 //Prototypen
 int startWinsock(void);

int main()
{
    long rc;
    SOCKET acceptSocket;
    SOCKET connectedSocket = NULL;
    SOCKADDR_IN addr;
    char buf[1024];
    char buf2[1024];

    SSL_CTX *ctx;
    SSL *ssl;
    int err;

    rc = startWinsock();
    if(rc != 0)
    {
        printf("Fehler: startWinsock, Error Code: %d\n", rc);
        return 1;
    }
    else
    {
        printf("Winsock Started!\n");
    }

    acceptSocket = socket(AF_INET,SOCK_STREAM,0);
    if(acceptSocket == INVALID_SOCKET)
    {
        printf("Socket cannot be created, Error Code: %d\n",WSAGetLastError());
        return 1;
    }
    else
    {
        printf("Socket Created!\n");
    }

    memset(&addr,0,sizeof(SOCKADDR_IN));
    addr.sin_family=AF_INET;
    addr.sin_port=htons(8888);
    addr.sin_addr.s_addr=INADDR_ANY;

    rc=bind(acceptSocket,(SOCKADDR*)&addr,sizeof(SOCKADDR_IN));
    if(rc==SOCKET_ERROR)
    {
        printf("Error: bind, Error code: %d\n",WSAGetLastError());
        return 1;
    }
    else
    {
        printf("Bind successfull..\n");
    }

    rc = listen(acceptSocket,10);
    if(rc == SOCKET_ERROR)
    {
        printf("Error: listen, error code: %d\n",WSAGetLastError());
        return 1;
    }
    else
    {
        printf("acceptSocket is in listen Mode....\n");
    }

    connectedSocket = accept(acceptSocket,NULL,NULL);
    if(connectedSocket==INVALID_SOCKET)
    {
        printf("Error: accept, error code: %d\n",WSAGetLastError());
        return 1;
    }
    else
    {
        printf("New connection is accepted...!\n");
    }

    SSL_load_error_strings();
    SSL_library_init();

    ctx=SSL_CTX_new(SSLv23_server_method());

    err = SSL_CTX_use_certificate_file(ctx, "serverCert.crt",  SSL_FILETYPE_PEM);
    if (err != 1)
        printf("SSL_CTX_use_certificate_file failed\n");
    else
        printf("certificate file loaded ok\n");

    /* Indicate the key file to be used */
    err = SSL_CTX_use_PrivateKey_file(ctx, "serverKey.key", SSL_FILETYPE_PEM);
    if (err != 1)
        printf("SSL_CTX_use_PrivateKey_file failed\n");
    else
        printf("private-key file loaded ok\n");

      /* Make sure the key and certificate file match. */
    if (SSL_CTX_check_private_key(ctx) != 1)
        printf("SSL_CTX_check_private_key failed\n");
    else
        printf("private key verified ok\n");

    if (SSL_CTX_load_verify_locations(ctx, "rootCAChain.chain", NULL ) != 1)
        printf("Error loading CA file and/or directory");

    // if (SSL_CTX_set_default_verify_paths(ctx) != 1)
        // printf("Error loading default CA file and/or directory");

    SSL_CTX_set_client_CA_list( ctx, SSL_load_client_CA_file( "rootCAChain.chain" ) );

    SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT|SSL_VERIFY_CLIENT_ONCE, NULL );

    SSL_CTX_set_verify_depth(ctx, 2);

    // SSL_CTX_set_options(ctx, SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3);

    ssl = SSL_new(ctx);
    if(!ssl) 
    {
        closesocket(connectedSocket);
        fprintf(stderr, "SSL creation error\n");
        return -1;
    }
    SSL_set_fd(ssl, connectedSocket);

    err = SSL_accept(ssl);
    if( err != 1 ) 
    {
        ERR_error_string_n( ERR_get_error(), buf, sizeof(buf) );
        printf( buf );
        exit( 1 );
    }
    printf("SSL accepted.. \n");
    while(1)
    {
        int read_size = SSL_read(ssl, buf, sizeof(buf) );
        if ( read_size > 0 )
        {
            buf[read_size]='\0';
            printf("Getting %d Bytes of Data\nData: %s\n", read_size, buf);
        }

        sprintf( buf2,"Du mich auch %s\r\n", "x" );
        err=SSL_write(ssl, buf2, strlen(buf2));
        if(!err) 
        {
            closesocket(connectedSocket);
            fprintf(stderr, "SSL write error\n");
            return -1;
        }

        Sleep(1000);
    } 

    SSL_shutdown(ssl);
    SSL_free(ssl);
    SSL_CTX_free(ctx);
    fflush(stdout);
    closesocket(acceptSocket);
    closesocket(connectedSocket);
    WSACleanup();
    return 0;
}

int startWinsock(void)
{
    WSADATA wsa;
    return WSAStartup(MAKEWORD(2,0),&wsa);
}

0 个答案:

没有答案