Discussion:
SSL_get_peer_certificate giving empty certificate on Yosemite.
Madhavi Shashi
2014-10-17 07:01:11 UTC
Permalink
Hi,

I am using below code to get domain name/server name from IP address on Mac
OS X. But SSL_get_peer_certificateis returning empty certificate for
twitter and some of the https sites.
This problem I am facing from Yesterday. After Yosemite release.


Log:
----------------------------------------------------
22:33:44 SSLUtil::ConnectToServerAsync in progress 23.52.67.194
22:33:45 **** successfully connected and got file descriptor 1
22:33:45 SSLUtil::ConnectToServerAsync connect success 36
22:33:45 SSL_ERROR_WANT_READ
22:33:45 sockstate read 4
22:33:45 SOCKET_OPERATION_OK
22:33:45 SSLUtil::RetrieveNameUsingSSL certificate empty
-----------------------------------------------

Source code:

bool SSLUtil::RetrieveNameUsingSSL(int &sock , std::string &serverName)
{
serverName="";
SSL_library_init();
SSL_METHOD *meth=SSLv3_method();
SSL_CTX *sslctx=SSL_CTX_new(meth);
if(!sslctx)
{
//printf("SSL_CTX_new failed");
MCLOG("SSLUtil::RetrieveNameUsingSSL SSL_CTX_new failed ");
//close(sock);
return false;
}
SSL_CTX_set_verify(sslctx,SSL_VERIFY_NONE,NULL);
SSL *ssl =SSL_new(sslctx);
if(!ssl)
{
//printf("SSL_new failed\n"); close(sock);
MCLOG("SSLUtil::RetrieveNameUsingSSL SSL_new failed ");
//exit(4);
return false;
}
int status=SSL_set_fd(ssl,sock);
if(!status)
{
//printf("SSL_set_fd failed\n"); close(sock);
//exit(5);
MCLOG("SSLUtil::RetrieveNameUsingSSL SSL_set_fd failed ");
return false;
}

status = SSL_connect(ssl);
int error=SSL_get_error(ssl,status);
//printf("Error %d\n",error);
switch(error)
{
case SSL_ERROR_NONE:
//printf("connect successful\n");
break;
case SSL_ERROR_ZERO_RETURN:
//printf("peer close ssl connection \n");
break;
case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_WRITE:
{
time_t seconds;
time_t future;
time_t now;

seconds = time(NULL);
future = seconds + 2;

MCLOG("SSLUtil::RetrieveNameUsingSSL Before SSL_ERROR_WANT_READ
& SSL_ERROR_WANT_WRITE");
while(error == SSL_ERROR_WANT_READ || error ==
SSL_ERROR_WANT_WRITE)
{
status = SSL_connect(ssl);
if(!WaitOnSocket(sock,TIMEOUT_SERVER))
{
MCLOG("WaitOnSocket func failed");
break;
}
now = time(NULL);
if(now > future)
{
MCLOG("*** break");
break;
}
error=SSL_get_error(ssl,status);
if(error == SSL_ERROR_NONE)
{
MCLOG("SSL_ERROR_NONE");
break;
}
}
}
break;

default:
MCLOG("SSLUtil::RetrieveNameUsingSSL failed ",error);
//printf("connect error is %d\n",error);
break;
}

X509* server_cert = SSL_get_peer_certificate (ssl);
if (server_cert != NULL)
{
//MessageLog.Write("Server certificate");
//str = X509_NAME_oneline(X509_get_subject_name(server_cert),0,0);
X509_NAME * name = X509_get_subject_name(server_cert);
char str[512] = {} ;
X509_NAME_get_text_by_NID(name, NID_commonName, str, 512);

if(str != NULL)
{
serverName = str;
//MessageLog.Write("Domain name :", str);
//MessageLog.Write("Successfully fetched the certificate");
}
else
{
MCLOG("SSLUtil::RetrieveNameUsingSSL server name empty ");
}

X509_free (server_cert);
}
else
{
MCLOG("SSLUtil::RetrieveNameUsingSSL certificate empty ");
}

if(ssl)
{
error = SSL_shutdown(ssl);
if(error == -1)
{
//MessageLog.Write("Failed to do SSLShutdown");
MCLOG("SSLUtil::RetrieveNameUsingSSL SSLShutdown failed ");
}
// Free the SSL structure
//MessageLog.Write("free SSL structure");
SSL_free(ssl);
}

// Free the SSL_CTX structure
if(sslctx)
{
SSL_CTX_free(sslctx);
}

return (!serverName.empty());

}

Why I am getting empty certificate?? I tried adding cipher
"SSL_set_cipher_list(ssl,"SSL_RSA_WITH_RC4_128_SHA);


Thanks and Regards,
Madhavi G.

Loading...