proxygen
FizzUtil.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018-present, 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.
7  */
8 #include <fizz/util/FizzUtil.h>
10 
11 #include <folly/FileUtil.h>
12 #include <folly/Format.h>
15 #include <folly/ssl/Init.h>
16 
17 namespace fizz {
18 
19 static int passwordCallback(char* password, int size, int, void* data) {
20  if (!password || !data || size < 1) {
21  LOG(ERROR) << "invalid password buffer, size is " << size;
22  return 0;
23  }
24  std::string userPassword;
25  static_cast<folly::PasswordInFile*>(data)->getPassword(userPassword, size);
26  if (userPassword.empty()) {
27  LOG(ERROR) << "empty private key password";
28  return 0;
29  }
30  auto length = std::min(static_cast<int>(userPassword.size()), size - 1);
31  memcpy(password, userPassword.data(), length);
32  password[length] = '\0';
33  return length;
34 }
35 
36 std::vector<folly::ssl::X509UniquePtr> FizzUtil::readChainFile(
37  const std::string& filename) {
38  std::string certData;
39  if (!folly::readFile(filename.c_str(), certData)) {
40  throw std::runtime_error(
41  folly::to<std::string>("couldn't read cert file: ", filename));
42  }
43  auto certRange = folly::ByteRange(folly::StringPiece(certData));
45  if (certs.empty()) {
46  throw std::runtime_error(
47  folly::to<std::string>("couldn't read any cert from: ", filename));
48  }
49  return certs;
50 }
51 
53  const std::string& filename,
54  const std::string& passwordFilename) {
56  folly::readFile(filename.c_str(), data);
57  try {
58  if (!passwordFilename.empty()) {
59  folly::PasswordInFile pf(passwordFilename);
60  return FizzUtil::decryptPrivateKey(data, &pf);
61  } else {
62  return FizzUtil::decryptPrivateKey(data, nullptr);
63  }
64  } catch (std::runtime_error& e) {
65  auto ex = folly::sformat(
66  "Failed to read private key from file: {}, password file: {}",
67  filename,
68  passwordFilename);
69  std::throw_with_nested(std::runtime_error(ex));
70  }
71 }
72 
74  const std::string& data,
76  folly::ssl::BioUniquePtr keyBio(BIO_new_mem_buf(data.data(), data.size()));
77  if (!keyBio) {
78  throw std::runtime_error("couldn't create bio");
79  }
80 
82  if (pf) {
83  pkey.reset(
84  PEM_read_bio_PrivateKey(keyBio.get(), nullptr, passwordCallback, pf));
85  } else {
86  pkey.reset(
87  PEM_read_bio_PrivateKey(keyBio.get(), nullptr, nullptr, nullptr));
88  }
89 
90  if (!pkey) {
91  throw std::runtime_error("couldn't read private key");
92  }
93 
94  return pkey;
95 }
96 
97 std::vector<std::string> FizzUtil::getAlpnsFromNpnList(
98  const std::list<folly::SSLContext::NextProtocolsItem>& list) {
99  CHECK(!list.empty());
100  auto maxWeight = list.front().weight;
101  auto protoList = &list.front().protocols;
102  for (const auto& item : list) {
103  if (item.weight > maxWeight) {
104  protoList = &item.protocols;
105  }
106  }
107  return std::vector<std::string>(protoList->begin(), protoList->end());
108 }
109 } // namespace fizz
bool readFile(int fd, Container &out, size_t num_bytes=std::numeric_limits< size_t >::max())
Definition: FileUtil.h:125
std::unique_ptr< BIO, BioDeleter > BioUniquePtr
static folly::ssl::EvpPkeyUniquePtr readPrivateKey(const std::string &filename, const std::string &passwordFilename)
Definition: FizzUtil.cpp:52
std::string sformat(StringPiece fmt, Args &&...args)
Definition: Format.h:280
static std::vector< std::string > getAlpnsFromNpnList(const std::list< folly::SSLContext::NextProtocolsItem > &list)
Definition: FizzUtil.cpp:97
std::unique_ptr< EVP_PKEY, EvpPkeyDeleter > EvpPkeyUniquePtr
static std::vector< folly::ssl::X509UniquePtr > readChainFile(const std::string &filename)
Definition: FizzUtil.cpp:36
constexpr auto size(C const &c) -> decltype(c.size())
Definition: Access.h:45
LogLevel min
Definition: LogLevel.cpp:30
Encoder::MutableCompressedList list
Definition: Actions.h:16
static folly::ssl::EvpPkeyUniquePtr decryptPrivateKey(const std::string &data, folly::PasswordInFile *pf)
Definition: FizzUtil.cpp:73
const char * string
Definition: Conv.cpp:212
Range< const unsigned char * > ByteRange
Definition: Range.h:1163
static std::vector< X509UniquePtr > readCertsFromBuffer(ByteRange range)
static int passwordCallback(char *password, int size, int, void *data)
Definition: FizzUtil.cpp:19
static constexpr uint64_t data[1]
Definition: Fingerprint.cpp:43