Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

346 lines
9.5 KiB

  1. /* Key.cpp : defines the key object.
  2. This file contains the routines that allow a key to store and restore itself
  3. */
  4. #include "stdafx.h"
  5. #include "resource.h"
  6. #include "KeyObjs.h"
  7. #include "cmnkey.h"
  8. #include "W3Key.h"
  9. #define KEY_VERSION 0x102
  10. /*========
  11. The scheme here is to create a handle that contains all the data necessary to
  12. restore the key object. The data contained in that handle is then stored as a
  13. secret on the target machine. This does require that the size of the handle be
  14. less than 65000 bytes, which should be no problem.
  15. */
  16. //------------------------------------------------------------------------------
  17. // generate a handle containing data that gets stored and then is used to restore
  18. // the key object at a later date. Restore this key by passing this dereferenced
  19. // handle back into the FInitKey routine above.
  20. HANDLE CW3Key::HGenerateDataHandle( BOOL fIncludePassword )
  21. {
  22. DWORD cbSize;
  23. DWORD cbChar = sizeof(TCHAR);
  24. PUCHAR p;
  25. HANDLE h;
  26. CString szReserved; // save an empty string so that one can be added later
  27. szReserved.Empty();
  28. // calculate the size of the handle
  29. cbSize = 2*sizeof(DWORD) + sizeof(BOOL);
  30. cbSize += sizeof(DWORD); // reserved dword
  31. cbSize += sizeof(DWORD) + szReserved.GetLength() * cbChar + cbChar;
  32. cbSize += sizeof(DWORD) + m_szName.GetLength() * cbChar + cbChar;
  33. cbSize += sizeof(DWORD) + m_szPassword.GetLength() * cbChar + cbChar;
  34. // no longer need to store all the distinguishing info now that crack certificate works
  35. cbSize += (sizeof(DWORD) + szReserved.GetLength() * cbChar + cbChar) * 6;
  36. /*
  37. cbSize += sizeof(DWORD) + m_szOrganization.GetLength() * cbChar + cbChar;
  38. cbSize += sizeof(DWORD) + m_szUnit.GetLength() * cbChar + cbChar;
  39. cbSize += sizeof(DWORD) + m_szNetAddress.GetLength() * cbChar + cbChar;
  40. cbSize += sizeof(DWORD) + m_szCountry.GetLength() * cbChar + cbChar;
  41. cbSize += sizeof(DWORD) + m_szStateProvince.GetLength() * cbChar + cbChar;
  42. cbSize += sizeof(DWORD) + m_szLocality.GetLength() * cbChar + cbChar;
  43. */
  44. cbSize += sizeof(DWORD) + m_szIPAddress.GetLength() * cbChar + cbChar;
  45. cbSize += sizeof(BOOL); //m_fDefault
  46. cbSize += sizeof(DWORD) + m_cbPrivateKey;
  47. cbSize += sizeof(DWORD) + m_cbCertificate;
  48. cbSize += sizeof(DWORD) + m_cbCertificateRequest;
  49. cbSize += sizeof(FILETIME); // no longer used
  50. // create the new handle and lock it
  51. h = GlobalAlloc( GHND, cbSize );
  52. if ( !h )
  53. {
  54. AfxThrowMemoryException();
  55. return NULL;
  56. }
  57. p = (PUCHAR)GlobalLock( h );
  58. // put in the version, fComplete, and nBits
  59. *((UNALIGNED DWORD*)p) = KEY_VERSION;
  60. p += sizeof(DWORD);
  61. *((UNALIGNED DWORD*)p) = 0; // no longer used
  62. p += sizeof(DWORD);
  63. *((UNALIGNED BOOL*)p) = (m_pCertificate != NULL); // no longer used
  64. p += sizeof(BOOL);
  65. // add in a reserved dword for future use.
  66. *((UNALIGNED DWORD*)p) = 0L;
  67. p += sizeof(DWORD);
  68. // now the strings......
  69. // for each string, first write out the size of the string, then the string data.
  70. // save the reserved string. If you need to add one later and don't want to
  71. // invalidate the older keys on a machine, replace this string.
  72. cbSize = szReserved.GetLength() * cbChar + cbChar;
  73. *((UNALIGNED DWORD*)p) = cbSize;
  74. p += sizeof(DWORD);
  75. CopyMemory( p, LPCTSTR(szReserved), cbSize );
  76. p += cbSize;
  77. // save the name
  78. cbSize = m_szName.GetLength() * cbChar + cbChar;
  79. *((UNALIGNED DWORD*)p) = cbSize;
  80. p += sizeof(DWORD);
  81. CopyMemory( p, LPCTSTR(m_szName), cbSize );
  82. p += cbSize;
  83. // save the password
  84. if ( fIncludePassword )
  85. {
  86. cbSize = m_szPassword.GetLength() * cbChar + cbChar;
  87. *((UNALIGNED DWORD*)p) = cbSize;
  88. p += sizeof(DWORD);
  89. CopyMemory( p, LPCTSTR(m_szPassword), cbSize );
  90. p += cbSize;
  91. }
  92. else
  93. // do not include the password - just put in an empty field
  94. {
  95. *((UNALIGNED DWORD*)p) = 0;
  96. p += sizeof(DWORD);
  97. }
  98. // no longer need to store all the distinguishing info now that crack certificate works
  99. for ( WORD i = 0; i < 6; i++ )
  100. {
  101. cbSize = szReserved.GetLength() * cbChar + cbChar;
  102. *((UNALIGNED DWORD*)p) = cbSize;
  103. p += sizeof(DWORD);
  104. CopyMemory( p, LPCTSTR(szReserved), cbSize );
  105. p += cbSize;
  106. }
  107. // save the ip address it is attached to
  108. cbSize = m_szIPAddress.GetLength() * cbChar + cbChar;
  109. *((UNALIGNED DWORD*)p) = cbSize;
  110. p += sizeof(DWORD);
  111. CopyMemory( p, LPCTSTR(m_szIPAddress), cbSize );
  112. p += cbSize;
  113. // put in the m_fDefault flag
  114. *((UNALIGNED BOOL*)p) = m_fDefault;
  115. p += sizeof(BOOL);
  116. // now put in the number of bytes in the private key
  117. *((UNALIGNED DWORD*)p) = m_cbPrivateKey;
  118. p += sizeof(DWORD);
  119. // put in the private key
  120. CopyMemory( p, m_pPrivateKey, m_cbPrivateKey );
  121. p += m_cbPrivateKey;
  122. // now put in the number of bytes in the certificate
  123. *((UNALIGNED DWORD*)p) = m_cbCertificate;
  124. p += sizeof(DWORD);
  125. // put in the certificate key
  126. CopyMemory( p, m_pCertificate, m_cbCertificate );
  127. p += m_cbCertificate;
  128. // now put in the number of bytes in the certificate request
  129. *((UNALIGNED DWORD*)p) = m_cbCertificateRequest;
  130. p += sizeof(DWORD);
  131. // put in the certificate request
  132. CopyMemory( p, m_pCertificateRequest, m_cbCertificateRequest );
  133. p += m_cbCertificateRequest;
  134. // and finally, add the timestamp
  135. FILETIME ft;
  136. memset( &ft, 0, sizeof(ft) );
  137. *((UNALIGNED FILETIME*)p) = ft;
  138. p += sizeof(FILETIME);
  139. // unlock the handle
  140. GlobalUnlock( h );
  141. // all done
  142. return h;
  143. }
  144. //------------------------------------------------------------------------------
  145. // Given a pointer to a block of data originally created by the above routine, fill
  146. // in the key object
  147. BOOL CW3Key::InitializeFromPointer( PUCHAR pSrc, DWORD cbSrc )
  148. {
  149. DWORD dword, version;
  150. DWORD cbChar = sizeof(TCHAR);
  151. PUCHAR p = pSrc;
  152. ASSERT(pSrc && cbSrc);
  153. // get the version of the data - just put it into dword for now
  154. version = *((UNALIGNED DWORD*)p);
  155. // check the version for validity
  156. if ( version > KEY_VERSION )
  157. {
  158. return FALSE;
  159. }
  160. p += sizeof(DWORD);
  161. // anything below version 0x101 is BAD. Do not accept it
  162. if ( version < 0x101 )
  163. {
  164. AfxMessageBox( IDS_INVALID_KEY, MB_OK|MB_ICONINFORMATION );
  165. return FALSE;
  166. }
  167. // get the bits and the complete flag
  168. // no longer used
  169. p += sizeof(DWORD);
  170. p += sizeof(BOOL);
  171. ASSERT( p < (pSrc + cbSrc) );
  172. // get the reserved dword - (acutally, just skip over it)
  173. p += sizeof(DWORD);
  174. // now the strings......
  175. // for each string, first get the size of the string, then the data from the string
  176. // get the reserved string - (actually, just skip over it)
  177. dword = *((UNALIGNED DWORD*)p);
  178. p += sizeof(DWORD);
  179. p += dword;
  180. // get the name
  181. dword = *((UNALIGNED DWORD*)p);
  182. p += sizeof(DWORD);
  183. m_szName= p;
  184. p += dword;
  185. ASSERT( p < (pSrc + cbSrc) );
  186. // get the password
  187. dword = *((UNALIGNED DWORD*)p);
  188. p += sizeof(DWORD);
  189. // if there is no password, don't worry, just skip it
  190. if ( dword )
  191. {
  192. m_szPassword = p;
  193. p += dword;
  194. ASSERT( p < (pSrc + cbSrc) );
  195. }
  196. // get the organization
  197. // no longer used - skip the DN info
  198. for ( WORD i = 0; i < 6; i++ )
  199. {
  200. dword = *((UNALIGNED DWORD*)p);
  201. p += sizeof(DWORD);
  202. p += dword;
  203. ASSERT( p < (pSrc + cbSrc) );
  204. }
  205. // get the ip addres it is attached to
  206. dword = *((UNALIGNED DWORD*)p);
  207. p += sizeof(DWORD);
  208. m_szIPAddress = p;
  209. p += dword;
  210. ASSERT( p < (pSrc + cbSrc) );
  211. // get the default flag
  212. m_fDefault = *((UNALIGNED BOOL*)p);
  213. p += sizeof(BOOL);
  214. // now put get the number of bytes in the private key
  215. m_cbPrivateKey = *((UNALIGNED DWORD*)p);
  216. p += sizeof(DWORD);
  217. ASSERT( p < (pSrc + cbSrc) );
  218. // if the private key already exists, kill it. Then make a new pointer for it
  219. if ( m_pPrivateKey )
  220. GlobalFree( (HANDLE)m_pPrivateKey );
  221. m_pPrivateKey = (PVOID)GlobalAlloc( GPTR, m_cbPrivateKey );
  222. if ( !m_pPrivateKey ) return FALSE;
  223. // put in the private key
  224. CopyMemory( m_pPrivateKey, p, m_cbPrivateKey );
  225. p += m_cbPrivateKey;
  226. ASSERT( p < (pSrc + cbSrc) );
  227. // now put get the number of bytes in the certificate
  228. m_cbCertificate = *((UNALIGNED DWORD*)p);
  229. p += sizeof(DWORD);
  230. ASSERT( p < (pSrc + cbSrc) );
  231. // if the private key already exists, kill it. Then make a new pointer for it
  232. if ( m_pCertificate )
  233. GlobalFree( (HANDLE)m_pCertificate );
  234. m_pCertificate = NULL;
  235. // only make a certificate pointer if m_cbCertificate is greater than zero
  236. if ( m_cbCertificate )
  237. {
  238. m_pCertificate = (PVOID)GlobalAlloc( GPTR, m_cbCertificate );
  239. if ( !m_pCertificate ) return FALSE;
  240. // put in the private key
  241. CopyMemory( m_pCertificate, p, m_cbCertificate );
  242. p += m_cbCertificate;
  243. if ( version >= KEY_VERSION )
  244. ASSERT( p < (pSrc + cbSrc) );
  245. else
  246. ASSERT( p == (pSrc + cbSrc) );
  247. }
  248. // added near the end
  249. if ( version >= KEY_VERSION )
  250. {
  251. // now put get the number of bytes in the certificte request
  252. m_cbCertificateRequest = *((UNALIGNED DWORD*)p);
  253. p += sizeof(DWORD);
  254. ASSERT( p < (pSrc + cbSrc) );
  255. // if the private key already exists, kill it. Then make a new pointer for it
  256. if ( m_pCertificateRequest )
  257. GlobalFree( (HANDLE)m_pCertificateRequest );
  258. m_pCertificateRequest = NULL;
  259. // only make a certificate pointer if m_cbCertificate is greater than zero
  260. if ( m_cbCertificateRequest )
  261. {
  262. m_pCertificateRequest = (PVOID)GlobalAlloc( GPTR, m_cbCertificateRequest );
  263. if ( !m_pCertificateRequest ) return FALSE;
  264. // put in the private key
  265. CopyMemory( m_pCertificateRequest, p, m_cbCertificateRequest );
  266. p += m_cbCertificateRequest;
  267. ASSERT( p < (pSrc + cbSrc) );
  268. }
  269. // finally read in the expiration timestamp
  270. // m_tsExpires = *((UNALIGNED FILETIME*)p);
  271. p += sizeof(FILETIME);
  272. }
  273. else
  274. {
  275. m_cbCertificateRequest = 0;
  276. if ( m_pCertificateRequest )
  277. GlobalFree( (HANDLE)m_pCertificateRequest );
  278. m_pCertificateRequest = NULL;
  279. // m_tsExpires.dwLowDateTime = 0;
  280. // m_tsExpires.dwHighDateTime = 0;
  281. }
  282. // all done
  283. return TRUE;
  284. }