openssl查询客户端证书

时间:2018-05-31 05:20:13

标签: c++ c ssl openssl

我的服务器无法获得对等证书 这适用于SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,0);已移除 添加它会导致客户端和服务器无法通信 从服务器查询客户端证书总是给出NULL

以下是以下代码: - 头文件socket.h,用于服务器和客户端示例

#ifndef SOCKET_H
#define SOCKET_H

#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <set>

#include <openssl/ssl.h>
#include <openssl/err.h>
#include <thread>

int g_start=[]()->int{
        system("../Servercert.sh");  /*create the certificates*/
        SSL_load_error_strings(); /* load all error messages */
        SSL_library_init(); /* load & register all cryptos, etc for TLS 1.2. */
        return 0;
        }();  //initialize this for all who use TLS 1.2

/*---------------------------------------------------------------------*/
/*--- LoadCertificates - load from files.                           ---*/
/*---------------------------------------------------------------------*/
void LoadCertificates(SSL_CTX* ctx, char* CertFile, char* KeyFile)
{
    /* set the local certificate from CertFile */
    if ( SSL_CTX_use_certificate_file(ctx, CertFile, SSL_FILETYPE_PEM) <= 0 )
    {
        ERR_print_errors_fp(stderr);
        abort();
    }
    /* set the private key from KeyFile (may be the same as CertFile) */
    if ( SSL_CTX_use_PrivateKey_file(ctx, KeyFile, SSL_FILETYPE_PEM) <= 0 )
    {
        ERR_print_errors_fp(stderr);
        abort();
    }
    /* verify private key */
    if ( !SSL_CTX_check_private_key(ctx) )
    {
        fprintf(stderr, "Private key does not match the public certificate\n");
        abort();
    }
}

SSL_CTX* InitCTX(void)
{   const SSL_METHOD *method;
    SSL_CTX *ctx;

    method = SSLv23_method(); /* Create new client-method instance */
    ctx = SSL_CTX_new(method); /* Create new context */
    if ( ctx == NULL )
    {
        ERR_print_errors_fp(stderr);
        abort();
    }
    return ctx;
}


#endif // SOCKET_H

我的服务器源文件

#include <iostream>
using namespace std;

#include "socket.h"

SSL *socketsInListenMode(SSL_CTX * &ctx,int portno)
{
    ctx = InitCTX(); /* initialize SSL */
    LoadCertificates(ctx, "server.cert","server.key");
    SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,0);

    sockaddr_in serv_addr={},cli_addr={};
    int sockListenfd = socket(AF_INET, SOCK_STREAM, 0);

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = htons(portno);

    int bindret=bind(sockListenfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
    cout<<bindret<<endl;
    if(bindret < 0) return 0;

    listen(sockListenfd,10);

    socklen_t s=0;
    int newsockfd = accept(sockListenfd, (struct sockaddr *)&cli_addr, &s);

    SSL *ssl = SSL_new(ctx);         /* get new SSL state with context */
    SSL_set_fd(ssl, newsockfd); /* set connection socket to SSL state */
    SSL_accept(ssl);

    close( sockListenfd );
    sockListenfd = 0;   //this will cause Accept to return
    return ssl;
}

#include<string>
int main()
{
    SSL_CTX *ctx=0;
    SSL *ssl = socketsInListenMode(ctx,5000);

    string s="asif";
    SSL_write(ssl,s.c_str(),s.length());  //may no write the full string (but thats okay for our sample)

    close(SSL_get_fd(ssl));
    SSL_free(ssl);
    SSL_CTX_free(ctx);
    return 0;
}

我的客户端源文件

#include <iostream>
#include "../server/socket.h"

using namespace std;

int SocketConnect(int portno, string strIP)
{
    struct sockaddr_in serv_addr={};

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = inet_addr(strIP.c_str());
    serv_addr.sin_port = htons(portno);

    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    int ret=connect(sockfd,(struct sockaddr *) &serv_addr, sizeof(serv_addr));
    if(-1 == ret)
    {
        return -1;
    }
    return sockfd;
}

SSL *secureConnect(SSL_CTX * &ctx,int portno, string strIP)
{
    ctx = InitCTX();

    LoadCertificates(ctx, "server.cert","server.key");
    SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,0);

    SSL *ssl = SSL_new(ctx); /* create new SSL connection state */

    int sfd=SocketConnect(portno,strIP);  //socketConnect

    if(-1 == sfd)
        return NULL;

    SSL_set_fd(ssl, sfd);
    SSL_connect(ssl);         //SSL connect

    return ssl;
}

int main()
{
    SSL_CTX *ctx=0;
    SSL *ssl = secureConnect(ctx,5000,"127.0.0.1");

    char buff[100]={};
    SSL_read(ssl,buff,sizeof(buff));
    cout<<buff<<endl<<flush;

    close(SSL_get_fd(ssl));
    SSL_free(ssl);
    SSL_CTX_free(ctx);
    return 0;
}

1 个答案:

答案 0 :(得分:1)

实际上,如果没有SSL_CTX_set_verify也不应该工作,因为在握手期间验证对等证书时未指定CA证书的位置,如果您使用了自签名证书可能会有效

您应该使用SSL_CTX_load_verify_locations来设置CA证书