打开 SSL 查询客户端证书

openssl query client certificate

本文关键字:证书 客户端 查询 SSL 打开      更新时间:2023-10-16

我的服务器无法获取对等证书 这在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 certificaten");
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;
}

实际上不应该在没有SSL_CTX_set_verify的情况下工作,因为您在握手期间验证对等证书时没有指定在哪里可以找到CA证书,如果您使用了自签名证书,它可能有效

应使用SSL_CTX_load_verify_locations设置 CA 证书