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.

281 lines
7.9 KiB

  1. // scuSecureArray.h -- implementation of a SecureArray template
  2. // (c) Copyright Schlumberger Technology Corp., unpublished work, created
  3. // 2002. This computer program includes Confidential, Proprietary
  4. // Information and is a Trade Secret of Schlumberger Technology Corp. All
  5. // use, disclosure, and/or reproduction is prohibited unless authorized
  6. // in writing. All Rights Reserved.
  7. #if !defined(SLBSCU_SECUREARRAY_H)
  8. #define SLBSCU_SECUREARRAY_H
  9. #include "DllSymDefn.h"
  10. namespace scu
  11. {
  12. // SecureArray is a simple template for arrays of basic types
  13. // (e.g. char, BYTE, int, DWORD, float, string, etc.) which
  14. // ensures that the buffer allocated
  15. // for the array is zeroed out before it is freed in order to
  16. // icrease the security of protecting sensitive information
  17. // scattered throughout the heap. This template assumes that the
  18. // parameter T provides an implementation of the assignment
  19. // operator and a constructor for T(0), which is used as a zero
  20. // element to clear the bufer up with.
  21. // USAGE NOTE: it is important to note that this template is
  22. // secure in the sense defined above if and only if T zeroes out
  23. // its store before freeing. This is the case with the
  24. // built in C++ types (char, BYTE, int, DWORD, float,
  25. // etc). However, it is NOT guaranteed to be secure with STL
  26. // objects, such as string, because such objects do not zero out
  27. // its buffer upon freeing it.
  28. template<class T>
  29. class SCU_DLLAPI SecureArray
  30. {
  31. public:
  32. // Types
  33. typedef T ElementType;
  34. // C'tors/D'tors
  35. SecureArray(const size_t nCount)
  36. :m_pDataStore(0),
  37. m_nSize(0)
  38. {
  39. if(nCount)
  40. m_pDataStore = new T[nCount];
  41. m_nSize = nCount;
  42. }
  43. SecureArray(T* pBuffer, size_t nCount)
  44. :m_pDataStore(0),
  45. m_nSize(0)
  46. {
  47. SetupFromBuffer(reinterpret_cast<T const *>(pBuffer),
  48. nCount);
  49. }
  50. SecureArray(T const * pBuffer, size_t nCount)
  51. :m_pDataStore(0),
  52. m_nSize(0)
  53. {
  54. SetupFromBuffer(pBuffer, nCount);
  55. }
  56. SecureArray(size_t nCount, T const & rt)
  57. :m_pDataStore(0),
  58. m_nSize(0)
  59. {
  60. m_pDataStore = new T[nCount];
  61. for(size_t nIdx=0; nIdx<nCount; nIdx++)
  62. m_pDataStore[nIdx] = rt;
  63. m_nSize = nCount;
  64. }
  65. SecureArray()
  66. :m_pDataStore(0),
  67. m_nSize(0)
  68. {}
  69. SecureArray(SecureArray<T> const &rsa)
  70. :m_pDataStore(0),
  71. m_nSize(0)
  72. {
  73. *this = rsa;
  74. }
  75. ~SecureArray() throw()
  76. {
  77. try
  78. {
  79. ClearDataStore();
  80. }
  81. catch(...)
  82. {
  83. }
  84. }
  85. // Operators
  86. SecureArray<T> &
  87. operator=(SecureArray<T> const &rother)
  88. {
  89. if(this != &rother)
  90. {
  91. // Deep copy
  92. ClearDataStore();
  93. if(rother.size())
  94. {
  95. m_pDataStore = new T[rother.size()];
  96. for(size_t nIdx=0; nIdx<rother.size(); nIdx++)
  97. this->operator[](nIdx)=rother[nIdx];
  98. }
  99. m_nSize = rother.size();
  100. }
  101. return *this;
  102. }
  103. SecureArray<T> &
  104. operator=(T const &rt)
  105. {
  106. for(size_t nIdx=0; nIdx<m_nSize; nIdx++)
  107. m_pDataStore[nIdx]=rt;
  108. return *this;
  109. }
  110. T&
  111. operator[](size_t nIdx)
  112. {
  113. return m_pDataStore[nIdx];
  114. }
  115. T const &
  116. operator[](size_t nIdx) const
  117. {
  118. return m_pDataStore[nIdx];
  119. }
  120. T&
  121. operator*()
  122. {
  123. return *data();
  124. }
  125. T const &
  126. operator*() const
  127. {
  128. return *data();
  129. }
  130. // Operations
  131. T*
  132. data()
  133. {
  134. return m_pDataStore;
  135. }
  136. T const *
  137. data() const
  138. {
  139. return m_pDataStore;
  140. }
  141. size_t
  142. size() const
  143. {
  144. return m_nSize;
  145. }
  146. size_t
  147. length() const
  148. {
  149. return size();
  150. }
  151. size_t
  152. length_string() const
  153. {
  154. if(size())
  155. return size()-1;
  156. else
  157. return 0;
  158. }
  159. SecureArray<T> &
  160. append(size_t nAddSize, T const & rval)
  161. {
  162. size_t nNewSize = size()+nAddSize;
  163. T* pTemp = new T[nNewSize];
  164. size_t nIdx=0;
  165. for(nIdx=0; nIdx<size(); nIdx++)
  166. pTemp[nIdx] = m_pDataStore[nIdx];
  167. for(nIdx=size(); nIdx<nNewSize; nIdx++)
  168. pTemp[nIdx] = rval;
  169. ClearDataStore();
  170. m_pDataStore = pTemp;
  171. m_nSize = nNewSize;
  172. return *this;
  173. }
  174. SecureArray<T> &
  175. append( T const * pBuf, size_t nAddSize)
  176. {
  177. size_t nNewSize = size()+nAddSize;
  178. T* pTemp = new T[nNewSize];
  179. size_t nIdx=0;
  180. for(nIdx=0; nIdx<size(); nIdx++)
  181. pTemp[nIdx] = m_pDataStore[nIdx];
  182. for(nIdx=size(); nIdx<nNewSize; nIdx++)
  183. pTemp[nIdx] = *pBuf++;
  184. ClearDataStore();
  185. m_pDataStore = pTemp;
  186. m_nSize = nNewSize;
  187. return *this;
  188. }
  189. SecureArray<T> &
  190. append_string(size_t nAddSize, T const & rval)
  191. {
  192. // Assumptions: the buffer contains a null terminated
  193. // string or is empty. The addional size is for the
  194. // non-null characters only, may be zero.
  195. size_t nNewSize = 0;
  196. size_t nEndIdx = 0;
  197. size_t nIdx=0;
  198. if(size())
  199. nNewSize = size()+nAddSize;
  200. else
  201. nNewSize = nAddSize+1;// space for the null terminator
  202. T* pTemp = new T[nNewSize];
  203. if(size())
  204. {
  205. // Copy the existing string to the new location
  206. nEndIdx = size()-1;//rhs guaranteed non-negative
  207. for(nIdx=0; nIdx<nEndIdx; nIdx++)
  208. pTemp[nIdx] = m_pDataStore[nIdx];
  209. }
  210. // Append it with the new characters
  211. for(nIdx=0; nIdx<nAddSize; nIdx++)
  212. pTemp[nEndIdx++] = rval;
  213. // Terminate the buffer
  214. pTemp[nEndIdx]=T(0);
  215. ClearDataStore();
  216. m_pDataStore = pTemp;
  217. m_nSize = nNewSize;
  218. return *this;
  219. }
  220. private:
  221. void
  222. ClearDataStore()
  223. {
  224. for(size_t nIdx=0; nIdx<m_nSize; nIdx++)
  225. m_pDataStore[nIdx]=T(0);
  226. delete [] m_pDataStore;
  227. m_pDataStore = 0;
  228. m_nSize = 0;
  229. }
  230. void
  231. SetupFromBuffer(T const * pBuffer, size_t nCount)
  232. {
  233. m_pDataStore = new T[nCount];
  234. for(size_t nIdx=0; nIdx<nCount; nIdx++)
  235. m_pDataStore[nIdx] = pBuffer[nIdx];
  236. m_nSize = nCount;
  237. }
  238. T * m_pDataStore;
  239. size_t m_nSize;
  240. };
  241. }
  242. #endif //SLBSCU_SECUREARRAY_H