Skip to content

Commit

Permalink
Added client-side events for new TLS alerts generated on the server side
Browse files Browse the repository at this point in the history
Early rejection of CN: TLS_ALERT_BAD_CERTIFICATE
Bad X509 key usage:    TLS_ALERT_UNSUPPORTED_CERTIFICATE
Bad peer-fingerprint:  TLS_ALERT_UNKNOWN_CA

Signed-off-by: James Yonan <[email protected]>
  • Loading branch information
jamesyonan committed Jan 11, 2025
1 parent cdd7852 commit 39fb73b
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 6 deletions.
6 changes: 6 additions & 0 deletions openvpn/client/cliconnect.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,12 @@ class ClientConnect : ClientProto::NotifyCallback,
case Error::TLS_ALERT_CERTIFICATE_REVOKED:
add_error_and_stop<ClientEvent::TLSAlertCertificateRevoked>(fatal_code);
break;
case Error::TLS_ALERT_BAD_CERTIFICATE:
add_error_and_stop<ClientEvent::TLSAlertBadCertificate>(fatal_code);
break;
case Error::TLS_ALERT_UNSUPPORTED_CERTIFICATE:
add_error_and_stop<ClientEvent::TLSAlertUnsupportedCertificate>(fatal_code);
break;
case Error::NEED_CREDS:
{
ClientEvent::Base::Ptr ev = new ClientEvent::NeedCreds();
Expand Down
20 changes: 20 additions & 0 deletions openvpn/client/clievent.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ enum Type
TLS_ALERT_HANDSHAKE_FAILURE,
TLS_ALERT_CERTIFICATE_EXPIRED,
TLS_ALERT_CERTIFICATE_REVOKED,
TLS_ALERT_BAD_CERTIFICATE,
TLS_ALERT_UNSUPPORTED_CERTIFICATE,
TLS_SIGALG_DISALLOWED_OR_UNSUPPORTED,
CLIENT_HALT,
CLIENT_SETUP,
Expand Down Expand Up @@ -142,6 +144,8 @@ inline const char *event_name(const Type type)
"TLS_ALERT_HANDSHAKE_FAILURE",
"TLS_ALERT_CERTIFICATE_EXPIRED",
"TLS_ALERT_CERTIFICATE_REVOKED",
"TLS_ALERT_BAD_CERTIFICATE",
"TLS_ALERT_UNSUPPORTED_CERTIFICATE",
"TLS_SIGALG_DISALLOWED_OR_UNSUPPORTED",
"CLIENT_HALT",
"CLIENT_SETUP",
Expand Down Expand Up @@ -374,6 +378,22 @@ struct TLSAlertCertificateRevoked : public Base
}
};

struct TLSAlertBadCertificate : public Base
{
TLSAlertBadCertificate()
: Base(TLS_ALERT_BAD_CERTIFICATE)
{
}
};

struct TLSAlertUnsupportedCertificate : public Base
{
TLSAlertUnsupportedCertificate()
: Base(TLS_ALERT_UNSUPPORTED_CERTIFICATE)
{
}
};

struct TLSSigAlgDisallowedOrUnsupported : public Base
{
TLSSigAlgDisallowedOrUnsupported()
Expand Down
4 changes: 4 additions & 0 deletions openvpn/error/error.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ enum Type
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_BAD_CERTIFICATE, // TLS Alert: bad/rejected certificate
TLS_ALERT_UNSUPPORTED_CERTIFICATE, // TLS Alert: unsupported certificate (X509 key usage)
TLS_ALERT_MISC, // Any TLS Alert that is in any of the previous TLS alerts
TLS_AUTH_FAIL, // tls-auth HMAC verification failed
TLS_CRYPT_META_FAIL, // tls-crypt-v2 metadata verification failed
Expand Down Expand Up @@ -166,6 +168,8 @@ inline const char *name(const size_t type)
"TLS_ALERT_CERTIFICATE_REQUIRED",
"TLS_ALERT_CERTIFICATE_EXPIRED",
"TLS_ALERT_CERTIFICATE_REVOKED",
"TLS_ALERT_BAD_CERTIFICATE",
"TLS_ALERT_UNSUPPORTED_CERTIFICATE",
"TLS_ALERT_MISC",
"TLS_AUTH_FAIL",
"TLS_CRYPT_META_FAIL",
Expand Down
15 changes: 9 additions & 6 deletions openvpn/openssl/ssl/sslctx.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1954,6 +1954,9 @@ class OpenSSLContext : public SSLFactoryAPI
cert_fail_code(err),
X509_verify_cert_error_string(err));

