C++ openssl查询客户端证书
我的服务器无法获取对等证书 当SSL\u CTX\u set\u verify(CTX,SSL\u verify\u PEER,0);被移除 添加它会导致客户端和服务器无法通信 从服务器查询客户端证书时,总是返回NULL 以下是以下代码:- 头文件socket.h,在服务器和客户端示例中使用C++ openssl查询客户端证书,c++,c,ssl,openssl,C++,C,Ssl,Openssl,我的服务器无法获取对等证书 当SSL\u CTX\u set\u verify(CTX,SSL\u verify\u PEER,0);被移除 添加它会导致客户端和服务器无法通信 从服务器查询客户端证书时,总是返回NULL 以下是以下代码:- 头文件socket.h,在服务器和客户端示例中使用 #ifndef SOCKET_H #define SOCKET_H #include <sys/types.h> #include <sys/socket.h> #include
#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;
}
\ifndef插座
#定义套接字
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
int g_start=[]()->int{
系统(“../Servercert.sh”);/*创建证书*/
SSL_load_error_strings();/*加载所有错误消息*/
SSL_library_init();/*加载并注册TLS 1.2的所有密码等*/
返回0;
}(); //为所有使用TLS 1.2的用户初始化此选项
/*---------------------------------------------------------------------*/
/*---LoadCertificates-从文件加载---*/
/*---------------------------------------------------------------------*/
无效加载证书(SSL_CTX*CTX、char*CertFile、char*KeyFile)
{
/*从证书文件设置本地证书*/
如果(SSL_CTX_use_certificate_file(CTX,CertFile,SSL_FILETYPE_PEM)实际上不应该在没有SSL_CTX_set_verify
的情况下工作,也因为在握手期间验证对等证书时,您没有指定在何处查找CA证书,如果您使用了自签名证书,它可能会工作吗
您应该使用SSL\u CTX\u load\u verify\u locations
设置CA证书以便正确调用了SSL\u CTX\u set\u verify(CTX,SSL\u verify\u PEER,0)?我在哪里调用X509*cert=SSL\u get\u PEER\u certificate(m\u SSL);[在我的服务器代码中]?最好在SSL\u CTX\u set\u verify()中设置回调,此回调也将接收对等证书,有关更多信息,请参阅openssl文档中的SSL\u CTX\u set\u verify,但更重要的是使用SSL\u CTX\u load\u verify\u位置设置您的信任存储,如我在回答中所述