Browse Source

LibTLS: Move AlertDescription to Extensions.h

Also add missing values from the IANA registry
stelar7 2 years ago
parent
commit
5853d9642a

+ 56 - 0
Userland/Libraries/LibTLS/Extensions.h

@@ -659,7 +659,63 @@ enum class CipherSuite : u16 {
     __ENUM_CIPHER_SUITES
 };
 
+// https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-6
+#define __ENUM_ALERT_DESCRIPTIONS                             \
+    _ENUM_KEY_VALUE(CLOSE_NOTIFY, 0)                          \
+    _ENUM_KEY_VALUE(UNEXPECTED_MESSAGE, 10)                   \
+    _ENUM_KEY_VALUE(BAD_RECORD_MAC, 20)                       \
+    _ENUM_KEY_VALUE(DECRYPTION_FAILED_RESERVED, 21)           \
+    _ENUM_KEY_VALUE(RECORD_OVERFLOW, 22)                      \
+    _ENUM_KEY_VALUE(DECOMPRESSION_FAILURE_RESERVED, 30)       \
+    _ENUM_KEY_VALUE(HANDSHAKE_FAILURE, 40)                    \
+    _ENUM_KEY_VALUE(NO_CERTIFICATE_RESERVED, 41)              \
+    _ENUM_KEY_VALUE(BAD_CERTIFICATE, 42)                      \
+    _ENUM_KEY_VALUE(UNSUPPORTED_CERTIFICATE, 43)              \
+    _ENUM_KEY_VALUE(CERTIFICATE_REVOKED, 44)                  \
+    _ENUM_KEY_VALUE(CERTIFICATE_EXPIRED, 45)                  \
+    _ENUM_KEY_VALUE(CERTIFICATE_UNKNOWN, 46)                  \
+    _ENUM_KEY_VALUE(ILLEGAL_PARAMETER, 47)                    \
+    _ENUM_KEY_VALUE(UNKNOWN_CA, 48)                           \
+    _ENUM_KEY_VALUE(ACCESS_DENIED, 49)                        \
+    _ENUM_KEY_VALUE(DECODE_ERROR, 50)                         \
+    _ENUM_KEY_VALUE(DECRYPT_ERROR, 51)                        \
+    _ENUM_KEY_VALUE(TOO_MANY_CIDS_REQUESTED, 52)              \
+    _ENUM_KEY_VALUE(EXPORT_RESTRICTION_RESERVED, 60)          \
+    _ENUM_KEY_VALUE(PROTOCOL_VERSION, 70)                     \
+    _ENUM_KEY_VALUE(INSUFFICIENT_SECURITY, 71)                \
+    _ENUM_KEY_VALUE(INTERNAL_ERROR, 80)                       \
+    _ENUM_KEY_VALUE(INAPPROPRIATE_FALLBACK, 86)               \
+    _ENUM_KEY_VALUE(USER_CANCELED, 90)                        \
+    _ENUM_KEY_VALUE(NO_RENEGOTIATION_RESERVED, 100)           \
+    _ENUM_KEY_VALUE(MISSING_EXTENSION, 109)                   \
+    _ENUM_KEY_VALUE(UNSUPPORTED_EXTENSION, 110)               \
+    _ENUM_KEY_VALUE(CERTIFICATE_UNOBTAINABLE_RESERVED, 111)   \
+    _ENUM_KEY_VALUE(UNRECOGNIZED_NAME, 112)                   \
+    _ENUM_KEY_VALUE(BAD_CERTIFICATE_STATUS_RESPONSE, 113)     \
+    _ENUM_KEY_VALUE(BAD_CERTIFICATE_HASH_VALUE_RESERVED, 114) \
+    _ENUM_KEY_VALUE(UNKNOWN_PSK_IDENTITY, 115)                \
+    _ENUM_KEY_VALUE(CERTIFICATE_REQUIRED, 116)                \
+    _ENUM_KEY_VALUE(NO_APPLICATION_PROTOCOL, 120)
+
+enum class AlertDescription : u8 {
+    __ENUM_ALERT_DESCRIPTIONS
+};
+
 #undef _ENUM_KEY
 #undef _ENUM_KEY_VALUE
 
