xref: /aosp_15_r20/external/libchrome/crypto/openssl_util.h (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
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