openssl.c 5.3 KB

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