Index: scoped_tss_type.h |
diff --git a/scoped_tss_type.h b/scoped_tss_type.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..1c01d1330e7434cc1c9e791538f34ef7c046a025 |
--- /dev/null |
+++ b/scoped_tss_type.h |
@@ -0,0 +1,115 @@ |
+// Copyright (c) 2011 The Chromium OS Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+// Implements a simple framework for scoping TSS values. |
+// Based on chrome's base/scoped_ptr_malloc implementation. |
+// |
+// Example usage: |
+// ScopedTssContext context; |
gauravsh
2011/03/29 19:16:06
context_handle
Will Drewry
2011/03/29 19:42:22
Ugh. I hate that variable name, but okay. :)
gauravsh
2011/03/29 20:21:54
I just meant that you use context_handle later in
|
+// TSS_RESULT result; |
+// if (!OpenAndConnectTpm(context_handle.get(), &result)) |
gauravsh
2011/03/29 20:21:54
As I was saying, you use context_handle here, just
|
+// ... |
+// ScopedTssKey srk(*context); |
gauravsh
2011/03/29 19:16:06
context_handle
Will Drewry
2011/03/29 19:42:22
Done.
|
+// if (!LoadSrk(*context_handle, srk_handle.get(), &result)) |
+// ... |
+// |
+// See the bottom of this file for common typedefs. |
+ |
+#include <assert.h> |
+#include <trousers/tss.h> |
+#include <trousers/trousers.h> |
+ |
+#include <base/compiler_specific.h> |
+#include <vector> |
+ |
+#ifndef CRYPTOHOME_SCOPED_TSS_TYPE_H_ |
+#define CRYPTOHOME_SCOPED_TSS_TYPE_H_ |
+ |
+namespace cryptohome { |
+ |
+class ScopedTssContextRelease { |
+ public: |
+ inline void operator()(TSS_HCONTEXT unused, TSS_HCONTEXT context) const { |
+ // Usually, only |context| is used, but if the ScopedTssContext is |
+ // used slightly differently, it may end up with a context in |unused|. |
+ // For now, treat that as a bug. |
+ assert(unused == 0); |
+ if (context) |
+ Tspi_Context_Close(context); |
+ } |
+}; |
+ |
+class ScopedTssMemoryRelease { |
+ public: |
+ inline void operator()(TSS_HCONTEXT context, BYTE* memory) const { |
+ if (memory) |
+ Tspi_Context_FreeMemory(context, memory); |
gauravsh
2011/03/29 19:16:06
so in ScopedTssContextRelease, you check for (cont
Will Drewry
2011/03/29 19:42:22
For ContextRelease I assert it _is_ 0 and not that
|
+ } |
+}; |
+ |
+class ScopedTssObjectRelease { |
+ public: |
+ inline void operator()(TSS_HCONTEXT context, TSS_HOBJECT handle) const { |
+ Tspi_Context_CloseObject(context, handle); |
+ } |
+}; |
+ |
+// Provide a basic scoped container for TSS managed objects. |
+template<class TssType, class ReleaseProc = ScopedTssObjectRelease> |
+class ScopedTssType { |
+ public: |
+ explicit ScopedTssType(TSS_HCONTEXT c = 0, TssType t = 0) : |
+ context_(c), |
+ type_(t) {} |
+ virtual ~ScopedTssType() { |
+ release_(context_, type_); |
+ } |
+ |
+ // Allow pointer-like access for getting the value. |
+ TssType& operator*() { |
+ return type_; |
+ } |
+ |
+ // Return a pointer to the storage to allow in place changes. |
+ // We could override &, but that seems like a bad idea. |
+ virtual TssType* get() { |
+ return &type_; |
+ } |
+ |
+ // Returns the assigned context. |
+ virtual TSS_HCONTEXT context() { |
+ return context_; |
+ } |
+ |
+ virtual TssType release() WARN_UNUSED_RESULT { |
+ TssType tmp = type_; |
+ type_ = 0; |
+ context_ = 0; |
+ return tmp; |
+ } |
+ |
+ virtual void reset(TSS_HCONTEXT c = 0, TssType t = 0) { |
+ release_(context_, type_); |
+ context_ = c; |
+ type_ = t; |
+ } |
+ |
+ private: |
+ static ReleaseProc const release_; |
+ TSS_HCONTEXT context_; |
+ TssType type_; |
+}; |
+ |
+// Provide clear-cut helpers for the common cases. |
+typedef ScopedTssType<TSS_HCONTEXT, ScopedTssContextRelease> ScopedTssContext; |
+typedef ScopedTssType<BYTE*, ScopedTssMemoryRelease> ScopedTssMemory; |
+ |
+typedef ScopedTssType<TSS_HOBJECT> ScopedTssObject; |
+typedef ScopedTssType<TSS_HKEY> ScopedTssKey; |
+typedef ScopedTssType<TSS_HPOLICY> ScopedTssPolicy; |
+typedef ScopedTssType<TSS_HPCRS> ScopedTssPcrs; |
+ |
+} // namespace cryptohome |
+ |
+#endif // CRYPTOHOME_SCOPED_TSS_TYPE_H_ |