xref: /aosp_15_r20/external/cronet/crypto/openssl_util.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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