1 /* 2 +----------------------------------------------------------------------+ 3 | Swoole | 4 +----------------------------------------------------------------------+ 5 | This source file is subject to version 2.0 of the Apache license, | 6 | that is bundled with this package in the file LICENSE, and is | 7 | available through the world-wide-web at the following url: | 8 | http://www.apache.org/licenses/LICENSE-2.0.html | 9 | If you did not receive a copy of the Apache2.0 license and are unable| 10 | to obtain it through the world-wide-web, please send a note to | 11 | license@php.net so we can mail you a copy immediately. | 12 +----------------------------------------------------------------------+ 13 | Author: Tianfeng Han <mikan.tenny@gmail.com> | 14 +----------------------------------------------------------------------+ 15 */ 16 17 #pragma once 18 19 #include "swoole.h" 20 21 #ifdef SW_USE_OPENSSL 22 23 #include <unordered_map> 24 #include <string> 25 #include <array> 26 27 #include <openssl/ssl.h> 28 #include <openssl/bio.h> 29 #include <openssl/err.h> 30 #include <openssl/conf.h> 31 #include <openssl/ossl_typ.h> 32 #include <openssl/crypto.h> 33 #include <openssl/x509.h> 34 #include <openssl/x509v3.h> 35 #include <openssl/rand.h> 36 #include <openssl/opensslv.h> 37 38 #if OPENSSL_VERSION_NUMBER >= 0x10100000L 39 #define SW_SUPPORT_DTLS 40 #endif 41 42 #if defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x3000000fL 43 #undef SW_SUPPORT_DTLS 44 #endif 45 46 #ifdef OPENSSL_IS_BORINGSSL 47 #define BIO_CTRL_DGRAM_SET_CONNECTED 32 48 #define BIO_CTRL_DGRAM_SET_PEER 44 49 #define BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT 45 50 #define BIO_dgram_get_peer(b,peer) \ 51 (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_PEER, 0, (char *)(peer)) 52 #define OPENSSL_assert(x) assert(x) 53 #endif 54 55 enum swSSLCreateFlag { 56 SW_SSL_SERVER = 1, 57 SW_SSL_CLIENT = 2, 58 }; 59 60 enum swSSLState { 61 SW_SSL_STATE_HANDSHAKE = 0, 62 SW_SSL_STATE_READY = 1, 63 SW_SSL_STATE_WAIT_STREAM = 2, 64 }; 65 66 enum swSSLVersion { 67 SW_SSL_SSLv2 = 1u << 1, 68 SW_SSL_SSLv3 = 1u << 2, 69 SW_SSL_TLSv1 = 1u << 3, 70 SW_SSL_TLSv1_1 = 1u << 4, 71 SW_SSL_TLSv1_2 = 1u << 5, 72 SW_SSL_TLSv1_3 = 1u << 6, 73 SW_SSL_DTLS = 1u << 7, 74 }; 75 76 #define SW_SSL_ALL (SW_SSL_SSLv2 | SW_SSL_SSLv3 | SW_SSL_TLSv1 | SW_SSL_TLSv1_1 | SW_SSL_TLSv1_2 | SW_SSL_TLSv1_3) 77 78 enum swSSLMethod { 79 SW_SSLv23_METHOD = 0, 80 SW_SSLv3_METHOD, 81 SW_SSLv3_SERVER_METHOD, 82 SW_SSLv3_CLIENT_METHOD, 83 SW_SSLv23_SERVER_METHOD, 84 SW_SSLv23_CLIENT_METHOD, 85 SW_TLSv1_METHOD, 86 SW_TLSv1_SERVER_METHOD, 87 SW_TLSv1_CLIENT_METHOD, 88 #ifdef TLS1_1_VERSION 89 SW_TLSv1_1_METHOD, 90 SW_TLSv1_1_SERVER_METHOD, 91 SW_TLSv1_1_CLIENT_METHOD, 92 #endif 93 #ifdef TLS1_2_VERSION 94 SW_TLSv1_2_METHOD, 95 SW_TLSv1_2_SERVER_METHOD, 96 SW_TLSv1_2_CLIENT_METHOD, 97 #endif 98 #ifdef SW_SUPPORT_DTLS 99 SW_DTLS_CLIENT_METHOD, 100 SW_DTLS_SERVER_METHOD, 101 #endif 102 }; 103 104 namespace swoole { 105 106 struct SSLContext { 107 uchar http : 1; 108 uchar http_v2 : 1; 109 uchar prefer_server_ciphers : 1; 110 uchar session_tickets : 1; 111 uchar stapling : 1; 112 uchar stapling_verify : 1; 113 std::string ciphers; 114 std::string ecdh_curve; 115 std::string session_cache; 116 std::string dhparam; 117 std::string cert_file; 118 std::string key_file; 119 std::string passphrase; 120 std::string client_cert_file; 121 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME 122 uchar disable_tls_host_name : 1; 123 std::string tls_host_name; 124 #endif 125 126 #ifdef OPENSSL_IS_BORINGSSL 127 uint8_t grease; 128 #endif 129 130 std::string cafile; 131 std::string capath; 132 uint8_t verify_depth; 133 uchar disable_compress : 1; 134 uchar verify_peer : 1; 135 uchar allow_self_signed : 1; 136 uint32_t protocols; 137 uint8_t create_flag; 138 SSL_CTX *context; 139 get_contextSSLContext140 SSL_CTX *get_context() { 141 return context; 142 } 143 readySSLContext144 bool ready() { 145 return context != nullptr; 146 } 147 set_protocolsSSLContext148 void set_protocols(uint32_t _protocols) { 149 protocols = _protocols; 150 } 151 set_cert_fileSSLContext152 bool set_cert_file(const std::string &_cert_file) { 153 if (access(_cert_file.c_str(), R_OK) < 0) { 154 swoole_warning("ssl cert file[%s] not found", _cert_file.c_str()); 155 return false; 156 } 157 cert_file = _cert_file; 158 return true; 159 } 160 set_key_fileSSLContext161 bool set_key_file(const std::string &_key_file) { 162 if (access(_key_file.c_str(), R_OK) < 0) { 163 swoole_warning("ssl key file[%s] not found", _key_file.c_str()); 164 return false; 165 } 166 key_file = _key_file; 167 return true; 168 } 169 170 bool create(); 171 bool set_capath(); 172 bool set_ciphers(); 173 bool set_client_certificate(); 174 bool set_ecdh_curve(); 175 bool set_dhparam(); 176 ~SSLContext(); 177 }; 178 } 179 180 void swoole_ssl_init(void); 181 void swoole_ssl_init_thread_safety(); 182 bool swoole_ssl_is_thread_safety(); 183 void swoole_ssl_server_http_advise(swoole::SSLContext &); 184 const char *swoole_ssl_get_error(); 185 int swoole_ssl_get_ex_connection_index(); 186 int swoole_ssl_get_ex_port_index(); 187 std::string swoole_ssl_get_version_message(); 188 189 #endif 190