1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#ifndef CRYPTO_SCOPED_CAPI_TYPES_H_ 6ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define CRYPTO_SCOPED_CAPI_TYPES_H_ 73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <windows.h> 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <wincrypt.h> 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <algorithm> 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/logging.h" 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsennamespace crypto { 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Simple destructor for the Free family of CryptoAPI functions, such as 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// CryptDestroyHash, which take only a single argument to release. 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <typename CAPIHandle, BOOL (WINAPI *Destroyer)(CAPIHandle)> 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct CAPIDestroyer { 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void operator()(CAPIHandle handle) const { 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (handle) { 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BOOL ok = Destroyer(handle); 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(ok); 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Destructor for the Close/Release family of CryptoAPI functions, which take 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// a second DWORD parameter indicating flags to use when closing or releasing. 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This includes functions like CertCloseStore or CryptReleaseContext. 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <typename CAPIHandle, BOOL (WINAPI *Destroyer)(CAPIHandle, DWORD), 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DWORD flags> 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct CAPIDestroyerWithFlags { 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void operator()(CAPIHandle handle) const { 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (handle) { 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BOOL ok = Destroyer(handle, flags); 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(ok); 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// scoped_ptr-like class for the CryptoAPI cryptography and certificate 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// handles. Because these handles are defined as integer types, and not 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// pointers, the existing scoped classes, such as scoped_ptr_malloc, are 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// insufficient. The semantics are the same as scoped_ptr. 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate <class CAPIHandle, typename FreeProc> 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ScopedCAPIHandle { 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch explicit ScopedCAPIHandle(CAPIHandle handle = NULL) : handle_(handle) {} 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ~ScopedCAPIHandle() { 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch free_(handle_); 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void reset(CAPIHandle handle = NULL) { 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (handle_ != handle) { 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch free_(handle_); 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch handle_ = handle; 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch operator CAPIHandle() const { return handle_; } 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CAPIHandle get() const { return handle_; } 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CAPIHandle* receive() { 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CHECK(handle_ == NULL); 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return &handle_; 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool operator==(CAPIHandle handle) const { 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return handle_ == handle; 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool operator!=(CAPIHandle handle) const { 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return handle_ != handle; 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void swap(ScopedCAPIHandle& b) { 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CAPIHandle tmp = b.handle_; 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch b.handle_ = handle_; 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch handle_ = tmp; 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CAPIHandle release() { 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CAPIHandle tmp = handle_; 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch handle_ = NULL; 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return tmp; 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CAPIHandle handle_; 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static const FreeProc free_; 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_COPY_AND_ASSIGN(ScopedCAPIHandle); 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate<class CH, typename FP> 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst FP ScopedCAPIHandle<CH, FP>::free_ = FP(); 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate<class CH, typename FP> inline 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool operator==(CH h, const ScopedCAPIHandle<CH, FP>& b) { 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return h == b.get(); 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtemplate<class CH, typename FP> inline 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool operator!=(CH h, const ScopedCAPIHandle<CH, FP>& b) { 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return h != b.get(); 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtypedef ScopedCAPIHandle< 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HCRYPTPROV, 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CAPIDestroyerWithFlags<HCRYPTPROV, 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CryptReleaseContext, 0> > ScopedHCRYPTPROV; 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtypedef ScopedCAPIHandle< 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HCRYPTKEY, CAPIDestroyer<HCRYPTKEY, CryptDestroyKey> > ScopedHCRYPTKEY; 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtypedef ScopedCAPIHandle< 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HCRYPTHASH, CAPIDestroyer<HCRYPTHASH, CryptDestroyHash> > ScopedHCRYPTHASH; 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} // namespace crypto 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 125ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif // CRYPTO_SCOPED_CAPI_TYPES_H_ 126