proxygen
SSLUtil.h
Go to the documentation of this file.
1 /*
2  * Copyright 2017-present 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 <list>
19 #include <mutex>
20 
21 #include <folly/String.h>
23 
24 namespace folly {
25 class AsyncSSLSocket;
26 }
27 
28 namespace wangle {
29 
35 enum class SSLResumeEnum : uint8_t {
36  HANDSHAKE = 0,
38  RESUME_TICKET = 3,
39  NA = 2,
40 };
41 
42 enum class SSLErrorEnum {
43  NO_ERROR,
44  TIMEOUT,
45  DROPPED,
46 };
47 
48 class SSLException : public std::runtime_error {
49  public:
52  const std::chrono::milliseconds& latency,
53  uint64_t bytesRead);
54 
55  SSLErrorEnum getError() const { return error_; }
56  std::chrono::milliseconds getLatency() const { return latency_; }
57  uint64_t getBytesRead() const { return bytesRead_; }
58 
59  private:
60  SSLErrorEnum error_{SSLErrorEnum::NO_ERROR};
61  std::chrono::milliseconds latency_;
62  uint64_t bytesRead_{0};
63 };
64 
65 class SSLUtil {
66  private:
68 
69  public:
74  static void getSSLCtxExIndex(int* pindex) {
75  std::lock_guard<std::mutex> g(sIndexLock_);
76  if (*pindex < 0) {
77  *pindex = SSL_CTX_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr);
78  }
79  }
80 
81  static void getRSAExIndex(int* pindex) {
82  std::lock_guard<std::mutex> g(sIndexLock_);
83  if (*pindex < 0) {
84  *pindex = RSA_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr);
85  }
86  }
87 
88  private:
89  // The following typedefs are needed for compatibility across various OpenSSL
90  // versions since each change the dup function param types ever so slightly
91 #if FOLLY_OPENSSL_IS_110 || defined(OPENSSL_IS_BORINGSSL)
92  using ex_data_dup_from_arg_t = const CRYPTO_EX_DATA*;
93 #else
94  using ex_data_dup_from_arg_t = CRYPTO_EX_DATA*;
95 #endif
96 
97 #ifdef OPENSSL_IS_BORINGSSL
98  using ex_data_dup_ptr_arg_t = void**;
99 #else
100  using ex_data_dup_ptr_arg_t = void*;
101 #endif
102 
103  public:
104  // ex data string dup func
105  static int exDataStdStringDup(
106  CRYPTO_EX_DATA* /* to */,
107  ex_data_dup_from_arg_t /* from */,
109  int /* idx */,
110  long /* argl */,
111  void* /* argp */) {
112  // TODO: With OpenSSL, ptr is passed in as a void* but is actually a void**
113  // So we need to convert it and then set to the duped data.
114  // see int_dup_ex_data in ex_data.c
115  // BoringSSL is saner and uses a void**
116  void** dataPtr = reinterpret_cast<void**>(ptr);
117  std::string* strData = reinterpret_cast<std::string*>(*dataPtr);
118  if (strData) {
119  *dataPtr = new std::string(*strData);
120  }
121  return 1;
122  }
123 
124  // ex data string free func
125  static void exDataStdStringFree(
126  void* /* parent */,
127  void* ptr,
128  CRYPTO_EX_DATA* /* ad */,
129  int /* idx */,
130  long /* argl */,
131  void* /* argp */) {
132  if (ptr) {
133  auto strPtr = reinterpret_cast<std::string*>(ptr);
134  delete strPtr;
135  }
136  }
137  // get an index that will store a std::string*
138  static void getSSLSessionExStrIndex(int* pindex) {
139  std::lock_guard<std::mutex> g(sIndexLock_);
140  if (*pindex < 0) {
141  *pindex = SSL_SESSION_get_ex_new_index(
142  0,
143  nullptr,
144  nullptr,
145  exDataStdStringDup,
146  exDataStdStringFree);
147  }
148  }
149 
150  static inline std::string hexlify(const std::string& binary) {
151  std::string hex;
152  folly::hexlify<std::string, std::string>(binary, hex);
153 
154  return hex;
155  }
156 
157  static inline const std::string& hexlify(const std::string& binary,
158  std::string& hex) {
159  folly::hexlify<std::string, std::string>(binary, hex);
160 
161  return hex;
162  }
163 
167  static SSLResumeEnum getResumeState(
168  folly::AsyncSSLSocket* sslSocket);
169 
175  static std::unique_ptr<std::string> getCommonName(const X509* cert);
176 
183  static std::unique_ptr<std::list<std::string>> getSubjectAltName(
184  const X509* cert);
185 
186 
192  static folly::ssl::X509UniquePtr getX509FromCertificate(
193  const std::string& certificateData);
194 };
195 
196 } // namespace wangle
void * ptr
SSLResumeEnum
Definition: SSLUtil.h:35
std::unique_ptr< X509, X509Deleter > X509UniquePtr
SSLErrorEnum
Definition: SSLUtil.h:42
static void getSSLSessionExStrIndex(int *pindex)
Definition: SSLUtil.h:138
static void exDataStdStringFree(void *, void *ptr, CRYPTO_EX_DATA *, int, long, void *)
Definition: SSLUtil.h:125
static void getSSLCtxExIndex(int *pindex)
Definition: SSLUtil.h:74
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
static int exDataStdStringDup(CRYPTO_EX_DATA *, ex_data_dup_from_arg_t, ex_data_dup_ptr_arg_t ptr, int, long, void *)
Definition: SSLUtil.h:105
requires And< SemiMovable< VN >... > &&SemiMovable< E > auto error(E e)
Definition: error.h:48
static const std::string & hexlify(const std::string &binary, std::string &hex)
Definition: SSLUtil.h:157
CRYPTO_EX_DATA * ex_data_dup_from_arg_t
Definition: SSLUtil.h:94
std::chrono::milliseconds getLatency() const
Definition: SSLUtil.h:56
void * ex_data_dup_ptr_arg_t
Definition: SSLUtil.h:100
SSLErrorEnum getError() const
Definition: SSLUtil.h:55
static void getRSAExIndex(int *pindex)
Definition: SSLUtil.h:81
std::mutex mutex
const char * string
Definition: Conv.cpp:212
g_t g(f_t)
static std::string hexlify(const std::string &binary)
Definition: SSLUtil.h:150
Container::value_type * dataPtr(Container &cont)
Definition: RangeTest.cpp:1082
static std::mutex sIndexLock_
Definition: SSLUtil.h:67
uint64_t getBytesRead() const
Definition: SSLUtil.h:57
std::chrono::milliseconds latency_
Definition: SSLUtil.h:61