blob: b0073e2314f7d53ebf85495a66d4864cfe1c381f [file] [log] [blame] [edit]
// 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_handle;
// TSS_RESULT result;
// if (!OpenAndConnectTpm(context_handle.get(), &result))
// ...
// ScopedTssKey srk(context_handle);
// 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 {
// TODO(wad) make the test code friendly for assert()ing context/memory != 0
if (context && memory)
Tspi_Context_FreeMemory(context, memory);
}
};
class ScopedTssObjectRelease {
public:
inline void operator()(TSS_HCONTEXT context, TSS_HOBJECT handle) const {
// TODO(wad) make the test code friendly for assert() context/handle != 0
if (context && handle)
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 typecasting to TssType.
operator TssType() { return type_; }
// Allow direct referencing of the wrapped value.
TssType* ptr() {
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_