OpenSSL wrapper strings management.
This commit is contained in:
+44
-41
@@ -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 */
|
||||||
|
|||||||
Reference in New Issue
Block a user