proxygen
AeadCookieCipher-inl.h
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 
10 
11 namespace fizz {
12 namespace server {
13 namespace detail {
14 
16  No = 0,
17  Yes = 1,
18 };
19 
21  auto buf = folly::IOBuf::create(100);
22  folly::io::Appender appender(buf.get(), 100);
23 
24  fizz::detail::write(state.version, appender);
25  fizz::detail::write(state.cipher, appender);
26 
27  if (state.group) {
29  fizz::detail::write(*state.group, appender);
30  } else {
32  }
33 
34  fizz::detail::writeBuf<uint16_t>(state.chloHash, appender);
35  fizz::detail::writeBuf<uint16_t>(state.appToken, appender);
36 
37  return buf;
38 }
39 
40 inline CookieState decodeCookie(Buf cookie) {
41  folly::io::Cursor cursor(cookie.get());
42 
44  fizz::detail::read(state.version, cursor);
45  fizz::detail::read(state.cipher, cursor);
46 
47  CookieHasGroup hasGroup;
48  fizz::detail::read(hasGroup, cursor);
49  if (hasGroup == CookieHasGroup::Yes) {
51  fizz::detail::read(group, cursor);
52  state.group = group;
53  }
54 
55  fizz::detail::readBuf<uint16_t>(state.chloHash, cursor);
56  fizz::detail::readBuf<uint16_t>(state.appToken, cursor);
57 
58  return state;
59 }
60 } // namespace detail
61 
62 template <typename AeadType, typename HkdfType>
63 boost::variant<AppToken, StatelessHelloRetryRequest>
65  Buf clientHello,
66  Buf appToken) const {
68  queue.append(std::move(clientHello));
69  auto msg = PlaintextReadRecordLayer().readEvent(queue);
70  if (!msg) {
71  throw std::runtime_error("no TLS message in initial");
72  }
73 
74  auto chlo = std::move(boost::get<ClientHello>(*msg));
75 
76  auto cookie = getExtension<Cookie>(chlo.extensions);
77  if (cookie) {
78  auto state = decrypt(std::move(cookie->cookie));
79  if (!state) {
80  throw std::runtime_error("cookie could not be decrypted");
81  }
82  AppToken token;
83  token.token = std::move(state->appToken);
84  return std::move(token);
85  } else {
87  hrr.data = getStatelessResponse(chlo, std::move(appToken));
88  return std::move(hrr);
89  }
90 }
91 
92 template <typename AeadType, typename HkdfType>
94  Buf cookie) const {
95  auto plaintext = tokenCipher_.decrypt(std::move(cookie));
96  if (plaintext) {
97  return detail::decodeCookie(std::move(*plaintext));
98  } else {
99  return folly::none;
100  }
101 }
102 
103 template <typename AeadType, typename HkdfType>
105  const ClientHello& chlo,
106  Buf appToken) const {
107  auto state = getCookieState(
108  *context_->getFactory(),
109  context_->getSupportedVersions(),
110  context_->getSupportedCiphers(),
111  context_->getSupportedGroups(),
112  chlo,
113  std::move(appToken));
114 
115  auto encoded = detail::encodeCookie(state);
116  auto cookie = tokenCipher_.encrypt(std::move(encoded));
117  if (!cookie) {
118  throw std::runtime_error("could not encrypt cookie");
119  }
120 
121  auto statelessMessage = getStatelessHelloRetryRequest(
122  state.version, state.cipher, state.group, std::move(*cookie));
123 
125  .writeHandshake(std::move(statelessMessage))
126  .data;
127 }
128 } // namespace server
129 } // namespace fizz
Buf getStatelessHelloRetryRequest(ProtocolVersion version, CipherSuite cipher, folly::Optional< NamedGroup > group, Buf cookie)
TLSContent writeHandshake(Buf &&encodedHandshakeMsg, Args &&...args) const
Definition: RecordLayer.h:74
boost::variant< AppToken, StatelessHelloRetryRequest > getTokenOrRetry(Buf clientHello, Buf appToken) const
CookieState decodeCookie(Buf cookie)
void write(const T &in, folly::io::Appender &appender)
Definition: Types-inl.h:112
static const std::string chlo
static std::unique_ptr< IOBuf > create(std::size_t capacity)
Definition: IOBuf.cpp:229
StringPiece cookie
CookieState getCookieState(const Factory &factory, const std::vector< ProtocolVersion > &supportedVersions, const std::vector< std::vector< CipherSuite >> &supportedCiphers, const std::vector< NamedGroup > &supportedGroups, const ClientHello &chlo, Buf appToken)
NamedGroup
Definition: Types.h:302
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
static Options cacheChainLength()
Definition: IOBufQueue.h:83
virtual folly::Optional< Param > readEvent(folly::IOBufQueue &socketBuf)
Definition: RecordLayer.cpp:18
size_t read(T &out, folly::io::Cursor &cursor)
Definition: Types-inl.h:258
Definition: Actions.h:16
ProtocolVersion version
Definition: CookieCipher.h:18
Optional< NamedGroup > group
std::unique_ptr< folly::IOBuf > Buf
Definition: Types.h:22
folly::Optional< NamedGroup > group
Definition: CookieCipher.h:20
folly::Optional< CookieState > decrypt(Buf cookie) const override
Buf getStatelessResponse(const ClientHello &chlo, Buf appToken) const
Buf encodeCookie(const CookieState &state)
state
Definition: http_parser.c:272
constexpr None none
Definition: Optional.h:87