proxygen
SecondaryAuthManager.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015-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. An additional grant
7  * of patent rights can be found in the PATENTS file in the same directory.
8  *
9  */
11 #include <folly/io/Cursor.h>
12 #include <folly/io/IOBufQueue.h>
13 using namespace fizz;
15 
16 namespace proxygen {
17 
18 SecondaryAuthManager::SecondaryAuthManager(
19  std::unique_ptr<fizz::SelfCert> cert) {
20  cert_ = std::move(cert);
21 }
22 
23 SecondaryAuthManager::~SecondaryAuthManager() {
24 }
25 
26 std::pair<uint16_t, std::unique_ptr<folly::IOBuf>>
27 SecondaryAuthManager::createAuthRequest(
28  std::unique_ptr<folly::IOBuf> certRequestContext,
29  std::vector<fizz::Extension> extensions) {
30  // The certificate_request_context has to include the two octets Request-ID.
31  uint16_t requestId = requestIdCounter_++;
33  auto contextLen =
34  sizeof(requestId) + certRequestContext->computeChainDataLength();
35  QueueAppender appender(&contextQueue, contextLen);
36  appender.writeBE<uint16_t>(requestId);
37  contextQueue.append(std::move(certRequestContext));
38  auto secureContext = contextQueue.move();
40  std::move(secureContext), std::move(extensions));
41  auto authRequestClone = authRequest->clone();
42  outstandingRequests_.insert(
43  std::make_pair(requestId, std::move(authRequest)));
44  return std::make_pair(requestId, std::move(authRequestClone));
45 }
46 
47 std::pair<uint16_t, std::unique_ptr<folly::IOBuf>>
48 SecondaryAuthManager::getAuthenticator(
49  const fizz::AsyncFizzBase& transport,
51  uint16_t requestId,
52  std::unique_ptr<folly::IOBuf> authRequest) {
53  uint16_t certId = certIdCounter_++;
54  std::unique_ptr<folly::IOBuf> authenticator;
55  if (dir == TransportDirection::UPSTREAM) {
57  transport, fizz::Direction::UPSTREAM, *cert_, std::move(authRequest));
58  } else {
60  transport, fizz::Direction::DOWNSTREAM, *cert_, std::move(authRequest));
61  }
62  requestCertMap_.insert(std::make_pair(requestId, certId));
63  return std::make_pair(certId, std::move(authenticator));
64 }
65 
66 bool SecondaryAuthManager::validateAuthenticator(
67  const fizz::AsyncFizzBase& transport,
69  uint16_t certId,
70  std::unique_ptr<folly::IOBuf> authenticator) {
71  // Verify the certificate_request_context contains the Request-ID of a
72  // previously-sent "CERTIFICATE_REQUEST".
73  auto authClone = authenticator->clone();
74  auto authRequest = verifyContext(std::move(authClone));
75  if (!authRequest) {
76  return false;
77  }
78  // Validate the authenticator with regard to the authenticator request.
80  if (dir == TransportDirection::UPSTREAM) {
82  transport,
84  std::move(*authRequest),
85  std::move(authenticator));
86  } else {
88  transport,
90  std::move(*authRequest),
91  std::move(authenticator));
92  }
93  if (!certs) {
94  return false;
95  } else if ((*certs).size() == 0) {
96  VLOG(4) << "Peer does not have appropriate certificate or does not want to "
97  "provide one, empty authenticator received";
98  } else {
99  receivedCerts_.insert(std::make_pair(certId, std::move(*certs)));
100  }
101  return true;
102 }
103 
105 SecondaryAuthManager::verifyContext(
106  std::unique_ptr<folly::IOBuf> authenticator) {
107  auto certRequestContext =
109  std::move(authenticator));
110  folly::io::Cursor cursor(certRequestContext.get());
111  uint16_t requestId = cursor.readBE<uint16_t>();
112  if (outstandingRequests_.find(requestId) == outstandingRequests_.end()) {
113  VLOG(4) << "No previous CERTIFICATE_REQUEST matches the the CERTIFICATE "
114  "with Request-ID="
115  << requestId;
116  return folly::none;
117  }
118  auto authRequest = std::move(outstandingRequests_[requestId]);
119  return authRequest;
120 }
121 
122 folly::Optional<uint16_t> SecondaryAuthManager::getCertId(uint16_t requestId) {
123  if (requestCertMap_.find(requestId) == requestCertMap_.end()) {
124  return folly::none;
125  } else {
126  folly::Optional<uint16_t> certId = requestCertMap_[requestId];
127  return certId;
128  }
129 }
130 
134  if (receivedCerts_.find(certId) == receivedCerts_.end()) {
135  return folly::none;
136  } else {
137  certChain = std::move(receivedCerts_[certId]);
138  return certChain;
139  }
140 }
141 
142 } // namespace proxygen
static folly::Optional< std::vector< CertificateEntry > > validateAuthenticator(const fizz::AsyncFizzBase &transport, Direction dir, Buf authenticatorRequest, Buf authenticator)
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
std::unique_ptr< IOBuf > clone() const
Definition: IOBuf.cpp:527
static Buf getAuthenticator(const fizz::AsyncFizzBase &transport, Direction dir, const SelfCert &cert, Buf authenticatorRequest)
static Buf getAuthenticatorRequest(Buf certificateRequestContext, std::vector< fizz::Extension > extensions)
static Options cacheChainLength()
Definition: IOBufQueue.h:83
Definition: Actions.h:16
std::size_t computeChainDataLength() const
Definition: IOBuf.cpp:501
std::shared_ptr< PeerCert > getPeerCert(const CertAndKey &cert)
Definition: Utilities.h:122
static Buf getAuthenticatorContext(Buf authenticator)
constexpr None none
Definition: Optional.h:87
void writeBE(T value)
Definition: Cursor.h:744