proxygen
fizz::EncryptedReadRecordLayer Class Reference

#include <EncryptedRecordLayer.h>

Inheritance diagram for fizz::EncryptedReadRecordLayer:
fizz::ReadRecordLayer fizz::MockEncryptedReadRecordLayer

Public Member Functions

 ~EncryptedReadRecordLayer () override=default
 
 EncryptedReadRecordLayer (EncryptionLevel encryptionLevel)
 
folly::Optional< TLSMessageread (folly::IOBufQueue &buf) override
 
virtual void setAead (folly::ByteRange, std::unique_ptr< Aead > aead)
 
virtual void setSkipFailedDecryption (bool enabled)
 
void setProtocolVersion (ProtocolVersion version)
 
EncryptionLevel getEncryptionLevel () const override
 
- Public Member Functions inherited from fizz::ReadRecordLayer
virtual ~ReadRecordLayer ()=default
 
virtual folly::Optional< ParamreadEvent (folly::IOBufQueue &socketBuf)
 
virtual bool hasUnparsedHandshakeData () const
 

Private Member Functions

folly::Optional< BufgetDecryptedBuf (folly::IOBufQueue &buf)
 

Private Attributes

EncryptionLevel encryptionLevel_
 
std::unique_ptr< Aeadaead_
 
bool skipFailedDecryption_ {false}
 
bool useAdditionalData_ {true}
 
uint64_t seqNum_ {0}
 

Additional Inherited Members

- Static Public Member Functions inherited from fizz::ReadRecordLayer
static folly::Optional< ParamdecodeHandshakeMessage (folly::IOBufQueue &buf)
 

Detailed Description

Definition at line 20 of file EncryptedRecordLayer.h.

Constructor & Destructor Documentation

fizz::EncryptedReadRecordLayer::~EncryptedReadRecordLayer ( )
overridedefault
fizz::EncryptedReadRecordLayer::EncryptedReadRecordLayer ( EncryptionLevel  encryptionLevel)
explicit

Definition at line 21 of file EncryptedRecordLayer.cpp.

23  : encryptionLevel_(encryptionLevel) {}

Member Function Documentation

folly::Optional< Buf > fizz::EncryptedReadRecordLayer::getDecryptedBuf ( folly::IOBufQueue buf)
private

Definition at line 25 of file EncryptedRecordLayer.cpp.

References aead_, fizz::alert, folly::IOBufQueue::chainLength(), fizz::change_cipher_spec, folly::IOBuf::coalesce(), folly::IOBuf::data(), folly::IOBufQueue::empty(), folly::IOBufQueue::front(), fizz::illegal_parameter, folly::IOBuf::length(), max, folly::gen::move, folly::none, folly::io::detail::CursorBase< Derived, BufType >::pull(), folly::range(), seqNum_, skipFailedDecryption_, fizz::toString(), folly::IOBufQueue::trimStart(), uint16_t, useAdditionalData_, and folly::IOBuf::wrapBufferAsValue().

Referenced by read(), and setProtocolVersion().

