GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage-daily/nodes/benchmark/out/../src/node_crypto_clienthello.h Lines: 5 5 100.0 %
Date: 2019-09-26 22:31:05 Branches: 0 0 - %

Line Branch Exec Source
1
// Copyright Joyent, Inc. and other Node contributors.
2
//
3
// Permission is hereby granted, free of charge, to any person obtaining a
4
// copy of this software and associated documentation files (the
5
// "Software"), to deal in the Software without restriction, including
6
// without limitation the rights to use, copy, modify, merge, publish,
7
// distribute, sublicense, and/or sell copies of the Software, and to permit
8
// persons to whom the Software is furnished to do so, subject to the
9
// following conditions:
10
//
11
// The above copyright notice and this permission notice shall be included
12
// in all copies or substantial portions of the Software.
13
//
14
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20
// USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22
#ifndef SRC_NODE_CRYPTO_CLIENTHELLO_H_
23
#define SRC_NODE_CRYPTO_CLIENTHELLO_H_
24
25
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
26
27
#include <cstddef>  // size_t
28
#include <cstdint>
29
30
namespace node {
31
namespace crypto {
32
33
// Parse the client hello so we can do async session resumption. OpenSSL's
34
// session resumption uses synchronous callbacks, see SSL_CTX_sess_set_get_cb
35
// and get_session_cb.
36
//
37
// TLS1.3 handshakes masquerade as TLS1.2 session resumption, and to do this,
38
// they always include a session_id in the ClientHello, making up a bogus value
39
// if necessary. The parser can't know if its a bogus id, and will cause a
40
// 'newSession' event to be emitted. This should do no harm, the id won't be
41
// found, and the handshake will continue.
42
class ClientHelloParser {
43
 public:
44
  inline ClientHelloParser();
45
46
  class ClientHello {
47
   public:
48
20
    inline uint8_t session_size() const { return session_size_; }
49
20
    inline const uint8_t* session_id() const { return session_id_; }
50
20
    inline bool has_ticket() const { return has_ticket_; }
51
18
    inline uint8_t servername_size() const { return servername_size_; }
52
38
    inline const uint8_t* servername() const { return servername_; }
53
54
   private:
55
    uint8_t session_size_;
56
    const uint8_t* session_id_;
57
    bool has_ticket_;
58
    uint8_t servername_size_;
59
    const uint8_t* servername_;
60
61
    friend class ClientHelloParser;
62
  };
63
64
  typedef void (*OnHelloCb)(void* arg, const ClientHello& hello);
65
  typedef void (*OnEndCb)(void* arg);
66
67
  void Parse(const uint8_t* data, size_t avail);
68
69
  inline void Reset();
70
  inline void Start(OnHelloCb onhello_cb, OnEndCb onend_cb, void* onend_arg);
71
  inline void End();
72
  inline bool IsPaused() const;
73
  inline bool IsEnded() const;
74
75
 private:
76
  static const size_t kMaxTLSFrameLen = 16 * 1024 + 5;
77
  static const size_t kMaxSSLExFrameLen = 32 * 1024;
78
  static const uint8_t kServernameHostname = 0;
79
  static const size_t kMinStatusRequestSize = 5;
80
81
  enum ParseState {
82
    kWaiting,
83
    kTLSHeader,
84
    kPaused,
85
    kEnded
86
  };
87
88
  enum FrameType {
89
    kChangeCipherSpec = 20,
90
    kAlert = 21,
91
    kHandshake = 22,
92
    kApplicationData = 23,
93
    kOther = 255
94
  };
95
96
  enum HandshakeType {
97
    kClientHello = 1
98
  };
99
100
  enum ExtensionType {
101
    kServerName = 0,
102
    kTLSSessionTicket = 35
103
  };
104
105
  bool ParseRecordHeader(const uint8_t* data, size_t avail);
106
  void ParseHeader(const uint8_t* data, size_t avail);
107
  void ParseExtension(const uint16_t type,
108
                      const uint8_t* data,
109
                      size_t len);
110
  bool ParseTLSClientHello(const uint8_t* data, size_t avail);
111
112
  ParseState state_;
113
  OnHelloCb onhello_cb_;
114
  OnEndCb onend_cb_;
115
  void* cb_arg_;
116
  size_t frame_len_ = 0;
117
  size_t body_offset_ = 0;
118
  size_t extension_offset_ = 0;
119
  uint8_t session_size_ = 0;
120
  const uint8_t* session_id_ = nullptr;
121
  uint16_t servername_size_ = 0;
122
  const uint8_t* servername_ = nullptr;
123
  uint16_t tls_ticket_size_ = -1;
124
  const uint8_t* tls_ticket_ = nullptr;
125
};
126
127
}  // namespace crypto
128
}  // namespace node
129
130
#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
131
132
#endif  // SRC_NODE_CRYPTO_CLIENTHELLO_H_