// Note on X509_STORE_CTX_set_error: see ssl/statem/statem_lib.c in
// OpenSSL source for mapping from X509_STORE_CTX_set_error() codes
// to TLS alert codes.
if (depth == 1) // issuer cert
{
// save the issuer cert fingerprint
Expand All @@ -1976,7 +1979,7 @@ class OpenSSLContext : public SSLFactoryAPI
self_ssl->authcert->add_fail(depth,
AuthCert::Fail::BAD_CERT_TYPE,
"bad peer-fingerprint in leaf certificate");
X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_SIGNATURE_FAILURE);
X509_STORE_CTX_set_error(ctx, X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE); // alert code: SSL_R_TLSV1_ALERT_UNKNOWN_CA
preverify_ok = false;
}

Expand All @@ -1988,7 +1991,7 @@ class OpenSSLContext : public SSLFactoryAPI
self_ssl->authcert->add_fail(depth,
AuthCert::Fail::BAD_CERT_TYPE,
"bad ns-cert-type in leaf certificate");
X509_STORE_CTX_set_error(ctx, X509_V_ERR_INVALID_PURPOSE);
X509_STORE_CTX_set_error(ctx, X509_V_ERR_INVALID_PURPOSE); // alert code: SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE
preverify_ok = false;
}

Expand All @@ -2000,7 +2003,7 @@ class OpenSSLContext : public SSLFactoryAPI
self_ssl->authcert->add_fail(depth,
AuthCert::Fail::BAD_CERT_TYPE,
"bad X509 key usage in leaf certificate");
X509_STORE_CTX_set_error(ctx, X509_V_ERR_INVALID_PURPOSE);
X509_STORE_CTX_set_error(ctx, X509_V_ERR_INVALID_PURPOSE); // alert code: SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE
preverify_ok = false;
}

Expand All @@ -2012,7 +2015,7 @@ class OpenSSLContext : public SSLFactoryAPI
self_ssl->authcert->add_fail(depth,
AuthCert::Fail::BAD_CERT_TYPE,
"bad X509 extended key usage in leaf certificate");
X509_STORE_CTX_set_error(ctx, X509_V_ERR_INVALID_PURPOSE);
X509_STORE_CTX_set_error(ctx, X509_V_ERR_INVALID_PURPOSE); // alert code: SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE
preverify_ok = false;
}

Expand All @@ -2027,14 +2030,14 @@ class OpenSSLContext : public SSLFactoryAPI
if (self->config->cn_reject_handler->reject(cn))
{
OVPN_LOG_INFO("VERIFY FAIL -- early rejection of leaf cert Common Name");
X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED);
X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED); // alert code: SSL_R_SSLV3_ALERT_BAD_CERTIFICATE
preverify_ok = false;
}
}
catch (const std::exception &e)
{
OVPN_LOG_INFO("VERIFY FAIL -- early rejection of leaf cert Common Name due to handler exception: " << e.what());
X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED);
X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED); // alert code: SSL_R_SSLV3_ALERT_BAD_CERTIFICATE
preverify_ok = false;
}
}
Expand Down
6 changes: 6 additions & 0 deletions openvpn/openssl/util/error.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,12 @@ class OpenSSLException : public ExceptionCode
case SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED:
set_code(Error::TLS_ALERT_CERTIFICATE_REVOKED, true);
break;
case SSL_R_SSLV3_ALERT_BAD_CERTIFICATE:
set_code(Error::TLS_ALERT_BAD_CERTIFICATE, true);
break;
case SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE:
set_code(Error::TLS_ALERT_UNSUPPORTED_CERTIFICATE, true);
break;
default:
if (reason > SSL_AD_REASON_OFFSET)
{
Expand Down

0 comments on commit 39fb73b

Please sign in to comment.