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