Expose SSL key materials to debug SSL
[folly.git] / folly / io / async / ssl / OpenSSLUtils.h
1 /*
2  * Copyright 2016 Facebook, Inc.
3  *
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
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 #pragma once
17
18 #include <folly/Range.h>
19 #include <folly/portability/Sockets.h>
20
21 #include <openssl/ssl.h>
22 #include <openssl/x509v3.h>
23
24 namespace folly {
25 namespace ssl {
26
27 class OpenSSLUtils {
28  public:
29   /*
30    * Get the TLS Session Master Key used to generate the TLS key material
31    *
32    * @param session ssl session
33    * @param keyOut destination for the master key, the buffer must be at least
34    * 48 bytes
35    * @return true if the master key is available (>= TLS1) and the output buffer
36    * large enough
37    */
38   static bool getTLSMasterKey(
39       const SSL_SESSION* session,
40       MutableByteRange keyOut);
41
42   /*
43    * Get the TLS Client Random used to generate the TLS key material
44    *
45    * @param ssl
46    * @param randomOut destination for the client random, the buffer must be at
47    * least 32 bytes
48    * @return true if the client random is available (>= TLS1) and the output
49    * buffer large enough
50    */
51   static bool getTLSClientRandom(const SSL* ssl, MutableByteRange randomOut);
52
53   /**
54    * Validate that the peer certificate's common name or subject alt names
55    * match what we expect.  Currently this only checks for IPs within
56    * subject alt names but it could easily be expanded to check common name
57    * and hostnames as well.
58    *
59    * @param cert    X509* peer certificate
60    * @param addr    sockaddr object containing sockaddr to verify
61    * @param addrLen length of sockaddr as returned by getpeername or accept
62    * @return true iff a subject altname IP matches addr
63    */
64   // TODO(agartrell): Add support for things like common name when
65   // necessary.
66   static bool validatePeerCertNames(X509* cert,
67                                     const sockaddr* addr,
68                                     socklen_t addrLen);
69
70   /**
71    * Get the peer socket address from an X509_STORE_CTX*.  Unlike the
72    * accept, getsockname, getpeername, etc family of operations, addrLen's
73    * initial value is ignored and reset.
74    *
75    * @param ctx         Context from which to retrieve peer sockaddr
76    * @param addrStorage out param for address
77    * @param addrLen     out param for length of address
78    * @return true on success, false on failure
79    */
80   static bool getPeerAddressFromX509StoreCtx(X509_STORE_CTX* ctx,
81                                              sockaddr_storage* addrStorage,
82                                              socklen_t* addrLen);
83
84   /**
85   * Wrappers for BIO operations that may be different across different
86   * versions/flavors of OpenSSL (including forks like BoringSSL)
87   */
88   static bool setCustomBioReadMethod(
89       BIO_METHOD* bioMeth,
90       int (*meth)(BIO*, char*, int));
91   static bool setCustomBioWriteMethod(
92       BIO_METHOD* bioMeth,
93       int (*meth)(BIO*, const char*, int));
94   static int getBioShouldRetryWrite(int ret);
95   static void setBioAppData(BIO* b, void* ptr);
96   static void* getBioAppData(BIO* b);
97   static void setCustomBioMethod(BIO*, BIO_METHOD*);
98   static int getBioFd(BIO* b, int* fd);
99   static void setBioFd(BIO* b, int fd, int flags);
100 };
101
102 } // ssl
103 } // folly