1
0

openssl.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. #include "hssl.h"
  2. #include "hlog.h"
  3. #ifdef WITH_OPENSSL
  4. #include "openssl/ssl.h"
  5. #include "openssl/err.h"
  6. #ifdef _MSC_VER
  7. //#pragma comment(lib, "libssl.a")
  8. //#pragma comment(lib, "libcrypto.a")
  9. #endif
  10. const char* hssl_backend() {
  11. return "openssl";
  12. }
  13. hssl_ctx_t hssl_ctx_new(hssl_ctx_opt_t* param) {
  14. static int s_initialized = 0;
  15. if (s_initialized == 0) {
  16. #if OPENSSL_VERSION_NUMBER < 0x10100000L
  17. SSL_library_init();
  18. SSL_load_error_strings();
  19. #else
  20. OPENSSL_init_ssl(OPENSSL_INIT_SSL_DEFAULT, NULL);
  21. #endif
  22. s_initialized = 1;
  23. }
  24. #if OPENSSL_VERSION_NUMBER < 0x10100000L
  25. SSL_CTX* ctx = SSL_CTX_new(SSLv23_method());
  26. #else
  27. SSL_CTX* ctx = SSL_CTX_new(TLS_method());
  28. #endif
  29. if (ctx == NULL) return NULL;
  30. int mode = SSL_VERIFY_NONE;
  31. const char* ca_file = NULL;
  32. const char* ca_path = NULL;
  33. if (param) {
  34. if (param->ca_file && *param->ca_file) {
  35. ca_file = param->ca_file;
  36. }
  37. if (param->ca_path && *param->ca_path) {
  38. ca_path = param->ca_path;
  39. }
  40. if (ca_file || ca_path) {
  41. if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_path)) {
  42. fprintf(stderr, "ssl ca_file/ca_path failed!\n");
  43. goto error;
  44. }
  45. }
  46. if (param->crt_file && *param->crt_file) {
  47. if (!SSL_CTX_use_certificate_chain_file(ctx, param->crt_file)) {
  48. fprintf(stderr, "ssl crt_file error!\n");
  49. goto error;
  50. }
  51. }
  52. if (param->key_file && *param->key_file) {
  53. if (!SSL_CTX_use_PrivateKey_file(ctx, param->key_file, SSL_FILETYPE_PEM)) {
  54. fprintf(stderr, "ssl key_file error!\n");
  55. goto error;
  56. }
  57. if (!SSL_CTX_check_private_key(ctx)) {
  58. fprintf(stderr, "ssl key_file check failed!\n");
  59. goto error;
  60. }
  61. }
  62. if (param->verify_peer) {
  63. mode = SSL_VERIFY_PEER;
  64. if (param->endpoint == HSSL_SERVER) {
  65. mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
  66. }
  67. }
  68. }
  69. if (mode == SSL_VERIFY_PEER && !ca_file && !ca_path) {
  70. SSL_CTX_set_default_verify_paths(ctx);
  71. }
  72. #ifdef SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER
  73. SSL_CTX_set_mode(ctx, SSL_CTX_get_mode(ctx) | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
  74. #endif
  75. SSL_CTX_set_verify(ctx, mode, NULL);
  76. return ctx;
  77. error:
  78. SSL_CTX_free(ctx);
  79. return NULL;
  80. }
  81. void hssl_ctx_free(hssl_ctx_t ssl_ctx) {
  82. if (!ssl_ctx) return;
  83. SSL_CTX_free((SSL_CTX*)ssl_ctx);
  84. }
  85. hssl_t hssl_new(hssl_ctx_t ssl_ctx, int fd) {
  86. SSL* ssl = SSL_new((SSL_CTX*)ssl_ctx);
  87. if (ssl == NULL) return NULL;
  88. SSL_set_fd(ssl, fd);
  89. return ssl;
  90. }
  91. void hssl_free(hssl_t ssl) {
  92. if (ssl) {
  93. SSL_free((SSL*)ssl);
  94. ssl = NULL;
  95. }
  96. }
  97. int hssl_accept(hssl_t ssl) {
  98. int ret = SSL_accept((SSL*)ssl);
  99. if (ret == 1) return 0;
  100. int err = SSL_get_error((SSL*)ssl, ret);
  101. if (err == SSL_ERROR_WANT_READ) {
  102. return HSSL_WANT_READ;
  103. }
  104. else if (err == SSL_ERROR_WANT_WRITE) {
  105. return HSSL_WANT_WRITE;
  106. }
  107. else if (err == SSL_ERROR_SYSCALL) {
  108. hloge("SSL_accept errno:%d,error:%s", errno, strerror(errno));
  109. }
  110. else {
  111. hloge("SSL_accept: %s", ERR_error_string(ERR_get_error(), NULL));
  112. }
  113. return err;
  114. }
  115. int hssl_connect(hssl_t ssl) {
  116. int ret = SSL_connect((SSL*)ssl);
  117. if (ret == 1) return 0;
  118. int err = SSL_get_error((SSL*)ssl, ret);
  119. if (err == SSL_ERROR_WANT_READ) {
  120. return HSSL_WANT_READ;
  121. }
  122. else if (err == SSL_ERROR_WANT_WRITE) {
  123. return HSSL_WANT_WRITE;
  124. }
  125. else if (err == SSL_ERROR_SYSCALL) {
  126. hloge("SSL_connect errno:%d,error:%s", errno, strerror(errno));
  127. }
  128. else {
  129. hloge("SSL_connect: %s", ERR_error_string(ERR_get_error(), NULL));
  130. }
  131. return err;
  132. }
  133. int hssl_read(hssl_t ssl, void* buf, int len) {
  134. return SSL_read((SSL*)ssl, buf, len);
  135. }
  136. int hssl_write(hssl_t ssl, const void* buf, int len) {
  137. return SSL_write((SSL*)ssl, buf, len);
  138. }
  139. int hssl_close(hssl_t ssl) {
  140. SSL_shutdown((SSL*)ssl);
  141. return 0;
  142. }
  143. int hssl_set_sni_hostname(hssl_t ssl, const char* hostname) {
  144. #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
  145. SSL_set_tlsext_host_name((SSL*)ssl, hostname);
  146. #endif
  147. return 0;
  148. }
  149. #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
  150. static int hssl_ctx_alpn_select_cb(SSL *ssl,
  151. const unsigned char **out, unsigned char *outlen,
  152. const unsigned char *in, unsigned int inlen,
  153. void *arg) {
  154. const unsigned char* protos = (unsigned char*)arg;
  155. unsigned int protos_len = strlen((char*)protos);
  156. // printf("hssl_ctx_alpn_select_cb(in=%*.s:%u out=%.*s:%u protos=%.*s:%u)\n", inlen, in, inlen, (int)*outlen, (char*)out, (int)*outlen, protos_len, protos, protos_len);
  157. if (SSL_select_next_proto((unsigned char **) out, outlen, protos, protos_len, in, inlen) != OPENSSL_NPN_NEGOTIATED) {
  158. fprintf(stderr, "SSL_select_next_proto failed!\n");
  159. return SSL_TLSEXT_ERR_ALERT_FATAL;
  160. }
  161. // printf("SSL_select_next_proto(out=%.*s:%u)\n", (int)*outlen, (char*)*out, (int)*outlen);
  162. return SSL_TLSEXT_ERR_OK;
  163. }
  164. #endif
  165. int hssl_ctx_set_alpn_protos(hssl_ctx_t ssl_ctx, const unsigned char* protos, unsigned int protos_len) {
  166. int ret = -1;
  167. // printf("hssl_ctx_set_alpn_protos(%.*s:%u)\n", protos_len, protos, protos_len);
  168. #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
  169. // for HSSL_CLIENT
  170. // ret = SSL_CTX_set_alpn_protos((SSL_CTX*)ssl_ctx, (const unsigned char*)protos, protos_len);
  171. // for HSSL_SERVER
  172. SSL_CTX_set_alpn_select_cb((SSL_CTX*)ssl_ctx, hssl_ctx_alpn_select_cb, (void*)protos);
  173. ret = 0;
  174. #endif
  175. return ret;
  176. }
  177. #endif // WITH_OPENSSL