Obtaining ssl certificate on windows using C++

前端 未结 1 968
囚心锁ツ
囚心锁ツ 2021-01-06 15:25

I am trying to obtain a remote server\'s ssl certificate on windows. One option I have found is to use openssl. The command to do that as indicated by some posts on the inte

相关标签:
1条回答
  • 2021-01-06 16:01

    Here is a minimalistic program I created that connects to a server and prints its ssl certificate to the standard output. 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. 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.

    0 讨论(0)
提交回复
热议问题