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