2 * Copyright 2015 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.
27 #include <openssl/ssl.h>
28 #include <openssl/tls1.h>
30 #include <sys/socket.h>
31 #include <netinet/in.h>
33 #include <glog/logging.h>
35 #ifndef FOLLY_NO_CONFIG
36 #include <folly/folly-config.h>
39 #include <folly/Random.h>
44 * Override the default password collector.
46 class PasswordCollector {
48 virtual ~PasswordCollector() = default;
50 * Interface for customizing how to collect private key password.
52 * By default, OpenSSL prints a prompt on screen and request for password
53 * while loading private key. To implement a custom password collector,
54 * implement this interface and register it with TSSLSocketFactory.
56 * @param password Pass collected password back to OpenSSL
57 * @param size Maximum length of password including nullptr character
59 virtual void getPassword(std::string& password, int size) = 0;
62 * Return a description of this collector for logging purposes
64 virtual std::string describe() const = 0;
68 * Wrap OpenSSL SSL_CTX into a class.
79 enum SSLVerifyPeerEnum{
82 VERIFY_REQ_CLIENT_CERT,
86 struct NextProtocolsItem {
87 NextProtocolsItem(int wt, const std::list<std::string>& ptcls):
88 weight(wt), protocols(ptcls) {}
90 std::list<std::string> protocols;
93 // Function that selects a client protocol given the server's list
94 using ClientProtocolFilterCallback = bool (*)(unsigned char**, unsigned int*,
95 const unsigned char*, unsigned int);
98 * Convenience function to call getErrors() with the current errno value.
100 * Make sure that you only call this when there was no intervening operation
101 * since the last OpenSSL error that may have changed the current errno value.
103 static std::string getErrors() {
104 return getErrors(errno);
110 * @param version The lowest or oldest SSL version to support.
112 explicit SSLContext(SSLVersion version = TLSv1);
113 virtual ~SSLContext();
116 * Set default ciphers to be used in SSL handshake process.
118 * @param ciphers A list of ciphers to use for TLSv1.0
120 virtual void ciphers(const std::string& ciphers);
123 * Low-level method that attempts to set the provided ciphers on the
124 * SSL_CTX object, and throws if something goes wrong.
126 virtual void setCiphersOrThrow(const std::string& ciphers);
129 * Method to set verification option in the context object.
131 * @param verifyPeer SSLVerifyPeerEnum indicating the verification
134 virtual void setVerificationOption(const SSLVerifyPeerEnum& verifyPeer);
137 * Method to check if peer verfication is set.
139 * @return true if peer verification is required.
142 virtual bool needsPeerVerification() {
143 return (verifyPeer_ == SSLVerifyPeerEnum::VERIFY ||
144 verifyPeer_ == SSLVerifyPeerEnum::VERIFY_REQ_CLIENT_CERT);
148 * Method to fetch Verification mode for a SSLVerifyPeerEnum.
149 * verifyPeer cannot be SSLVerifyPeerEnum::USE_CTX since there is no
152 * @param verifyPeer SSLVerifyPeerEnum for which the flags need to
155 * @return mode flags that can be used with SSL_set_verify
157 static int getVerificationMode(const SSLVerifyPeerEnum& verifyPeer);
160 * Method to fetch Verification mode determined by the options
161 * set using setVerificationOption.
163 * @return mode flags that can be used with SSL_set_verify
165 virtual int getVerificationMode();
168 * Enable/Disable authentication. Peer name validation can only be done
169 * if checkPeerCert is true.
171 * @param checkPeerCert If true, require peer to present valid certificate
172 * @param checkPeerName If true, validate that the certificate common name
173 * or alternate name(s) of peer matches the hostname
175 * @param peerName If non-empty, validate that the certificate common
176 * name of peer matches the given string (altername
177 * name(s) are not used in this case).
179 virtual void authenticate(bool checkPeerCert, bool checkPeerName,
180 const std::string& peerName = std::string());
182 * Load server certificate.
184 * @param path Path to the certificate file
185 * @param format Certificate file format
187 virtual void loadCertificate(const char* path, const char* format = "PEM");
191 * @param path Path to the private key file
192 * @param format Private key file format
194 virtual void loadPrivateKey(const char* path, const char* format = "PEM");
196 * Load trusted certificates from specified file.
198 * @param path Path to trusted certificate file
200 virtual void loadTrustedCertificates(const char* path);
202 * Load trusted certificates from specified X509 certificate store.
204 * @param store X509 certificate store.
206 virtual void loadTrustedCertificates(X509_STORE* store);
208 * Load a client CA list for validating clients
210 virtual void loadClientCAList(const char* path);
212 * Override default OpenSSL password collector.
214 * @param collector Instance of user defined password collector
216 virtual void passwordCollector(std::shared_ptr<PasswordCollector> collector);
218 * Obtain password collector.
220 * @return User defined password collector
222 virtual std::shared_ptr<PasswordCollector> passwordCollector() {
225 #if OPENSSL_VERSION_NUMBER >= 0x1000105fL && !defined(OPENSSL_NO_TLSEXT)
227 * Provide SNI support
229 enum ServerNameCallbackResult {
231 SERVER_NAME_NOT_FOUND,
232 SERVER_NAME_NOT_FOUND_ALERT_FATAL,
235 * Callback function from openssl to give the application a
236 * chance to check the tlsext_hostname just right after parsing
237 * the Client Hello or Server Hello message.
239 * It is for the server to switch the SSL to another SSL_CTX
240 * to continue the handshake. (i.e. Server Name Indication, SNI, in RFC6066).
242 * If the ServerNameCallback returns:
244 * server: Send a tlsext_hostname in the Server Hello
246 * SERVER_NAME_NOT_FOUND:
247 * server: Does not send a tlsext_hostname in Server Hello
248 * and continue the handshake.
250 * SERVER_NAME_NOT_FOUND_ALERT_FATAL:
251 * server and client: Send fatal TLS1_AD_UNRECOGNIZED_NAME alert to
254 * Quote from RFC 6066:
256 * If the server understood the ClientHello extension but
257 * does not recognize the server name, the server SHOULD take one of two
258 * actions: either abort the handshake by sending a fatal-level
259 * unrecognized_name(112) alert or continue the handshake. It is NOT
260 * RECOMMENDED to send a warning-level unrecognized_name(112) alert,
261 * because the client's behavior in response to warning-level alerts is
267 * Set the ServerNameCallback
269 typedef std::function<ServerNameCallbackResult(SSL* ssl)> ServerNameCallback;
270 virtual void setServerNameCallback(const ServerNameCallback& cb);
273 * Generic callbacks that are run after we get the Client Hello (right
274 * before we run the ServerNameCallback)
276 typedef std::function<void(SSL* ssl)> ClientHelloCallback;
277 virtual void addClientHelloCallback(const ClientHelloCallback& cb);
281 * Create an SSL object from this context.
283 SSL* createSSL() const;
286 * Set the options on the SSL_CTX object.
288 void setOptions(long options);
290 enum class NextProtocolType : uint8_t {
296 #ifdef OPENSSL_NPN_NEGOTIATED
298 * Set the list of protocols that this SSL context supports. In server
299 * mode, this is the list of protocols that will be advertised for Next
300 * Protocol Negotiation (NPN) or Application Layer Protocol Negotiation
301 * (ALPN). In client mode, the first protocol advertised by the server
302 * that is also on this list is chosen. Invoking this function with a list
303 * of length zero causes NPN to be disabled.
305 * @param protocols List of protocol names. This method makes a copy,
306 * so the caller needn't keep the list in scope after
307 * the call completes. The list must have at least
308 * one element to enable NPN. Each element must have
309 * a string length < 256.
310 * @param protocolType What type of protocol negotiation to support.
311 * @return true if NPN/ALPN has been activated. False if NPN/ALPN is disabled.
313 bool setAdvertisedNextProtocols(
314 const std::list<std::string>& protocols,
315 NextProtocolType protocolType = NextProtocolType::ANY);
317 * Set weighted list of lists of protocols that this SSL context supports.
318 * In server mode, each element of the list contains a list of protocols that
319 * could be advertised for Next Protocol Negotiation (NPN) or Application
320 * Layer Protocol Negotiation (ALPN). The list of protocols that will be
321 * advertised to a client is selected randomly, based on weights of elements.
322 * Client mode doesn't support randomized NPN/ALPN, so this list should
323 * contain only 1 element. The first protocol advertised by the server that
324 * is also on the list of protocols of this element is chosen. Invoking this
325 * function with a list of length zero causes NPN/ALPN to be disabled.
327 * @param items List of NextProtocolsItems, Each item contains a list of
328 * protocol names and weight. After the call of this fucntion
329 * each non-empty list of protocols will be advertised with
330 * probability weight/sum_of_weights. This method makes a copy,
331 * so the caller needn't keep the list in scope after the call
332 * completes. The list must have at least one element with
333 * non-zero weight and non-empty protocols list to enable NPN.
334 * Each name of the protocol must have a string length < 256.
335 * @param protocolType What type of protocol negotiation to support.
336 * @return true if NPN/ALPN has been activated. False if NPN/ALPN is disabled.
338 bool setRandomizedAdvertisedNextProtocols(
339 const std::list<NextProtocolsItem>& items,
340 NextProtocolType protocolType = NextProtocolType::ANY);
342 void setClientProtocolFilterCallback(ClientProtocolFilterCallback cb) {
343 clientProtoFilter_ = cb;
346 ClientProtocolFilterCallback getClientProtocolFilterCallback() {
347 return clientProtoFilter_;
350 * Disables NPN on this SSL context.
352 void unsetNextProtocols();
353 void deleteNextProtocolsStrings();
355 #if defined(SSL_MODE_HANDSHAKE_CUTTHROUGH) && \
356 FOLLY_SSLCONTEXT_USE_TLS_FALSE_START
357 bool canUseFalseStartWithCipher(const SSL_CIPHER *cipher);
359 #endif // OPENSSL_NPN_NEGOTIATED
362 * Gets the underlying SSL_CTX for advanced usage
364 SSL_CTX *getSSLCtx() const {
375 * Set preferences for how to treat locks in OpenSSL. This must be
376 * called before the instantiation of any SSLContext objects, otherwise
377 * the defaults will be used.
379 * OpenSSL has a lock for each module rather than for each object or
380 * data that needs locking. Some locks protect only refcounts, and
381 * might be better as spinlocks rather than mutexes. Other locks
382 * may be totally unnecessary if the objects being protected are not
383 * shared between threads in the application.
385 * By default, all locks are initialized as mutexes. OpenSSL's lock usage
386 * may change from version to version and you should know what you are doing
387 * before disabling any locks entirely.
389 * Example: if you don't share SSL sessions between threads in your
390 * application, you may be able to do this
392 * setSSLLockTypes({{CRYPTO_LOCK_SSL_SESSION, SSLContext::LOCK_NONE}})
394 static void setSSLLockTypes(std::map<int, SSLLockType> lockTypes);
397 * Examine OpenSSL's error stack, and return a string description of the
400 * This operation removes the errors from OpenSSL's error stack.
402 static std::string getErrors(int errnoCopy);
405 * We want to vary which cipher we'll use based on the client's TLS version.
407 void switchCiphersIfTLS11(
409 const std::string& tls11CipherString
412 bool checkPeerName() { return checkPeerName_; }
413 std::string peerFixedName() { return peerFixedName_; }
416 * Helper to match a hostname versus a pattern.
418 static bool matchName(const char* host, const char* pattern, int size);
421 * Functions for setting up and cleaning up openssl.
422 * They can be invoked during the start of the application.
424 static void initializeOpenSSL();
425 static void cleanupOpenSSL();
428 * Mark openssl as initialized without actually performing any initialization.
429 * Please use this only if you are using a library which requires that it must
430 * make its own calls to SSL_library_init() and related functions.
432 static void markInitialized();
435 * Default randomize method.
437 static void randomize();
443 SSLVerifyPeerEnum verifyPeer_{SSLVerifyPeerEnum::NO_VERIFY};
446 std::string peerFixedName_;
447 std::shared_ptr<PasswordCollector> collector_;
448 #if OPENSSL_VERSION_NUMBER >= 0x1000105fL && !defined(OPENSSL_NO_TLSEXT)
449 ServerNameCallback serverNameCb_;
450 std::vector<ClientHelloCallback> clientHelloCbs_;
453 ClientProtocolFilterCallback clientProtoFilter_{nullptr};
455 static bool initialized_;
457 #ifdef OPENSSL_NPN_NEGOTIATED
459 struct AdvertisedNextProtocolsItem {
460 unsigned char* protocols;
465 * Wire-format list of advertised protocols for use in NPN.
467 std::vector<AdvertisedNextProtocolsItem> advertisedNextProtocols_;
468 std::vector<int> advertisedNextProtocolWeights_;
469 std::discrete_distribution<int> nextProtocolDistribution_;
470 Random::DefaultGenerator nextProtocolPicker_;
472 static int sNextProtocolsExDataIndex_;
474 static int advertisedNextProtocolCallback(SSL* ssl,
475 const unsigned char** out, unsigned int* outlen, void* data);
476 static int selectNextProtocolCallback(
477 SSL* ssl, unsigned char **out, unsigned char *outlen,
478 const unsigned char *server, unsigned int server_len, void *args);
480 #if OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined(OPENSSL_NO_TLSEXT)
481 static int alpnSelectCallback(SSL* ssl,
482 const unsigned char** out,
483 unsigned char* outlen,
484 const unsigned char* in,
488 size_t pickNextProtocols();
490 #if defined(SSL_MODE_HANDSHAKE_CUTTHROUGH) && \
491 FOLLY_SSLCONTEXT_USE_TLS_FALSE_START
492 // This class contains all allowed ciphers for SSL false start. Call its
493 // `canUseFalseStartWithCipher` to check for cipher qualification.
494 class SSLFalseStartChecker {
496 SSLFalseStartChecker();
498 bool canUseFalseStartWithCipher(const SSL_CIPHER *cipher);
501 static int compare_ulong(const void *x, const void *y);
503 // All ciphers that are allowed to use false start.
504 unsigned long ciphers_[47];
505 unsigned int length_;
509 SSLFalseStartChecker falseStartChecker_;
512 #endif // OPENSSL_NPN_NEGOTIATED
514 static int passwordCallback(char* password, int size, int, void* data);
516 #if OPENSSL_VERSION_NUMBER >= 0x1000105fL && !defined(OPENSSL_NO_TLSEXT)
518 * The function that will be called directly from openssl
519 * in order for the application to get the tlsext_hostname just after
520 * parsing the Client Hello or Server Hello message. It will then call
521 * the serverNameCb_ function object. Hence, it is sort of a
522 * wrapper/proxy between serverNameCb_ and openssl.
524 * The openssl's primary intention is for SNI support, but we also use it
525 * generically for performing logic after the Client Hello comes in.
527 static int baseServerNameOpenSSLCallback(
529 int* al /* alert (return value) */,
534 std::string providedCiphersString_;
536 // Functions are called when locked by the calling function.
537 static void initializeOpenSSLLocked();
538 static void cleanupOpenSSLLocked();
541 typedef std::shared_ptr<SSLContext> SSLContextPtr;
543 std::ostream& operator<<(std::ostream& os, const folly::PasswordCollector& collector);
548 * Validate that the peer certificate's common name or subject alt names
549 * match what we expect. Currently this only checks for IPs within
550 * subject alt names but it could easily be expanded to check common name
551 * and hostnames as well.
553 * @param cert X509* peer certificate
554 * @param addr sockaddr object containing sockaddr to verify
555 * @param addrLen length of sockaddr as returned by getpeername or accept
556 * @return true iff a subject altname IP matches addr
558 // TODO(agartrell): Add support for things like common name when
560 static bool validatePeerCertNames(X509* cert,
561 const sockaddr* addr,
565 * Get the peer socket address from an X509_STORE_CTX*. Unlike the
566 * accept, getsockname, getpeername, etc family of operations, addrLen's
567 * initial value is ignored and reset.
569 * @param ctx Context from which to retrieve peer sockaddr
570 * @param addrStorage out param for address
571 * @param addrLen out param for length of address
572 * @return true on success, false on failure
574 static bool getPeerAddressFromX509StoreCtx(X509_STORE_CTX* ctx,
575 sockaddr_storage* addrStorage,