天天看点

curl和https,及openssl

如果使用curl访问https(注意不是http),则会牵涉到OpenSSL,就需要注意多线程安全问题。

一是OpenSSL需要编译成多线程安全版本,二是需要为OpenSSL注册两个回调函数。如果不这样多线程环境应用时,会遇到coredump问题。

curl和https,及openssl

OpenSSL初始化和注册两个回调函数可参考如下代码:

CSSLmanager::CSSLmanager()

    : m_ctx(NULL), m_lock_cs(NULL)

{

}

void CSSLmanager::SSLFini()

    CRYPTO_set_locking_callback(NULL);

    for (int i = 0; i CRYPTO_num_locks(); i++)

    {

        pthread_mutex_destroy(&m_lock_cs[i]);

    }

    OPENSSL_free(m_lock_cs);

    if (m_ctx != NULL)

        SSL_CTX_free((SSL_CTX *)m_ctx);

        m_ctx = NULL;

    ERR_free_strings();

    EVP_cleanup();

bool CSSLmanager::SSLInit(const TChar* cacert, const TChar * privkey)

    SSL_library_init(); // SSL库初始化

    OpenSSL_add_all_algorithms(); // 载入所有 SSL 算法

    SSL_load_error_strings(); // 载入所有SSL错误消息

    while (true)

        // 以 SSL V2 和 V3 标准兼容方式产生一个 SSL_CTX ,即 SSL Content Text

        SSL_CTX* ctx = SSL_CTX_new(SSLv23_server_method());

        if (NULL == ctx)

            break;

        // 载入用户的数字证书, 此证书用来发送给客户端,证书里包含有公钥

        if (SSL_CTX_use_certificate_file(ctx, cacert, SSL_FILETYPE_PEM) != 1)

        // 载入用户私钥

        if (SSL_CTX_use_PrivateKey_file(ctx, privkey, SSL_FILETYPE_PEM) != 1)

        // 检查用户私钥是否正确

        if (SSL_CTX_check_private_key(ctx) != 1)

        m_ctx = (void *)ctx;

        m_lock_cs = (pthread_mutex_t *)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));

        for (int i = 0; i CRYPTO_num_locks(); ++i)

        {

            pthread_mutex_init(&(m_lock_cs[i]),NULL);

        }

        CRYPTO_set_id_callback(IDFunction); // 注册回调

        CRYPTO_set_locking_callback(LockingFunction); // 注册回调

        return true;

    SSLFini();

    return false;

unsigned long CSSLmanager::IDFunction( void )

    return ((unsigned long)pthread_self());

void CSSLmanager::LockingFunction(int mode, int type, const char *file, int line)

    pthread_mutex_t* lock = CSSLmanager::singleton()->GetLock();

    if (mode & CRYPTO_LOCK) {

        pthread_mutex_lock(&lock[type]);

    } else {

        pthread_mutex_unlock(&lock[type]);

继续阅读