folly: build with -Wunused-parameter
[folly.git] / folly / io / async / SSLContext.cpp
index 4e8ea69f5a4b5d82a1d73b416fa33fbcf7785c51..788491c0ec1369de2684c93f5b77d2b2ab36d01c 100644 (file)
@@ -22,7 +22,9 @@
 #include <openssl/x509v3.h>
 
 #include <folly/Format.h>
+#include <folly/Memory.h>
 #include <folly/SpinLock.h>
+#include <folly/io/async/OpenSSLPtrTypes.h>
 
 // ---------------------------------------------------------------------
 // SSLContext implementation
@@ -43,7 +45,10 @@ std::mutex& initMutex() {
   return m;
 }
 
-}  // anonymous namespace
+inline void BIO_free_fb(BIO* bio) { CHECK_EQ(1, BIO_free(bio)); }
+using BIO_deleter = folly::static_function_deleter<BIO, &BIO_free_fb>;
+
+} // anonymous namespace
 
 #ifdef OPENSSL_NPN_NEGOTIATED
 int SSLContext::sNextProtocolsExDataIndex_ = -1;
@@ -186,10 +191,35 @@ void SSLContext::loadCertificate(const char* path, const char* format) {
   }
 }
 
+void SSLContext::loadCertificateFromBufferPEM(folly::StringPiece cert) {
+  if (cert.data() == nullptr) {
+    throw std::invalid_argument("loadCertificate: <cert> is nullptr");
+  }
+
+  std::unique_ptr<BIO, BIO_deleter> bio(BIO_new(BIO_s_mem()));
+  if (bio == nullptr) {
+    throw std::runtime_error("BIO_new: " + getErrors());
+  }
+
+  int written = BIO_write(bio.get(), cert.data(), cert.size());
+  if (written <= 0 || static_cast<unsigned>(written) != cert.size()) {
+    throw std::runtime_error("BIO_write: " + getErrors());
+  }
+
+  X509_UniquePtr x509(PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
+  if (x509 == nullptr) {
+    throw std::runtime_error("PEM_read_bio_X509: " + getErrors());
+  }
+
+  if (SSL_CTX_use_certificate(ctx_, x509.get()) == 0) {
+    throw std::runtime_error("SSL_CTX_use_certificate: " + getErrors());
+  }
+}
+
 void SSLContext::loadPrivateKey(const char* path, const char* format) {
   if (path == nullptr || format == nullptr) {
     throw std::invalid_argument(
-         "loadPrivateKey: either <path> or <format> is nullptr");
+        "loadPrivateKey: either <path> or <format> is nullptr");
   }
   if (strcmp(format, "PEM") == 0) {
     if (SSL_CTX_use_PrivateKey_file(ctx_, path, SSL_FILETYPE_PEM) == 0) {
@@ -200,10 +230,35 @@ void SSLContext::loadPrivateKey(const char* path, const char* format) {
   }
 }
 
+void SSLContext::loadPrivateKeyFromBufferPEM(folly::StringPiece pkey) {
+  if (pkey.data() == nullptr) {
+    throw std::invalid_argument("loadPrivateKey: <pkey> is nullptr");
+  }
+
+  std::unique_ptr<BIO, BIO_deleter> bio(BIO_new(BIO_s_mem()));
+  if (bio == nullptr) {
+    throw std::runtime_error("BIO_new: " + getErrors());
+  }
+
+  int written = BIO_write(bio.get(), pkey.data(), pkey.size());
+  if (written <= 0 || static_cast<unsigned>(written) != pkey.size()) {
+    throw std::runtime_error("BIO_write: " + getErrors());
+  }
+
+  EVP_PKEY_UniquePtr key(
+      PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
+  if (key == nullptr) {
+    throw std::runtime_error("PEM_read_bio_PrivateKey: " + getErrors());
+  }
+
+  if (SSL_CTX_use_PrivateKey(ctx_, key.get()) == 0) {
+    throw std::runtime_error("SSL_CTX_use_PrivateKey: " + getErrors());
+  }
+}
+
 void SSLContext::loadTrustedCertificates(const char* path) {
   if (path == nullptr) {
-    throw std::invalid_argument(
-         "loadTrustedCertificates: <path> is nullptr");
+    throw std::invalid_argument("loadTrustedCertificates: <path> is nullptr");
   }
   if (SSL_CTX_load_verify_locations(ctx_, path, nullptr) == 0) {
     throw std::runtime_error("SSL_CTX_load_verify_locations: " + getErrors());
@@ -310,7 +365,7 @@ void SSLContext::switchCiphersIfTLS11(
 #endif
 
 #if OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined(OPENSSL_NO_TLSEXT)
-int SSLContext::alpnSelectCallback(SSL* ssl,
+int SSLContext::alpnSelectCallback(SSL* /* ssl */,
                                    const unsigned char** out,
                                    unsigned char* outlen,
                                    const unsigned char* in,
@@ -515,9 +570,12 @@ bool SSLContext::canUseFalseStartWithCipher(const SSL_CIPHER *cipher) {
 }
 #endif
 
-int SSLContext::selectNextProtocolCallback(
-  SSL* ssl, unsigned char **out, unsigned char *outlen,
-  const unsigned char *server, unsigned int server_len, void *data) {
+int SSLContext::selectNextProtocolCallback(SSL* /* ssl */,
+                                           unsigned char** out,
+                                           unsigned char* outlen,
+                                           const unsigned char* server,
+                                           unsigned int server_len,
+                                           void* data) {
 
   SSLContext* ctx = (SSLContext*)data;
   if (ctx->advertisedNextProtocols_.size() > 1) {
@@ -828,7 +886,7 @@ bool OpenSSLUtils::getPeerAddressFromX509StoreCtx(X509_STORE_CTX* ctx,
 
 bool OpenSSLUtils::validatePeerCertNames(X509* cert,
                                          const sockaddr* addr,
-                                         socklen_t addrLen) {
+                                         socklen_t /* addrLen */) {
   // Try to extract the names within the SAN extension from the certificate
   auto altNames =
     reinterpret_cast<STACK_OF(GENERAL_NAME)*>(