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