+constexpr static StringView enum_to_string(AlertDescription descriptor)
+{
+#define _ENUM_KEY_VALUE(name, value) \
+    case AlertDescription::name:     \
+        return #name##sv;
+
+    switch (descriptor) {
+        __ENUM_ALERT_DESCRIPTIONS
+    }
+
+    return "Unknown"sv;
+#undef _ENUM_KEY_VALUE
+}
+
 }

+ 11 - 11
Userland/Libraries/LibTLS/Handshake.cpp

@@ -424,58 +424,58 @@ ssize_t TLSv12::handle_handshake_payload(ReadonlyBytes vbuffer)
         if (payload_res < 0) {
             switch ((Error)payload_res) {
             case Error::UnexpectedMessage: {
-                auto packet = build_alert(true, (u8)AlertDescription::UnexpectedMessage);
+                auto packet = build_alert(true, (u8)AlertDescription::UNEXPECTED_MESSAGE);
                 write_packet(packet);
                 break;
             }
             case Error::CompressionNotSupported: {
-                auto packet = build_alert(true, (u8)AlertDescription::DecompressionFailure);
+                auto packet = build_alert(true, (u8)AlertDescription::DECOMPRESSION_FAILURE_RESERVED);
                 write_packet(packet);
                 break;
             }
             case Error::BrokenPacket: {
-                auto packet = build_alert(true, (u8)AlertDescription::DecodeError);
+                auto packet = build_alert(true, (u8)AlertDescription::DECODE_ERROR);
                 write_packet(packet);
                 break;
             }
             case Error::NotVerified: {
-                auto packet = build_alert(true, (u8)AlertDescription::BadRecordMAC);
+                auto packet = build_alert(true, (u8)AlertDescription::BAD_RECORD_MAC);
                 write_packet(packet);
                 break;
             }
             case Error::BadCertificate: {
-                auto packet = build_alert(true, (u8)AlertDescription::BadCertificate);
+                auto packet = build_alert(true, (u8)AlertDescription::BAD_CERTIFICATE);
                 write_packet(packet);
                 break;
             }
             case Error::UnsupportedCertificate: {
-                auto packet = build_alert(true, (u8)AlertDescription::UnsupportedCertificate);
+                auto packet = build_alert(true, (u8)AlertDescription::UNSUPPORTED_CERTIFICATE);
                 write_packet(packet);
                 break;
             }
             case Error::NoCommonCipher: {
-                auto packet = build_alert(true, (u8)AlertDescription::InsufficientSecurity);
+                auto packet = build_alert(true, (u8)AlertDescription::INSUFFICIENT_SECURITY);
                 write_packet(packet);
                 break;
             }
             case Error::NotUnderstood:
             case Error::OutOfMemory: {
-                auto packet = build_alert(true, (u8)AlertDescription::InternalError);
+                auto packet = build_alert(true, (u8)AlertDescription::INTERNAL_ERROR);
                 write_packet(packet);
                 break;
             }
             case Error::NoRenegotiation: {
-                auto packet = build_alert(true, (u8)AlertDescription::NoRenegotiation);
+                auto packet = build_alert(true, (u8)AlertDescription::NO_RENEGOTIATION_RESERVED);
                 write_packet(packet);
                 break;
             }
             case Error::DecryptionFailed: {
-                auto packet = build_alert(true, (u8)AlertDescription::DecryptionFailed);
+                auto packet = build_alert(true, (u8)AlertDescription::DECRYPTION_FAILED_RESERVED);
                 write_packet(packet);
                 break;
             }
             case Error::NotSafe: {
-                auto packet = build_alert(true, (u8)AlertDescription::DecryptError);
+                auto packet = build_alert(true, (u8)AlertDescription::DECRYPT_ERROR);
                 write_packet(packet);
                 break;
             }

+ 1 - 1
Userland/Libraries/LibTLS/HandshakeClient.cpp

@@ -365,7 +365,7 @@ ByteBuffer TLSv12::build_client_key_exchange()
     bool chain_verified = m_context.verify_chain(m_context.extensions.SNI);
     if (!chain_verified) {
         dbgln("certificate verification failed :(");
-        alert(AlertLevel::FATAL, AlertDescription::BadCertificate);
+        alert(AlertLevel::FATAL, AlertDescription::BAD_CERTIFICATE);
         return {};
     }
 

+ 11 - 11
Userland/Libraries/LibTLS/Record.cpp

@@ -359,7 +359,7 @@ ssize_t TLSv12::handle_message(ReadonlyBytes buffer)
                 VERIFY(is_aead());
                 if (length < 24) {
                     dbgln("Invalid packet length");
-                    auto packet = build_alert(true, (u8)AlertDescription::DecryptError);
+                    auto packet = build_alert(true, (u8)AlertDescription::DECRYPT_ERROR);
                     write_packet(packet);
                     return_value = Error::BrokenPacket;
                     return;
@@ -418,7 +418,7 @@ ssize_t TLSv12::handle_message(ReadonlyBytes buffer)
 
                 if (consistency != Crypto::VerificationConsistency::Consistent) {
                     dbgln("integrity check failed (tag length {})", tag.size());
-                    auto packet = build_alert(true, (u8)AlertDescription::BadRecordMAC);
+                    auto packet = build_alert(true, (u8)AlertDescription::BAD_RECORD_MAC);
                     write_packet(packet);
 
                     return_value = Error::IntegrityCheckFailed;
@@ -453,7 +453,7 @@ ssize_t TLSv12::handle_message(ReadonlyBytes buffer)
                 auto mac_size = mac_length();
                 if (length < mac_size) {
                     dbgln("broken packet");
-                    auto packet = build_alert(true, (u8)AlertDescription::DecryptError);
+                    auto packet = build_alert(true, (u8)AlertDescription::DECRYPT_ERROR);
                     write_packet(packet);
                     return_value = Error::BrokenPacket;
                     return;
@@ -473,7 +473,7 @@ ssize_t TLSv12::handle_message(ReadonlyBytes buffer)
                     print_buffer(message_mac);
                     dbgln("mac computed:");
                     print_buffer(hmac);
-                    auto packet = build_alert(true, (u8)AlertDescription::BadRecordMAC);
+                    auto packet = build_alert(true, (u8)AlertDescription::BAD_RECORD_MAC);
                     write_packet(packet);
 
                     return_value = Error::IntegrityCheckFailed;
@@ -493,14 +493,14 @@ ssize_t TLSv12::handle_message(ReadonlyBytes buffer)
         if (m_context.connection_status != ConnectionStatus::Established) {
             dbgln("unexpected application data");
             payload_res = (i8)Error::UnexpectedMessage;
-            auto packet = build_alert(true, (u8)AlertDescription::UnexpectedMessage);
+            auto packet = build_alert(true, (u8)AlertDescription::UNEXPECTED_MESSAGE);
             write_packet(packet);
         } else {
             dbgln_if(TLS_DEBUG, "application data message of size {}", plain.size());
 
             if (m_context.application_buffer.try_append(plain.data(), plain.size()).is_error()) {
                 payload_res = (i8)Error::DecryptionFailed;
-                auto packet = build_alert(true, (u8)AlertDescription::DecryptionFailed);
+                auto packet = build_alert(true, (u8)AlertDescription::DECRYPTION_FAILED_RESERVED);
                 write_packet(packet);
             }
         }
@@ -512,7 +512,7 @@ ssize_t TLSv12::handle_message(ReadonlyBytes buffer)
     case ContentType::CHANGE_CIPHER_SPEC:
         if (m_context.connection_status != ConnectionStatus::KeyExchange) {
             dbgln("unexpected change cipher message");
-            auto packet = build_alert(true, (u8)AlertDescription::UnexpectedMessage);
+            auto packet = build_alert(true, (u8)AlertDescription::UNEXPECTED_MESSAGE);
             write_packet(packet);
             payload_res = (i8)Error::UnexpectedMessage;
         } else {
@@ -532,19 +532,19 @@ ssize_t TLSv12::handle_message(ReadonlyBytes buffer)
             dbgln_if(TLS_DEBUG, "Alert received with level {}, code {}", level, code);
 
             if (level == (u8)AlertLevel::FATAL) {
-                dbgln("We were alerted of a critical error: {} ({})", code, alert_name((AlertDescription)code));
+                dbgln("We were alerted of a critical error: {} ({})", code, enum_to_string((AlertDescription)code));
                 m_context.critical_error = code;
                 try_disambiguate_error();
                 res = (i8)Error::UnknownError;
             }
 
-            if (code == (u8)AlertDescription::CloseNotify) {
+            if (code == (u8)AlertDescription::CLOSE_NOTIFY) {
                 res += 2;
-                alert(AlertLevel::FATAL, AlertDescription::CloseNotify);
+                alert(AlertLevel::FATAL, AlertDescription::CLOSE_NOTIFY);
                 if (!m_context.cipher_spec_set) {
                     // AWS CloudFront hits this.
                     dbgln("Server sent a close notify and we haven't agreed on a cipher suite. Treating it as a handshake failure.");
-                    m_context.critical_error = (u8)AlertDescription::HandshakeFailure;
+                    m_context.critical_error = (u8)AlertDescription::HANDSHAKE_FAILURE;
                     try_disambiguate_error();
                 }
                 m_context.close_notify = true;

+ 4 - 4
Userland/Libraries/LibTLS/Socket.cpp

@@ -91,7 +91,7 @@ ErrorOr<NonnullOwnPtr<TLSv12>> TLSv12::connect(DeprecatedString const& host, u16
 
     tls_socket->try_disambiguate_error();
     // FIXME: Should return richer information here.
-    return AK::Error::from_string_view(alert_name(static_cast<AlertDescription>(256 - result)));
+    return AK::Error::from_string_view(enum_to_string(static_cast<AlertDescription>(256 - result)));
 }
 
 ErrorOr<NonnullOwnPtr<TLSv12>> TLSv12::connect(DeprecatedString const& host, Core::Socket& underlying_stream, Options options)
@@ -112,7 +112,7 @@ ErrorOr<NonnullOwnPtr<TLSv12>> TLSv12::connect(DeprecatedString const& host, Cor
 
     tls_socket->try_disambiguate_error();
     // FIXME: Should return richer information here.
-    return AK::Error::from_string_view(alert_name(static_cast<AlertDescription>(256 - result)));
+    return AK::Error::from_string_view(enum_to_string(static_cast<AlertDescription>(256 - result)));
 }
 
 void TLSv12::setup_connection()
@@ -135,7 +135,7 @@ void TLSv12::setup_connection()
                 if (timeout_diff < m_max_wait_time_for_handshake_in_seconds + 1) {
                     // The server did not respond fast enough,
                     // time the connection out.
-                    alert(AlertLevel::FATAL, AlertDescription::UserCanceled);
+                    alert(AlertLevel::FATAL, AlertDescription::USER_CANCELED);
                     m_context.tls_buffer.clear();
                     m_context.error_code = Error::TimedOut;
                     m_context.critical_error = (u8)Error::TimedOut;
@@ -317,7 +317,7 @@ ErrorOr<bool> TLSv12::flush()
 
 void TLSv12::close()
 {
-    alert(AlertLevel::FATAL, AlertDescription::CloseNotify);
+    alert(AlertLevel::FATAL, AlertDescription::CLOSE_NOTIFY);
     // bye bye.
     m_context.connection_status = ConnectionStatus::Disconnected;
 }

+ 15 - 15
Userland/Libraries/LibTLS/TLSv12.cpp

@@ -138,55 +138,55 @@ void TLSv12::try_disambiguate_error() const
 {
     dbgln("Possible failure cause(s): ");
     switch ((AlertDescription)m_context.critical_error) {
-    case AlertDescription::HandshakeFailure:
+    case AlertDescription::HANDSHAKE_FAILURE:
         if (!m_context.cipher_spec_set) {
             dbgln("- No cipher suite in common with {}", m_context.extensions.SNI);
         } else {
             dbgln("- Unknown internal issue");
         }
         break;
-    case AlertDescription::InsufficientSecurity:
+    case AlertDescription::INSUFFICIENT_SECURITY:
         dbgln("- No cipher suite in common with {} (the server is oh so secure)", m_context.extensions.SNI);
         break;
-    case AlertDescription::ProtocolVersion:
+    case AlertDescription::PROTOCOL_VERSION:
         dbgln("- The server refused to negotiate with TLS 1.2 :(");
         break;
-    case AlertDescription::UnexpectedMessage:
+    case AlertDescription::UNEXPECTED_MESSAGE:
         dbgln("- We sent an invalid message for the state we're in.");
         break;
-    case AlertDescription::BadRecordMAC:
+    case AlertDescription::BAD_RECORD_MAC:
         dbgln("- Bad MAC record from our side.");
         dbgln("- Ciphertext wasn't an even multiple of the block length.");
         dbgln("- Bad block cipher padding.");
         dbgln("- If both sides are compliant, the only cause is messages being corrupted in the network.");
         break;
-    case AlertDescription::RecordOverflow:
+    case AlertDescription::RECORD_OVERFLOW:
         dbgln("- Sent a ciphertext record which has a length bigger than 18432 bytes.");
         dbgln("- Sent record decrypted to a compressed record that has a length bigger than 18432 bytes.");
         dbgln("- If both sides are compliant, the only cause is messages being corrupted in the network.");
         break;
-    case AlertDescription::DecompressionFailure:
+    case AlertDescription::DECOMPRESSION_FAILURE_RESERVED:
         dbgln("- We sent invalid input for decompression (e.g. data that would expand to excessive length)");
         break;
-    case AlertDescription::IllegalParameter:
+    case AlertDescription::ILLEGAL_PARAMETER:
         dbgln("- We sent a parameter in the handshake that is out of range or inconsistent with the other parameters.");
         break;
-    case AlertDescription::DecodeError:
+    case AlertDescription::DECODE_ERROR:
         dbgln("- The message we sent cannot be decoded because a field was out of range or the length was incorrect.");
         dbgln("- If both sides are compliant, the only cause is messages being corrupted in the network.");
         break;
-    case AlertDescription::DecryptError:
+    case AlertDescription::DECRYPT_ERROR:
         dbgln("- A handshake crypto operation failed. This includes signature verification and validating Finished.");
         break;
-    case AlertDescription::AccessDenied:
+    case AlertDescription::ACCESS_DENIED:
         dbgln("- The certificate is valid, but once access control was applied, the sender decided to stop negotiation.");
         break;
-    case AlertDescription::InternalError:
+    case AlertDescription::INTERNAL_ERROR:
         dbgln("- No one knows, but it isn't a protocol failure.");
         break;
-    case AlertDescription::DecryptionFailed:
-    case AlertDescription::NoCertificate:
-    case AlertDescription::ExportRestriction:
+    case AlertDescription::DECRYPTION_FAILED_RESERVED:
+    case AlertDescription::NO_CERTIFICATE_RESERVED:
+    case AlertDescription::EXPORT_RESTRICTION_RESERVED:
         dbgln("- No one knows, the server sent a non-compliant alert.");
         break;
     default:

+ 0 - 49
Userland/Libraries/LibTLS/TLSv12.h

@@ -40,55 +40,6 @@ inline void print_buffer(u8 const* buffer, size_t size)
 
 class Socket;
 
-#define ENUMERATE_ALERT_DESCRIPTIONS                        \
-    ENUMERATE_ALERT_DESCRIPTION(CloseNotify, 0)             \
-    ENUMERATE_ALERT_DESCRIPTION(UnexpectedMessage, 10)      \
-    ENUMERATE_ALERT_DESCRIPTION(BadRecordMAC, 20)           \
-    ENUMERATE_ALERT_DESCRIPTION(DecryptionFailed, 21)       \
-    ENUMERATE_ALERT_DESCRIPTION(RecordOverflow, 22)         \
-    ENUMERATE_ALERT_DESCRIPTION(DecompressionFailure, 30)   \
-    ENUMERATE_ALERT_DESCRIPTION(HandshakeFailure, 40)       \
-    ENUMERATE_ALERT_DESCRIPTION(NoCertificate, 41)          \
-    ENUMERATE_ALERT_DESCRIPTION(BadCertificate, 42)         \
-    ENUMERATE_ALERT_DESCRIPTION(UnsupportedCertificate, 43) \
-    ENUMERATE_ALERT_DESCRIPTION(CertificateRevoked, 44)     \
-    ENUMERATE_ALERT_DESCRIPTION(CertificateExpired, 45)     \
-    ENUMERATE_ALERT_DESCRIPTION(CertificateUnknown, 46)     \
-    ENUMERATE_ALERT_DESCRIPTION(IllegalParameter, 47)       \
-    ENUMERATE_ALERT_DESCRIPTION(UnknownCA, 48)              \
-    ENUMERATE_ALERT_DESCRIPTION(AccessDenied, 49)           \
-    ENUMERATE_ALERT_DESCRIPTION(DecodeError, 50)            \
-    ENUMERATE_ALERT_DESCRIPTION(DecryptError, 51)           \
-    ENUMERATE_ALERT_DESCRIPTION(ExportRestriction, 60)      \
-    ENUMERATE_ALERT_DESCRIPTION(ProtocolVersion, 70)        \
-    ENUMERATE_ALERT_DESCRIPTION(InsufficientSecurity, 71)   \
-    ENUMERATE_ALERT_DESCRIPTION(InternalError, 80)          \
-    ENUMERATE_ALERT_DESCRIPTION(InappropriateFallback, 86)  \
-    ENUMERATE_ALERT_DESCRIPTION(UserCanceled, 90)           \
-    ENUMERATE_ALERT_DESCRIPTION(NoRenegotiation, 100)       \
-    ENUMERATE_ALERT_DESCRIPTION(UnsupportedExtension, 110)  \
-    ENUMERATE_ALERT_DESCRIPTION(NoError, 255)
-
-enum class AlertDescription : u8 {
-#define ENUMERATE_ALERT_DESCRIPTION(name, value) name = value,
-    ENUMERATE_ALERT_DESCRIPTIONS
-#undef ENUMERATE_ALERT_DESCRIPTION
-};
-
-constexpr static StringView alert_name(AlertDescription descriptor)
-{
-#define ENUMERATE_ALERT_DESCRIPTION(name, value) \
-    case AlertDescription::name:                 \
-        return #name##sv;
-
-    switch (descriptor) {
-        ENUMERATE_ALERT_DESCRIPTIONS
-    }
-
-    return "Unknown"sv;
-#undef ENUMERATE_ALERT_DESCRIPTION
-}
-
 enum class Error : i8 {
     NoError = 0,
     UnknownError = -1,

+ 2 - 2
Userland/Services/RequestServer/ConnectionCache.h

@@ -146,9 +146,9 @@ ErrorOr<void> recreate_socket_if_needed(T& connection, URL const& url)
             TLS::Options options;
             options.set_alert_handler([&connection](TLS::AlertDescription alert) {
                 Core::NetworkJob::Error reason;
-                if (alert == TLS::AlertDescription::HandshakeFailure)
+                if (alert == TLS::AlertDescription::HANDSHAKE_FAILURE)
                     reason = Core::NetworkJob::Error::ProtocolFailed;
-                else if (alert == TLS::AlertDescription::DecryptError)
+                else if (alert == TLS::AlertDescription::DECRYPT_ERROR)
                     reason = Core::NetworkJob::Error::ConnectionFailed;
                 else
                     reason = Core::NetworkJob::Error::TransmissionFailed;