2 * Copyright 2017 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include <folly/Range.h>
19 #include <folly/portability/OpenSSL.h>
20 #include <folly/portability/Sockets.h>
21 #include <folly/ssl/OpenSSLPtrTypes.h>
29 * Get the TLS Session Master Key used to generate the TLS key material
31 * @param session ssl session
32 * @param keyOut destination for the master key, the buffer must be at least
34 * @return true if the master key is available (>= TLS1) and the output buffer
37 static bool getTLSMasterKey(
38 const SSL_SESSION* session,
39 MutableByteRange keyOut);
42 * Get the TLS Client Random used to generate the TLS key material
45 * @param randomOut destination for the client random, the buffer must be at
47 * @return true if the client random is available (>= TLS1) and the output
50 static bool getTLSClientRandom(const SSL* ssl, MutableByteRange randomOut);
53 * Validate that the peer certificate's common name or subject alt names
54 * match what we expect. Currently this only checks for IPs within
55 * subject alt names but it could easily be expanded to check common name
56 * and hostnames as well.
58 * @param cert X509* peer certificate
59 * @param addr sockaddr object containing sockaddr to verify
60 * @param addrLen length of sockaddr as returned by getpeername or accept
61 * @return true iff a subject altname IP matches addr
63 // TODO(agartrell): Add support for things like common name when
65 static bool validatePeerCertNames(X509* cert,
70 * Get the peer socket address from an X509_STORE_CTX*. Unlike the
71 * accept, getsockname, getpeername, etc family of operations, addrLen's
72 * initial value is ignored and reset.
74 * @param ctx Context from which to retrieve peer sockaddr
75 * @param addrStorage out param for address
76 * @param addrLen out param for length of address
77 * @return true on success, false on failure
79 static bool getPeerAddressFromX509StoreCtx(X509_STORE_CTX* ctx,
80 sockaddr_storage* addrStorage,
84 * Get a stringified cipher name (e.g., ECDHE-ECDSA-CHACHA20-POLY1305) given
85 * the 2-byte code (e.g., 0xcca9) for the cipher. The name conversion only
86 * works for the ciphers built into the linked OpenSSL library
88 * @param cipherCode A 16-bit IANA cipher code (machine endianness)
89 * @return Cipher name, or empty if the code is not found
91 static const std::string& getCipherName(uint16_t cipherCode);
94 * Set the 'initial_ctx' SSL_CTX* inside an SSL. The initial_ctx is used to
95 * point to the SSL_CTX on which servername callback and session callbacks,
96 * as well as session caching stats are set. If we want to enforce SSL_CTX
97 * thread-based ownership (e.g., thread-local SSL_CTX) in the application, we
98 * need to also set/reset the initial_ctx when we call SSL_set_SSL_CTX.
100 * @param ssl SSL pointer
101 * @param ctx SSL_CTX pointer
102 * @return Cipher name, or empty if the code is not found
104 static void setSSLInitialCtx(SSL* ssl, SSL_CTX* ctx);
105 static SSL_CTX* getSSLInitialCtx(SSL* ssl);
108 * Wrappers for BIO operations that may be different across different
109 * versions/flavors of OpenSSL (including forks like BoringSSL)
111 static BioMethodUniquePtr newSocketBioMethod();
112 static bool setCustomBioReadMethod(
114 int (*meth)(BIO*, char*, int));
115 static bool setCustomBioWriteMethod(
117 int (*meth)(BIO*, const char*, int));
118 static int getBioShouldRetryWrite(int ret);
119 static void setBioAppData(BIO* b, void* ptr);
120 static void* getBioAppData(BIO* b);
121 static int getBioFd(BIO* b, int* fd);
122 static void setBioFd(BIO* b, int fd, int flags);