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
16namespace rtc {
17
18// A base class for CSecBuffer<T>. Contains
19// all implementation that does not require
20// template arguments.
21class 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.
58template <void (*pfnFreeBuffer)(void *ptr)>
59class 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
90class 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.
99template <int num_buffers,
100          void (*pfnFreeBuffer)(void *ptr) = CSecBufferBase::FreeNone>
101class 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  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
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