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.

Reply via email to