26  {
27  while (true) {
28  folly::io::Cursor cursor(buf.front());
29 
30  if (buf.empty() || !cursor.canAdvance(kEncryptedHeaderSize)) {
31  return folly::none;
32  }
33 
34  std::array<uint8_t, kEncryptedHeaderSize> ad;
35  folly::io::Cursor adCursor(cursor);
36  adCursor.pull(ad.data(), ad.size());
38 
39  auto contentType =
40  static_cast<ContentType>(cursor.readBE<ContentTypeType>());
41  cursor.skip(sizeof(ProtocolVersion));
42 
43  auto length = cursor.readBE<uint16_t>();
44  if (length == 0) {
45  throw std::runtime_error("received 0 length encrypted record");
46  }
47  if (length > kMaxEncryptedRecordSize) {
48  throw std::runtime_error("received too long encrypted record");
49  }
50  if (buf.chainLength() < (cursor - buf.front()) + length) {
51  return folly::none;
52  }
53 
54  if (contentType == ContentType::alert && length == 2) {
55  auto alert = decode<Alert>(cursor);
56  throw std::runtime_error(folly::to<std::string>(
57  "received plaintext alert in encrypted record: ",
58  toString(alert.description)));
59  }
60 
61  std::unique_ptr<folly::IOBuf> encrypted;
62  cursor.clone(encrypted, length);
63  buf.trimStart(cursor - buf.front());
64 
65  if (contentType == ContentType::change_cipher_spec) {
66  encrypted->coalesce();
67  if (encrypted->length() == 1 && *encrypted->data() == 0x01) {
68  continue;
69  } else {
70  throw FizzException(
71  "received ccs", AlertDescription::illegal_parameter);
72  }
73  }
74 
75  TLSMessage msg;
77  throw std::runtime_error("max read seq num");
78  }
80  auto decryptAttempt = aead_->tryDecrypt(
81  std::move(encrypted), useAdditionalData_ ? &adBuf : nullptr, seqNum_);
82  if (decryptAttempt) {
83  seqNum_++;
84  skipFailedDecryption_ = false;
85  return decryptAttempt;
86  } else {
87  continue;
88  }
89  } else {
90  return aead_->decrypt(
91  std::move(encrypted),
92  useAdditionalData_ ? &adBuf : nullptr,
93  seqNum_++);
94  }
95  }
96 }
const folly::IOBuf * front() const
Definition: IOBufQueue.h:476
folly::StringPiece toString(StateEnum state)
Definition: State.cpp:16
size_t chainLength() const
Definition: IOBufQueue.h:492
LogLevel max
Definition: LogLevel.cpp:31
ByteRange coalesce()
Definition: IOBuf.h:1095
static constexpr uint16_t kMaxEncryptedRecordSize
bool empty() const
Definition: IOBufQueue.h:503
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
const uint8_t * data() const
Definition: IOBuf.h:499
ProtocolVersion
Definition: Types.h:24
std::size_t length() const
Definition: IOBuf.h:533
constexpr Range< Iter > range(Iter first, Iter last)
Definition: Range.h:1114
static constexpr size_t kEncryptedHeaderSize
static IOBuf wrapBufferAsValue(const void *buf, std::size_t capacity) noexcept
Definition: IOBuf.cpp:357
void trimStart(size_t amount)
Definition: IOBufQueue.cpp:255
typename std::underlying_type< ContentType >::type ContentTypeType
ContentType
Definition: Types.h:46
constexpr None none
Definition: Optional.h:87
EncryptionLevel fizz::EncryptedReadRecordLayer::getEncryptionLevel ( ) const
overridevirtual

Returns the current encryption level of the data that the read record layer can process.

Implements fizz::ReadRecordLayer.

Definition at line 139 of file EncryptedRecordLayer.cpp.

References encryptionLevel_.

Referenced by fizz::EncryptedWriteRecordLayer::setMinDesiredRecord(), and setProtocolVersion().

139  {
140  return encryptionLevel_;
141 }
folly::Optional< TLSMessage > fizz::EncryptedReadRecordLayer::read ( folly::IOBufQueue buf)
overridevirtual

Reads a fragment from the record layer. Returns an empty optional if insuficient data available. Throws if data malformed. On success, advances buf the amount read.

Implements fizz::ReadRecordLayer.

Definition at line 98 of file EncryptedRecordLayer.cpp.

References folly::io::detail::CursorBase< Derived, BufType >::advanceToEnd(), fizz::alert, folly::IOBufQueue::append(), fizz::application_data, folly::IOBuf::create(), data, fizz::TLSMessage::fragment, folly::IOBufQueue::front(), getDecryptedBuf(), fizz::handshake, folly::IOBufQueue::move(), folly::gen::move, folly::none, folly::IOBufQueue::trimEnd(), and fizz::TLSMessage::type.

