[英]Obtaining ssl certificate on windows using C++
I am trying to obtain a remote server's ssl certificate on windows. 我试图在Windows上获取远程服务器的ssl证书。 One option I have found is to use openssl.
我发现的一个选择是使用openssl。 The command to do that as indicated by some posts on the internet is:
互联网上一些帖子所指示的命令是:
openssl.exe s_client -showcerts -connect {REMOTE_SERVER_IP}:{REMOTE_SERVER_PORT}
This works perfectly, but my problem is that the above command has a timeout of 300 seconds. 这很好用,但我的问题是上面的命令超时为300秒。 The certificate itself gets printed pretty fast and I see no reason to wait 300 seconds when I get all I want in the first few seconds.
证书本身打印速度非常快,当我在最初的几秒钟内得到所有我想要的东西时,我认为没有理由等待300秒。 Still I think there is no way to change the timeout parameter on s_client.
我仍然认为没有办法更改s_client上的timeout参数。 So I tried to figure a way to kill a process on windows after a given period of time but again had no luck there.
所以我试图找到一种方法在一段时间后杀死Windows上的一个进程,但那里再没有运气。 Any ideas on how can this be done?
关于如何做到这一点的任何想法? If there is some other windows way to a obtain a remote servers ssl certificate and store it in a file this will also do the job.
如果有一些其他窗口方式来获取远程服务器ssl证书并将其存储在文件中,这也将完成这项工作。
EDIT: as per Bruno's request adding more information. 编辑:根据布鲁诺的要求添加更多信息。 I am trying to create a c++ application that gets the SSL certificate of a remote server and stores it in a file for further processing.
我正在尝试创建一个c ++应用程序,它获取远程服务器的SSL证书并将其存储在文件中以供进一步处理。 As my application already makes use of openssl.exe I either need a solution that uses openssl.exe or a standard windows command(ie does not require any additional libraries).
由于我的应用程序已经使用openssl.exe,我需要一个使用openssl.exe或标准Windows命令的解决方案(即不需要任何其他库)。
EDIT2: I have found a way to avoid the waiting in linux - just create an empty file and redirect the input of openssl s_client to it(or use pipe to pass empty input). EDIT2:我找到了一种方法来避免在linux中等待 - 只需创建一个空文件并将openssl s_client的输入重定向到它(或使用管道传递空输入)。 This works on windows as well but with older versions of openssl(0.9.8l).
这适用于Windows,但使用旧版本的openssl(0.9.8l)。 I tried it with 0.9.8r and with 1.0.1b and redirecting the input to an empty file does not help there.
我尝试使用0.9.8r和1.0.1b并将输入重定向到空文件没有帮助。
Here is a minimalistic program I created that connects to a server and prints its ssl certificate to the standard output. 这是我创建的一个简约程序,它连接到服务器并将其ssl证书打印到标准输出。 Hope it will help someone else to resolve similar issue:
希望它能帮助其他人解决类似的问题:
#ifdef WIN32
#include <windows.h>
#include <winsock2.h>
#else
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#endif
#include <openssl/ssl.h>
#include <cstdlib>
#include <iostream>
static const char *host= "10.23.10.12";
static int port=443;
int tcp_connect(const char *host,int port)
{
#ifdef WIN32
WSADATA wsaData;
WORD version;
int error;
version = MAKEWORD( 2, 0 );
error = WSAStartup( version, &wsaData );
/* check for error */
if ( error != 0 )
{
/* error occured */
return -1;
}
/* check for correct version */
if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 0 )
{
/* incorrect WinSock version */
WSACleanup();
return -1;
}
/* WinSock has been initialized */
#endif
struct hostent *hp;
struct sockaddr_in addr;
int sock;
if(!(hp=gethostbyname(host)))
printf("Couldn't resolve host");
memset(&addr,0,sizeof(addr));
addr.sin_addr=*(struct in_addr*)
hp->h_addr_list[0];
addr.sin_family=AF_INET;
addr.sin_port=htons(port);
if((sock=(int)socket(AF_INET,SOCK_STREAM,
IPPROTO_TCP))<0)
printf("Couldn't create socket");
if(connect(sock,(struct sockaddr *)&addr,
sizeof(addr))<0)
printf("Couldn't connect socket");
return sock;
}
int main(int argc,char **argv)
{
SSL_CTX *ctx;
SSL *ssl;
BIO *sbio;
int sock;
SSL_METHOD *meth=NULL;
meth=SSLv23_client_method();
OpenSSL_add_ssl_algorithms();
SSL_load_error_strings();
ctx=SSL_CTX_new(meth);
/* Connect the TCP socket*/
sock=tcp_connect(host,port);
/* Connect the SSL socket */
ssl=SSL_new(ctx);
sbio=BIO_new_socket(sock,BIO_NOCLOSE);
SSL_set_bio(ssl,sbio,sbio);
if(SSL_connect(ssl)<=0)
printf("SSL connect error");
X509 *peer;
peer=SSL_get_peer_certificate(ssl);
PEM_write_X509(stdout, peer);
SSL_CTX_free(ctx);
close(sock);
#ifdef WIN32
closesocket(sock);
WSACleanup();
#else
close(sock);
#endif
exit(0);
}
The code is modified version of the examples found here as suggested by this post . 该代码被修改的发现实例的版本在这里所建议这个职位 。
EDIT: I kept getting the error OPENSSL_UPLINK: no OPENSSL_APPLINK on windows. 编辑:我不断收到错误OPENSSL_UPLINK:在Windows上没有OPENSSL_APPLINK。 After a lot of searching around the internet I found this post and added this to my code:
在互联网上进行了大量搜索之后,我找到了这篇文章并将其添加到我的代码中:
extern "C" {
#include <openssl/applink.c>
}
Seems this is some work around to avoid the requirement for compiler and run-time options compatibility. 似乎这是一些解决方法,以避免编译器和运行时选项兼容性的要求。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.