// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CRYPTO_SCOPED_CAPI_TYPES_H_ #define CRYPTO_SCOPED_CAPI_TYPES_H_ #include #include #include "base/logging.h" #include "base/macros.h" #include "crypto/wincrypt_shim.h" namespace crypto { // Simple destructor for the Free family of CryptoAPI functions, such as // CryptDestroyHash, which take only a single argument to release. template struct CAPIDestroyer { void operator()(CAPIHandle handle) const { if (handle) { BOOL ok = Destroyer(handle); DCHECK(ok); } } }; // Destructor for the Close/Release family of CryptoAPI functions, which take // a second DWORD parameter indicating flags to use when closing or releasing. // This includes functions like CertCloseStore or CryptReleaseContext. template struct CAPIDestroyerWithFlags { void operator()(CAPIHandle handle) const { if (handle) { BOOL ok = Destroyer(handle, flags); DCHECK(ok); } } }; // scoped_ptr-like class for the CryptoAPI cryptography and certificate // handles. Because these handles are defined as integer types, and not // pointers, the existing scoped classes, such as scoped_ptr, are insufficient. // The semantics are the same as scoped_ptr. template class ScopedCAPIHandle { public: explicit ScopedCAPIHandle(CAPIHandle handle = NULL) : handle_(handle) {} ~ScopedCAPIHandle() { reset(); } void reset(CAPIHandle handle = NULL) { if (handle_ != handle) { FreeProc free_proc; free_proc(handle_); handle_ = handle; } } operator CAPIHandle() const { return handle_; } CAPIHandle get() const { return handle_; } CAPIHandle* receive() { CHECK(handle_ == NULL); return &handle_; } bool operator==(CAPIHandle handle) const { return handle_ == handle; } bool operator!=(CAPIHandle handle) const { return handle_ != handle; } void swap(ScopedCAPIHandle& b) { CAPIHandle tmp = b.handle_; b.handle_ = handle_; handle_ = tmp; } CAPIHandle release() { CAPIHandle tmp = handle_; handle_ = NULL; return tmp; } private: CAPIHandle handle_; DISALLOW_COPY_AND_ASSIGN(ScopedCAPIHandle); }; template inline bool operator==(CH h, const ScopedCAPIHandle& b) { return h == b.get(); } template inline bool operator!=(CH h, const ScopedCAPIHandle& b) { return h != b.get(); } typedef ScopedCAPIHandle< HCRYPTPROV, CAPIDestroyerWithFlags > ScopedHCRYPTPROV; typedef ScopedCAPIHandle< HCRYPTKEY, CAPIDestroyer > ScopedHCRYPTKEY; typedef ScopedCAPIHandle< HCRYPTHASH, CAPIDestroyer > ScopedHCRYPTHASH; } // namespace crypto #endif // CRYPTO_SCOPED_CAPI_TYPES_H_