forked from f1xpl/aasdk
-
Notifications
You must be signed in to change notification settings - Fork 47
SSLWrapper_8cpp
github-actions edited this page Mar 15, 2026
·
3 revisions
title: src/Transport/SSLWrapper.cpp
| Name |
|---|
| aasdk |
| aasdk::transport |
// This file is part of aasdk library project.
// Copyright (C) 2018 f1x.studio (Michal Szwaj)
// Copyright (C) 2024 CubeOne (Simon Dean - simon.dean@cubeone.co.uk)
// Copyright (C) 2024 OpenCarDev (Matthew Hilton - matthilton2005@gmail.com)
// Copyright (C) 2026 OpenCarDev (Matthew Hilton - matthilton2005@gmail.com)
//
// aasdk is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// aasdk is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with aasdk. If not, see <http://www.gnu.org/licenses/>.
#include <string>
#include <cerrno>
#include <cstring>
#if defined(__has_include) && __has_include(<openssl/engine.h>) && !defined(OPENSSL_NO_ENGINE)
#include <openssl/engine.h>
#define HAVE_ENGINE_H
#endif
#include <openssl/err.h>
#include <openssl/ssl.h>
#include <openssl/conf.h>
#include <aasdk/Transport/SSLWrapper.hpp>
#include <aasdk/Common/Log.hpp>
#include <aasdk/Common/ModernLogger.hpp>
namespace aasdk {
namespace transport {
static auto sslErrorToString(int sslErrorCode) -> const char* {
switch (sslErrorCode) {
case SSL_ERROR_NONE:
return "SSL_ERROR_NONE";
case SSL_ERROR_SSL:
return "SSL_ERROR_SSL";
case SSL_ERROR_WANT_READ:
return "SSL_ERROR_WANT_READ";
case SSL_ERROR_WANT_WRITE:
return "SSL_ERROR_WANT_WRITE";
case SSL_ERROR_WANT_X509_LOOKUP:
return "SSL_ERROR_WANT_X509_LOOKUP";
case SSL_ERROR_SYSCALL:
return "SSL_ERROR_SYSCALL";
case SSL_ERROR_ZERO_RETURN:
return "SSL_ERROR_ZERO_RETURN";
#if defined(SSL_ERROR_WANT_CONNECT)
case SSL_ERROR_WANT_CONNECT:
return "SSL_ERROR_WANT_CONNECT";
#endif
#if defined(SSL_ERROR_WANT_ACCEPT)
case SSL_ERROR_WANT_ACCEPT:
return "SSL_ERROR_WANT_ACCEPT";
#endif
default:
return "SSL_ERROR_UNKNOWN";
}
}
SSLWrapper::SSLWrapper() {
SSL_library_init();
SSL_load_error_strings(); // Optional: Can also be removed if not needed.
OpenSSL_add_all_algorithms();
}
SSLWrapper::~SSLWrapper() {
#ifdef FIPS_mode_set
FIPS_mode_set(0); // FIPS_mode_set removed in later versions of OpenSSL.
#endif
#ifdef HAVE_ENGINE_H
ENGINE_cleanup();
#endif
CONF_modules_unload(1);
EVP_cleanup();
CRYPTO_cleanup_all_ex_data();
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
ERR_remove_state(0);
#endif
ERR_free_strings();
}
X509 *SSLWrapper::readCertificate(const std::string &certificate) {
auto bio = BIO_new_mem_buf(certificate.c_str(), certificate.size());
X509 *x509Certificate = PEM_read_bio_X509_AUX(bio, nullptr, nullptr, nullptr);
BIO_free(bio);
return x509Certificate;
}
EVP_PKEY *SSLWrapper::readPrivateKey(const std::string &privateKey) {
auto bio = BIO_new_mem_buf(privateKey.c_str(), privateKey.size());
auto result = PEM_read_bio_PrivateKey(bio, nullptr, nullptr, nullptr);
BIO_free(bio);
return result;
}
const SSL_METHOD *SSLWrapper::getMethod() {
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
return TLSv1_2_client_method();
#else
return TLS_client_method();
#endif
}
SSL_CTX *SSLWrapper::createContext(const SSL_METHOD *method) {
SSL_CTX *ctx = SSL_CTX_new(method);
/*
if (ctx != nullptr) {
// Configure for Android Auto compatibility with OpenSSL 3.x
// Set minimum TLS version to 1.2 (Android Auto uses TLS 1.2+)
SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION);
SSL_CTX_set_max_proto_version(ctx, TLS1_3_VERSION);
// Lower security level for compatibility (Android Auto uses older ciphers)
SSL_CTX_set_security_level(ctx, 1);
// Set cipher list to include ciphers Android Auto expects
SSL_CTX_set_cipher_list(ctx, "DEFAULT:@SECLEVEL=1");
// Enable legacy renegotiation for older Android Auto versions
SSL_CTX_set_options(ctx, SSL_OP_LEGACY_SERVER_CONNECT);
AASDK_LOG(info) << "[SSLWrapper] SSL context configured for Android Auto (TLS 1.2-1.3, SECLEVEL=1)";
}
*/
return ctx;
}
bool SSLWrapper::useCertificate(SSL_CTX *context, X509 *certificate) {
return SSL_CTX_use_certificate(context, certificate) == 1;
}
bool SSLWrapper::usePrivateKey(SSL_CTX *context, EVP_PKEY *privateKey) {
return SSL_CTX_use_PrivateKey(context, privateKey) == 1;
}
SSL *SSLWrapper::createInstance(SSL_CTX *context) {
return SSL_new(context);
}
bool SSLWrapper::checkPrivateKey(SSL *ssl) {
return SSL_check_private_key(ssl) == 1;
}
std::pair<BIO *, BIO *> SSLWrapper::createBIOs() {
auto readBIO = BIO_new(BIO_s_mem());
auto writeBIO = BIO_new(BIO_s_mem());
return {readBIO, writeBIO};
}
void SSLWrapper::setBIOs(SSL *ssl, const BIOs &bIOs, size_t maxBufferSize) {
SSL_set_bio(ssl, bIOs.first, bIOs.second);
BIO_set_write_buf_size(bIOs.first, maxBufferSize);
BIO_set_write_buf_size(bIOs.second, maxBufferSize);
}
void SSLWrapper::setConnectState(SSL *ssl) {
SSL_set_connect_state(ssl);
SSL_set_verify(ssl, SSL_VERIFY_NONE, nullptr);
}
int SSLWrapper::doHandshake(SSL *ssl) {
auto result = SSL_do_handshake(ssl);
auto errorCode = SSL_get_error(ssl, result);
return errorCode;
}
void SSLWrapper::free(SSL *ssl) {
SSL_free(ssl);
}
void SSLWrapper::free(SSL_CTX *context) {
SSL_CTX_free(context);
}
void SSLWrapper::free(BIO *bio) {
BIO_free(bio);
}
void SSLWrapper::free(X509 *certificate) {
X509_free(certificate);
}
void SSLWrapper::free(EVP_PKEY *privateKey) {
EVP_PKEY_free(privateKey);
}
size_t SSLWrapper::bioCtrlPending(BIO *b) {
return BIO_ctrl_pending(b);
}
int SSLWrapper::bioRead(BIO *b, void *data, int len) {
return BIO_read(b, data, len);
}
int SSLWrapper::bioWrite(BIO *b, const void *data, int len) {
return BIO_write(b, data, len);
}
int SSLWrapper::getAvailableBytes(const SSL *ssl) {
return SSL_pending(ssl);
}
int SSLWrapper::sslRead(SSL *ssl, void *buf, int num) {
return SSL_read(ssl, buf, num);
}
int SSLWrapper::sslWrite(SSL *ssl, const void *buf, int num) {
return SSL_write(ssl, buf, num);
}
int SSLWrapper::getError(SSL *ssl, int returnCode) {
const int sslErrorCode = SSL_get_error(ssl, returnCode);
const int savedErrno = errno;
const bool fatalError =
sslErrorCode != SSL_ERROR_NONE &&
sslErrorCode != SSL_ERROR_WANT_READ &&
sslErrorCode != SSL_ERROR_WANT_WRITE &&
sslErrorCode != SSL_ERROR_WANT_X509_LOOKUP;
if (fatalError) {
AASDK_LOG(error) << "[SSLWrapper] getError returnCode=" << returnCode
<< " ssl_error=" << sslErrorCode
<< "(" << sslErrorToString(sslErrorCode) << ")"
<< " errno=" << savedErrno
<< "(" << std::strerror(savedErrno) << ")"
<< " state="
<< (ssl ? SSL_state_string_long(ssl) : "<null-ssl>");
} else {
AASDK_LOG(debug) << "[SSLWrapper] getError returnCode=" << returnCode
<< " ssl_error=" << sslErrorCode
<< "(" << sslErrorToString(sslErrorCode) << ")"
<< " errno=" << savedErrno
<< "(" << std::strerror(savedErrno) << ")"
<< " state="
<< (ssl ? SSL_state_string_long(ssl) : "<null-ssl>");
}
if (fatalError) {
while (auto err = ERR_get_error()) {
AASDK_LOG(error) << "[SSLWrapper] SSL Error " << ERR_error_string(err, NULL);
}
}
return sslErrorCode;
}
}
}Updated on 2026-03-15 at 09:02:41 +0000