Gray C++ Libraries  0.0.2
A set of C++ libraries for MSVC, GNU on Windows, WinCE, Linux
cSecureChannel.h
Go to the documentation of this file.
1 //
7 //
8 #ifndef _INC_cSecureChannel_H
9 #define _INC_cSecureChannel_H 0x1D // This is the version stamp for the protocol
10 #ifndef NO_PRAGMA_ONCE
11 #pragma once
12 #endif
13 
14 #include "../Net/cProtocol.h"
15 #include "../UID/cFourCC.h"
16 #include "../Hash/cHashSHA256.h"
17 #include "../Cipher/cCipherBase.h"
18 #include "../Codec/cStreamCipher.h"
20 #include "GrayCore/include/StrA.h"
23 
24 namespace GrayLib
25 {
28 
30  {
35 
36  public:
39 
40  public:
41  cSecureId(cStringA sAppId = "", cStringA sUserId = "") noexcept
42  : m_sAppId(sAppId)
43  , m_sUserId(sUserId)
44  {
45  }
46  bool IsSame(const cSecureId& k) const
47  {
48  if (m_sAppId.Compare(k.m_sAppId))
49  return false;
50  if (m_sUserId.Compare(k.m_sUserId))
51  return false;
52  return true;
53  }
54  };
55 
57  {
60  public:
61  typedef cSecureId SUPER_t;
62 
64  {
67  CIPHER_None = 0,
71 
72  // Other future crypto...
74 
75  CIPHER_KEY_RSA = 31,
76  };
77 
78  static const FOURCC k_SIGNATURE = MAKEFOURCC('G', 'S', 'e', 'c');
79  static const size_t k_SizeMin = 14;
80 
82  WORD m_nVersion;
84 
85  public:
86 
87  cSecureKnock(cStringA sAppId = "", cStringA sUserId = "", WORD nCryptAbilities = _1BITMASK(CIPHER_RC4) | _1BITMASK(CIPHER_None))
88  : cSecureId(sAppId, sUserId)
89  , m_nSignature(k_SIGNATURE)
90  , m_nVersion(_INC_cSecureChannel_H)
91  , m_nCryptAbilities(nCryptAbilities) // CIPHER_TYPE
92  {
93  }
94 
95  HRESULT Serialize(cArchive& a);
96  HRESULT SetSecureKnock(cStreamInput& s);
97  HRESULT SetSecureKnock(const void* pData, size_t nSize);
98 
99  void SetClear() noexcept
100  {
101  m_nSignature = 0;
102  m_nVersion = 0;
103  }
104  bool IsSame(const cSecureKnock& k) const;
105  };
106 
108  {
116 
117  public:
119  {
122  STATE_0 = 0,
132  };
133 
134  public:
138 
139  protected:
146 
147  protected:
148  virtual HRESULT SetStateSecure();
149  HRESULT GetCipher(OUT cNewPtr<cCipherBase>& rCipher, bool bEncodeMode, const cSecureHash& hashKey);
150 
151  public:
152  cSecureChannel();
153  virtual ~cSecureChannel();
154 
155  STATE_TYPE get_State() const noexcept
156  {
157  return m_eState;
158  }
159  bool isStateSecure() const noexcept
160  {
162  return get_State() == STATE_Secure;
163  }
164 
165  cStreamInput* get_SecureInp() const;
166  cStreamOutput* get_SecureOut() const;
167 
168  static void GRAYCALL ComputeHash(OUT cSecureHash& rHash, const cHashCode& r1, const cHashCode& r2);
169 
171  };
172 
174  {
177 
178  typedef cSecureChannel SUPER_t;
179 
180  protected:
183 
184  private:
185  HRESULT OnState0();
186  HRESULT OnStateKnock();
187  HRESULT OnStateLogin();
188 
189  public:
190  cSecureClient(cStreamInput* pStreamInp, cStreamOutput* pStreamOut);
191  virtual ~cSecureClient();
192 
193  HRESULT AdvanceState();
194 
196  {
198  if (m_pCipherInp == nullptr) // From the raw channel. CIPHER_None = No Crypt. Pass Through.
199  return m_pStreamInp;
200  return SUPER_t::get_SecureInp();
201  }
203  {
205  if (m_pCipherOut == nullptr) // From the raw channel. CIPHER_None = No Crypt. Pass Through.
206  return m_pStreamOut;
207  return SUPER_t::get_SecureOut();
208  }
209  };
210 
212 
214  {
217 
218  friend class cSecureServerFactory;
219 
220  public:
221  static const size_t k_ChallengeSize = cSecureHash::k_Size;
223 
224  private:
225  HRESULT SendFailState0(HRESULT hResRet);
226  HRESULT OnState0();
227  HRESULT OnStateChallenge();
228  HRESULT OnStateSecure();
229 
230  public:
231  cSecureServerStream(cSecureServerFactory* pFactory, IUnkObject* pServerConnection, cStreamInput* pStreamInp, cStreamOutput* pStreamOut);
232  virtual ~cSecureServerStream();
233 
235 
236  virtual HRESULT DisposeThis() override;
237 
238  HASHCODE_t get_HashCode() const noexcept
239  {
241  }
242  STDMETHOD_(HASHCODE_t, get_HashCodeX)() const noexcept override
243  {
245  }
246 
248  {
250  if (m_pCipherInp == nullptr) // From the raw channel. CIPHER_None = No Crypt. Pass Through.
253  }
255  {
257  if (m_pCipherOut == nullptr) // From the raw channel. CIPHER_None = No Crypt. Pass Through.
260  }
261 
262  virtual HRESULT SetStateSecure();
263  virtual HRESULT ProcessStreamPacket() override;
264  };
266 
268  {
271 
272  protected:
274 
275  public:
276  virtual const char* get_ProtocolName() const override
277  {
279  return "GSec";
280  }
281  virtual HRESULT TestProtocol(const BYTE* pszPrefixData, size_t iPrefixLen) const override
282  {
288  cSecureKnock knock;
289  const HRESULT hRes = knock.SetSecureKnock(pszPrefixData, iPrefixLen);
290  return hRes;
291  }
292  virtual cProtocolStreamPtr CreateProtocolStream(IUnkObject* pServerConnection, cStreamInput* pStreamInp, cStreamOutput* pStreamOut) override
293  {
294  return new cSecureServerStream(this, pServerConnection, pStreamInp, pStreamOut);
295  }
296  virtual HRESULT FindChallengeMatch(cSecureServerStream* pStream, const void* pData, size_t nDataSize);
297  };
298 };
299 #endif // _INC_cSecureChannel_H
#define GRAYCALL
declare calling convention for static functions so everyone knows the arg passing scheme....
Definition: GrayCore.h:36
#define GRAYLIB_LINK
Definition: GrayLibBase.h:35
INT32 HRESULT
_WIN32 style error codes. INT32
Definition: SysTypes.h:465
#define _1BITMASK(b)
default bitmask type = size_t. Use cBits::Mask1() for other type.
Definition: cBits.h:32
UINT32 FOURCC
32 bit code. Also defined in _MMSYSTEM_H
Definition: cFourCC.h:19
#define MAKEFOURCC(ch0, ch1, ch2, ch3)
Definition: cFourCC.h:24
#define _INC_cSecureChannel_H
Definition: cSecureChannel.h:9
Definition: cHashCode.h:43
Definition: cHashSHA256.h:19
Definition: cProtocol.h:147
Definition: cProtocol.h:24
cStreamInput * get_StreamInp() const
Definition: cProtocol.h:75
HASHCODE_t get_HashCode() const noexcept
Definition: cProtocol.h:48
cStreamOutput * get_StreamOut() const
Definition: cProtocol.h:79
Definition: cSecureChannel.h:108
cHashCode m_HashPass
The working PASSCODE for login.
Definition: cSecureChannel.h:136
STATE_TYPE m_eState
current state of the negotiation of the connection.
Definition: cSecureChannel.h:140
STATE_TYPE
Definition: cSecureChannel.h:119
@ Client_Login
Definition: cSecureChannel.h:125
@ Client_Knock
Client starts by sending cSecureKnock. protocol id,version,cipher ability. time? server host?
Definition: cSecureChannel.h:123
@ Server_Challenge
Server sends response as protocol id,version,preferred CIPHER_TYPE, length prefix,...
Definition: cSecureChannel.h:124
@ STATE_Secure
Definition: cSecureChannel.h:128
@ STATE_Failed
Channel is junk.
Definition: cSecureChannel.h:131
cSecureId m_Id
My USERNAME and APPNAME.
Definition: cSecureChannel.h:137
bool isStateSecure() const noexcept
Definition: cSecureChannel.h:159
cStreamInput * get_SecureInp() const
Definition: cSecureChannel.cpp:110
UNITTEST_FRIEND(cSecureChannel)
cSecureKnock::CIPHER_TYPE m_eCipherType
the selected crypto type. <0=Failed login, 0=no crypt by choice, 1=cCipherRC4, 2=cCipherBlowfish
Definition: cSecureChannel.h:141
STATE_TYPE get_State() const noexcept
Definition: cSecureChannel.h:155
cNewPtr< cCipherBase > m_pCipherEnc
the selected encryption of the channel.
Definition: cSecureChannel.h:142
cStreamOutput * get_SecureOut() const
Definition: cSecureChannel.cpp:104
cNewPtr< cCipherBase > m_pCipherDec
the selected decryption of the channel.
Definition: cSecureChannel.h:144
cHashCode m_Challenge
the random data used to form the challenge. part of crypto key for data stream.
Definition: cSecureChannel.h:135
cNewPtr< cStreamCipherEnc > m_pCipherOut
m_pCipher as a encrypt/output stream. pads to get_BlockAlignSize(). m_pCipherEnc
Definition: cSecureChannel.h:143
cNewPtr< cStreamCipherDec > m_pCipherInp
m_pCipher as a decrypt/input stream. m_pCipherDec
Definition: cSecureChannel.h:145
Definition: cSecureChannel.h:174
cStreamOutput * get_SecureOut() const
Definition: cSecureChannel.h:202
cStreamInput * m_pStreamInp
the raw data stream from the cNetSocket
Definition: cSecureChannel.h:181
cStreamInput * get_SecureInp() const
Definition: cSecureChannel.h:195
cStreamOutput * m_pStreamOut
the raw data stream to the cNetSocket
Definition: cSecureChannel.h:182
Definition: cSecureChannel.h:30
cStringA m_sAppId
The clients declared Purpose/Application in talking to the server. e.g. "Browser",...
Definition: cSecureChannel.h:37
cSecureId(cStringA sAppId="", cStringA sUserId="") noexcept
Definition: cSecureChannel.h:41
cStringA m_sUserId
The clients User/Account/InstanceId name it wants to login with. derives security privilege level fro...
Definition: cSecureChannel.h:38
bool IsSame(const cSecureId &k) const
Definition: cSecureChannel.h:46
Definition: cSecureChannel.h:57
FOURCC m_nSignature
const cSecureKnock::k_SIGNATURE to declare my protocol
Definition: cSecureChannel.h:81
WORD m_nCryptAbilities
Am i limited in my crypt abilities ? mask of CIPHER_TYPE. CIPHER_KEY_RSA.
Definition: cSecureChannel.h:83
cSecureKnock(cStringA sAppId="", cStringA sUserId="", WORD nCryptAbilities=_1BITMASK(CIPHER_RC4)|_1BITMASK(CIPHER_None))
Definition: cSecureChannel.h:87
CIPHER_TYPE
Definition: cSecureChannel.h:64
@ CIPHER_RC4
cCipherRC4. Worst cipher. but has no block size/padding. Try not to use this ?
Definition: cSecureChannel.h:68
@ CIPHER_Blowfish
cCipherBlowfish has block alignment size. needs padding.
Definition: cSecureChannel.h:69
@ CIPHER_AES
cCipherAES. Best but has block alignment size. needs padding.
Definition: cSecureChannel.h:70
@ CIPHER_QTY
Definition: cSecureChannel.h:73
HRESULT SetSecureKnock(cStreamInput &s)
Definition: cSecureChannel.cpp:41
cSecureId SUPER_t
Definition: cSecureChannel.h:61
WORD m_nVersion
const _INC_cSecureChannel_H = my protocol version id
Definition: cSecureChannel.h:82
void SetClear() noexcept
Definition: cSecureChannel.h:99
Definition: cSecureChannel.h:268
virtual cProtocolStreamPtr CreateProtocolStream(IUnkObject *pServerConnection, cStreamInput *pStreamInp, cStreamOutput *pStreamOut) override
Definition: cSecureChannel.h:292
virtual const char * get_ProtocolName() const override
Definition: cSecureChannel.h:276
virtual HRESULT TestProtocol(const BYTE *pszPrefixData, size_t iPrefixLen) const override
Definition: cSecureChannel.h:281
cProtocolFactories m_Factories
What protocols are we wrapping?
Definition: cSecureChannel.h:273
Definition: cSecureChannel.h:214
HASHCODE_t get_HashCode() const noexcept
Definition: cSecureChannel.h:238
cStreamOutput * get_SecureOut() const
Definition: cSecureChannel.h:254
cProtocolStreamPtr m_pProtocol2
The protocol wrapped by this cSecureServerStream.
Definition: cSecureChannel.h:222
cStreamInput * get_SecureInp() const
Definition: cSecureChannel.h:247
STDMETHOD_(HASHCODE_t, get_HashCodeX)() const noexcept override
Definition: cSecureChannel.h:242
COMPARE_t Compare(const _TYPE_CH *pszStr) const
Definition: cString.h:265
Definition: cArchive.h:20
static const size_t k_Size
All hashes of this type are this size (bytes).
Definition: cMem.h:289
Definition: cNewPtr.h:18
Definition: cRefPtr.h:22
Definition: cRefPtr.h:225
Definition: cStream.h:306
Definition: cStream.h:126
Definition: cMesh.h:22
cHashSHA256 cSecureHash
compute my hashes via this.
Definition: cSecureChannel.h:27
UNITTEST2_PREDEF(cQuadtree)
cRefPtr< cSecureServerStream > cSecureServerStreamPtr
Definition: cSecureChannel.h:265
class __DECL_IMPORT cSecureServerFactory
Definition: cSecureChannel.h:211
UINT_PTR HASHCODE_t
could hold a pointer converted to a number? maybe 64 or 32 bit ? same as size_t.
Definition: GrayCore.h:116
Definition: cProtocol.h:125