copy wangle back into folly
[folly.git] / folly / wangle / ssl / SSLUtil.h
1 /*
2  *  Copyright (c) 2015, Facebook, Inc.
3  *  All rights reserved.
4  *
5  *  This source code is licensed under the BSD-style license found in the
6  *  LICENSE file in the root directory of this source tree. An additional grant
7  *  of patent rights can be found in the PATENTS file in the same directory.
8  *
9  */
10 #pragma once
11
12 #include <folly/String.h>
13 #include <mutex>
14 #include <folly/io/async/AsyncSSLSocket.h>
15
16 namespace folly {
17
18 /**
19  * SSL session establish/resume status
20  *
21  * changing these values will break logging pipelines
22  */
23 enum class SSLResumeEnum : uint8_t {
24   HANDSHAKE = 0,
25   RESUME_SESSION_ID = 1,
26   RESUME_TICKET = 3,
27   NA = 2
28 };
29
30 enum class SSLErrorEnum {
31   NO_ERROR,
32   TIMEOUT,
33   DROPPED
34 };
35
36 class SSLUtil {
37  private:
38   static std::mutex sIndexLock_;
39
40  public:
41   /**
42    * Ensures only one caller will allocate an ex_data index for a given static
43    * or global.
44    */
45   static void getSSLCtxExIndex(int* pindex) {
46     std::lock_guard<std::mutex> g(sIndexLock_);
47     if (*pindex < 0) {
48       *pindex = SSL_CTX_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr);
49     }
50   }
51
52   static void getRSAExIndex(int* pindex) {
53     std::lock_guard<std::mutex> g(sIndexLock_);
54     if (*pindex < 0) {
55       *pindex = RSA_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr);
56     }
57   }
58
59   static inline std::string hexlify(const std::string& binary) {
60     std::string hex;
61     folly::hexlify<std::string, std::string>(binary, hex);
62
63     return hex;
64   }
65
66   static inline const std::string& hexlify(const std::string& binary,
67                                            std::string& hex) {
68     folly::hexlify<std::string, std::string>(binary, hex);
69
70     return hex;
71   }
72
73   /**
74    * Return the SSL resume type for the given socket.
75    */
76   static inline SSLResumeEnum getResumeState(
77     AsyncSSLSocket* sslSocket) {
78     return sslSocket->getSSLSessionReused() ?
79       (sslSocket->sessionIDResumed() ?
80         SSLResumeEnum::RESUME_SESSION_ID :
81         SSLResumeEnum::RESUME_TICKET) :
82       SSLResumeEnum::HANDSHAKE;
83   }
84
85   /**
86    * Get the Common Name from an X.509 certificate
87    * @param cert  certificate to inspect
88    * @return  common name, or null if an error occurs
89    */
90   static std::unique_ptr<std::string> getCommonName(const X509* cert);
91
92   /**
93    * Get the Subject Alternative Name value(s) from an X.509 certificate
94    * @param cert  certificate to inspect
95    * @return  set of zero or more alternative names, or null if
96    *            an error occurs
97    */
98   static std::unique_ptr<std::list<std::string>> getSubjectAltName(
99       const X509* cert);
100 };
101
102 }