1 /* 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 // @file Contains utility classes that make it easier to use SecBuffers 12 13 #ifndef WEBRTC_BASE_SEC_BUFFER_H__ 14 #define WEBRTC_BASE_SEC_BUFFER_H__ 15 16 namespace rtc { 17 18 // A base class for CSecBuffer<T>. Contains 19 // all implementation that does not require 20 // template arguments. 21 class CSecBufferBase : public SecBuffer { 22 public: CSecBufferBase()23 CSecBufferBase() { 24 Clear(); 25 } 26 27 // Uses the SSPI to free a pointer, must be 28 // used for buffers returned from SSPI APIs. FreeSSPI(void * ptr)29 static void FreeSSPI(void *ptr) { 30 if ( ptr ) { 31 SECURITY_STATUS status; 32 status = ::FreeContextBuffer(ptr); 33 ASSERT(SEC_E_OK == status); // "Freeing context buffer" 34 } 35 } 36 37 // Deletes a buffer with operator delete FreeDelete(void * ptr)38 static void FreeDelete(void *ptr) { 39 delete [] reinterpret_cast<char*>(ptr); 40 } 41 42 // A noop delete, for buffers over other 43 // people's memory FreeNone(void * ptr)44 static void FreeNone(void *ptr) { 45 } 46 47 protected: 48 // Clears the buffer to EMPTY & NULL Clear()49 void Clear() { 50 this->BufferType = SECBUFFER_EMPTY; 51 this->cbBuffer = 0; 52 this->pvBuffer = NULL; 53 } 54 }; 55 56 // Wrapper class for SecBuffer to take care 57 // of initialization and destruction. 58 template <void (*pfnFreeBuffer)(void *ptr)> 59 class CSecBuffer: public CSecBufferBase { 60 public: 61 // Initializes buffer to empty & NULL CSecBuffer()62 CSecBuffer() { 63 } 64 65 // Frees any allocated memory ~CSecBuffer()66 ~CSecBuffer() { 67 Release(); 68 } 69 70 // Frees the buffer appropriately, and re-nulls Release()71 void Release() { 72 pfnFreeBuffer(this->pvBuffer); 73 Clear(); 74 } 75 76 private: 77 // A placeholder function for compile-time asserts on the class CompileAsserts()78 void CompileAsserts() { 79 // never invoked... 80 assert(false); // _T("Notreached") 81 82 // This class must not extend the size of SecBuffer, since 83 // we use arrays of CSecBuffer in CSecBufferBundle below 84 cassert(sizeof(CSecBuffer<SSPIFree> == sizeof(SecBuffer))); 85 } 86 }; 87 88 // Contains all generic implementation for the 89 // SecBufferBundle class 90 class SecBufferBundleBase { 91 public: 92 }; 93 94 // A template class that bundles a SecBufferDesc with 95 // one or more SecBuffers for convenience. Can take 96 // care of deallocating buffers appropriately, as indicated 97 // by pfnFreeBuffer function. 98 // By default does no deallocation. 99 template <int num_buffers, 100 void (*pfnFreeBuffer)(void *ptr) = CSecBufferBase::FreeNone> 101 class CSecBufferBundle : public SecBufferBundleBase { 102 public: 103 // Constructs a security buffer bundle with num_buffers 104 // buffers, all of which are empty and nulled. CSecBufferBundle()105 CSecBufferBundle() { 106 desc_.ulVersion = SECBUFFER_VERSION; 107 desc_.cBuffers = num_buffers; 108 desc_.pBuffers = buffers_; 109 } 110 111 // Frees all currently used buffers. ~CSecBufferBundle()112 ~CSecBufferBundle() { 113 Release(); 114 } 115 116 // Accessor for the descriptor desc()117 PSecBufferDesc desc() { 118 return &desc_; 119 } 120 121 // Accessor for the descriptor desc()122 const PSecBufferDesc desc() const { 123 return &desc_; 124 } 125 126 // returns the i-th security buffer 127 SecBuffer &operator[] (size_t num) { 128 ASSERT(num < num_buffers); // "Buffer index out of bounds" 129 return buffers_[num]; 130 } 131 132 // returns the i-th security buffer 133 const SecBuffer &operator[] (size_t num) const { 134 ASSERT(num < num_buffers); // "Buffer index out of bounds" 135 return buffers_[num]; 136 } 137 138 // Frees all non-NULL security buffers, 139 // using the deallocation function Release()140 void Release() { 141 for ( size_t i = 0; i < num_buffers; ++i ) { 142 buffers_[i].Release(); 143 } 144 } 145 146 private: 147 // Our descriptor 148 SecBufferDesc desc_; 149 // Our bundled buffers, each takes care of its own 150 // initialization and destruction 151 CSecBuffer<pfnFreeBuffer> buffers_[num_buffers]; 152 }; 153 154 } // namespace rtc 155 156 #endif // WEBRTC_BASE_SEC_BUFFER_H__ 157