1 /* 2 * nghttp2 - HTTP/2 C Library 3 * 4 * Copyright (c) 2012 Tatsuhiro Tsujikawa 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining 7 * a copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sublicense, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be 15 * included in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 */ 25 #ifndef SHRPX_TLS_H 26 #define SHRPX_TLS_H 27 28 #include "shrpx.h" 29 30 #include <vector> 31 #include <mutex> 32 33 #include "ssl_compat.h" 34 35 #ifdef NGHTTP2_OPENSSL_IS_WOLFSSL 36 # include <wolfssl/options.h> 37 # include <wolfssl/openssl/ssl.h> 38 # include <wolfssl/openssl/err.h> 39 #else // !NGHTTP2_OPENSSL_IS_WOLFSSL 40 # include <openssl/ssl.h> 41 # include <openssl/err.h> 42 #endif // !NGHTTP2_OPENSSL_IS_WOLFSSL 43 44 #include <ev.h> 45 46 #ifdef HAVE_NEVERBLEED 47 # include <neverbleed.h> 48 #endif // HAVE_NEVERBLEED 49 50 #include "network.h" 51 #include "shrpx_config.h" 52 #include "shrpx_router.h" 53 54 namespace shrpx { 55 56 class ClientHandler; 57 class Worker; 58 class DownstreamConnectionPool; 59 struct DownstreamAddr; 60 struct UpstreamAddr; 61 62 namespace tls { 63 64 struct TLSSessionCache { 65 // ASN1 representation of SSL_SESSION object. See 66 // i2d_SSL_SESSION(3SSL). 67 std::vector<uint8_t> session_data; 68 // The last time stamp when this cache entry is created or updated. 69 std::chrono::steady_clock::time_point last_updated; 70 }; 71 72 // This struct stores the additional information per SSL_CTX. This is 73 // attached to SSL_CTX using SSL_CTX_set_app_data(). 74 struct TLSContextData { 75 // SCT data formatted so that this can be directly sent as 76 // extension_data of signed_certificate_timestamp. 77 std::vector<uint8_t> sct_data; 78 #ifndef HAVE_ATOMIC_STD_SHARED_PTR 79 // Protects ocsp_data; 80 std::mutex mu; 81 #endif // !HAVE_ATOMIC_STD_SHARED_PTR 82 // OCSP response 83 #ifdef HAVE_ATOMIC_STD_SHARED_PTR 84 std::atomic<std::shared_ptr<std::vector<uint8_t>>> ocsp_data; 85 #else // !HAVE_ATOMIC_STD_SHARED_PTR 86 std::shared_ptr<std::vector<uint8_t>> ocsp_data; 87 #endif // !HAVE_ATOMIC_STD_SHARED_PTR 88 89 // Path to certificate file 90 const char *cert_file; 91 }; 92 93 // Create server side SSL_CTX 94 SSL_CTX *create_ssl_context(const char *private_key_file, const char *cert_file, 95 const std::vector<uint8_t> &sct_data 96 97 #ifdef HAVE_NEVERBLEED 98 , 99 neverbleed_t *nb 100 #endif // HAVE_NEVERBLEED 101 ); 102 103 // Create client side SSL_CTX. This does not configure ALPN settings. 104 SSL_CTX *create_ssl_client_context( 105 #ifdef HAVE_NEVERBLEED 106 neverbleed_t *nb, 107 #endif // HAVE_NEVERBLEED 108 const StringRef &cacert, const StringRef &cert_file, 109 const StringRef &private_key_file); 110 111 ClientHandler *accept_connection(Worker *worker, int fd, sockaddr *addr, 112 int addrlen, const UpstreamAddr *faddr); 113 114 // Check peer's certificate against given |address| and |host|. 115 int check_cert(SSL *ssl, const Address *addr, const StringRef &host); 116 // Check peer's certificate against given host name described in 117 // |addr| and numeric address in |raddr|. Note that |raddr| might not 118 // point to &addr->addr. 119 int check_cert(SSL *ssl, const DownstreamAddr *addr, const Address *raddr); 120 121 // Verify |cert| using numeric IP address. |hostname| and |addr| 122 // should contain the same numeric IP address. This function returns 123 // 0 if it succeeds, or -1. 124 int verify_numeric_hostname(X509 *cert, const StringRef &hostname, 125 const Address *addr); 126 127 // Verify |cert| using DNS name hostname. This function returns 0 if 128 // it succeeds, or -1. 129 int verify_dns_hostname(X509 *cert, const StringRef &hostname); 130 131 struct WildcardRevPrefix { WildcardRevPrefixWildcardRevPrefix132 WildcardRevPrefix(const StringRef &prefix, size_t idx) 133 : prefix(std::begin(prefix), std::end(prefix)), idx(idx) {} 134 135 // "Prefix" of wildcard pattern. It is reversed from original form. 136 // For example, if the original wildcard is "test*.nghttp2.org", 137 // prefix would be "tset". 138 ImmutableString prefix; 139 // The index of SSL_CTX. See ConnectionHandler::get_ssl_ctx(). 140 size_t idx; 141 }; 142 143 struct WildcardPattern { 144 // Wildcard host sharing only suffix is probably rare, so we just do 145 // linear search. 146 std::vector<WildcardRevPrefix> rev_prefix; 147 }; 148 149 class CertLookupTree { 150 public: 151 CertLookupTree(); 152 153 // Adds hostname pattern |hostname| to the lookup tree, associating 154 // value |index|. When the queried host matches this pattern, 155 // |index| is returned. We support wildcard pattern. The left most 156 // '*' is considered as wildcard character, and it must match at 157 // least one character. If the same pattern has been already added, 158 // this function does not alter the tree, and returns the existing 159 // matching index. 160 // 161 // The caller should lower-case |hostname| since this function does 162 // do that, and lookup function performs case-sensitive match. 163 // 164 // TODO Treat wildcard pattern described as RFC 6125. 165 // 166 // This function returns the index. It returns -1 if it fails 167 // (e.g., hostname is too long). If the returned index equals to 168 // |index|, then hostname is added to the tree with the value 169 // |index|. If it is not -1, and does not equal to |index|, same 170 // hostname has already been added to the tree. 171 ssize_t add_cert(const StringRef &hostname, size_t index); 172 173 // Looks up index using the given |hostname|. The exact match takes 174 // precedence over wildcard match. For wildcard match, longest 175 // match (sum of matched suffix and prefix length in bytes) is 176 // preferred, breaking a tie with longer suffix. 177 // 178 // The caller should lower-case |hostname| since this function 179 // performs case-sensitive match. 180 ssize_t lookup(const StringRef &hostname); 181 182 // Dumps the contents of this lookup tree to stderr. 183 void dump() const; 184 185 private: 186 // Exact match 187 Router router_; 188 // Wildcard reversed suffix match. The returned index is into 189 // wildcard_patterns_. 190 Router rev_wildcard_router_; 191 // Stores wildcard suffix patterns. 192 std::vector<WildcardPattern> wildcard_patterns_; 193 }; 194 195 // Adds hostnames in certificate in |ssl_ctx| to lookup tree |lt|. 196 // The subjectAltNames and commonName are considered as eligible 197 // hostname. If there is at least one dNSName in subjectAltNames, 198 // commonName is not considered. |ssl_ctx| is also added to 199 // |indexed_ssl_ctx|. This function returns 0 if it succeeds, or -1. 200 int cert_lookup_tree_add_ssl_ctx( 201 CertLookupTree *lt, std::vector<std::vector<SSL_CTX *>> &indexed_ssl_ctx, 202 SSL_CTX *ssl_ctx); 203 204 // Returns true if |proto| is included in the 205 // protocol list |protos|. 206 bool in_proto_list(const std::vector<StringRef> &protos, 207 const StringRef &proto); 208 209 // Returns true if security requirement for HTTP/2 is fulfilled. 210 bool check_http2_requirement(SSL *ssl); 211 212 // Returns SSL/TLS option mask to disable SSL/TLS protocol version not 213 // included in |tls_proto_list|. The returned mask can be directly 214 // passed to SSL_CTX_set_options(). 215 long int create_tls_proto_mask(const std::vector<StringRef> &tls_proto_list); 216 217 int set_alpn_prefs(std::vector<unsigned char> &out, 218 const std::vector<StringRef> &protos); 219 220 // Setups server side SSL_CTX. This function inspects get_config() 221 // and if upstream_no_tls is true, returns nullptr. Otherwise 222 // construct default SSL_CTX. If subcerts are available 223 // (get_config()->subcerts), caller should provide CertLookupTree 224 // object as |cert_tree| parameter, otherwise SNI does not work. All 225 // the created SSL_CTX is stored into |all_ssl_ctx|. They are also 226 // added to |indexed_ssl_ctx|. |cert_tree| uses its index to 227 // associate hostname to the SSL_CTX. 228 SSL_CTX * 229 setup_server_ssl_context(std::vector<SSL_CTX *> &all_ssl_ctx, 230 std::vector<std::vector<SSL_CTX *>> &indexed_ssl_ctx, 231 CertLookupTree *cert_tree 232 #ifdef HAVE_NEVERBLEED 233 , 234 neverbleed_t *nb 235 #endif // HAVE_NEVERBLEED 236 ); 237 238 #ifdef ENABLE_HTTP3 239 SSL_CTX *setup_quic_server_ssl_context( 240 std::vector<SSL_CTX *> &all_ssl_ctx, 241 std::vector<std::vector<SSL_CTX *>> &indexed_ssl_ctx, 242 CertLookupTree *cert_tree 243 # ifdef HAVE_NEVERBLEED 244 , 245 neverbleed_t *nb 246 # endif // HAVE_NEVERBLEED 247 ); 248 #endif // ENABLE_HTTP3 249 250 // Setups client side SSL_CTX. 251 SSL_CTX *setup_downstream_client_ssl_context( 252 #ifdef HAVE_NEVERBLEED 253 neverbleed_t *nb 254 #endif // HAVE_NEVERBLEED 255 ); 256 257 // Sets ALPN settings in |SSL| suitable for HTTP/2 use. 258 void setup_downstream_http2_alpn(SSL *ssl); 259 // Sets ALPN settings in |SSL| suitable for HTTP/1.1 use. 260 void setup_downstream_http1_alpn(SSL *ssl); 261 262 // Creates CertLookupTree. If frontend is configured not to use TLS, 263 // this function returns nullptr. 264 std::unique_ptr<CertLookupTree> create_cert_lookup_tree(); 265 266 SSL *create_ssl(SSL_CTX *ssl_ctx); 267 268 // Returns true if SSL/TLS is enabled on upstream 269 bool upstream_tls_enabled(const ConnectionConfig &connconf); 270 271 // Performs TLS hostname match. |pattern| can contain wildcard 272 // character '*', which matches prefix of target hostname. There are 273 // several restrictions to make wildcard work. The matching algorithm 274 // is based on RFC 6125. 275 bool tls_hostname_match(const StringRef &pattern, const StringRef &hostname); 276 277 // Caches |session|. |session| is serialized into ASN1 278 // representation, and stored. |t| is used as a time stamp. 279 // Depending on the existing cache's time stamp, |session| might not 280 // be cached. 281 void try_cache_tls_session(TLSSessionCache *cache, SSL_SESSION *session, 282 const std::chrono::steady_clock::time_point &t); 283 284 // Returns cached session associated |addr|. If no cache entry is 285 // found associated to |addr|, nullptr will be returned. 286 SSL_SESSION *reuse_tls_session(const TLSSessionCache &addr); 287 288 // Loads certificate form file |filename|. The caller should delete 289 // the returned object using X509_free(). 290 X509 *load_certificate(const char *filename); 291 292 // Returns TLS version from |v|. The returned value is defined in 293 // OpenSSL header file. This function returns -1 if |v| is not valid 294 // TLS version string. 295 int proto_version_from_string(const StringRef &v); 296 297 // Verifies OCSP response |ocsp_resp| of length |ocsp_resplen|. This 298 // function returns 0 if it succeeds, or -1. 299 int verify_ocsp_response(SSL_CTX *ssl_ctx, const uint8_t *ocsp_resp, 300 size_t ocsp_resplen); 301 302 // Stores fingerprint of |x| in |dst| of length |dstlen|. |md| 303 // specifies hash function to use, and |dstlen| must be large enough 304 // to include hash value (e.g., 32 bytes for SHA-256). This function 305 // returns the number of bytes written in |dst|, or -1. 306 ssize_t get_x509_fingerprint(uint8_t *dst, size_t dstlen, const X509 *x, 307 const EVP_MD *md); 308 309 // Returns subject name of |x|. If this function fails to get subject 310 // name, it returns an empty string. 311 StringRef get_x509_subject_name(BlockAllocator &balloc, X509 *x); 312 313 // Returns issuer name of |x|. If this function fails to get issuer 314 // name, it returns an empty string. 315 StringRef get_x509_issuer_name(BlockAllocator &balloc, X509 *x); 316 317 // Returns serial number of |x|. If this function fails to get serial 318 // number, it returns an empty string. number 319 StringRef get_x509_serial(BlockAllocator &balloc, X509 *x); 320 321 // Fills NotBefore of |x| in |t|. This function returns 0 if it 322 // succeeds, or -1. 323 int get_x509_not_before(time_t &t, X509 *x); 324 325 // Fills NotAfter of |x| in |t|. This function returns 0 if it 326 // succeeds, or -1. 327 int get_x509_not_after(time_t &t, X509 *x); 328 329 } // namespace tls 330 331 } // namespace shrpx 332 333 #endif // SHRPX_TLS_H 334