1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file. 4*635a8641SAndroid Build Coastguard Worker 5*635a8641SAndroid Build Coastguard Worker #ifndef CRYPTO_OPENSSL_UTIL_H_ 6*635a8641SAndroid Build Coastguard Worker #define CRYPTO_OPENSSL_UTIL_H_ 7*635a8641SAndroid Build Coastguard Worker 8*635a8641SAndroid Build Coastguard Worker #include <stddef.h> 9*635a8641SAndroid Build Coastguard Worker 10*635a8641SAndroid Build Coastguard Worker #include "base/location.h" 11*635a8641SAndroid Build Coastguard Worker #include "base/macros.h" 12*635a8641SAndroid Build Coastguard Worker #include "crypto/crypto_export.h" 13*635a8641SAndroid Build Coastguard Worker 14*635a8641SAndroid Build Coastguard Worker namespace crypto { 15*635a8641SAndroid Build Coastguard Worker 16*635a8641SAndroid Build Coastguard Worker // Provides a buffer of at least MIN_SIZE bytes, for use when calling OpenSSL's 17*635a8641SAndroid Build Coastguard Worker // SHA256, HMAC, etc functions, adapting the buffer sizing rules to meet those 18*635a8641SAndroid Build Coastguard Worker // of our base wrapper APIs. 19*635a8641SAndroid Build Coastguard Worker // This allows the library to write directly to the caller's buffer if it is of 20*635a8641SAndroid Build Coastguard Worker // sufficient size, but if not it will write to temporary |min_sized_buffer_| 21*635a8641SAndroid Build Coastguard Worker // of required size and then its content is automatically copied out on 22*635a8641SAndroid Build Coastguard Worker // destruction, with truncation as appropriate. 23*635a8641SAndroid Build Coastguard Worker template<int MIN_SIZE> 24*635a8641SAndroid Build Coastguard Worker class ScopedOpenSSLSafeSizeBuffer { 25*635a8641SAndroid Build Coastguard Worker public: ScopedOpenSSLSafeSizeBuffer(unsigned char * output,size_t output_len)26*635a8641SAndroid Build Coastguard Worker ScopedOpenSSLSafeSizeBuffer(unsigned char* output, size_t output_len) 27*635a8641SAndroid Build Coastguard Worker : output_(output), 28*635a8641SAndroid Build Coastguard Worker output_len_(output_len) { 29*635a8641SAndroid Build Coastguard Worker } 30*635a8641SAndroid Build Coastguard Worker ~ScopedOpenSSLSafeSizeBuffer()31*635a8641SAndroid Build Coastguard Worker ~ScopedOpenSSLSafeSizeBuffer() { 32*635a8641SAndroid Build Coastguard Worker if (output_len_ < MIN_SIZE) { 33*635a8641SAndroid Build Coastguard Worker // Copy the temporary buffer out, truncating as needed. 34*635a8641SAndroid Build Coastguard Worker memcpy(output_, min_sized_buffer_, output_len_); 35*635a8641SAndroid Build Coastguard Worker } 36*635a8641SAndroid Build Coastguard Worker // else... any writing already happened directly into |output_|. 37*635a8641SAndroid Build Coastguard Worker } 38*635a8641SAndroid Build Coastguard Worker safe_buffer()39*635a8641SAndroid Build Coastguard Worker unsigned char* safe_buffer() { 40*635a8641SAndroid Build Coastguard Worker return output_len_ < MIN_SIZE ? min_sized_buffer_ : output_; 41*635a8641SAndroid Build Coastguard Worker } 42*635a8641SAndroid Build Coastguard Worker 43*635a8641SAndroid Build Coastguard Worker private: 44*635a8641SAndroid Build Coastguard Worker // Pointer to the caller's data area and its associated size, where data 45*635a8641SAndroid Build Coastguard Worker // written via safe_buffer() will [eventually] end up. 46*635a8641SAndroid Build Coastguard Worker unsigned char* output_; 47*635a8641SAndroid Build Coastguard Worker size_t output_len_; 48*635a8641SAndroid Build Coastguard Worker 49*635a8641SAndroid Build Coastguard Worker // Temporary buffer writen into in the case where the caller's 50*635a8641SAndroid Build Coastguard Worker // buffer is not of sufficient size. 51*635a8641SAndroid Build Coastguard Worker unsigned char min_sized_buffer_[MIN_SIZE]; 52*635a8641SAndroid Build Coastguard Worker 53*635a8641SAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(ScopedOpenSSLSafeSizeBuffer); 54*635a8641SAndroid Build Coastguard Worker }; 55*635a8641SAndroid Build Coastguard Worker 56*635a8641SAndroid Build Coastguard Worker // Initialize OpenSSL if it isn't already initialized. This must be called 57*635a8641SAndroid Build Coastguard Worker // before any other OpenSSL functions though it is safe and cheap to call this 58*635a8641SAndroid Build Coastguard Worker // multiple times. 59*635a8641SAndroid Build Coastguard Worker // This function is thread-safe, and OpenSSL will only ever be initialized once. 60*635a8641SAndroid Build Coastguard Worker // OpenSSL will be properly shut down on program exit. 61*635a8641SAndroid Build Coastguard Worker CRYPTO_EXPORT void EnsureOpenSSLInit(); 62*635a8641SAndroid Build Coastguard Worker 63*635a8641SAndroid Build Coastguard Worker // Drains the OpenSSL ERR_get_error stack. On a debug build the error codes 64*635a8641SAndroid Build Coastguard Worker // are send to VLOG(1), on a release build they are disregarded. In most 65*635a8641SAndroid Build Coastguard Worker // cases you should pass FROM_HERE as the |location|. 66*635a8641SAndroid Build Coastguard Worker CRYPTO_EXPORT void ClearOpenSSLERRStack(const base::Location& location); 67*635a8641SAndroid Build Coastguard Worker 68*635a8641SAndroid Build Coastguard Worker // Place an instance of this class on the call stack to automatically clear 69*635a8641SAndroid Build Coastguard Worker // the OpenSSL error stack on function exit. 70*635a8641SAndroid Build Coastguard Worker class OpenSSLErrStackTracer { 71*635a8641SAndroid Build Coastguard Worker public: 72*635a8641SAndroid Build Coastguard Worker // Pass FROM_HERE as |location|, to help track the source of OpenSSL error 73*635a8641SAndroid Build Coastguard Worker // messages. Note any diagnostic emitted will be tagged with the location of 74*635a8641SAndroid Build Coastguard Worker // the constructor call as it's not possible to trace a destructor's callsite. OpenSSLErrStackTracer(const base::Location & location)75*635a8641SAndroid Build Coastguard Worker explicit OpenSSLErrStackTracer(const base::Location& location) 76*635a8641SAndroid Build Coastguard Worker : location_(location) { 77*635a8641SAndroid Build Coastguard Worker EnsureOpenSSLInit(); 78*635a8641SAndroid Build Coastguard Worker } ~OpenSSLErrStackTracer()79*635a8641SAndroid Build Coastguard Worker ~OpenSSLErrStackTracer() { 80*635a8641SAndroid Build Coastguard Worker ClearOpenSSLERRStack(location_); 81*635a8641SAndroid Build Coastguard Worker } 82*635a8641SAndroid Build Coastguard Worker 83*635a8641SAndroid Build Coastguard Worker private: 84*635a8641SAndroid Build Coastguard Worker const base::Location location_; 85*635a8641SAndroid Build Coastguard Worker 86*635a8641SAndroid Build Coastguard Worker DISALLOW_IMPLICIT_CONSTRUCTORS(OpenSSLErrStackTracer); 87*635a8641SAndroid Build Coastguard Worker }; 88*635a8641SAndroid Build Coastguard Worker 89*635a8641SAndroid Build Coastguard Worker } // namespace crypto 90*635a8641SAndroid Build Coastguard Worker 91*635a8641SAndroid Build Coastguard Worker #endif // CRYPTO_OPENSSL_UTIL_H_ 92