|  | // 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_OPENSSL_UTIL_H_ | 
|  | #define CRYPTO_OPENSSL_UTIL_H_ | 
|  |  | 
|  | #include "base/basictypes.h" | 
|  | #include "base/location.h" | 
|  | #include "crypto/crypto_export.h" | 
|  |  | 
|  | namespace crypto { | 
|  |  | 
|  | // Provides a buffer of at least MIN_SIZE bytes, for use when calling OpenSSL's | 
|  | // SHA256, HMAC, etc functions, adapting the buffer sizing rules to meet those | 
|  | // of the our base wrapper APIs. | 
|  | // This allows the library to write directly to the caller's buffer if it is of | 
|  | // sufficient size, but if not it will write to temporary |min_sized_buffer_| | 
|  | // of required size and then its content is automatically copied out on | 
|  | // destruction, with truncation as appropriate. | 
|  | template<int MIN_SIZE> | 
|  | class ScopedOpenSSLSafeSizeBuffer { | 
|  | public: | 
|  | ScopedOpenSSLSafeSizeBuffer(unsigned char* output, size_t output_len) | 
|  | : output_(output), | 
|  | output_len_(output_len) { | 
|  | } | 
|  |  | 
|  | ~ScopedOpenSSLSafeSizeBuffer() { | 
|  | if (output_len_ < MIN_SIZE) { | 
|  | // Copy the temporary buffer out, truncating as needed. | 
|  | memcpy(output_, min_sized_buffer_, output_len_); | 
|  | } | 
|  | // else... any writing already happened directly into |output_|. | 
|  | } | 
|  |  | 
|  | unsigned char* safe_buffer() { | 
|  | return output_len_ < MIN_SIZE ? min_sized_buffer_ : output_; | 
|  | } | 
|  |  | 
|  | private: | 
|  | // Pointer to the caller's data area and its associated size, where data | 
|  | // written via safe_buffer() will [eventually] end up. | 
|  | unsigned char* output_; | 
|  | size_t output_len_; | 
|  |  | 
|  | // Temporary buffer writen into in the case where the caller's | 
|  | // buffer is not of sufficient size. | 
|  | unsigned char min_sized_buffer_[MIN_SIZE]; | 
|  |  | 
|  | DISALLOW_COPY_AND_ASSIGN(ScopedOpenSSLSafeSizeBuffer); | 
|  | }; | 
|  |  | 
|  | // Initialize OpenSSL if it isn't already initialized. This must be called | 
|  | // before any other OpenSSL functions though it is safe and cheap to call this | 
|  | // multiple times. | 
|  | // This function is thread-safe, and OpenSSL will only ever be initialized once. | 
|  | // OpenSSL will be properly shut down on program exit. | 
|  | void CRYPTO_EXPORT EnsureOpenSSLInit(); | 
|  |  | 
|  | // Drains the OpenSSL ERR_get_error stack. On a debug build the error codes | 
|  | // are send to VLOG(1), on a release build they are disregarded. In most | 
|  | // cases you should pass FROM_HERE as the |location|. | 
|  | void CRYPTO_EXPORT ClearOpenSSLERRStack( | 
|  | const tracked_objects::Location& location); | 
|  |  | 
|  | // Place an instance of this class on the call stack to automatically clear | 
|  | // the OpenSSL error stack on function exit. | 
|  | class OpenSSLErrStackTracer { | 
|  | public: | 
|  | // Pass FROM_HERE as |location|, to help track the source of OpenSSL error | 
|  | // messages. Note any diagnostic emitted will be tagged with the location of | 
|  | // the constructor call as it's not possible to trace a destructor's callsite. | 
|  | explicit OpenSSLErrStackTracer(const tracked_objects::Location& location) | 
|  | : location_(location) { | 
|  | EnsureOpenSSLInit(); | 
|  | } | 
|  | ~OpenSSLErrStackTracer() { | 
|  | ClearOpenSSLERRStack(location_); | 
|  | } | 
|  |  | 
|  | private: | 
|  | const tracked_objects::Location location_; | 
|  |  | 
|  | DISALLOW_IMPLICIT_CONSTRUCTORS(OpenSSLErrStackTracer); | 
|  | }; | 
|  |  | 
|  | }  // namespace crypto | 
|  |  | 
|  | #endif  // CRYPTO_OPENSSL_UTIL_H_ |