monero-c
C ABI for using Monero
Loading...
Searching...
No Matches
monero_c_tls.h
Go to the documentation of this file.
1
23#ifndef MONERO_C_TLS_H
24#define MONERO_C_TLS_H
25
26#include <cctype>
27#include <functional>
28#include <string>
29
30// where OpenSSL finds the CA certificates of the system. Not part of the public ABI, and it needs no OpenSSL header, so a test
31// can run it on a fake file system
32namespace monero_c {
33
34// what to export as SSL_CERT_FILE and SSL_CERT_DIR. An empty string leaves the variable as it is
35struct ca_paths {
36 std::string file;
37 std::string dir;
38};
39
40// the bundles of the CA certificates of the common systems, in the order that they are tried: Debian and Ubuntu, Fedora and RHEL,
41// openSUSE, then Alpine and macOS
42static const char* const CA_FILES[] = {
43 "/etc/ssl/certs/ca-certificates.crt",
44 "/etc/pki/tls/certs/ca-bundle.crt",
45 "/etc/ssl/ca-bundle.pem",
46 "/etc/ssl/cert.pem",
47};
48
49// the directories of certificates by hashed name (5ad8a5d6.0), the one of Android included
50static const char* const CA_DIRS[] = {
51 "/etc/ssl/certs",
52 "/etc/pki/tls/certs",
53 "/system/etc/security/cacerts",
54};
55
56// true if the name is a certificate by its hashed name, which is 8 hex digits, a dot and a number, such as 5ad8a5d6.0
57inline bool is_hashed_certificate_name(const std::string& name) {
58 if (name.size() < 10 || name[8] != '.') return false;
59 for (size_t i = 0; i < 8; i++) {
60 if (!std::isxdigit(static_cast<unsigned char>(name[i]))) return false;
61 }
62 for (size_t i = 9; i < name.size(); i++) {
63 if (!std::isdigit(static_cast<unsigned char>(name[i]))) return false;
64 }
65 return true;
66}
67
68// chooses what to export so that OpenSSL finds the CA certificates. The OpenSSL in the library has the directory of the machine
69// that built it in its code, and it looks for the certificates there, so a connection with a certificate of a CA fails where that
70// directory isn't, such as a Mac without Homebrew. Nothing is chosen if the caller set SSL_CERT_FILE or SSL_CERT_DIR, or if
71// OpenSSL finds the certificates by itself: its default file is there, or its default directory has certificates by hashed name.
72// A directory that exists proves nothing, since the one of Homebrew exists and is empty. is_file tells that a path is a file with
73// content, and has_certificates that a path is a directory with certificates by hashed name
74inline ca_paths find_ca_paths(const char* env_file, const char* env_dir, const std::string& default_file, const std::string& default_dir,
75 const std::function<bool(const std::string&)>& is_file, const std::function<bool(const std::string&)>& has_certificates) {
76 ca_paths paths;
77 if ((env_file != nullptr && env_file[0] != '\0') || (env_dir != nullptr && env_dir[0] != '\0')) return paths;
78 if (!default_file.empty() && is_file(default_file)) return paths;
79 if (!default_dir.empty() && has_certificates(default_dir)) return paths;
80 for (const char* file : CA_FILES) {
81 if (is_file(file)) {
82 paths.file = file;
83 break;
84 }
85 }
86 for (const char* dir : CA_DIRS) {
87 if (has_certificates(dir)) {
88 paths.dir = dir;
89 break;
90 }
91 }
92 return paths;
93}
94
95} // namespace monero_c
96
97#endif // MONERO_C_TLS_H
Copyright (c) Libmonero.
Definition monero_c_tls.h:32
ca_paths find_ca_paths(const char *env_file, const char *env_dir, const std::string &default_file, const std::string &default_dir, const std::function< bool(const std::string &)> &is_file, const std::function< bool(const std::string &)> &has_certificates)
Definition monero_c_tls.h:74
bool is_hashed_certificate_name(const std::string &name)
Definition monero_c_tls.h:57
Definition monero_c_tls.h:35
std::string dir
Definition monero_c_tls.h:37
std::string file
Definition monero_c_tls.h:36