proxygen
fizz::ExportedAuthenticator Class Reference

#include <ExportedAuthenticator.h>

Static Public Member Functions

static Buf getAuthenticatorRequest (Buf certificateRequestContext, std::vector< fizz::Extension > extensions)
 
static Buf getAuthenticator (const fizz::AsyncFizzBase &transport, Direction dir, const SelfCert &cert, Buf authenticatorRequest)
 
static Buf makeAuthenticator (std::unique_ptr< KeyDerivation > &kderiver, std::vector< SignatureScheme > supportedSchemes, const SelfCert &cert, Buf authenticatorRequest, Buf handshakeContext, Buf finishedMacKey, CertificateVerifyContext context)
 
static Buf getAuthenticatorContext (Buf authenticator)
 
static folly::Optional< std::vector< CertificateEntry > > validateAuthenticator (const fizz::AsyncFizzBase &transport, Direction dir, Buf authenticatorRequest, Buf authenticator)
 
static folly::Optional< std::vector< CertificateEntry > > validate (std::unique_ptr< KeyDerivation > &kderiver, Buf authenticatorRequest, Buf authenticator, Buf handshakeContext, Buf finishedMacKey, CertificateVerifyContext context)
 

Detailed Description

Public facing interface for Exported Authenticators (draft-ietf-tls-exported-authenticator) which enable application layer protocols to request or export "authenticators" that can convey proof of additionally identities after the TLS session is established.

Definition at line 32 of file ExportedAuthenticator.h.

Member Function Documentation

Buf fizz::ExportedAuthenticator::getAuthenticator ( const fizz::AsyncFizzBase transport,
Direction  dir,
const SelfCert cert,
Buf  authenticatorRequest 
)
static

"authenticate" API

Constructs an authenticator in response to the authenticator request given in |authenticatorRequest|, conveying the identity in |cert|.

Definition at line 31 of file ExportedAuthenticator.cpp.

References cipher, fizz::AsyncFizzBase::getCipher(), fizz::AsyncFizzBase::getEkm(), fizz::AsyncFizzBase::getSupportedSigSchemes(), fizz::Factory::makeKeyDeriver(), and folly::gen::move.

Referenced by proxygen::SecondaryAuthManager::getAuthenticator().

