14c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom// Copyright (c) 2010 The Chromium Authors. All rights reserved. 24c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom// Use of this source code is governed by a BSD-style license that can be 34c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom// found in the LICENSE file. 44c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 54c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom#ifndef BASE_OPENSSL_UTIL_H_ 64c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom#define BASE_OPENSSL_UTIL_H_ 74c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom#pragma once 84c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 94c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom#include "base/basictypes.h" 104c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom#include "base/compiler_specific.h" 114c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom#include "base/tracked.h" 124c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 134c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromnamespace base { 144c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 154c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom// A helper class that takes care of destroying OpenSSL objects when it goes out 164c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom// of scope. 174c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromtemplate <typename T, void (*destructor)(T*)> 184c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromclass ScopedOpenSSL { 194c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom public: 204c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ScopedOpenSSL() : ptr_(NULL) { } 214c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom explicit ScopedOpenSSL(T* ptr) : ptr_(ptr) { } 224c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ~ScopedOpenSSL() { 234c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom reset(NULL); 244c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 254c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 264c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom T* get() const { return ptr_; } 274c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom void reset(T* ptr) { 284c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (ptr != ptr_) { 294c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (ptr_) (*destructor)(ptr_); 304c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ptr_ = ptr; 314c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 324c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 334c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom T* release() WARN_UNUSED_RESULT { 344c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom T* result = ptr_; 354c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ptr_ = NULL; 364c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return result; 374c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 384c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 394c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom private: 404c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom T* ptr_; 414c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 424c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom DISALLOW_COPY_AND_ASSIGN(ScopedOpenSSL); 434c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom}; 444c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 454c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom// Provides a buffer of at least MIN_SIZE bytes, for use when calling OpenSSL's 464c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom// SHA256, HMAC, etc functions, adapting the buffer sizing rules to meet those 474c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom// of the our base wrapper APIs. 484c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom// This allows the library to write directly to the caller's buffer if it is of 494c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom// sufficient size, but if not it will write to temporary |min_sized_buffer_| 504c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom// of required size and then its content is automatically copied out on 514c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom// destruction, with truncation as appropriate. 524c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromtemplate<int MIN_SIZE> 534c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromclass ScopedOpenSSLSafeSizeBuffer { 544c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom public: 554c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ScopedOpenSSLSafeSizeBuffer(unsigned char* output, size_t output_len) 564c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom : output_(output), 574c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom output_len_(output_len) { 584c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 594c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 604c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ~ScopedOpenSSLSafeSizeBuffer() { 614c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom if (output_len_ < MIN_SIZE) { 624c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom // Copy the temporary buffer out, truncating as needed. 634c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom memcpy(output_, min_sized_buffer_, output_len_); 644c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 654c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom // else... any writing already happened directly into |output_|. 664c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 674c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 684c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom unsigned char* safe_buffer() { 694c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return output_len_ < MIN_SIZE ? min_sized_buffer_ : output_; 704c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 714c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 724c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom private: 734c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom // Pointer to the caller's data area and it's associated size, where data 744c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom // written via safe_buffer() will [eventually] end up. 754c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom unsigned char* output_; 764c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom size_t output_len_; 774c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 784c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom // Temporary buffer writen into in the case where the caller's 794c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom // buffer is not of sufficient size. 804c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom unsigned char min_sized_buffer_[MIN_SIZE]; 814c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 824c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom DISALLOW_COPY_AND_ASSIGN(ScopedOpenSSLSafeSizeBuffer); 834c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom}; 844c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 854c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom// Initialize OpenSSL if it isn't already initialized. This must be called 864c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom// before any other OpenSSL functions. 874c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom// This function is thread-safe, and OpenSSL will only ever be initialized once. 884c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom// OpenSSL will be properly shut down on program exit. 894c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromvoid EnsureOpenSSLInit(); 904c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 914c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom// Drains the OpenSSL ERR_get_error stack. On a debug build the error codes 924c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom// are send to VLOG(1), on a release build they are disregarded. In most 934c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom// cases you should pass FROM_HERE as the |location|. 944c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromvoid ClearOpenSSLERRStack(const tracked_objects::Location& location); 954c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 964c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom// Place an instance of this class on the call stack to automatically clear 974c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom// the OpenSSL error stack on function exit. 984c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromclass OpenSSLErrStackTracer { 994c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom public: 1004c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom // Pass FROM_HERE as |location|, to help track the source of OpenSSL error 1014c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom // messages. Note any diagnostic emitted will be tagged with the location of 1024c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom // the constructor call as it's not possible to trace a destructor's callsite. 1034c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom explicit OpenSSLErrStackTracer(const tracked_objects::Location& location) 1044c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom : location_(location) { 1054c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom EnsureOpenSSLInit(); 1064c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 1074c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ~OpenSSLErrStackTracer() { 1084c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ClearOpenSSLERRStack(location_); 1094c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 1104c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 1114c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom private: 1124c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom const tracked_objects::Location location_; 1134c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 1144c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom DISALLOW_IMPLICIT_CONSTRUCTORS(OpenSSLErrStackTracer); 1154c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom}; 1164c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 1174c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom} // namespace base 1184c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 1194c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom#endif // BASE_OPENSSL_UTIL_H_ 1204c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom