0
0
mirror of https://github.com/OpenVPN/openvpn3.git synced 2024-09-19 19:52:15 +02:00

Trigger events on common TLS alerts

OpenVPN 2.7/master will no longer suppress TLS Alerts but send them
out to the client. Create event for the common events that occur and
notify them to the UI process.

Jira: OVPN-1215
Signed-off-by: Arne Schwabe <arne@openvpn.net>
This commit is contained in:
Arne Schwabe 2024-06-17 17:56:20 +02:00 committed by Jenkins-dev
parent ae3f94a1f5
commit fe91436cc4
5 changed files with 153 additions and 2 deletions

View File

@ -584,7 +584,27 @@ class ClientConnect : ClientProto::NotifyCallback,
case Error::NTLM_MISSING_CRYPTO: case Error::NTLM_MISSING_CRYPTO:
add_error_and_stop<ClientEvent::NtlmMissingCryptoError>(client.get()); add_error_and_stop<ClientEvent::NtlmMissingCryptoError>(client.get());
break; break;
case Error::TLS_ALERT_PROTOCOL_VERSION:
add_error_and_stop<ClientEvent::TLSAlertProtocolVersion>(fatal_code);
break;
case Error::TLS_SIGALG_DISALLOWED_OR_UNSUPPORTED:
add_error_and_stop<ClientEvent::TLSSigAlgDisallowedOrUnsupported>(fatal_code);
break;
case Error::TLS_ALERT_UNKNOWN_CA:
add_error_and_stop<ClientEvent::TLSAlertProtocolUnknownCA>(fatal_code);
break;
case Error::TLS_ALERT_MISC:
add_error_and_stop<ClientEvent::TLSAlertMisc>(fatal_code, fatal_reason);
break;
case Error::TLS_ALERT_HANDSHAKE_FAILURE:
add_error_and_stop<ClientEvent::TLSAlertHandshakeFailure>(fatal_code);
break;
case Error::TLS_ALERT_CERTIFICATE_EXPIRED:
add_error_and_stop<ClientEvent::TLSAlertCertificateExpire>(fatal_code);
break;
case Error::TLS_ALERT_CERTIFICATE_REVOKED:
add_error_and_stop<ClientEvent::TLSAlertCertificateRevoked>(fatal_code);
break;
default: default:
throw client_connect_unhandled_exception(); throw client_connect_unhandled_exception();
} }

View File