35  {
36  auto cipher = transport.getCipher();
37  auto deriver = Factory().makeKeyDeriver(*cipher);
38  auto hashLength = deriver->hashLength();
39  auto supportedSchemes = transport.getSupportedSigSchemes();
40  Buf handshakeContext;
41  Buf finishedMacKey;
42  if (dir == Direction::UPSTREAM) {
43  handshakeContext = transport.getEkm(
44  "EXPORTER-client authenticator handshake context", nullptr, hashLength);
45  finishedMacKey = transport.getEkm(
46  "EXPORTER-client authenticator finished key", nullptr, hashLength);
47  } else {
48  handshakeContext = transport.getEkm(
49  "EXPORTER-server authenticator handshake context", nullptr, hashLength);
50  finishedMacKey = transport.getEkm(
51  "EXPORTER-server authenticator finished key", nullptr, hashLength);
52  }
53  return makeAuthenticator(
54  deriver,
55  supportedSchemes,
56  cert,
57  std::move(authenticatorRequest),
58  std::move(handshakeContext),
59  std::move(finishedMacKey),
61 }
virtual std::vector< SignatureScheme > getSupportedSigSchemes() const =0
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
CipherSuite cipher
static Buf makeAuthenticator(std::unique_ptr< KeyDerivation > &kderiver, std::vector< SignatureScheme > supportedSchemes, const SelfCert &cert, Buf authenticatorRequest, Buf handshakeContext, Buf finishedMacKey, CertificateVerifyContext context)
virtual Buf getEkm(folly::StringPiece label, const Buf &context, uint16_t length) const =0
std::unique_ptr< folly::IOBuf > Buf
Definition: Types.h:22
virtual folly::Optional< CipherSuite > getCipher() const =0
Buf fizz::ExportedAuthenticator::getAuthenticatorContext ( Buf  authenticator)
static

"get context" API

Returns the certificate_request_context given an authenticator

Definition at line 63 of file ExportedAuthenticator.cpp.

References folly::IOBufQueue::cacheChainLength(), fizz::ReadRecordLayer::decodeHandshakeMessage(), and folly::gen::move.

Referenced by proxygen::SecondaryAuthManager::verifyContext().

63  {
65  authQueue.append(std::move(authenticator));
66  auto param = fizz::ReadRecordLayer::decodeHandshakeMessage(authQueue);
67  auto& certMsg = boost::get<CertificateMsg>(*param);
68  return std::move(certMsg.certificate_request_context);
69 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
static folly::Optional< Param > decodeHandshakeMessage(folly::IOBufQueue &buf)
Definition: RecordLayer.cpp:93
static Options cacheChainLength()
Definition: IOBufQueue.h:83
Buf fizz::ExportedAuthenticator::getAuthenticatorRequest ( Buf  certificateRequestContext,
std::vector< fizz::Extension extensions 
)
static

"request" API

Returns an opaque string that should be transmitted by the application over a secure channel to request an authenticator.

|certificateRequestContext| is an arbitrary sequence of bytes that should be used to prevent replays.

Definition at line 16 of file ExportedAuthenticator.cpp.

References fizz::CertificateRequest::certificate_request_context, fizz::encode< CertificateRequest >(), fizz::CertificateRequest::extensions, and folly::gen::move.

Referenced by proxygen::SecondaryAuthManager::createAuthRequest().

18  {
19  if (!certificateRequestContext || certificateRequestContext->empty()) {
20  throw FizzException(
21  "certificate request context must not be empty",
23  }
24 
26  cr.certificate_request_context = std::move(certificateRequestContext);
27  cr.extensions = std::move(extensions);
29 }
Buf encode< CertificateRequest >(CertificateRequest &&cr)
Definition: Types-inl.h:384
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
Buf fizz::ExportedAuthenticator::makeAuthenticator ( std::unique_ptr< KeyDerivation > &  kderiver,
std::vector< SignatureScheme supportedSchemes,
const SelfCert cert,
Buf  authenticatorRequest,
Buf  handshakeContext,
Buf  finishedMacKey,
CertificateVerifyContext  context 
)
static

Definition at line 103 of file ExportedAuthenticator.cpp.

References fizz::CertificateVerify::algorithm, fizz::certificate, fizz::detail::computeFinishedTranscript(), fizz::detail::computeTranscript(), fizz::detail::computeTranscriptHash(), fizz::detail::decodeAuthRequest(), fizz::encodeHandshake(), fizz::finished, fizz::SelfCert::getCertMessage(), fizz::detail::getEmptyAuthenticator(), fizz::detail::getFinishedData(), fizz::detail::getSignatureScheme(), folly::gen::move, folly::sig, fizz::SelfCert::sign(), fizz::CertificateVerify::signature, verify(), and fizz::Finished::verify_data.

110  {
111  Buf certificateRequestContext;
112  std::vector<fizz::Extension> extensions;
113  std::tie(certificateRequestContext, extensions) =
114  detail::decodeAuthRequest(authenticatorRequest);
116  detail::getSignatureScheme(supportedSchemes, cert, extensions);
117  // No proper signature scheme could be selected, return an empty
118  // authenticator.
119  if (!scheme) {
120  auto emptyAuth = detail::getEmptyAuthenticator(
121  kderiver,
122  std::move(authenticatorRequest),
123  std::move(handshakeContext),
124  std::move(finishedMacKey));
125  return emptyAuth;
126  }
127  // Compute CertificateMsg.
128  CertificateMsg certificate =
129  cert.getCertMessage(std::move(certificateRequestContext));
130  auto encodedCertMsg = encodeHandshake(std::move(certificate));
131  // Compute CertificateVerify.
132  auto transcript = detail::computeTranscript(
133  handshakeContext, authenticatorRequest, encodedCertMsg);
134  auto transcriptHash = detail::computeTranscriptHash(kderiver, transcript);
135  auto sig = cert.sign(*scheme, context, transcriptHash->coalesce());
137  verify.algorithm = *scheme;
138  verify.signature = std::move(sig);
139  auto encodedCertificateVerify = encodeHandshake(std::move(verify));
140  // Compute Finished.
141  auto finishedTranscript =
142  detail::computeFinishedTranscript(transcript, encodedCertificateVerify);
143  auto finishedTranscriptHash =
144  detail::computeTranscriptHash(kderiver, finishedTranscript);
145  auto verifyData =
146  detail::getFinishedData(kderiver, finishedMacKey, finishedTranscriptHash);
148  finished.verify_data = std::move(verifyData);
149  auto encodedFinished = encodeHandshake(std::move(finished));
150 
152  encodedCertMsg, encodedCertificateVerify, encodedFinished);
153 }
Buf encodeHandshake(T &&handshakeMsg)
Definition: Types-inl.h:515
void verify(int extras)
context
Definition: CMakeCache.txt:563
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
Buf computeTranscript(const Buf &handshakeContext, const Buf &authenticatorRequest, const Buf &certificate)
constexpr detail::Sig< Sig > const sig
Definition: Poly.h:1165
folly::Optional< SignatureScheme > getSignatureScheme(const std::vector< SignatureScheme > &supportedSchemes, const SelfCert &cert, const std::vector< fizz::Extension > &authRequestExtensions)
Buf getEmptyAuthenticator(std::unique_ptr< KeyDerivation > &kderiver, Buf authRequest, Buf handshakeContext, Buf finishedMacKey)
Buf getFinishedData(std::unique_ptr< KeyDerivation > &deriver, Buf &finishedMacKey, const Buf &finishedTranscript)
std::unique_ptr< folly::IOBuf > Buf
Definition: Types.h:22
std::tuple< Buf, std::vector< fizz::Extension > > decodeAuthRequest(const Buf &authRequest)
Buf computeTranscriptHash(std::unique_ptr< KeyDerivation > &deriver, const Buf &toBeHashed)
Buf computeFinishedTranscript(const Buf &crTranscript, const Buf &certVerify)
folly::Optional< std::vector< CertificateEntry > > fizz::ExportedAuthenticator::validate ( std::unique_ptr< KeyDerivation > &  kderiver,
Buf  authenticatorRequest,
Buf  authenticator,
Buf  handshakeContext,
Buf  finishedMacKey,
CertificateVerifyContext  context 
)
static

Definition at line 155 of file ExportedAuthenticator.cpp.

References folly::IOBufQueue::cacheChainLength(), fizz::detail::computeFinishedTranscript(), fizz::detail::computeTranscript(), fizz::detail::computeTranscriptHash(), folly::IOBuf::create(), fizz::ReadRecordLayer::decodeHandshakeMessage(), encodedCertVerify, fizz::encodeHandshake(), fizz::finished, fizz::detail::getEmptyAuthenticator(), fizz::detail::getFinishedData(), folly::gen::move, folly::none, uint16_t, and fizz::detail::writeBuf().

161  {
164  constexpr uint16_t capacity = 256;
165  // Clone the authenticator which is later compared to the re-calculated empty
166  // authenticator.
167  auto authClone = authenticator->clone();
168  authQueue.append(std::move(authenticator));
169  auto param = fizz::ReadRecordLayer::decodeHandshakeMessage(authQueue);
170  if (!param) {
171  return folly::none;
172  }
173  // First check if the authenticator is empty.
174  auto finished = boost::get<Finished>(&(*param));
175  if (finished) {
176  auto emptyAuth = detail::getEmptyAuthenticator(
177  kderiver,
178  std::move(authenticatorRequest),
179  std::move(handshakeContext),
180  std::move(finishedMacKey));
181  if (folly::IOBufEqualTo()(emptyAuth, authClone)) {
182  return std::vector<CertificateEntry>();
183  } else {
184  return folly::none;
185  }
186  }
187  auto param2 = fizz::ReadRecordLayer::decodeHandshakeMessage(authQueue);
188  if (!param2) {
189  return folly::none;
190  }
191  auto param3 = fizz::ReadRecordLayer::decodeHandshakeMessage(authQueue);
192  if (!param3) {
193  return folly::none;
194  }
195  auto certMsg = boost::get<CertificateMsg>(&(*param));
196  auto certVerify = boost::get<CertificateVerify>(&(*param2));
197  finished = boost::get<Finished>(&(*param3));
198  if (!certMsg || !certVerify || !finished) {
199  return folly::none;
200  }
201 
202  auto leafCert = folly::IOBuf::create(capacity);
203  folly::io::Appender appender(leafCert.get(), capacity);
204  detail::writeBuf(certMsg->certificate_list.front().cert_data, appender);
205  auto peerCert = CertUtils::makePeerCert(std::move(leafCert));
206  auto encodedCertMsg = encodeHandshake(std::move(*certMsg));
207  auto transcript = detail::computeTranscript(
208  handshakeContext, authenticatorRequest, encodedCertMsg);
209  auto transcriptHash = detail::computeTranscriptHash(kderiver, transcript);
210  try {
211  peerCert->verify(
212  certVerify->algorithm,
213  context,
214  transcriptHash->coalesce(),
215  certVerify->signature->coalesce());
216  } catch (const std::runtime_error&) {
217  return folly::none;
218  }
219  // Verify if Finished message matches.
220  auto encodedCertVerify = encodeHandshake(std::move(*certVerify));
221  auto finishedTranscript =
223  auto finishedTranscriptHash =
224  detail::computeTranscriptHash(kderiver, finishedTranscript);
225  auto verifyData =
226  detail::getFinishedData(kderiver, finishedMacKey, finishedTranscriptHash);
227 
228  if (folly::IOBufEqualTo()(finished->verify_data, verifyData)) {
229  certs = std::move(certMsg->certificate_list);
230  return certs;
231  } else {
232  return folly::none;
233  }
234 }
Buf encodeHandshake(T &&handshakeMsg)
Definition: Types-inl.h:515
static std::unique_ptr< IOBuf > create(std::size_t capacity)
Definition: IOBuf.cpp:229
context
Definition: CMakeCache.txt:563
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
static const std::string encodedCertVerify
void writeBuf(const Buf &buf, folly::io::Appender &out)
static folly::Optional< Param > decodeHandshakeMessage(folly::IOBufQueue &buf)
Definition: RecordLayer.cpp:93
static Options cacheChainLength()
Definition: IOBufQueue.h:83
Buf computeTranscript(const Buf &handshakeContext, const Buf &authenticatorRequest, const Buf &certificate)
Buf getEmptyAuthenticator(std::unique_ptr< KeyDerivation > &kderiver, Buf authRequest, Buf handshakeContext, Buf finishedMacKey)
Buf getFinishedData(std::unique_ptr< KeyDerivation > &deriver, Buf &finishedMacKey, const Buf &finishedTranscript)
static std::unique_ptr< PeerCert > makePeerCert(Buf certData)
Definition: Certificate.cpp:87
Buf computeTranscriptHash(std::unique_ptr< KeyDerivation > &deriver, const Buf &toBeHashed)
Buf computeFinishedTranscript(const Buf &crTranscript, const Buf &certVerify)
constexpr None none
Definition: Optional.h:87
folly::Optional< std::vector< CertificateEntry > > fizz::ExportedAuthenticator::validateAuthenticator ( const fizz::AsyncFizzBase transport,
Direction  dir,
Buf  authenticatorRequest,
Buf  authenticator 
)
static

"validate" API

Returns the certificate chain and extensions. If the authenticator was empty, the certificate chain will contain no certificates.

Definition at line 72 of file ExportedAuthenticator.cpp.

References cipher, fizz::AsyncFizzBase::getCipher(), fizz::AsyncFizzBase::getEkm(), fizz::Factory::makeKeyDeriver(), and folly::gen::move.

Referenced by proxygen::SecondaryAuthManager::validateAuthenticator().

76  {
77  auto cipher = transport.getCipher();
78  auto deriver = Factory().makeKeyDeriver(*cipher);
79  auto hashLength = deriver->hashLength();
80  Buf handshakeContext;
81  Buf finishedMacKey;
82  if (dir == Direction::UPSTREAM) {
83  handshakeContext = transport.getEkm(
84  "EXPORTER-server authenticator handshake context", nullptr, hashLength);
85  finishedMacKey = transport.getEkm(
86  "EXPORTER-server authenticator finished key", nullptr, hashLength);
87  } else {
88  handshakeContext = transport.getEkm(
89  "EXPORTER-client authenticator handshake context", nullptr, hashLength);
90  finishedMacKey = transport.getEkm(
91  "EXPORTER-client authenticator finished key", nullptr, hashLength);
92  }
93  auto certs = validate(
94  deriver,
95  std::move(authenticatorRequest),
96  std::move(authenticator),
97  std::move(handshakeContext),
98  std::move(finishedMacKey),
100  return certs;
101 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
CipherSuite cipher
virtual Buf getEkm(folly::StringPiece label, const Buf &context, uint16_t length) const =0
std::unique_ptr< folly::IOBuf > Buf
Definition: Types.h:22
virtual folly::Optional< CipherSuite > getCipher() const =0
static folly::Optional< std::vector< CertificateEntry > > validate(std::unique_ptr< KeyDerivation > &kderiver, Buf authenticatorRequest, Buf authenticator, Buf handshakeContext, Buf finishedMacKey, CertificateVerifyContext context)

The documentation for this class was generated from the following files: