OpenSSL wrapper strings management.

This commit is contained in:
2026-05-05 21:48:51 -04:00
parent a7042d1ddf
commit cbc863718d
+44 -41
View File
@@ -64,6 +64,10 @@
#define CERT_STATUS_BAD 3 #define CERT_STATUS_BAD 3
#define CERT_STATUS_USER_ACCEPTED 4 #define CERT_STATUS_USER_ACCEPTED 4
#include <string>
using namespace std::literals::string_literals;
struct Server_t { struct Server_t {
char *hostname; char *hostname;
int port; int port;
@@ -211,7 +215,6 @@ static void Tls_load_certificates(void)
* something to work with. * something to work with.
*/ */
uint_t u; uint_t u;
char *userpath;
static const char *const ca_files[] = { static const char *const ca_files[] = {
"/etc/ssl/certs/ca-certificates.crt", "/etc/ssl/certs/ca-certificates.crt",
"/etc/pki/tls/certs/ca-bundle.crt", "/etc/pki/tls/certs/ca-bundle.crt",
@@ -240,9 +243,8 @@ static void Tls_load_certificates(void)
X509_LOOKUP_add_dir(lookup, ca_paths[u], X509_FILETYPE_PEM); X509_LOOKUP_add_dir(lookup, ca_paths[u], X509_FILETYPE_PEM);
} }
userpath = dStrconcat(dGethomedir(), "/.flenser/certs/", NULL); auto userpath = dGethomedir_string().value() + "/.flenser/certs/";
X509_LOOKUP_add_dir(lookup, userpath, X509_FILETYPE_PEM); X509_LOOKUP_add_dir(lookup, userpath.c_str(), X509_FILETYPE_PEM);
dFree(userpath);
/* Clear out errors in the queue (file not found, etc.) */ /* Clear out errors in the queue (file not found, etc.) */
while(ERR_get_error()) while(ERR_get_error())
@@ -613,7 +615,6 @@ static bool Tls_check_cert_hostname(X509 *cert, const char *host,
if (cert == NULL || host == NULL) if (cert == NULL || host == NULL)
return FALSE; return FALSE;
char *msg;
GENERAL_NAMES *subjectAltNames; GENERAL_NAMES *subjectAltNames;
bool success = true, alt_name_checked = false;; bool success = true, alt_name_checked = false;;
char common_name[256]; char common_name[256];
@@ -723,11 +724,11 @@ static bool Tls_check_cert_hostname(X509 *cert, const char *host,
if (!pattern_match (common_name, host)) if (!pattern_match (common_name, host))
{ {
success = false; success = false;
msg = dStrconcat("Certificate common name ", common_name,
" doesn't match requested host name ", host, NULL); auto msg = "Certificate common name "s + common_name +
" doesn't match requested host name " + host;
*choice = a_Dialog_choice("Flenser TLS security warning", *choice = a_Dialog_choice("Flenser TLS security warning",
msg, "Continue", "Cancel", NULL); msg.c_str(), "Continue", "Cancel", NULL);
dFree(msg);
switch (*choice){ switch (*choice){
case 1: case 1:
@@ -767,13 +768,12 @@ static bool Tls_check_cert_hostname(X509 *cert, const char *host,
if (strlen (common_name) != (size_t)ASN1_STRING_length (sdata)) if (strlen (common_name) != (size_t)ASN1_STRING_length (sdata))
{ {
success = FALSE; success = FALSE;
msg = dStrconcat("Certificate common name is invalid (contains a NUL " auto msg = "Certificate common name is invalid (contains a NUL "
"character). This may be an indication that the " "character). This may be an indication that the "
"host is not who it claims to be -- that is, not " "host is not who it claims to be -- that is, not "
"the real ", host, NULL); "the real "s + host;
*choice = a_Dialog_choice("Flenser TLS security warning", *choice = a_Dialog_choice("Flenser TLS security warning",
msg, "Continue", "Cancel", NULL); msg.c_str(), "Continue", "Cancel", NULL);
dFree(msg);
switch (*choice){ switch (*choice){
case 1: case 1:
@@ -842,9 +842,9 @@ static int Tls_examine_certificate(SSL *ssl, Server_t *srv)
X509 *remote_cert; X509 *remote_cert;
long st; long st;
const uint_t buflen = 4096; const uint_t buflen = 4096;
char buf[buflen], *cn, *msg; char buf[buflen], *cn;
int choice = -1, ret = -1; int choice = -1, ret = -1;
char *title = dStrconcat("Flenser TLS security warning: ",srv->hostname,NULL); const std::string title = "Flenser TLS security warning: "s + srv->hostname;
#if OPENSSL_VERSION_NUMBER < 0x30000000L #if OPENSSL_VERSION_NUMBER < 0x30000000L
remote_cert = SSL_get_peer_certificate(ssl); remote_cert = SSL_get_peer_certificate(ssl);
@@ -854,7 +854,7 @@ static int Tls_examine_certificate(SSL *ssl, Server_t *srv)
#endif #endif
if (remote_cert == NULL){ if (remote_cert == NULL){
/* Inform user that remote system cannot be trusted */ /* Inform user that remote system cannot be trusted */
choice = a_Dialog_choice(title, choice = a_Dialog_choice(title.c_str(),
"The remote system is not presenting a certificate. " "The remote system is not presenting a certificate. "
"This site cannot be trusted. Sending data is not safe.", "This site cannot be trusted. Sending data is not safe.",
"Continue", "Cancel", NULL); "Continue", "Cancel", NULL);
@@ -893,11 +893,12 @@ static int Tls_examine_certificate(SSL *ssl, Server_t *srv)
buf[cn_end - cn] = '\0'; buf[cn_end - cn] = '\0';
} }
OPENSSL_free(subj); OPENSSL_free(subj);
msg = dStrconcat("The remote certificate is self-signed and " {
"untrusted. For address: ", buf, NULL); auto msg = "The remote certificate is self-signed and "
choice = a_Dialog_choice(title, "untrusted. For address: "s + buf;
msg, "Continue", "Cancel", "Save Certificate", NULL); choice = a_Dialog_choice(title.c_str(),
dFree(msg); msg.c_str(), "Continue", "Cancel", "Save Certificate", NULL);
}
switch (choice){ switch (choice){
case 1: case 1:
@@ -916,7 +917,7 @@ static int Tls_examine_certificate(SSL *ssl, Server_t *srv)
break; break;
case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
choice = a_Dialog_choice(title, choice = a_Dialog_choice(title.c_str(),
"The issuer for the remote certificate cannot be found. " "The issuer for the remote certificate cannot be found. "
"The authenticity of the remote certificate cannot be trusted.", "The authenticity of the remote certificate cannot be trusted.",
"Continue", "Cancel", NULL); "Continue", "Cancel", NULL);
@@ -930,7 +931,7 @@ static int Tls_examine_certificate(SSL *ssl, Server_t *srv)
case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
case X509_V_ERR_CERT_SIGNATURE_FAILURE: case X509_V_ERR_CERT_SIGNATURE_FAILURE:
case X509_V_ERR_CRL_SIGNATURE_FAILURE: case X509_V_ERR_CRL_SIGNATURE_FAILURE:
choice = a_Dialog_choice(title, choice = a_Dialog_choice(title.c_str(),
"The remote certificate signature could not be read " "The remote certificate signature could not be read "
"or is invalid and should not be trusted", "or is invalid and should not be trusted",
"Continue", "Cancel", NULL); "Continue", "Cancel", NULL);
@@ -941,7 +942,7 @@ static int Tls_examine_certificate(SSL *ssl, Server_t *srv)
break; break;
case X509_V_ERR_CERT_NOT_YET_VALID: case X509_V_ERR_CERT_NOT_YET_VALID:
case X509_V_ERR_CRL_NOT_YET_VALID: case X509_V_ERR_CRL_NOT_YET_VALID:
choice = a_Dialog_choice(title, choice = a_Dialog_choice(title.c_str(),
"Part of the remote certificate is not yet valid. " "Part of the remote certificate is not yet valid. "
"Certificates usually have a range of dates over which " "Certificates usually have a range of dates over which "
"they are to be considered valid, and the certificate " "they are to be considered valid, and the certificate "
@@ -955,21 +956,22 @@ static int Tls_examine_certificate(SSL *ssl, Server_t *srv)
break; break;
case X509_V_ERR_CERT_HAS_EXPIRED: case X509_V_ERR_CERT_HAS_EXPIRED:
case X509_V_ERR_CRL_HAS_EXPIRED: case X509_V_ERR_CRL_HAS_EXPIRED:
{
Tls_get_expiration_str(remote_cert, buf, buflen); Tls_get_expiration_str(remote_cert, buf, buflen);
msg = dStrconcat("The remote certificate expired on: ", buf, auto msg = "The remote certificate expired on: "s + buf +
". This site can no longer be trusted.", NULL); ". This site can no longer be trusted.";
choice = a_Dialog_choice(title, msg, "Continue", "Cancel", NULL); choice = a_Dialog_choice(title.c_str(), msg.c_str(), "Continue", "Cancel", NULL);
if (choice == 1) { if (choice == 1) {
ret = 0; ret = 0;
} }
dFree(msg);
break; break;
}
case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
choice = a_Dialog_choice(title, choice = a_Dialog_choice(title.c_str(),
"There was an error in the certificate presented. " "There was an error in the certificate presented. "
"Some of the certificate data was improperly formatted " "Some of the certificate data was improperly formatted "
"making it impossible to determine if the certificate " "making it impossible to determine if the certificate "
@@ -984,7 +986,7 @@ static int Tls_examine_certificate(SSL *ssl, Server_t *srv)
case X509_V_ERR_CERT_UNTRUSTED: case X509_V_ERR_CERT_UNTRUSTED:
case X509_V_ERR_CERT_REJECTED: case X509_V_ERR_CERT_REJECTED:
case X509_V_ERR_KEYUSAGE_NO_CERTSIGN: case X509_V_ERR_KEYUSAGE_NO_CERTSIGN:
choice = a_Dialog_choice(title, choice = a_Dialog_choice(title.c_str(),
"One of the certificates in the chain is being used " "One of the certificates in the chain is being used "
"incorrectly (possibly due to configuration problems " "incorrectly (possibly due to configuration problems "
"with the remote system. The connection should not " "with the remote system. The connection should not "
@@ -997,7 +999,7 @@ static int Tls_examine_certificate(SSL *ssl, Server_t *srv)
case X509_V_ERR_SUBJECT_ISSUER_MISMATCH: case X509_V_ERR_SUBJECT_ISSUER_MISMATCH:
case X509_V_ERR_AKID_SKID_MISMATCH: case X509_V_ERR_AKID_SKID_MISMATCH:
case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH: case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH:
choice = a_Dialog_choice(title, choice = a_Dialog_choice(title.c_str(),
"Some of the information presented by the remote system " "Some of the information presented by the remote system "
"does not match other information presented. " "does not match other information presented. "
"This may be an attempt to eavesdrop on communications", "This may be an attempt to eavesdrop on communications",
@@ -1007,29 +1009,31 @@ static int Tls_examine_certificate(SSL *ssl, Server_t *srv)
} }
break; break;
case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
{
Tls_get_issuer_name(Tls_get_end_of_chain(ssl), buf, buflen); Tls_get_issuer_name(Tls_get_end_of_chain(ssl), buf, buflen);
msg = dStrconcat("Certificate chain led to a self-signed certificate " auto msg = "Certificate chain led to a self-signed certificate "
"instead of a trusted root. Name: ", buf , NULL); "instead of a trusted root. Name: "s + buf;
choice = a_Dialog_choice(title, msg, "Continue", "Cancel", NULL); choice = a_Dialog_choice(title.c_str(), msg.c_str(), "Continue", "Cancel", NULL);
if (choice == 1) { if (choice == 1) {
ret = 0; ret = 0;
} }
dFree(msg);
break; break;
}
case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
{
Tls_get_issuer_name(Tls_get_end_of_chain(ssl), buf, buflen); Tls_get_issuer_name(Tls_get_end_of_chain(ssl), buf, buflen);
msg = dStrconcat("The issuer certificate of an untrusted certificate " auto msg = "The issuer certificate of an untrusted certificate "
"cannot be found. Issuer: ", buf, NULL); "cannot be found. Issuer: "s + buf;
choice = a_Dialog_choice(title, msg, "Continue", "Cancel", NULL); choice = a_Dialog_choice(title.c_str(), msg.c_str(), "Continue", "Cancel", NULL);
if (choice == 1) { if (choice == 1) {
ret = 0; ret = 0;
} }
dFree(msg);
break; break;
}
default: /* Need to add more options later */ default: /* Need to add more options later */
snprintf(buf, 80, snprintf(buf, 80,
"The remote certificate cannot be verified (code %ld)", st); "The remote certificate cannot be verified (code %ld)", st);
choice = a_Dialog_choice(title, choice = a_Dialog_choice(title.c_str(),
buf, "Continue", "Cancel", NULL); buf, "Continue", "Cancel", NULL);
/* abort on anything but "Continue" */ /* abort on anything but "Continue" */
if (choice == 1){ if (choice == 1){
@@ -1039,7 +1043,6 @@ static int Tls_examine_certificate(SSL *ssl, Server_t *srv)
X509_free(remote_cert); X509_free(remote_cert);
remote_cert = 0; remote_cert = 0;
} }
dFree(title);
if (choice == -1) { if (choice == -1) {
srv->cert_status = CERT_STATUS_CLEAN; /* no warning popups */ srv->cert_status = CERT_STATUS_CLEAN; /* no warning popups */