OpenSSLUtils.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /*
  2. * Copyright 2016-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. #include <folly/Range.h>
  18. #include <folly/portability/OpenSSL.h>
  19. #include <folly/portability/Sockets.h>
  20. #include <folly/ssl/OpenSSLPtrTypes.h>
  21. namespace folly {
  22. namespace ssl {
  23. class OpenSSLUtils {
  24. public:
  25. /*
  26. * Get the TLS Session Master Key used to generate the TLS key material
  27. *
  28. * @param session ssl session
  29. * @param keyOut destination for the master key, the buffer must be at least
  30. * 48 bytes
  31. * @return true if the master key is available (>= TLS1) and the output buffer
  32. * large enough
  33. */
  34. static bool getTLSMasterKey(
  35. const SSL_SESSION* session,
  36. MutableByteRange keyOut);
  37. /*
  38. * Get the TLS Client Random used to generate the TLS key material
  39. *
  40. * @param ssl
  41. * @param randomOut destination for the client random, the buffer must be at
  42. * least 32 bytes
  43. * @return true if the client random is available (>= TLS1) and the output
  44. * buffer large enough
  45. */
  46. static bool getTLSClientRandom(const SSL* ssl, MutableByteRange randomOut);
  47. /**
  48. * Validate that the peer certificate's common name or subject alt names
  49. * match what we expect. Currently this only checks for IPs within
  50. * subject alt names but it could easily be expanded to check common name
  51. * and hostnames as well.
  52. *
  53. * @param cert X509* peer certificate
  54. * @param addr sockaddr object containing sockaddr to verify
  55. * @param addrLen length of sockaddr as returned by getpeername or accept
  56. * @return true iff a subject altname IP matches addr
  57. */
  58. // TODO(agartrell): Add support for things like common name when
  59. // necessary.
  60. static bool
  61. validatePeerCertNames(X509* cert, const sockaddr* addr, socklen_t addrLen);
  62. /**
  63. * Get the peer socket address from an X509_STORE_CTX*. Unlike the
  64. * accept, getsockname, getpeername, etc family of operations, addrLen's
  65. * initial value is ignored and reset.
  66. *
  67. * @param ctx Context from which to retrieve peer sockaddr
  68. * @param addrStorage out param for address
  69. * @param addrLen out param for length of address
  70. * @return true on success, false on failure
  71. */
  72. static bool getPeerAddressFromX509StoreCtx(
  73. X509_STORE_CTX* ctx,
  74. sockaddr_storage* addrStorage,
  75. socklen_t* addrLen);
  76. /**
  77. * Get a stringified cipher name (e.g., ECDHE-ECDSA-CHACHA20-POLY1305) given
  78. * the 2-byte code (e.g., 0xcca9) for the cipher. The name conversion only
  79. * works for the ciphers built into the linked OpenSSL library
  80. *
  81. * @param cipherCode A 16-bit IANA cipher code (machine endianness)
  82. * @return Cipher name, or empty if the code is not found
  83. */
  84. static const std::string& getCipherName(uint16_t cipherCode);
  85. /**
  86. * Set the 'initial_ctx' SSL_CTX* inside an SSL. The initial_ctx is used to
  87. * point to the SSL_CTX on which servername callback and session callbacks,
  88. * as well as session caching stats are set. If we want to enforce SSL_CTX
  89. * thread-based ownership (e.g., thread-local SSL_CTX) in the application, we
  90. * need to also set/reset the initial_ctx when we call SSL_set_SSL_CTX.
  91. *
  92. * @param ssl SSL pointer
  93. * @param ctx SSL_CTX pointer
  94. * @return Cipher name, or empty if the code is not found
  95. */
  96. static void setSSLInitialCtx(SSL* ssl, SSL_CTX* ctx);
  97. static SSL_CTX* getSSLInitialCtx(SSL* ssl);
  98. /**
  99. * Get the common name out of a cert. Return empty if x509 is null.
  100. */
  101. static std::string getCommonName(X509* x509);
  102. /**
  103. * Wrappers for BIO operations that may be different across different
  104. * versions/flavors of OpenSSL (including forks like BoringSSL)
  105. */
  106. static BioMethodUniquePtr newSocketBioMethod();
  107. static bool setCustomBioReadMethod(
  108. BIO_METHOD* bioMeth,
  109. int (*meth)(BIO*, char*, int));
  110. static bool setCustomBioWriteMethod(
  111. BIO_METHOD* bioMeth,
  112. int (*meth)(BIO*, const char*, int));
  113. static int getBioShouldRetryWrite(int ret);
  114. static void setBioAppData(BIO* b, void* ptr);
  115. static void* getBioAppData(BIO* b);
  116. static int getBioFd(BIO* b, int* fd);
  117. static void setBioFd(BIO* b, int fd, int flags);
  118. };
  119. } // namespace ssl
  120. } // namespace folly