99  {
100  auto decryptedBuf = getDecryptedBuf(buf);
101  if (!decryptedBuf) {
102  return folly::none;
103  }
104 
105  folly::IOBufQueue decrypted;
106  decrypted.append(std::move(*decryptedBuf));
107 
108  folly::io::Cursor paddingCursor(decrypted.front());
109  paddingCursor.advanceToEnd();
110  while (!*(paddingCursor -= 1).data()) {
111  }
112  TLSMessage msg;
113  msg.type = static_cast<ContentType>(paddingCursor.readBE<ContentTypeType>());
114  decrypted.trimEnd(paddingCursor.totalLength() + sizeof(ContentType));
115  msg.fragment = decrypted.move();
116 
117  switch (msg.type) {
119  case ContentType::alert:
121  break;
122  default:
123  throw std::runtime_error(folly::to<std::string>(
124  "received encrypted content type ",
125  static_cast<ContentTypeType>(msg.type)));
126  }
127 
128  if (!msg.fragment) {
129  if (msg.type == ContentType::application_data) {
130  msg.fragment = folly::IOBuf::create(0);
131  } else {
132  throw std::runtime_error("received empty fragment");
133  }
134  }
135 
136  return std::move(msg);
137 }
const folly::IOBuf * front() const
Definition: IOBufQueue.h:476
void append(std::unique_ptr< folly::IOBuf > &&buf, bool pack=false)
Definition: IOBufQueue.cpp:143
static std::unique_ptr< IOBuf > create(std::size_t capacity)
Definition: IOBuf.cpp:229
folly::Optional< Buf > getDecryptedBuf(folly::IOBufQueue &buf)
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
std::unique_ptr< folly::IOBuf > move()
Definition: IOBufQueue.h:459
typename std::underlying_type< ContentType >::type ContentTypeType
void trimEnd(size_t amount)
Definition: IOBufQueue.cpp:283
static constexpr uint64_t data[1]
Definition: Fingerprint.cpp:43
ContentType
Definition: Types.h:46
constexpr None none
Definition: Optional.h:87
virtual void fizz::EncryptedReadRecordLayer::setAead ( folly::ByteRange  ,
std::unique_ptr< Aead aead 
)
inlinevirtual

Reimplemented in fizz::MockEncryptedReadRecordLayer.

Definition at line 28 of file EncryptedRecordLayer.h.

References aead_, folly::gen::move, and seqNum_.

30  {
31  if (seqNum_ != 0) {
32  throw std::runtime_error("aead set after read");
33  }
34  aead_ = std::move(aead);
35  }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
void fizz::EncryptedReadRecordLayer::setProtocolVersion ( ProtocolVersion  version)
inline
virtual void fizz::EncryptedReadRecordLayer::setSkipFailedDecryption ( bool  enabled)
inlinevirtual

Definition at line 37 of file EncryptedRecordLayer.h.

References skipFailedDecryption_.

37  {
38  skipFailedDecryption_ = enabled;
39  }

Member Data Documentation

std::unique_ptr<Aead> fizz::EncryptedReadRecordLayer::aead_
private
EncryptionLevel fizz::EncryptedReadRecordLayer::encryptionLevel_
private

Definition at line 58 of file EncryptedRecordLayer.h.

Referenced by getEncryptionLevel().

uint64_t fizz::EncryptedReadRecordLayer::seqNum_ {0}
mutableprivate
bool fizz::EncryptedReadRecordLayer::skipFailedDecryption_ {false}
private

Definition at line 60 of file EncryptedRecordLayer.h.

Referenced by getDecryptedBuf(), and setSkipFailedDecryption().

bool fizz::EncryptedReadRecordLayer::useAdditionalData_ {true}
private

Definition at line 62 of file EncryptedRecordLayer.h.

Referenced by getDecryptedBuf(), and setProtocolVersion().


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