Leaked source code of windows server 2003
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.

370 lines
9.4 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows NT Security
  4. // Copyright (C) Microsoft Corporation, 1997 - 1999
  5. //
  6. // File: cba.cpp
  7. //
  8. // Contents: Implementation of CCryptBlobArray
  9. //
  10. // History: 23-Jul-97 kirtd Created
  11. //
  12. //----------------------------------------------------------------------------
  13. #include <global.hxx>
  14. //+---------------------------------------------------------------------------
  15. //
  16. // Member: CCryptBlobArray::CCryptBlobArray, public
  17. //
  18. // Synopsis: Initialize the internal CRYPT_BLOB_ARRAY
  19. //
  20. //----------------------------------------------------------------------------
  21. CCryptBlobArray::CCryptBlobArray (
  22. ULONG cMinBlobs,
  23. ULONG cGrowBlobs,
  24. BOOL& rfResult
  25. )
  26. {
  27. rfResult = TRUE;
  28. m_cGrowBlobs = cGrowBlobs;
  29. m_cba.cBlob = 0;
  30. m_cba.rgBlob = new CRYPT_DATA_BLOB [cMinBlobs];
  31. if ( m_cba.rgBlob != NULL )
  32. {
  33. memset( m_cba.rgBlob, 0, sizeof(CRYPT_DATA_BLOB)*cMinBlobs );
  34. m_cArray = cMinBlobs;
  35. }
  36. else
  37. {
  38. SetLastError( (DWORD) E_OUTOFMEMORY );
  39. rfResult = FALSE;
  40. }
  41. }
  42. //+---------------------------------------------------------------------------
  43. //
  44. // Member: CCryptBlobArray::CCryptBlobArray, public
  45. //
  46. // Synopsis: Initialize the internal CRYPT_BLOB_ARRAY with a native form
  47. // blob array created via ::GetArrayInNativeForm
  48. //
  49. //----------------------------------------------------------------------------
  50. CCryptBlobArray::CCryptBlobArray (
  51. PCRYPT_BLOB_ARRAY pcba,
  52. ULONG cGrowBlobs
  53. )
  54. {
  55. m_cGrowBlobs = cGrowBlobs;
  56. m_cba.cBlob = pcba->cBlob;
  57. m_cba.rgBlob = pcba->rgBlob;
  58. m_cArray = pcba->cBlob;
  59. }
  60. //+---------------------------------------------------------------------------
  61. //
  62. // Member: CCryptBlobArray::AllocBlob, public, static
  63. //
  64. // Synopsis: allocate a blob using the same allocator used for ::AddBlob
  65. // copies. This means that the resulting blob can be added
  66. // without copying.
  67. //
  68. //----------------------------------------------------------------------------
  69. LPBYTE
  70. CCryptBlobArray::AllocBlob (ULONG cb)
  71. {
  72. return( (LPBYTE)CryptMemAlloc( cb ) );
  73. }
  74. //+---------------------------------------------------------------------------
  75. //
  76. // Member: CCryptBlobArray::ReallocBlob, public, static
  77. //
  78. // Synopsis: see ::AllocBlob
  79. //
  80. //----------------------------------------------------------------------------
  81. LPBYTE
  82. CCryptBlobArray::ReallocBlob (LPBYTE pb, ULONG cb)
  83. {
  84. return( (LPBYTE)CryptMemRealloc( pb, cb ) );
  85. }
  86. //+---------------------------------------------------------------------------
  87. //
  88. // Member: CCryptBlobArray::FreeBlob, public
  89. //
  90. // Synopsis: free blob allocated using ::AllocBlob or ::ReallocBlob
  91. //
  92. //----------------------------------------------------------------------------
  93. VOID
  94. CCryptBlobArray::FreeBlob (LPBYTE pb)
  95. {
  96. CryptMemFree( pb );
  97. }
  98. //+---------------------------------------------------------------------------
  99. //
  100. // Member: CCryptBlobArray::AddBlob, public
  101. //
  102. // Synopsis: add a blob
  103. //
  104. //----------------------------------------------------------------------------
  105. BOOL
  106. CCryptBlobArray::AddBlob (
  107. ULONG cb,
  108. LPBYTE pb,
  109. BOOL fCopyBlob
  110. )
  111. {
  112. BOOL fResult = TRUE;
  113. LPBYTE pbToUse;
  114. //
  115. // If we need to copy the blob, do so
  116. //
  117. if ( fCopyBlob == TRUE )
  118. {
  119. pbToUse = AllocBlob( cb );
  120. if ( pbToUse != NULL )
  121. {
  122. memcpy( pbToUse, pb, cb );
  123. }
  124. else
  125. {
  126. SetLastError( (DWORD) E_OUTOFMEMORY );
  127. return( FALSE );
  128. }
  129. }
  130. else
  131. {
  132. pbToUse = pb;
  133. }
  134. //
  135. // If we need to grow the array, do so
  136. //
  137. if ( m_cArray == m_cba.cBlob )
  138. {
  139. fResult = GrowArray();
  140. }
  141. //
  142. // Add the blob to the array
  143. //
  144. if ( fResult == TRUE )
  145. {
  146. m_cba.rgBlob[m_cba.cBlob].cbData = cb;
  147. m_cba.rgBlob[m_cba.cBlob].pbData = pbToUse;
  148. m_cba.cBlob += 1;
  149. }
  150. else if ( fCopyBlob == TRUE )
  151. {
  152. FreeBlob( pbToUse );
  153. }
  154. return( fResult );
  155. }
  156. //+---------------------------------------------------------------------------
  157. //
  158. // Member: CCryptBlobArray::GetBlob, public
  159. //
  160. // Synopsis: gets blob given an index
  161. //
  162. //----------------------------------------------------------------------------
  163. PCRYPT_DATA_BLOB
  164. CCryptBlobArray::GetBlob (ULONG index)
  165. {
  166. assert( m_cba.cBlob > index );
  167. return( &m_cba.rgBlob[index] );
  168. }
  169. //+---------------------------------------------------------------------------
  170. //
  171. // Member: CCryptBlobArray::GetBlobCount, public
  172. //
  173. // Synopsis: get the count of blobs
  174. //
  175. //----------------------------------------------------------------------------
  176. ULONG
  177. CCryptBlobArray::GetBlobCount ()
  178. {
  179. return( m_cba.cBlob );
  180. }
  181. //+---------------------------------------------------------------------------
  182. //
  183. // Member: CCryptBlobArray::GetArrayInNativeForm, public
  184. //
  185. // Synopsis: get the array in native form
  186. //
  187. //----------------------------------------------------------------------------
  188. VOID
  189. CCryptBlobArray::GetArrayInNativeForm (PCRYPT_BLOB_ARRAY pcba)
  190. {
  191. pcba->cBlob = m_cba.cBlob;
  192. pcba->rgBlob = m_cba.rgBlob;
  193. }
  194. //+---------------------------------------------------------------------------
  195. //
  196. // Member: CCryptBlobArray::GetArrayInSingleBufferEncodedForm, public
  197. //
  198. // Synopsis: gets the array in a single buffer encoded form
  199. //
  200. //----------------------------------------------------------------------------
  201. BOOL
  202. CCryptBlobArray::GetArrayInSingleBufferEncodedForm (
  203. PCRYPT_BLOB_ARRAY* ppcba,
  204. ULONG* pcb
  205. )
  206. {
  207. ULONG cbStruct;
  208. ULONG cbPointers;
  209. ULONG cbData;
  210. ULONG cb;
  211. ULONG cbSize;
  212. ULONG cCount;
  213. PCRYPT_BLOB_ARRAY pcba = NULL;
  214. //
  215. // Calculate the buffer size we will need and allocate it
  216. //
  217. cbStruct = sizeof( CRYPT_BLOB_ARRAY );
  218. cbPointers = m_cba.cBlob * sizeof( CRYPT_DATA_BLOB );
  219. for ( cCount = 0, cbData = 0; cCount < m_cba.cBlob; cCount++ )
  220. {
  221. cbData += m_cba.rgBlob[cCount].cbData;
  222. }
  223. cbSize = cbStruct + cbPointers + cbData;
  224. pcba = (PCRYPT_BLOB_ARRAY)CryptMemAlloc( cbSize );
  225. if ( pcba == NULL )
  226. {
  227. SetLastError( (DWORD) E_OUTOFMEMORY );
  228. return( FALSE );
  229. }
  230. //
  231. // Fill in the data
  232. //
  233. pcba->cBlob = m_cba.cBlob;
  234. pcba->rgBlob = (PCRYPT_DATA_BLOB)((LPBYTE)pcba+cbStruct);
  235. __try
  236. {
  237. for ( cCount = 0, cb = 0; cCount < m_cba.cBlob; cCount++ )
  238. {
  239. pcba->rgBlob[cCount].cbData = m_cba.rgBlob[cCount].cbData;
  240. pcba->rgBlob[cCount].pbData = (LPBYTE)pcba+cbStruct+cbPointers+cb;
  241. memcpy(
  242. pcba->rgBlob[cCount].pbData,
  243. m_cba.rgBlob[cCount].pbData,
  244. m_cba.rgBlob[cCount].cbData
  245. );
  246. cb += m_cba.rgBlob[cCount].cbData;
  247. }
  248. }
  249. __except( EXCEPTION_EXECUTE_HANDLER )
  250. {
  251. CryptMemFree( pcba );
  252. SetLastError( GetExceptionCode() );
  253. return( FALSE );
  254. }
  255. *ppcba = pcba;
  256. if ( pcb != NULL )
  257. {
  258. *pcb = cbSize;
  259. }
  260. return( TRUE );
  261. }
  262. //+---------------------------------------------------------------------------
  263. //
  264. // Member: CCryptBlobArray::FreeArray, public
  265. //
  266. // Synopsis: frees the array and optionally frees the blobs
  267. //
  268. //----------------------------------------------------------------------------
  269. VOID
  270. CCryptBlobArray::FreeArray (BOOL fFreeBlobs)
  271. {
  272. if ( fFreeBlobs == TRUE )
  273. {
  274. ULONG cCount;
  275. for ( cCount = 0; cCount < m_cba.cBlob; cCount++ )
  276. {
  277. FreeBlob( m_cba.rgBlob[cCount].pbData );
  278. }
  279. }
  280. delete m_cba.rgBlob;
  281. }
  282. //+---------------------------------------------------------------------------
  283. //
  284. // Member: CCryptBlobArray::GrowArray, private
  285. //
  286. // Synopsis: grows the array
  287. //
  288. //----------------------------------------------------------------------------
  289. BOOL
  290. CCryptBlobArray::GrowArray ()
  291. {
  292. ULONG cNewArray;
  293. PCRYPT_DATA_BLOB pcba;
  294. //
  295. // Check if we are allowed to grow
  296. //
  297. //
  298. if ( m_cGrowBlobs == 0 )
  299. {
  300. SetLastError( (DWORD) E_INVALIDARG );
  301. return( FALSE );
  302. }
  303. //
  304. // Allocate and initialize the new array
  305. //
  306. cNewArray = m_cArray + m_cGrowBlobs;
  307. pcba = new CRYPT_DATA_BLOB [cNewArray];
  308. if ( pcba == NULL )
  309. {
  310. SetLastError( (DWORD) E_OUTOFMEMORY );
  311. return( FALSE );
  312. }
  313. memset(pcba, 0, cNewArray*sizeof( CRYPT_DATA_BLOB ));
  314. //
  315. // Copy the old to the new
  316. //
  317. memcpy(pcba, m_cba.rgBlob, m_cba.cBlob*sizeof( CRYPT_DATA_BLOB ) );
  318. //
  319. // Free the old and use the new
  320. //
  321. delete m_cba.rgBlob;
  322. m_cba.rgBlob = pcba;
  323. m_cArray = cNewArray;
  324. return( TRUE );
  325. }