proxygen
Extensions-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 
9 #include <vector>
10 
11 #include <fizz/record/Types.h>
12 
13 namespace fizz {
14 
15 inline std::vector<Extension>::const_iterator findExtension(
16  const std::vector<Extension>& extensions,
18  for (auto it = extensions.begin(); it != extensions.end(); ++it) {
19  if (it->extension_type == type) {
20  return it;
21  }
22  }
23  return extensions.end();
24 }
25 
26 template <class T>
28  const std::vector<Extension>& extensions) {
29  auto it = findExtension(extensions, T::extension_type);
30  if (it == extensions.end()) {
31  return folly::none;
32  }
33  folly::io::Cursor cs{it->extension_data.get()};
34  auto ret = getExtension<T>(cs);
35  if (!cs.isAtEnd()) {
36  throw std::runtime_error("didn't read entire extension");
37  }
38  return ret;
39 }
40 
41 template <>
44  detail::readVector<uint16_t>(sigs.supported_signature_algorithms, cs);
45  return sigs;
46 }
47 
48 template <>
50  SupportedGroups groups;
51  detail::readVector<uint16_t>(groups.named_group_list, cs);
52  return groups;
53 }
54 
55 template <>
57  const std::vector<Extension>& extensions) {
59  auto it = findExtension(extensions, ExtensionType::key_share);
60  if (it == extensions.end()) {
62  if (it == extensions.end()) {
63  return folly::none;
64  }
65  share.preDraft23 = true;
66  }
67  folly::io::Cursor cs{it->extension_data.get()};
68  detail::readVector<uint16_t>(share.client_shares, cs);
69  return std::move(share);
70 }
71 
72 template <>
75  detail::read(share.server_share, cs);
76  return share;
77 }
78 
79 template <>
82  detail::read(share.selected_group, cs);
83  return share;
84 }
85 
86 template <>
89  detail::readVector<uint16_t>(share.identities, cs);
90  detail::readVector<uint16_t>(share.binders, cs);
91  return share;
92 }
93 
94 template <>
98  return share;
99 }
100 
101 template <>
103  return ClientEarlyData();
104 }
105 
106 template <>
108  return ServerEarlyData();
109 }
110 
111 template <>
113  TicketEarlyData early;
115  return early;
116 }
117 
118 template <>
120  Cookie cookie;
121  detail::readBuf<uint16_t>(cookie.cookie, cs);
122  return cookie;
123 }
124 
125 template <>
127  SupportedVersions versions;
128  detail::readVector<uint8_t>(versions.versions, cs);
129  return versions;
130 }
131 
132 template <>
134  ServerSupportedVersions versions;
135  detail::read(versions.selected_version, cs);
136  return versions;
137 }
138 
139 template <>
141  PskKeyExchangeModes modes;
142  detail::readVector<uint8_t>(modes.modes, cs);
143  return modes;
144 }
145 
146 template <>
148  ProtocolNameList names;
149  detail::readVector<uint16_t>(names.protocol_name_list, cs);
150  return names;
151 }
152 
153 template <>
155  ServerNameList names;
156  detail::readVector<uint16_t>(names.server_name_list, cs);
157  return names;
158 }
159 
160 template <>
163  detail::readVector<uint16_t>(authorities.authorities, cs);
164  return authorities;
165 }
166 
167 template <>
170  detail::readVector<uint8_t>(cca.algorithms, cs);
171  return cca;
172 }
173 
174 template <>
176  Extension ext;
179  folly::io::Appender appender(ext.extension_data.get(), 10);
180  detail::writeVector<uint16_t>(sig.supported_signature_algorithms, appender);
181  return ext;
182 }
183 
184 template <>
186  Extension ext;
189  folly::io::Appender appender(ext.extension_data.get(), 10);
190  detail::writeVector<uint16_t>(groups.named_group_list, appender);
191  return ext;
192 }
193 
194 template <>
196  Extension ext;
200  folly::io::Appender appender(ext.extension_data.get(), 10);
201  detail::writeVector<uint16_t>(share.client_shares, appender);
202  return ext;
203 }
204 
205 template <>
207  Extension ext;
211  folly::io::Appender appender(ext.extension_data.get(), 10);
212  detail::write(share.server_share, appender);
213  return ext;
214 }
215 
216 template <>
218  Extension ext;
222  folly::io::Appender appender(ext.extension_data.get(), 10);
223  detail::write(share.selected_group, appender);
224  return ext;
225 }
226 
227 template <>
229  Extension ext;
232  folly::io::Appender appender(ext.extension_data.get(), 10);
233  detail::writeVector<uint16_t>(share.identities, appender);
234  detail::writeVector<uint16_t>(share.binders, appender);
235  return ext;
236 }
237 
238 template <>
240  Extension ext;
243  folly::io::Appender appender(ext.extension_data.get(), 10);
244  detail::write(share.selected_identity, appender);
245  return ext;
246 }
247 
248 template <>
250  Extension ext;
253  return ext;
254 }
255 
256 template <>
258  Extension ext;
261  return ext;
262 }
263 
264 template <>
266  Extension ext;
269  folly::io::Appender appender(ext.extension_data.get(), 10);
270  detail::write(early.max_early_data_size, appender);
271  return ext;
272 }
273 
274 template <>
275 inline Extension encodeExtension(const Cookie& cookie) {
276  Extension ext;
279  folly::io::Appender appender(ext.extension_data.get(), 10);
280  detail::writeBuf<uint16_t>(cookie.cookie, appender);
281  return ext;
282 }
283 
284 template <>
285 inline Extension encodeExtension(const SupportedVersions& versions) {
286  Extension ext;
289  folly::io::Appender appender(ext.extension_data.get(), 10);
290  detail::writeVector<uint8_t>(versions.versions, appender);
291  return ext;
292 }
293 
294 template <>
296  Extension ext;
299  folly::io::Appender appender(ext.extension_data.get(), 10);
300  detail::write(versions.selected_version, appender);
301  return ext;
302 }
303 
304 template <>
306  Extension ext;
309  folly::io::Appender appender(ext.extension_data.get(), 10);
310  detail::writeVector<uint8_t>(modes.modes, appender);
311  return ext;
312 }
313 
314 template <>
316  Extension ext;
319  folly::io::Appender appender(ext.extension_data.get(), 10);
320  detail::writeVector<uint16_t>(names.protocol_name_list, appender);
321  return ext;
322 }
323 
324 template <>
326  Extension ext;
329  folly::io::Appender appender(ext.extension_data.get(), 10);
330  detail::writeVector<uint16_t>(names.server_name_list, appender);
331  return ext;
332 }
333 
334 template <>
336  Extension ext;
339  folly::io::Appender appender(ext.extension_data.get(), 10);
340  detail::writeVector<uint16_t>(authorities.authorities, appender);
341  return ext;
342 }
343 
344 template <>
346  Extension ext;
349  folly::io::Appender appender(ext.extension_data.get(), 10);
350  detail::writeVector<uint8_t>(cca.algorithms, appender);
351  return ext;
352 }
353 
354 inline size_t getBinderLength(const ClientHello& chlo) {
355  if (chlo.extensions.empty() ||
356  chlo.extensions.back().extension_type != ExtensionType::pre_shared_key) {
357  throw FizzException(
358  "psk not at end of client hello", AlertDescription::decode_error);
359  }
360  folly::io::Cursor cursor(chlo.extensions.back().extension_data.get());
361  uint16_t identitiesLen;
362  detail::read(identitiesLen, cursor);
363  cursor.skip(identitiesLen);
364  uint16_t binderLen;
365  detail::read(binderLen, cursor);
366  if (cursor.totalLength() != binderLen) {
367  throw FizzException(
368  "malformed binder length", AlertDescription::decode_error);
369  }
370  return sizeof(binderLen) + binderLen;
371 }
372 
373 namespace detail {
374 
375 template <>
377  template <class T>
378  size_t read(KeyShareEntry& out, folly::io::Cursor& cursor) {
379  size_t len = 0;
380  len += detail::read(out.group, cursor);
381  len += readBuf<uint16_t>(out.key_exchange, cursor);
382  return len;
383  }
384 };
385 
386 template <>
388  template <class T>
390  detail::write(share.group, out);
391  detail::writeBuf<uint16_t>(share.key_exchange, out);
392  }
393 };
394 
395 template <>
397  template <class T>
398  size_t getSize(const KeyShareEntry& share) {
399  return sizeof(NamedGroup) + getBufSize<uint16_t>(share.key_exchange);
400  }
401 };
402 
403 template <>
405  template <class T>
406  size_t read(PskIdentity& out, folly::io::Cursor& cursor) {
407  size_t len = 0;
408  len += readBuf<uint16_t>(out.psk_identity, cursor);
409  len += detail::read(out.obfuscated_ticket_age, cursor);
410  return len;
411  }
412 };
413 
414 template <>
416  template <class T>
417  void write(const PskIdentity& ident, folly::io::Appender& out) {
418  writeBuf<uint16_t>(ident.psk_identity, out);
420  }
421 };
422 
423 template <>
425  template <class T>
426  size_t getSize(const PskIdentity& ident) {
427  return getBufSize<uint16_t>(ident.psk_identity) + sizeof(uint32_t);
428  }
429 };
430 
431 template <>
432 struct Reader<PskBinder> {
433  template <class T>
434  size_t read(PskBinder& out, folly::io::Cursor& cursor) {
435  return readBuf<uint8_t>(out.binder, cursor);
436  }
437 };
438 
439 template <>
440 struct Writer<PskBinder> {
441  template <class T>
442  void write(const PskBinder& binder, folly::io::Appender& out) {
443  writeBuf<uint8_t>(binder.binder, out);
444  }
445 };
446 
447 template <>
448 struct Sizer<PskBinder> {
449  template <class T>
450  size_t getSize(const PskBinder& binder) {
451  return getBufSize<uint8_t>(binder.binder);
452  }
453 };
454 
455 template <>
457  template <class T>
459  return readBuf<uint8_t>(name.name, cursor);
460  }
461 };
462 
463 template <>
465  template <class T>
467  writeBuf<uint8_t>(name.name, out);
468  }
469 };
470 
471 template <>
473  template <class T>
474  size_t getSize(const ProtocolName& name) {
475  return getBufSize<uint8_t>(name.name);
476  }
477 };
478 
479 template <>
481  template <class T>
482  size_t read(ServerName& name, folly::io::Cursor& cursor) {
483  size_t size = 0;
484  size += detail::read(name.name_type, cursor);
485  size += readBuf<uint16_t>(name.hostname, cursor);
486  return size;
487  }
488 };
489 
490 template <>
492  template <class T>
494  detail::write(name.name_type, out);
495  writeBuf<uint16_t>(name.hostname, out);
496  }
497 };
498 
499 template <>
500 struct Sizer<ServerName> {
501  template <class T>
502  size_t getSize(const ServerName& name) {
503  return sizeof(ServerNameType) + getBufSize<uint16_t>(name.hostname);
504  }
505 };
506 
507 template <>
509  template <class T>
510  size_t read(DistinguishedName& dn, folly::io::Cursor& cursor) {
511  return readBuf<uint16_t>(dn.encoded_name, cursor);
512  }
513 };
514 
515 template <>
517  template <class T>
519  writeBuf<uint16_t>(dn.encoded_name, out);
520  }
521 };
522 
523 template <>
525  template <class T>
526  size_t getSize(const DistinguishedName& dn) {
527  return getBufSize<uint16_t>(dn.encoded_name);
528  }
529 };
530 } // namespace detail
531 } // namespace fizz
uint32_t obfuscated_ticket_age
Definition: Extensions.h:56
size_t getSize(const PskIdentity &ident)
std::vector< Extension >::const_iterator findExtension(const std::vector< Extension > &extensions, ExtensionType type)
std::vector< PskBinder > binders
Definition: Extensions.h:65
size_t getBinderLength(const ClientHello &chlo)
size_t getSize(const ServerName &name)
void write(const T &in, folly::io::Appender &appender)
Definition: Types-inl.h:112
uint32_t max_early_data_size
Definition: Extensions.h:83
ServerNameType
Definition: Extensions.h:120
static const std::string chlo
static std::unique_ptr< IOBuf > create(std::size_t capacity)
Definition: IOBuf.cpp:229
PUSHMI_INLINE_VAR constexpr detail::share_fn< TN... > share
Definition: share.h:53
StringPiece cookie
PskType type
size_t read(ProtocolName &name, folly::io::Cursor &cursor)
size_t getSize(const DistinguishedName &dn)
KeyShareEntry server_share
Definition: Extensions.h:41
NamedGroup
Definition: Types.h:302
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
std::vector< PskKeyExchangeMode > modes
Definition: Extensions.h:105
size_t getSize(const PskBinder &binder)
void write(const ServerName &name, folly::io::Appender &out)
void write(const DistinguishedName &dn, folly::io::Appender &out)
Buf extension_data
Definition: Types.h:175
std::vector< NamedGroup > named_group_list
Definition: Extensions.h:23
size_t read(PskIdentity &out, folly::io::Cursor &cursor)
size_t read(ServerName &name, folly::io::Cursor &cursor)
std::vector< KeyShareEntry > client_shares
Definition: Extensions.h:34
NamedGroup group
Definition: Extensions.h:29
folly::Optional< TokenBindingParameters > getExtension(const std::vector< Extension > &extensions)
Definition: Types.cpp:99
size_t read(KeyShareEntry &out, folly::io::Cursor &cursor)
void write(const ProtocolName &name, folly::io::Appender &out)
const char * name
Definition: http_parser.c:437
constexpr auto size(C const &c) -> decltype(c.size())
Definition: Access.h:45
ProtocolVersion selected_version
Definition: Extensions.h:99
void write(const PskIdentity &ident, folly::io::Appender &out)
size_t read(T &out, folly::io::Cursor &cursor)
Definition: Types-inl.h:258
size_t getSize(const ProtocolName &name)
size_t read(DistinguishedName &dn, folly::io::Cursor &cursor)
size_t read(PskBinder &out, folly::io::Cursor &cursor)
std::vector< SignatureScheme > supported_signature_algorithms
Definition: Extensions.h:17
constexpr detail::Sig< Sig > const sig
Definition: Poly.h:1165
Definition: Actions.h:16
std::vector< Extension > extensions
Definition: Types.h:193
StringPiece authorities
std::vector< ProtocolVersion > versions
Definition: Extensions.h:93
ExtensionType
Definition: Types.h:95
ExtensionType extension_type
Definition: Types.h:174
ServerNameType name_type
Definition: Extensions.h:123
void write(const PskBinder &binder, folly::io::Appender &out)
void write(const KeyShareEntry &share, folly::io::Appender &out)
std::vector< ProtocolName > protocol_name_list
Definition: Extensions.h:115
std::vector< PskIdentity > identities
Definition: Extensions.h:64
std::vector< DistinguishedName > authorities
Definition: Extensions.h:137
Extension encodeExtension(const TokenBindingParameters &params)
Definition: Types.cpp:113
size_t getSize(const KeyShareEntry &share)
std::vector< CertificateCompressionAlgorithm > algorithms
Definition: Extensions.h:143
constexpr None none
Definition: Optional.h:87
std::vector< ServerName > server_name_list
Definition: Extensions.h:128