微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用C在Windows上获取ssl证书

我试图在Windows获取远程服务器的ssl证书.我发现的一个选择是使用openssl.如internet上的一些帖子所示,执行此操作的命令是:

openssl.exe s_client -showcerts -connect {REMOTE_SERVER_IP}:{REMOTE_SERVER_PORT}

这很好用,但我的问题是上面的命令超时为300秒.证书本身打印速度非常快,当我在最初的几秒钟内得到所有我想要的东西时,我认为没有理由等待300秒.我仍然认为没有办法更改s_client上的timeout参数.所以我试图找到一种方法在一段时间后杀死Windows上的一个进程,但那里再没有运气.关于如何做到这一点的任何想法?如果有一些其他窗口方式来获取远程服务器ssl证书并将其存储在文件中,这也将完成这项工作.

编辑:根据布鲁诺的要求添加更多信息.
我正在尝试创建一个获取远程服务器的SSL证书的c应用程序,并将其存储在文件中以供进一步处理.由于我的应用程序已经使用openssl.exe,我需要一个使用openssl.exe或标准Windows命令的解决方案(即不需要任何其他库).

EDIT2:我找到了一种方法来避免在linux中等待 – 只需创建一个文件并将openssl s_client的输入重定向到它(或使用管道传递空输入).这适用于Windows,但使用旧版本的openssl(0.9.8l).我尝试使用0.9.8r和1.0.1b并将输入重定向到空文件没有帮助.

解决方法:

这是我创建的一个简约程序,它连接到服务器并将其ssl证书打印到标准输出.希望它能帮助其他人解决类似的问题:

#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);
}

代码this post建议的here的示例的修改版本.

编辑:我不断收到错误OPENSSL_UPLINK:在Windows上没有OPENSSL_APPLINK.在网上搜索了很多次后,我找到了this post并将其添加到我的代码中:

extern "C" {
   #include <openssl/applink.c>
}

似乎这是一些解决方法,以避免编译器和运行时选项兼容性的要求.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