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