关键词搜索

源码搜索 ×
×

tars源码分析之18

发布2022-07-10浏览752次

详情内容

ssl加密管理类:

  1. #if TARS_SSL
  2. #include "util/tc_sslmgr.h"
  3. #include "util/tc_buffer.h"
  4. #include <arpa/inet.h>
  5. #include <openssl/ssl.h>
  6. #include <openssl/err.h>
  7. namespace tars
  8. {
  9. SSLManager::SSLManager()
  10. {
  11. }
  12. void SSLManager::GlobalInit()
  13. {
  14. (void)SSL_library_init();
  15. OpenSSL_add_all_algorithms();
  16. ERR_load_ERR_strings();
  17. SSL_load_error_strings();
  18. }
  19. SSLManager::~SSLManager()
  20. {
  21. for (CTX_MAP::iterator it(_ctxSet.begin());
  22. it != _ctxSet.end();
  23. ++ it)
  24. {
  25. SSL_CTX_free(it->second);
  26. }
  27. ERR_free_strings();
  28. EVP_cleanup();
  29. }
  30. bool SSLManager::AddCtx(const std::string& name,
  31. const std::string& cafile,
  32. const std::string& certfile,
  33. const std::string& keyfile,
  34. bool verifyClient)
  35. {
  36. if (_ctxSet.count(name))
  37. return false;
  38. SSL_CTX* ctx = SSL_CTX_new(SSLv23_method());
  39. if (!ctx)
  40. return false;
  41. #define RETURN_IF_FAIL(call) \
  42. if ((call) <= 0) { \
  43. ERR_print_errors_fp(stderr); \
  44. return false;\
  45. }
  46. if (verifyClient)
  47. SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
  48. else
  49. SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
  50. SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
  51. SSL_CTX_clear_options(ctx, SSL_OP_LEGACY_SERVER_CONNECT);
  52. SSL_CTX_clear_options(ctx, SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION);
  53. RETURN_IF_FAIL (SSL_CTX_set_session_id_context(ctx, (const unsigned char*)ctx, sizeof ctx));
  54. if (!cafile.empty())
  55. RETURN_IF_FAIL (SSL_CTX_load_verify_locations(ctx, cafile.data(), NULL));
  56. // 客户端可以不提供证书的
  57. if (!certfile.empty())
  58. RETURN_IF_FAIL (SSL_CTX_use_certificate_file(ctx, certfile.data(), SSL_FILETYPE_PEM));
  59. if (!keyfile.empty())
  60. {
  61. RETURN_IF_FAIL (SSL_CTX_use_PrivateKey_file(ctx, keyfile.data(), SSL_FILETYPE_PEM));
  62. RETURN_IF_FAIL (SSL_CTX_check_private_key(ctx));
  63. }
  64. #undef RETURN_IF_FAIL
  65. return _ctxSet.insert(std::make_pair(name, ctx)).second;
  66. }
  67. SSL_CTX* SSLManager::GetCtx(const std::string& name) const
  68. {
  69. CTX_MAP::const_iterator it = _ctxSet.find(name);
  70. return it == _ctxSet.end() ? NULL: it->second;
  71. }
  72. SSL* NewSSL(const std::string& ctxName)
  73. {
  74. SSL_CTX* ctx = SSLManager::getInstance()->GetCtx(ctxName);
  75. if (!ctx)
  76. return NULL;
  77. SSL* ssl = SSL_new(ctx);
  78. SSL_set_mode(ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); // allow retry ssl-write with different args
  79. SSL_set_bio(ssl, BIO_new(BIO_s_mem()), BIO_new(BIO_s_mem()));
  80. BIO_set_mem_eof_return(SSL_get_rbio(ssl), -1);
  81. BIO_set_mem_eof_return(SSL_get_wbio(ssl), -1);
  82. return ssl;
  83. }
  84. void GetMemData(BIO* bio, TC_Buffer& buf)
  85. {
  86. while (true)
  87. {
  88. buf.AssureSpace(16 * 1024);
  89. int bytes = BIO_read(bio, buf.WriteAddr(), buf.WritableSize());
  90. if (bytes <= 0)
  91. return;
  92. buf.Produce(bytes);
  93. }
  94. // never here
  95. }
  96. void GetSSLHead(const char* data, char& type, unsigned short& ver, unsigned short& len)
  97. {
  98. type = data[0];
  99. ver = *(unsigned short*)(data + 1);
  100. len = *(unsigned short*)(data + 3);
  101. ver = ntohs(ver);
  102. len = ntohs(len);
  103. }
  104. bool DoSSLRead(SSL* ssl, std::string& out)
  105. {
  106. while (true)
  107. {
  108. char plainBuf[32 * 1024];
  109. ERR_clear_error();
  110. int bytes = SSL_read(ssl, plainBuf, sizeof plainBuf);
  111. if (bytes > 0)
  112. {
  113. out.append(plainBuf, bytes);
  114. }
  115. else
  116. {
  117. int err = SSL_get_error(ssl, bytes);
  118. // when peer issued renegotiation, here will demand us to send handshake data.
  119. // write to mem bio will always success, only need to check whether has data to send.
  120. //assert (err != SSL_ERROR_WANT_WRITE);
  121. if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_ZERO_RETURN)
  122. {
  123. printf("DoSSLRead err %d\n", err);
  124. return false;
  125. }
  126. break;
  127. }
  128. }
  129. return true;
  130. }
  131. } // end namespace tars
  132. #endif // end #if TARS_SSL

相关技术文章

点击QQ咨询
开通会员
返回顶部
×
微信扫码支付
微信扫码支付
确定支付下载
请使用微信描二维码支付
×

提示信息

×

选择支付方式

  • 微信支付
  • 支付宝付款
确定支付下载