fizz/server/TicketCodec-inl.h (75 lines of code) (raw):
/*
* Copyright (c) 2018-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree.
*/
namespace fizz {
namespace server {
template <CertificateStorage Storage>
constexpr folly::StringPiece TicketCodec<Storage>::Label;
template <CertificateStorage Storage>
Buf TicketCodec<Storage>::encode(ResumptionState resState) {
Buf selfIdentity = folly::IOBuf::create(0);
if (resState.serverCert) {
selfIdentity = folly::IOBuf::copyBuffer(resState.serverCert->getIdentity());
}
uint64_t ticketIssueTime = std::chrono::duration_cast<std::chrono::seconds>(
resState.ticketIssueTime.time_since_epoch())
.count();
auto buf = folly::IOBuf::create(60);
folly::io::Appender appender(buf.get(), 60);
fizz::detail::write(resState.version, appender);
fizz::detail::write(resState.cipher, appender);
fizz::detail::writeBuf<uint16_t>(resState.resumptionSecret, appender);
fizz::detail::writeBuf<uint16_t>(selfIdentity, appender);
appendClientCertificate(Storage, resState.clientCert, appender);
fizz::detail::write(resState.ticketAgeAdd, appender);
fizz::detail::write(ticketIssueTime, appender);
if (resState.alpn) {
auto alpnBuf = folly::IOBuf::copyBuffer(*resState.alpn);
fizz::detail::writeBuf<uint8_t>(alpnBuf, appender);
} else {
fizz::detail::writeBuf<uint8_t>(nullptr, appender);
}
fizz::detail::writeBuf<uint16_t>(resState.appToken, appender);
uint64_t handshakeTime = std::chrono::duration_cast<std::chrono::seconds>(
resState.handshakeTime.time_since_epoch())
.count();
fizz::detail::write(handshakeTime, appender);
return buf;
}
template <CertificateStorage Storage>
ResumptionState TicketCodec<Storage>::decode(
Buf encoded,
const Factory& factory,
const CertManager& certManager) {
folly::io::Cursor cursor(encoded.get());
ResumptionState resState;
fizz::detail::read(resState.version, cursor);
fizz::detail::read(resState.cipher, cursor);
fizz::detail::readBuf<uint16_t>(resState.resumptionSecret, cursor);
Buf selfIdentity;
fizz::detail::readBuf<uint16_t>(selfIdentity, cursor);
resState.clientCert = readClientCertificate(cursor, factory);
fizz::detail::read(resState.ticketAgeAdd, cursor);
uint64_t seconds;
fizz::detail::read(seconds, cursor);
Buf alpnBuf;
fizz::detail::readBuf<uint8_t>(alpnBuf, cursor);
if (!alpnBuf->empty()) {
resState.alpn = alpnBuf->moveToFbString().toStdString();
}
resState.ticketIssueTime = std::chrono::time_point<std::chrono::system_clock>(
std::chrono::seconds(seconds));
// If unset, set handshake timestamp to ticket timestamp
resState.handshakeTime = resState.ticketIssueTime;
resState.serverCert =
certManager.getCert(selfIdentity->moveToFbString().toStdString());
if (cursor.isAtEnd()) {
return resState;
}
fizz::detail::readBuf<uint16_t>(resState.appToken, cursor);
if (cursor.isAtEnd()) {
return resState;
}
fizz::detail::read(seconds, cursor);
resState.handshakeTime = std::chrono::time_point<std::chrono::system_clock>(
std::chrono::seconds(seconds));
return resState;
}
} // namespace server
} // namespace fizz