Chinaunix首页 | 论坛 | 博客
  • 博客访问: 8053281
  • 博文数量: 594
  • 博客积分: 13065
  • 博客等级: 上将
  • 技术积分: 10324
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-26 16:44
个人简介

推荐: blog.csdn.net/aquester https://github.com/eyjian https://www.cnblogs.com/aquester http://blog.chinaunix.net/uid/20682147.html

文章分类

全部博文(594)

分类: C/C++

2015-06-12 11:28:08

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

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

OpenSSL编程入门(含完整示例).pdf ssl_test.zip ssl_manager.zip
OpenSSL初始化和注册两个回调函数可参考如下代码:

  1. CSSLmanager::CSSLmanager()
  2.     : m_ctx(NULL), m_lock_cs(NULL)
  3. {
  4. }

  5. void CSSLmanager::SSLFini()
  6. {
  7.     CRYPTO_set_locking_callback(NULL);
  8.     for (int i = 0; i < CRYPTO_num_locks(); i++)
  9.     {
  10.         pthread_mutex_destroy(&m_lock_cs[i]);
  11.     }

  12.     OPENSSL_free(m_lock_cs);
  13.     if (m_ctx != NULL)
  14.     {
  15.         SSL_CTX_free((SSL_CTX *)m_ctx);
  16.         m_ctx = NULL;
  17.     }

  18.     ERR_free_strings();
  19.     EVP_cleanup();
  20. }

  21. bool CSSLmanager::SSLInit(const TChar* cacert, const TChar * privkey)
  22. {
  23.     SSL_library_init(); // SSL库初始化
  24.     OpenSSL_add_all_algorithms(); // 载入所有 SSL 算法
  25.     SSL_load_error_strings(); // 载入所有SSL错误消息
  26.     
  27.     while (true)
  28.     {
  29.         // 以 SSL V2 和 V3 标准兼容方式产生一个 SSL_CTX ,即 SSL Content Text
  30.         SSL_CTX* ctx = SSL_CTX_new(SSLv23_server_method());
  31.         if (NULL == ctx)
  32.             break;
  33.         
  34.         // 载入用户的数字证书, 此证书用来发送给客户端,证书里包含有公钥
  35.         if (SSL_CTX_use_certificate_file(ctx, cacert, SSL_FILETYPE_PEM) != 1)
  36.             break;

  37.         // 载入用户私钥
  38.         if (SSL_CTX_use_PrivateKey_file(ctx, privkey, SSL_FILETYPE_PEM) != 1)
  39.             break;

  40.         // 检查用户私钥是否正确
  41.         if (SSL_CTX_check_private_key(ctx) != 1)
  42.             break;

  43.         m_ctx = (void *)ctx;
  44.         m_lock_cs = (pthread_mutex_t *)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));
  45.         for (int i = 0; i < CRYPTO_num_locks(); ++i)
  46.         {
  47.             pthread_mutex_init(&(m_lock_cs[i]),NULL);
  48.         }

  49.         CRYPTO_set_id_callback(IDFunction); // 注册回调
  50.         CRYPTO_set_locking_callback(LockingFunction); // 注册回调
  51.         return true;
  52.     }

  53.     SSLFini();
  54.     return false;
  55. }

  56. unsigned long CSSLmanager::IDFunction( void )
  57. {
  58.     return ((unsigned long)pthread_self());
  59. }

  60. void CSSLmanager::LockingFunction(int mode, int type, const char *file, int line)
  61. {
  62.     pthread_mutex_t* lock = CSSLmanager::singleton()->GetLock();

  63.     if (mode & CRYPTO_LOCK) {
  64.         pthread_mutex_lock(&lock[type]);
  65.     } else {
  66.         pthread_mutex_unlock(&lock[type]);
  67.     }
  68. }

阅读(2886) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~