12 using namespace folly;
16 Buf ExportedAuthenticator::getAuthenticatorRequest(
17 Buf certificateRequestContext,
18 std::vector<fizz::Extension> extensions) {
19 if (!certificateRequestContext || certificateRequestContext->empty()) {
21 "certificate request context must not be empty",
22 AlertDescription::illegal_parameter);
31 Buf ExportedAuthenticator::getAuthenticator(
35 Buf authenticatorRequest) {
38 auto hashLength = deriver->hashLength();
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);
48 handshakeContext = transport.
getEkm(
49 "EXPORTER-server authenticator handshake context",
nullptr, hashLength);
50 finishedMacKey = transport.
getEkm(
51 "EXPORTER-server authenticator finished key",
nullptr, hashLength);
53 return makeAuthenticator(
60 CertificateVerifyContext::Authenticator);
63 Buf ExportedAuthenticator::getAuthenticatorContext(
Buf authenticator) {
65 authQueue.append(
std::move(authenticator));
67 auto& certMsg = boost::get<CertificateMsg>(*param);
68 return std::move(certMsg.certificate_request_context);
72 ExportedAuthenticator::validateAuthenticator(
75 Buf authenticatorRequest,
79 auto hashLength = deriver->hashLength();
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);
88 handshakeContext = transport.
getEkm(
89 "EXPORTER-client authenticator handshake context",
nullptr, hashLength);
90 finishedMacKey = transport.
getEkm(
91 "EXPORTER-client authenticator finished key",
nullptr, hashLength);
93 auto certs = validate(
99 CertificateVerifyContext::Authenticator);
103 Buf ExportedAuthenticator::makeAuthenticator(
104 std::unique_ptr<KeyDerivation>& kderiver,
105 std::vector<SignatureScheme> supportedSchemes,
107 Buf authenticatorRequest,
108 Buf handshakeContext,
111 Buf certificateRequestContext;
112 std::vector<fizz::Extension> extensions;
113 std::tie(certificateRequestContext, extensions) =
133 handshakeContext, authenticatorRequest, encodedCertMsg);
135 auto sig = cert.
sign(*scheme, context, transcriptHash->coalesce());
141 auto finishedTranscript =
143 auto finishedTranscriptHash =
152 encodedCertMsg, encodedCertificateVerify, encodedFinished);
156 std::unique_ptr<KeyDerivation>& kderiver,
157 Buf authenticatorRequest,
159 Buf handshakeContext,
167 auto authClone = authenticator->clone();
168 authQueue.append(
std::move(authenticator));
174 auto finished = boost::get<Finished>(&(*param));
182 return std::vector<CertificateEntry>();
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) {
205 auto peerCert = CertUtils::makePeerCert(
std::move(leafCert));
208 handshakeContext, authenticatorRequest, encodedCertMsg);
212 certVerify->algorithm,
214 transcriptHash->coalesce(),
215 certVerify->signature->coalesce());
216 }
catch (
const std::runtime_error&) {
221 auto finishedTranscript =
223 auto finishedTranscriptHash =
229 certs =
std::move(certMsg->certificate_list);
239 const Buf& authRequest) {
240 Buf certRequestContext;
241 std::vector<fizz::Extension> exts;
242 if (authRequest && !(authRequest->empty())) {
246 std::move(decodedCertRequest.certificate_request_context);
247 exts =
std::move(decodedCertRequest.extensions);
255 std::unique_ptr<KeyDerivation>& deriver,
256 const Buf& toBeHashed) {
257 auto hashLength = deriver->hashLength();
259 data->append(hashLength);
260 auto transcriptHash =
262 deriver->hash(*toBeHashed, transcriptHash);
267 if (buf && !(buf->empty())) {
269 size_t chainElements = buf->countChainElements();
270 for (
size_t i = 0;
i < chainElements; ++
i) {
278 const Buf& handshakeContext,
279 const Buf& authenticatorRequest,
280 const Buf& certificate) {
300 std::unique_ptr<KeyDerivation>& deriver,
302 const Buf& finishedTranscript) {
303 auto hashLength = deriver->hashLength();
305 data->append(hashLength);
307 deriver->hmac(finishedMacKey->coalesce(), *finishedTranscript, outRange);
312 const std::vector<fizz::Extension>& authRequestExtensions) {
313 if (!(authRequestExtensions.empty())) {
314 auto sigAlgsExtension =
315 getExtension<SignatureAlgorithms>(authRequestExtensions);
316 if (sigAlgsExtension) {
317 auto requestedSchemes = sigAlgsExtension->supported_signature_algorithms;
318 return requestedSchemes;
328 const std::vector<SignatureScheme>& supportedSchemes,
330 const std::vector<fizz::Extension>& authRequestExtensions) {
335 if (requestedSchemes) {
336 for (
const auto& scheme : supportedSchemes) {
337 if (std::find(certSchemes.begin(), certSchemes.end(), scheme) !=
340 (*requestedSchemes).begin(), (*requestedSchemes).end(), scheme) !=
341 (*requestedSchemes).end()) {
342 selectedScheme = scheme;
348 if (!selectedScheme) {
349 VLOG(1) <<
"authenticator request without proper signature algorithms";
350 for (
const auto& scheme : supportedSchemes) {
351 if (std::find(certSchemes.begin(), certSchemes.end(), scheme) !=
353 selectedScheme = scheme;
358 return selectedScheme;
362 std::unique_ptr<KeyDerivation>& kderiver,
364 Buf handshakeContext,
365 Buf finishedMacKey) {
371 handshakeContext, authRequest, encodedEmptyCertMsg);
372 auto emptyAuthTranscriptHash =
375 kderiver, finishedMacKey, emptyAuthTranscriptHash);
379 return encodedEmptyAuth;
virtual std::vector< SignatureScheme > getSupportedSigSchemes() const =0
Buf encodeHandshake(T &&handshakeMsg)
virtual CertificateMsg getCertMessage(Buf certificateRequestContext=nullptr) const =0
static std::unique_ptr< IOBuf > create(std::size_t capacity)
Buf encode< CertificateRequest >(CertificateRequest &&cr)
constexpr detail::Map< Move > move
void push(const uint8_t *buf, size_t len)
—— Concurrent Priority Queue Implementation ——
Range< unsigned char * > MutableByteRange
static const std::string encodedCertVerify
Buf certificate_request_context
Buf certificate_request_context
void writeBuf(const Buf &buf, folly::io::Appender &out)
static folly::Optional< Param > decodeHandshakeMessage(folly::IOBufQueue &buf)
static Options cacheChainLength()
std::vector< Extension > extensions
constexpr auto data(C &c) -> decltype(c.data())
virtual Buf getEkm(folly::StringPiece label, const Buf &context, uint16_t length) const =0
Buf computeTranscript(const Buf &handshakeContext, const Buf &authenticatorRequest, const Buf &certificate)
constexpr detail::Sig< Sig > const sig
folly::Optional< std::vector< SignatureScheme > > getRequestedSchemes(const std::vector< fizz::Extension > &authRequestExtensions)
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)
virtual Buf sign(SignatureScheme scheme, CertificateVerifyContext context, folly::ByteRange toBeSigned) const =0
Buf getFinishedData(std::unique_ptr< KeyDerivation > &deriver, Buf &finishedMacKey, const Buf &finishedTranscript)
SignatureScheme algorithm
std::unique_ptr< folly::IOBuf > Buf
std::tuple< Buf, std::vector< fizz::Extension > > decodeAuthRequest(const Buf &authRequest)
Buf computeTranscriptHash(std::unique_ptr< KeyDerivation > &deriver, const Buf &toBeHashed)
static std::unique_ptr< IOBuf > copyBuffer(const void *buf, std::size_t size, std::size_t headroom=0, std::size_t minTailroom=0)
virtual folly::Optional< CipherSuite > getCipher() const =0
virtual std::unique_ptr< KeyDerivation > makeKeyDeriver(CipherSuite cipher) const
Buf computeFinishedTranscript(const Buf &crTranscript, const Buf &certVerify)
virtual std::vector< SignatureScheme > getSigSchemes() const =0