Gray C++ Libraries  0.0.2
A set of C++ libraries for MSVC, GNU on Windows, WinCE, Linux
cSSLMsg.h
Go to the documentation of this file.
1 //
4 //
5 #ifndef _INC_cSSLMsgL_H
6 #define _INC_cSSLMsg_H
7 #ifndef NO_PRAGMA_ONCE
8 #pragma once
9 #endif
10 
11 #include "SSLTypes.h"
14 
15 namespace GrayLib
16 {
17  UNITTEST2_PREDEF(cSSLMsg);
18  class cHashWrap;
19 
20 #pragma pack(1) // byte packed.
21 
23  {
26 
27  public:
28  static const size_t k_nSizePref = 3;
29 
30  BYTE m_nMsgType;
31  BYTE m_nVersion3;
32  BYTE m_nVersion;
33 
36 
37  public:
38  cSSLMsgHeader() noexcept
39  {
40  // uninit.
41  }
42  cSSLMsgHeader(SSL_MSG_TYPE eMsgType, SSL_VERSION_TYPE eVer, WORD wContLen)
43  : m_nMsgType((BYTE)eMsgType)
44  , m_nVersion3(SSL_VERSION_MAJOR_BYTE)
45  , m_nVersion((BYTE)eVer)
46  , m_nContLengthH(HIBYTE(wContLen))
47  , m_nContLengthL(LOBYTE(wContLen))
48  {
49  ASSERT(isValid());
50  }
51 
52  bool isValidMsgType() const noexcept
53  {
54  // Only known valid messages.
55  switch (m_nMsgType)
56  {
58  case SSL_MSG_ALERT:
59  case SSL_MSG_HANDSHAKE:
61  return true;
62  default:
63  return false;
64  }
65  }
66  SSL_MSG_TYPE get_MsgType() const noexcept
67  {
68  return (SSL_MSG_TYPE)m_nMsgType;
69  }
70  void put_MsgType(SSL_MSG_TYPE eMsgType)
71  {
72  m_nMsgType = (BYTE)eMsgType;
73  ASSERT(isValidMsgType());
74  }
75 
76  bool isValidVersion() const noexcept
77  {
78  // Only known valid versions.
79  if (m_nVersion3 != SSL_VERSION_MAJOR_BYTE)
80  return false;
81  if (m_nVersion < SSL_VER_SSL_3 || m_nVersion > SSL_VERSION_SUPPORT_MAX)
82  return false; // not valid version.
83  return true;
84  }
85  SSL_VERSION_TYPE get_Version() const noexcept
86  {
89  return (SSL_VERSION_TYPE)m_nVersion;
90  }
92  {
93  m_nVersion3 = SSL_VERSION_MAJOR_BYTE;
94  m_nVersion = (BYTE)v;
95  ASSERT(isValidVersion());
96  }
97 
98  bool isValidContLength() const noexcept
99  {
100  // TLS encrypted messages can have up to 256 bytes of padding
101  WORD nContLength = get_ContLength();
102  if (nContLength < 1 || nContLength > k_Content_Size_Max) // upper bounds.
103  return false;
104  return true;
105  }
106  WORD get_ContLength() const noexcept
107  {
109  return MAKEWORD(m_nContLengthL, m_nContLengthH);
110  }
111  void put_ContLength(WORD nContLen)
112  {
113  m_nContLengthH = HIBYTE(nContLen);
114  m_nContLengthL = LOBYTE(nContLen);
115  ASSERT(isValidContLength());
116  }
117 
118  bool isValid() const
119  {
121  return isValidMsgType() && isValidVersion() && isValidContLength();
122  }
123 
124  void Set(SSL_MSG_TYPE eMsgType, SSL_VERSION_TYPE eVer, WORD wContLength)
125  {
126  put_MsgType(eMsgType);
127  put_Version(eVer);
128  put_ContLength(wContLength);
129  }
130  };
131 
133  {
136  };
137 
139  {
142 
143  public:
144  BYTE m_nTypeH;
145  BYTE m_nTypeL;
146  BYTE m_nLengthH;
147  BYTE m_nLengthL;
148 
149  public:
150  TLS_EXT_TYPE get_ExtType() const noexcept
151  {
152  return (TLS_EXT_TYPE)MAKEWORD(m_nTypeL, m_nTypeH);
153  }
154  void put_ExtType(TLS_EXT_TYPE eType) noexcept
155  {
156  m_nTypeH = HIBYTE(eType);
157  m_nTypeL = LOBYTE(eType);
158  }
159  WORD get_ExtLen() const noexcept
160  {
161  return MAKEWORD(m_nLengthL, m_nLengthH);
162  }
163  void put_ExtLen(size_t wLen) noexcept
164  {
165  m_nLengthH = HIBYTE(wLen);
166  m_nLengthL = LOBYTE(wLen);
167  }
168 
169  BYTE* get_ExtData() noexcept
170  {
171  return (BYTE*)(this + 1); // Data block to follow.
172  }
173  const BYTE* get_ExtData() const noexcept
174  {
175  return (const BYTE*)(this + 1); // Data block to follow.
176  }
177  };
178 
180  {
184 
185  public:
186  BYTE m_nHandType;
187  BYTE m_aLen[3];
188 
189  // Followed by Handshake content/payload. cSSLMsgHandHello, cSSLMsgHandExt, etc.
190 
191  public:
192 
194  {
195  return (SSL_HAND_TYPE)m_nHandType;
196  }
197  void put_HandType(SSL_HAND_TYPE eHandType)
198  {
199  m_nHandType = (BYTE)eHandType;
200  }
201 
202  DWORD get_Length() const
203  {
205  return cMemT::GetNVal3(m_aLen);
206  }
207  void put_Length(DWORD len)
208  {
209  cMemT::SetNVal3(m_aLen, len);
210  }
211 
212  const BYTE* get_DataPtr() const
213  {
214  // Data to follow.
215  // cSSLMsgHandHello etc.
216  return (const BYTE*)(this + 1);
217  }
218  BYTE* get_DataPtr()
219  {
220  // Data to follow.
221  return (BYTE*)(this + 1);
222  }
223  };
224 
226  {
230  public:
231  BYTE m_Level;
233  public:
235  {
236  return (SSL_ALERT_LEVEL_TYPE)m_Level;
237  }
239  {
240  return (SSL_ALERT_TYPE)m_Description;
241  }
242  };
243 
245  {
250  public:
252  };
253 
254  class CATTR_PACKED cSSLMsgX : public cSSL
255  {
261 
262  public:
263 
265 #if defined(USE_ZLIB)
266  static const size_t k_SSL_COMPRESSION_ADD = 1024;
267 #else
268  static const size_t k_SSL_COMPRESSION_ADD = 0;
269 #endif
270 
272  static const size_t k_SSL_PADDING_ADD = 256; // (0-256)
273 
275  static const size_t k_Msg_Size_Max = sizeof(cSSLMsgHeader) + 16 /* IV 8 + 8 */ + k_MAC_Size_Max + k_SSL_PADDING_ADD + k_Content_Size_Max + k_SSL_COMPRESSION_ADD;
276 
278 
280  {
284 
286  {
289  } m_Application;
290 
291  BYTE m_Iv[8]; // May prefix other data if Ver >= 1
292 
293  } m_u;
294 
295  // Only after CipherStateChange has occurred. extra stuff.
296  // Message authentication code (MAC)(optional) http://en.wikipedia.org/wiki/Message_authentication_code
297  // Padding for block ciphers.
298  // etc.
299 
300  public:
301  static HRESULT GRAYCALL CheckSSLClientHello(const void* pData, size_t nSize);
302  };
303 
305  {
308 
309  typedef cSSLCtr THIS_t;
310 
311  private:
312  BYTE m_Data[8];
313 
314  public:
316  {
317  SetZeroCtr();
318  }
319  cSSLCtr(UINT i)
320  {
321  SetZeroCtr();
322  cMemT::SetHtoN(m_Data + sizeof(m_Data) - sizeof(UINT), i);
323  }
324  void SetZeroCtr()
325  {
327  cMem::Zero(m_Data, sizeof(m_Data));
328  }
329  bool isZero() const
330  {
331  return cMem::IsZeros(m_Data, sizeof(m_Data));
332  }
333  const BYTE* get_Ctr() const
334  {
336  return m_Data;
337  }
338  void SetFillCtr()
339  {
341  cMem::Fill(m_Data, sizeof(m_Data) - 1, 0xFF);
342  m_Data[sizeof(m_Data) - 1] = 0x00;
343  }
344  COMPARE_t Compare(const THIS_t& n) const
345  {
346  return ::memcmp(m_Data, n.m_Data, sizeof(THIS_t));
347  }
348 
349  bool IncCtr();
350  };
351 
352 #pragma pack() // end packing.
353 
354  //**********************************************************
355 
357  {
369 
370  public:
373 
375  BYTE m_Random[28];
376 
381 
382  public:
383  HRESULT ReadHello(const BYTE* pData, size_t nSize);
384  size_t get_WriteHelloSize() const noexcept;
385  HRESULT WriteHello(BYTE* pData) const;
386  };
387 
388  class GRAYLIB_LINK cSSLMsg : public cHeapBlock, public cSSL
389  {
392 
393  typedef cHeapBlock SUPER_t;
394 
395  private:
396  WORD m_nContLength;
397 
398  public:
399  cSSLMsg(size_t nSizeMax = cSSLMsgX::k_Msg_Size_Max) noexcept;
400  cSSLMsg(SSL_MSG_TYPE eMsgType, SSL_VERSION_TYPE eVer, WORD wContLen);
401  ~cSSLMsg();
402 
403  const BYTE* get_MsgRaw() const noexcept
404  {
405  // may be nullptr?
406  return SUPER_t::get_DataBytes();
407  }
408  cSSLMsgX& get_Msg() const
409  {
410  ASSERT(SUPER_t::isValidPtr());
411  return *((cSSLMsgX*)get_Data());
412  }
413 
414  void ResetMsg()
415  {
416  ASSERT(SUPER_t::isValidPtr());
417  m_nContLength = 0;
418  cMem::Zero(get_Data(), sizeof(cSSLMsgHeader));
419  }
420 
421  SSL_MSG_TYPE get_MsgType() const
422  {
423  if (m_nContLength == 0)
424  return SSL_MSG_UNK;
425  return get_Msg().m_Hdr.get_MsgType();
426  }
427  void put_MsgType(SSL_MSG_TYPE eMsgType)
428  {
429  get_Msg().m_Hdr.put_MsgType(eMsgType);
430  }
431 
432  SSL_VERSION_TYPE get_Version() const
433  {
434  return get_Msg().m_Hdr.get_Version();
435  }
436  void put_Version(SSL_VERSION_TYPE v)
437  {
438  get_Msg().m_Hdr.put_Version(v);
439  }
440 
441  size_t get_ContLength() const noexcept
442  {
443  return m_nContLength;
444  }
445  void put_ContLength(size_t nContLen)
446  {
447  this->m_nContLength = (WORD)nContLen;
448  get_Msg().m_Hdr.put_ContLength((WORD)nContLen);
449  }
450 
451  BYTE* get_Cont0() const
452  {
455  return get_Msg().m_u.m_Iv;
456  }
457  BYTE* get_Iv() const
458  {
460  return get_Cont0();
461  }
462 
463  bool UpdateReadHdr();
464 
465  HRESULT ReadRecord(cStreamInput& s);
466 
467  UNITTEST2_PREDEF(cSSLMsg);
468  };
469 
470  class GRAYLIB_LINK cSSLMsgBuilder : public cSSLMsg
471  {
475 
476  typedef cSSLMsg SUPER_t;
477 
478  private:
479  bool m_bCompleteMsg;
480  BYTE* m_pContApp;
481 
482  public:
483  size_t m_nIntIndex;
485 
486  public:
487  cSSLMsgBuilder();
488  ~cSSLMsgBuilder();
489 
490  const BYTE* get_Ctr() const noexcept
491  {
492  return m_Ctr.get_Ctr();
493  }
494 
495  BYTE* get_ContApp() const noexcept
496  {
498  return m_pContApp;
499  }
500  void put_ContAppIvSize(size_t nSizeIv)
501  {
503  m_pContApp = get_Cont0() + nSizeIv;
504  }
505 
506  bool isCompleteMsg() const noexcept
507  {
508  return m_bCompleteMsg;
509  }
510  void SetCompleteMsg() noexcept
511  {
512  // We now have a complete message.
513  m_bCompleteMsg = true;
514  m_nIntIndex = 0; // may now read it read the start.
515  }
516 
517  bool InitMsg();
518  void ResetMsg(bool bHandshake)
519  {
520  // We are done with this buffer. reset it for re-use.
521  // We do NOT have a complete message.
522  SUPER_t::ResetMsg();
523  m_bCompleteMsg = false;
524  m_nIntIndex = 0;
525  if (bHandshake)
526  {
527  m_pContApp = get_Cont0(); // SSL_VER_TLS_1_1 may move this.
528  }
529  // Leave m_Ctr
530  }
531 
532  void UpdateHashV3(cHashWrap& rHasher, const BYTE* pSecret);
533  void UpdateHmac(cHashWrap& rHasher, bool bEncrypt);
534  void UpdateHmacExtra(cHashWrap& rHasher, size_t nSizePad, BYTE nCorrect);
535 
536  HRESULT ReadFill(cStreamInput* pReader, size_t nSizeExpect);
537  HRESULT WriteFlush(cStreamOutput* pWriter, bool bWait);
538  };
539 
540 };
541 #endif
#define GRAYCALL
declare calling convention for static functions so everyone knows the arg passing scheme....
Definition: GrayCore.h:36
#define CATTR_PACKED
Definition: GrayCore.h:87
#define GRAYLIB_LINK
Definition: GrayLibBase.h:35
INT32 HRESULT
_WIN32 style error codes. INT32
Definition: SysTypes.h:465
#define ASSERT(exp)
Definition: cDebugAssert.h:87
Definition: cHashWrap.h:18
Definition: cSSLMsg.h:305
cSSLCtr(UINT i)
Definition: cSSLMsg.h:319
const BYTE * get_Ctr() const
Definition: cSSLMsg.h:333
COMPARE_t Compare(const THIS_t &n) const
Definition: cSSLMsg.h:344
void SetZeroCtr()
Definition: cSSLMsg.h:324
void SetFillCtr()
Definition: cSSLMsg.h:338
bool isZero() const
Definition: cSSLMsg.h:329
cSSLCtr()
Definition: cSSLMsg.h:315
Definition: cSSLMsg.h:226
SSL_ALERT_TYPE get_Description() const
Definition: cSSLMsg.h:238
BYTE m_Description
SSL_ALERT_TYPE. This field identifies which type of alert is being sent. 0 = Close notify,...
Definition: cSSLMsg.h:232
SSL_ALERT_LEVEL_TYPE get_Level() const
Definition: cSSLMsg.h:234
BYTE m_Level
1 = warning SSL_ALERT_LEVEL_WARNING, 2 = fatal error. SSL_ALERT_LEVEL_FATAL
Definition: cSSLMsg.h:231
Definition: cSSLMsg.h:471
const BYTE * get_Ctr() const noexcept
Definition: cSSLMsg.h:490
void ResetMsg(bool bHandshake)
Definition: cSSLMsg.h:518
BYTE * get_ContApp() const noexcept
Definition: cSSLMsg.h:495
bool isCompleteMsg() const noexcept
Definition: cSSLMsg.h:506
void put_ContAppIvSize(size_t nSizeIv)
Definition: cSSLMsg.h:500
void SetCompleteMsg() noexcept
Definition: cSSLMsg.h:510
size_t m_nIntIndex
Amount of data read/written so far in m_pHdr. ( if !m_bCompleteMsg includes sizeof(cSSLMsgHeader) els...
Definition: cSSLMsg.h:483
cSSLCtr m_Ctr
Counter added to the hash.
Definition: cSSLMsg.h:484
Definition: cSSLMsg.h:245
BYTE m_ProtocolType
CCS protocol type = 1 = SSL3_MT_CCS. Only value allowed.
Definition: cSSLMsg.h:251
Definition: cSSLMsg.h:133
Definition: cSSLMsg.h:139
BYTE m_nTypeL
TLS_EXT_TYPE.
Definition: cSSLMsg.h:145
BYTE m_nLengthH
Length.
Definition: cSSLMsg.h:146
void put_ExtLen(size_t wLen) noexcept
Definition: cSSLMsg.h:163
TLS_EXT_TYPE get_ExtType() const noexcept
Definition: cSSLMsg.h:150
BYTE m_nTypeH
TLS_EXT_TYPE.
Definition: cSSLMsg.h:144
WORD get_ExtLen() const noexcept
Definition: cSSLMsg.h:159
const BYTE * get_ExtData() const noexcept
Definition: cSSLMsg.h:173
BYTE m_nLengthL
Definition: cSSLMsg.h:147
void put_ExtType(TLS_EXT_TYPE eType) noexcept
Definition: cSSLMsg.h:154
BYTE * get_ExtData() noexcept
Definition: cSSLMsg.h:169
Definition: cSSLMsg.h:357
BYTE m_nClientVersion
Minor version byte from SSL_VERSION_TYPE. ProtocolVersion.
Definition: cSSLMsg.h:372
cArrayVal< SSL_CipherSuite_t > m_aCipherSuite
Cryptographic suite selector. a key exchange algorithm and a CipherSpec combo. (2^16-1)
Definition: cSSLMsg.h:378
cHeapBlock m_SessionId
(var len <= 32)
Definition: cSSLMsg.h:377
cHeapBlock m_Extensions
Other stuff for forward version compatibility. cSSLMsgHandExt.
Definition: cSSLMsg.h:380
BYTE m_nClientVersion3
Major version is always 3. SSL_VERSION_MAJOR_BYTE.
Definition: cSSLMsg.h:371
DWORD m_TimeUnixGmt
32 bit cTimeInt/TIMESEC_t. used as part of random below.
Definition: cSSLMsg.h:374
cArrayVal< SSL_Compress_t > m_aCompressionMethod
(2^8-1)
Definition: cSSLMsg.h:379
Definition: cSSLMsg.h:180
const BYTE * get_DataPtr() const
Definition: cSSLMsg.h:212
void put_Length(DWORD len)
Definition: cSSLMsg.h:207
DWORD get_Length() const
Definition: cSSLMsg.h:202
SSL_HAND_TYPE get_HandType() const
Definition: cSSLMsg.h:193
BYTE m_nHandType
SSL_HAND_TYPE. sub message type. e.g. SSL_HAND_ClientHello.
Definition: cSSLMsg.h:186
void put_HandType(SSL_HAND_TYPE eHandType)
Definition: cSSLMsg.h:197
BYTE * get_DataPtr()
Definition: cSSLMsg.h:218
Definition: cSSLMsg.h:23
void put_MsgType(SSL_MSG_TYPE eMsgType)
Definition: cSSLMsg.h:70
bool isValidContLength() const noexcept
Definition: cSSLMsg.h:98
BYTE m_nVersion3
Major version is always 3. Anything but 3 is junk. SSL_VERSION_MAJOR_BYTE.
Definition: cSSLMsg.h:31
cSSLMsgHeader(SSL_MSG_TYPE eMsgType, SSL_VERSION_TYPE eVer, WORD wContLen)
Definition: cSSLMsg.h:42
void put_Version(SSL_VERSION_TYPE v)
Definition: cSSLMsg.h:91
BYTE m_nContLengthL
CONTENT/payload length of m_u to follow. network order = high,low order bytes. not include self.
Definition: cSSLMsg.h:35
void Set(SSL_MSG_TYPE eMsgType, SSL_VERSION_TYPE eVer, WORD wContLength)
Definition: cSSLMsg.h:124
SSL_VERSION_TYPE get_Version() const noexcept
Definition: cSSLMsg.h:85
cSSLMsgHeader() noexcept
Definition: cSSLMsg.h:38
WORD get_ContLength() const noexcept
Definition: cSSLMsg.h:106
bool isValidMsgType() const noexcept
Definition: cSSLMsg.h:52
void put_ContLength(WORD nContLen)
Definition: cSSLMsg.h:111
BYTE m_nVersion
Minor version byte from SSL_VERSION_TYPE.
Definition: cSSLMsg.h:32
bool isValid() const
Definition: cSSLMsg.h:118
BYTE m_nMsgType
SSL_MSG_TYPE. Message or content type.
Definition: cSSLMsg.h:30
BYTE m_nContLengthH
k_Content_Size_Max
Definition: cSSLMsg.h:34
bool isValidVersion() const noexcept
Definition: cSSLMsg.h:76
SSL_MSG_TYPE get_MsgType() const noexcept
Definition: cSSLMsg.h:66
Definition: cSSLMsg.h:255
cSSLMsgHeader m_Hdr
header. size=5
Definition: cSSLMsg.h:277
static const size_t k_Msg_Size_Max
Max possible size of *this.
Definition: cSSLMsg.h:275
Definition: cHeap.h:156
Definition: cMem.h:311
Definition: cStream.h:306
Definition: cStream.h:126
Definition: cMesh.h:22
TLS_EXT_TYPE
Definition: SSLTypes.h:192
SSL_MSG_TYPE
Definition: SSLTypes.h:45
@ SSL_MSG_APPLICATION_DATA
0x17 = any application defined data.
Definition: SSLTypes.h:54
@ SSL_MSG_UNK
Definition: SSLTypes.h:50
@ SSL_MSG_ALERT
0x15 = closing or some error.
Definition: SSLTypes.h:52
@ SSL_MSG_CHANGE_CIPHER_SPEC
0x14 = switch to the negotiated encryption.
Definition: SSLTypes.h:51
@ SSL_MSG_HANDSHAKE
0x16 = get this first. SSL3_RT_HANDSHAKE. negotiate the channel. SSL_HAND_TYPE
Definition: SSLTypes.h:53
UNITTEST2_PREDEF(cQuadtree)
SSL_ALERT_TYPE
Definition: SSLTypes.h:235
SSL_VERSION_TYPE
Definition: SSLTypes.h:66
@ SSL_VERSION_SUPPORT_MAX
Definition: SSLTypes.h:74
SSL_HAND_TYPE
Definition: SSLTypes.h:152
@ SSL_VERSION_MAJOR_BYTE
Definition: SSLTypes.h:63
SSL_ALERT_LEVEL_TYPE
Definition: SSLTypes.h:227
int COMPARE_t
result of compare. 0=same, 1=a>b, -1=a<b
Definition: cValT.h:17
class __DECL_IMPORT cStreamInput
Definition: cString.h:26
Definition: SSLTypes.h:270
static void SetNVal3(BYTE *p, DWORD nVal) noexcept
Definition: cMem.h:597
static void SetHtoN(void *pData, TYPE nVal) noexcept
Definition: cMem.h:584
static DWORD GetNVal3(const BYTE *p) noexcept
Definition: cMem.h:591
static void Zero(void *pData, size_t nSizeBlock) noexcept
Definition: cMem.h:100
static bool IsZeros(const void *pData, size_t nSize) noexcept
Definition: cMem.h:65
static void Fill(void *pDst, size_t nSize, BYTE bVal) noexcept
Definition: cMem.h:174
< m_nMsgType packet content/payload type specific data.
Definition: cSSLMsg.h:280
cSSLMsgChangeCipherSpec m_ChangeCipherSpec
m_nMsgType = SSL_MSG_CHANGE_CIPHER_SPEC = 0x14.
Definition: cSSLMsg.h:281
cSSLMsgHandshake m_Handshake
m_nMsgType = SSL_MSG_HANDSHAKE = 0x16 can repeat inside the message up to m_wLength.
Definition: cSSLMsg.h:283
cSSLMsgAlert m_Alert
m_nMsgType = SSL_MSG_ALERT = 0x15 = Some error occurred.
Definition: cSSLMsg.h:282