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