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
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.