src: replace naive search in Buffer::IndexOf
[platform/upstream/nodejs.git] / src / node_crypto_clienthello.h
1 #ifndef SRC_NODE_CRYPTO_CLIENTHELLO_H_
2 #define SRC_NODE_CRYPTO_CLIENTHELLO_H_
3
4 #include "node.h"
5
6 #include <stddef.h>  // size_t
7 #include <stdlib.h>  // nullptr
8
9 namespace node {
10
11 class ClientHelloParser {
12  public:
13   ClientHelloParser() : state_(kEnded),
14                         onhello_cb_(nullptr),
15                         onend_cb_(nullptr),
16                         cb_arg_(nullptr),
17                         session_size_(0),
18                         session_id_(nullptr),
19                         servername_size_(0),
20                         servername_(nullptr),
21                         ocsp_request_(0),
22                         tls_ticket_size_(0),
23                         tls_ticket_(nullptr) {
24     Reset();
25   }
26
27   class ClientHello {
28    public:
29     inline uint8_t session_size() const { return session_size_; }
30     inline const uint8_t* session_id() const { return session_id_; }
31     inline bool has_ticket() const { return has_ticket_; }
32     inline uint8_t servername_size() const { return servername_size_; }
33     inline const uint8_t* servername() const { return servername_; }
34     inline int ocsp_request() const { return ocsp_request_; }
35
36    private:
37     uint8_t session_size_;
38     const uint8_t* session_id_;
39     bool has_ticket_;
40     uint8_t servername_size_;
41     const uint8_t* servername_;
42     int ocsp_request_;
43
44     friend class ClientHelloParser;
45   };
46
47   typedef void (*OnHelloCb)(void* arg, const ClientHello& hello);
48   typedef void (*OnEndCb)(void* arg);
49
50   void Parse(const uint8_t* data, size_t avail);
51
52   inline void Reset();
53   inline void Start(OnHelloCb onhello_cb, OnEndCb onend_cb, void* onend_arg);
54   inline void End();
55   inline bool IsPaused() const;
56   inline bool IsEnded() const;
57
58  private:
59   static const size_t kMaxTLSFrameLen = 16 * 1024 + 5;
60   static const size_t kMaxSSLExFrameLen = 32 * 1024;
61   static const uint8_t kServernameHostname = 0;
62   static const uint8_t kStatusRequestOCSP = 1;
63   static const size_t kMinStatusRequestSize = 5;
64
65   enum ParseState {
66     kWaiting,
67     kTLSHeader,
68     kPaused,
69     kEnded
70   };
71
72   enum FrameType {
73     kChangeCipherSpec = 20,
74     kAlert = 21,
75     kHandshake = 22,
76     kApplicationData = 23,
77     kOther = 255
78   };
79
80   enum HandshakeType {
81     kClientHello = 1
82   };
83
84   enum ExtensionType {
85     kServerName = 0,
86     kStatusRequest = 5,
87     kTLSSessionTicket = 35
88   };
89
90   bool ParseRecordHeader(const uint8_t* data, size_t avail);
91   void ParseHeader(const uint8_t* data, size_t avail);
92   void ParseExtension(ExtensionType type,
93                       const uint8_t* data,
94                       size_t len);
95   bool ParseTLSClientHello(const uint8_t* data, size_t avail);
96
97   ParseState state_;
98   OnHelloCb onhello_cb_;
99   OnEndCb onend_cb_;
100   void* cb_arg_;
101   size_t frame_len_;
102   size_t body_offset_;
103   size_t extension_offset_;
104   uint8_t session_size_;
105   const uint8_t* session_id_;
106   uint16_t servername_size_;
107   const uint8_t* servername_;
108   uint8_t ocsp_request_;
109   uint16_t tls_ticket_size_;
110   const uint8_t* tls_ticket_;
111 };
112
113 }  // namespace node
114
115 #endif  // SRC_NODE_CRYPTO_CLIENTHELLO_H_