Home | History | Annotate | Download | only in base
      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:
     23   CSecBufferBase() {
     24     Clear();
     25   }
     26 
     27   // Uses the SSPI to free a pointer, must be
     28   // used for buffers returned from SSPI APIs.
     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
     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
     44   static void FreeNone(void *ptr) {
     45   }
     46 
     47  protected:
     48   // Clears the buffer to EMPTY & NULL
     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
     62   CSecBuffer() {
     63   }
     64 
     65   // Frees any allocated memory
     66   ~CSecBuffer() {
     67     Release();
     68   }
     69 
     70   // Frees the buffer appropriately, and re-nulls
     71   void Release() {
     72     pfnFreeBuffer(this->pvBuffer);
     73     Clear();
     74   }
     75 
     76  private:
     77   // A placeholder function for compile-time asserts on the class
     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.
    105   CSecBufferBundle() {
    106     desc_.ulVersion = SECBUFFER_VERSION;
    107     desc_.cBuffers = num_buffers;
    108     desc_.pBuffers = buffers_;
    109   }
    110 
    111   // Frees all currently used buffers.
    112   ~CSecBufferBundle() {
    113     Release();
    114   }
    115 
    116   // Accessor for the descriptor
    117   PSecBufferDesc desc() {
    118     return &desc_;
    119   }
    120 
    121   // Accessor for the descriptor
    122   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
    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