@ -75,6 +75,13 @@ enum Type
AUTH_FAILED, AUTH_FAILED,
CERT_VERIFY_FAIL, CERT_VERIFY_FAIL,
TLS_VERSION_MIN, TLS_VERSION_MIN,
TLS_ALERT_PROTOCOL_VERSION,
TLS_ALERT_UNKNOWN_CA,
TLS_ALERT_MISC,
TLS_ALERT_HANDSHAKE_FAILURE,
TLS_ALERT_CERTIFICATE_EXPIRED,
TLS_ALERT_CERTIFICATE_REVOKED,
TLS_SIGALG_DISALLOWED_OR_UNSUPPORTED,
CLIENT_HALT, CLIENT_HALT,
CLIENT_SETUP, CLIENT_SETUP,
TUN_HALT, TUN_HALT,
@ -138,6 +145,13 @@ inline const char *event_name(const Type type)
"AUTH_FAILED", "AUTH_FAILED",
"CERT_VERIFY_FAIL", "CERT_VERIFY_FAIL",
"TLS_VERSION_MIN", "TLS_VERSION_MIN",
"TLS_ALERT_PROTOCOL_VERSION",
"TLS_ALERT_UNKNOWN_CA",
"TLS_ALERT_MISC",
"TLS_ALERT_HANDSHAKE_FAILURE",
"TLS_ALERT_CERTIFICATE_EXPIRED",
"TLS_ALERT_CERTIFICATE_REVOKED",
"TLS_SIGALG_DISALLOWED_OR_UNSUPPORTED",
"CLIENT_HALT", "CLIENT_HALT",
"CLIENT_SETUP", "CLIENT_SETUP",
"TUN_HALT", "TUN_HALT",
@ -320,6 +334,14 @@ struct InactiveTimeout : public Base
} }
}; };
struct TLSMinVersion : public Base
{
TLSMinVersion()
: Base(TLS_VERSION_MIN)
{
}
};
struct TLSVersionMinFail : public Base struct TLSVersionMinFail : public Base
{ {
TLSVersionMinFail() TLSVersionMinFail()
@ -328,6 +350,56 @@ struct TLSVersionMinFail : public Base
} }
}; };
struct TLSAlertProtocolVersion : public Base
{
TLSAlertProtocolVersion()
: Base(TLS_ALERT_PROTOCOL_VERSION)
{
}
};
struct TLSAlertHandshakeFailure : public Base
{
TLSAlertHandshakeFailure()
: Base(TLS_ALERT_HANDSHAKE_FAILURE)
{
}
};
struct TLSAlertCertificateExpire : public Base
{
TLSAlertCertificateExpire()
: Base(TLS_ALERT_CERTIFICATE_EXPIRED)
{
}
};
struct TLSAlertCertificateRevoked : public Base
{
TLSAlertCertificateRevoked()
: Base(TLS_ALERT_CERTIFICATE_REVOKED)
{
}
};
struct TLSSigAlgDisallowedOrUnsupported : public Base
{
TLSSigAlgDisallowedOrUnsupported()
: Base(TLS_SIGALG_DISALLOWED_OR_UNSUPPORTED)
{
}
};
struct TLSAlertProtocolUnknownCA : public Base
{
TLSAlertProtocolUnknownCA()
: Base(TLS_ALERT_UNKNOWN_CA)
{
}
};
#ifdef HAVE_JSON #ifdef HAVE_JSON
struct InfoJSON : public Base struct InfoJSON : public Base
@ -444,6 +516,15 @@ struct ReasonBase : public Base
std::string reason; std::string reason;
}; };
/* thrown if no other of the TLSAlert* events are matching */
struct TLSAlertMisc : public ReasonBase
{
TLSAlertMisc(std::string reason)
: ReasonBase(TLS_ALERT_MISC, std::move(reason))
{
}
};
struct AuthFailed : public ReasonBase struct AuthFailed : public ReasonBase
{ {
AuthFailed(std::string reason) AuthFailed(std::string reason)
@ -540,6 +621,7 @@ struct NtlmMissingCryptoError : public ReasonBase
} }
}; };
struct ProxyNeedCreds : public ReasonBase struct ProxyNeedCreds : public ReasonBase
{ {
ProxyNeedCreds(std::string reason) ProxyNeedCreds(std::string reason)

View File

@ -74,6 +74,13 @@ enum Type
PRIMARY_EXPIRE, // primary key context expired PRIMARY_EXPIRE, // primary key context expired
TLS_VERSION_MIN, // peer cannot handshake at our minimum required TLS version TLS_VERSION_MIN, // peer cannot handshake at our minimum required TLS version
TLS_SIGALG_DISALLOWED_OR_UNSUPPORTED, // signature algorithm required by TLS peer is not supported TLS_SIGALG_DISALLOWED_OR_UNSUPPORTED, // signature algorithm required by TLS peer is not supported
TLS_ALERT_PROTOCOL_VERSION, // TLS Alert: No common TLS version between server and client
TLS_ALERT_UNKNOWN_CA, // TLS Alert: Unknown CA (client certificate verify failed or peer-fingerprint failed)
TLS_ALERT_HANDSHAKE_FAILURE, // TLS Alert: Generic handshake failure from the other side
TLS_ALERT_CERTIFICATE_REQUIRED, // TLS Alert: certificate is required
TLS_ALERT_CERTIFICATE_EXPIRED, // TLS Alert: certificate has expired
TLS_ALERT_CERTIFICATE_REVOKED, // TLS Alert: certificate is revoked
TLS_ALERT_MISC, // Any TLS Alert that is in any of the previous TLS alerts
TLS_AUTH_FAIL, // tls-auth HMAC verification failed TLS_AUTH_FAIL, // tls-auth HMAC verification failed
TLS_CRYPT_META_FAIL, // tls-crypt-v2 metadata verification failed TLS_CRYPT_META_FAIL, // tls-crypt-v2 metadata verification failed
CERT_VERIFY_FAIL, // peer certificate verification failure CERT_VERIFY_FAIL, // peer certificate verification failure
@ -161,6 +168,13 @@ inline const char *name(const size_t type)
"PRIMARY_EXPIRE", "PRIMARY_EXPIRE",
"TLS_VERSION_MIN", "TLS_VERSION_MIN",
"TLS_SIGALG_DISALLOWED_OR_UNSUPPORTED", "TLS_SIGALG_DISALLOWED_OR_UNSUPPORTED",
"TLS_ALERT_PROTOCOL_VERSION",
"TLS_ALERT_UNKNOWN_CA",
"TLS_ALERT_HANDSHAKE_FAILURE",
"TLS_ALERT_CERTIFICATE_REQUIRED",
"TLS_ALERT_CERTIFICATE_EXPIRED",
"TLS_ALERT_CERTIFICATE_REVOKED",
"TLS_ALERT_MISC",
"TLS_AUTH_FAIL", "TLS_AUTH_FAIL",
"TLS_CRYPT_META_FAIL", "TLS_CRYPT_META_FAIL",
"CERT_VERIFY_FAIL", "CERT_VERIFY_FAIL",

View File

@ -140,12 +140,19 @@ class OpenSSLException : public ExceptionCode
if (n_err < MAX_ERRORS) if (n_err < MAX_ERRORS)
errstack[n_err++] = err; errstack[n_err++] = err;
ERR_error_string_n(err, buf, sizeof(buf)); ERR_error_string_n(err, buf, sizeof(buf));
auto reason = ERR_GET_REASON(err);
tmp << prefix << buf; tmp << prefix << buf;
if (reason >= SSL_AD_REASON_OFFSET)
{
tmp << "[" << SSL_alert_desc_string_long(reason - SSL_AD_REASON_OFFSET) << "]";
}
prefix = " / "; prefix = " / ";
// for certain OpenSSL errors, translate them to an OpenVPN error code, // for certain OpenSSL errors, translate them to an OpenVPN error code,
// so they can be propagated up to the higher levels (such as UI level) // so they can be propagated up to the higher levels (such as UI level)
switch (ERR_GET_REASON(err))
switch (reason)
{ {
case SSL_R_CERTIFICATE_VERIFY_FAILED: case SSL_R_CERTIFICATE_VERIFY_FAILED:
set_code(Error::CERT_VERIFY_FAIL, true); set_code(Error::CERT_VERIFY_FAIL, true);
@ -172,6 +179,30 @@ class OpenSSLException : public ExceptionCode
case SSL_R_DH_KEY_TOO_SMALL: case SSL_R_DH_KEY_TOO_SMALL:
set_code(Error::SSL_DH_KEY_TOO_SMALL, true); set_code(Error::SSL_DH_KEY_TOO_SMALL, true);
break; break;
case SSL_R_TLSV1_ALERT_PROTOCOL_VERSION:
set_code(Error::TLS_ALERT_PROTOCOL_VERSION, true);
break;
case SSL_R_TLSV1_ALERT_UNKNOWN_CA:
set_code(Error::TLS_ALERT_UNKNOWN_CA, true);
break;
case SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE:
set_code(Error::TLS_ALERT_HANDSHAKE_FAILURE, true);
break;
case SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED:
set_code(Error::TLS_ALERT_CERTIFICATE_REQUIRED, true);
break;
case SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED:
set_code(Error::TLS_ALERT_CERTIFICATE_EXPIRED, true);
break;
case SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED:
set_code(Error::TLS_ALERT_CERTIFICATE_REVOKED, true);
break;
default:
if (reason > SSL_AD_REASON_OFFSET)
{
/* all TLS alerts use TLS alert code + SSL_AD_REASON_OFFSET in OpenSSL */
set_code(Error::TLS_ALERT_MISC, true);
}
} }
} }
errtxt = tmp.str(); errtxt = tmp.str();

View File

@ -341,6 +341,10 @@ class Client : public ClientBase
std::cout << "Unrecognized INFO/INFO_PRE message: " << ev.info << std::endl; std::cout << "Unrecognized INFO/INFO_PRE message: " << ev.info << std::endl;
} }
} }
else
{
std::cout << "Received event " << ev.name << " " << ev.info << std::endl;
}
} }
void handle_dpc1_protocol(const ClientAPI::AppCustomControlMessageEvent &acev) void handle_dpc1_protocol(const ClientAPI::AppCustomControlMessageEvent &acev)