1 // Copyright 2019 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 UTIL_CRYPTO_OPENSSL_UTIL_H_
6 #define UTIL_CRYPTO_OPENSSL_UTIL_H_
7 
8 #include <openssl/ssl.h>
9 #include <stddef.h>
10 
11 #include <cstring>
12 
13 #include "platform/base/error.h"
14 #include "platform/base/location.h"
15 #include "platform/base/macros.h"
16 
17 namespace openscreen {
18 // Initialize OpenSSL if it isn't already initialized. This must be called
19 // before any other OpenSSL functions though it is safe and cheap to call this
20 // multiple times.
21 // This function is thread-safe, and OpenSSL will only ever be initialized once.
22 // OpenSSL will be properly shut down on program exit.
23 // Multiple sequential calls to EnsureOpenSSLInit or EnsureOpenSSLCleanup are
24 // ignored by OpenSSL itself.
25 void EnsureOpenSSLInit();
26 void EnsureOpenSSLCleanup();
27 
28 // Drains the OpenSSL ERR_get_error stack. On a debug build the error codes
29 // are send to VLOG(1), on a release build they are disregarded. In most
30 // cases you should pass CURRENT_LOCATION as the |location|.
31 void ClearOpenSSLERRStack(const Location& location);
32 
33 Error GetSSLError(const SSL* ssl, int return_code);
34 
35 // Place an instance of this class on the call stack to automatically clear
36 // the OpenSSL error stack on function exit.
37 class OpenSSLErrStackTracer {
38  public:
39   // Pass CURRENT_LOCATION as |location|, to help track the source of OpenSSL
40   // error messages. Note any diagnostic emitted will be tagged with the
41   // location of the constructor call as it's not possible to trace a
42   // destructor's callsite.
OpenSSLErrStackTracer(const Location & location)43   explicit OpenSSLErrStackTracer(const Location& location)
44       : location_(location) {
45     EnsureOpenSSLInit();
46   }
~OpenSSLErrStackTracer()47   ~OpenSSLErrStackTracer() { ClearOpenSSLERRStack(location_); }
48 
49  private:
50   const Location location_;
51 
52   OSP_DISALLOW_IMPLICIT_CONSTRUCTORS(OpenSSLErrStackTracer);
53 };
54 
55 }  // namespace openscreen
56 
57 #endif  // UTIL_CRYPTO_OPENSSL_UTIL_H_
58