/* Go through the hello extensions in |ss->ssl3.hs.remoteExtensions|. * For each one, find the extension handler in the table, and * if present, invoke that handler. * Servers ignore any extensions with unknown extension types. * Clients reject any extensions with unadvertised extension types * * In TLS >= 1.3, the client checks that extensions appear in the * right phase. */ SECStatus ssl3_HandleParsedExtensions(sslSocket *ss, SSLHandshakeType message) { const ssl3ExtensionHandler *handlers; /* HelloRetryRequest doesn't set ss->version. It might be safe to * do so, but we weren't entirely sure. TODO([email protected]). */ PRBool isTLS13 = (ss->version >= SSL_LIBRARY_VERSION_TLS_1_3) || (message == ssl_hs_hello_retry_request); /* The following messages can include extensions that were not included in * the original ClientHello. */ PRBool allowNotOffered = (message == ssl_hs_client_hello) || (message == ssl_hs_certificate_request) || (message == ssl_hs_new_session_ticket); PRCList *cursor; switch (message) { case ssl_hs_client_hello: handlers = clientHelloHandlers; break; case ssl_hs_new_session_ticket: PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3); handlers = newSessionTicketHandlers; break; case ssl_hs_hello_retry_request: handlers = helloRetryRequestHandlers; break; case ssl_hs_encrypted_extensions: PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3); /* fall through */ case ssl_hs_server_hello: if (ss->version > SSL_LIBRARY_VERSION_3_0) { handlers = serverHelloHandlersTLS; } else { handlers = serverHelloHandlersSSL3; } break; case ssl_hs_certificate: PORT_Assert(!ss->sec.isServer); handlers = serverCertificateHandlers; break; case ssl_hs_certificate_request: PORT_Assert(!ss->sec.isServer); handlers = certificateRequestHandlers; break; default: PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); PORT_Assert(0); return SECFailure; } for (cursor = PR_NEXT_LINK(&ss->ssl3.hs.remoteExtensions); cursor != &ss->ssl3.hs.remoteExtensions; cursor = PR_NEXT_LINK(cursor)) { TLSExtension *extension = (TLSExtension *)cursor; SECStatus rv; /* Check whether the server sent an extension which was not advertised * in the ClientHello. * * Note that a TLS 1.3 server should check if CertificateRequest * extensions were sent. But the extensions used for CertificateRequest * do not have any response, so we rely on * ssl3_ExtensionAdvertised to return false on the server. That * results in the server only rejecting any extension. */ if (!allowNotOffered && (extension->type != ssl_tls13_cookie_xtn) && !ssl3_ExtensionAdvertised(ss, extension->type)) { (void)SSL3_SendAlert(ss, alert_fatal, unsupported_extension); PORT_SetError(SSL_ERROR_RX_UNEXPECTED_EXTENSION); return SECFailure; } /* Check that this is a legal extension in TLS 1.3 */ if (isTLS13 && !ssl_FindCustomExtensionHooks(ss, extension->type)) { switch (tls13_ExtensionStatus(extension->type, message)) { case tls13_extension_allowed: break; case tls13_extension_unknown: if (allowNotOffered) { continue; /* Skip over unknown extensions. */ } /* Fall through. */ case tls13_extension_disallowed: SSL_TRC(3, ("%d: TLS13: unexpected extension %d in message %d", SSL_GETPID(), extension, message)); tls13_FatalError(ss, SSL_ERROR_EXTENSION_DISALLOWED_FOR_VERSION, unsupported_extension); return SECFailure; } } /* Special check for this being the last extension if it's * PreSharedKey */ if (ss->sec.isServer && isTLS13 && (extension->type == ssl_tls13_pre_shared_key_xtn) && (PR_NEXT_LINK(cursor) != &ss->ssl3.hs.remoteExtensions)) { tls13_FatalError(ss, SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, illegal_parameter); return SECFailure; } rv = ssl_CallExtensionHandler(ss, message, extension, handlers); if (rv != SECSuccess) { return SECFailure; } } return SECSuccess; }
/* Go through the hello extensions in |ss->ssl3.hs.remoteExtensions|. * For each one, find the extension handler in the table, and * if present, invoke that handler. * Servers ignore any extensions with unknown extension types. * Clients reject any extensions with unadvertised extension types * * In TLS >= 1.3, the client checks that extensions appear in the * right phase. */ SECStatus ssl3_HandleParsedExtensions(sslSocket *ss, SSL3HandshakeType handshakeMessage) { const ssl3ExtensionHandler *handlers; PRBool isTLS13 = ss->version >= SSL_LIBRARY_VERSION_TLS_1_3; PRCList *cursor; switch (handshakeMessage) { case client_hello: handlers = clientHelloHandlers; break; case new_session_ticket: PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3); handlers = newSessionTicketHandlers; break; case hello_retry_request: handlers = helloRetryRequestHandlers; break; case encrypted_extensions: PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3); /* fall through */ case server_hello: if (ss->version > SSL_LIBRARY_VERSION_3_0) { handlers = serverHelloHandlersTLS; } else { handlers = serverHelloHandlersSSL3; } break; case certificate: PORT_Assert(!ss->sec.isServer); handlers = serverCertificateHandlers; break; default: PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); PORT_Assert(0); return SECFailure; } for (cursor = PR_NEXT_LINK(&ss->ssl3.hs.remoteExtensions); cursor != &ss->ssl3.hs.remoteExtensions; cursor = PR_NEXT_LINK(cursor)) { TLSExtension *extension = (TLSExtension *)cursor; const ssl3ExtensionHandler *handler; /* Check whether the server sent an extension which was not advertised * in the ClientHello */ if (!ss->sec.isServer && !ssl3_ClientExtensionAdvertised(ss, extension->type) && (handshakeMessage != new_session_ticket) && (extension->type != ssl_tls13_cookie_xtn)) { (void)SSL3_SendAlert(ss, alert_fatal, unsupported_extension); PORT_SetError(SSL_ERROR_RX_UNEXPECTED_EXTENSION); return SECFailure; } /* Check that this is a legal extension in TLS 1.3 */ if (isTLS13 && !tls13_ExtensionAllowed(extension->type, handshakeMessage)) { if (handshakeMessage == client_hello) { /* Skip extensions not used in TLS 1.3 */ continue; } tls13_FatalError(ss, SSL_ERROR_EXTENSION_DISALLOWED_FOR_VERSION, unsupported_extension); return SECFailure; } /* Special check for this being the last extension if it's * PreSharedKey */ if (ss->sec.isServer && isTLS13 && (extension->type == ssl_tls13_pre_shared_key_xtn) && (PR_NEXT_LINK(cursor) != &ss->ssl3.hs.remoteExtensions)) { tls13_FatalError(ss, SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, illegal_parameter); return SECFailure; } /* find extension_type in table of Hello Extension Handlers */ for (handler = handlers; handler->ex_type >= 0; handler++) { /* if found, call this handler */ if (handler->ex_type == extension->type) { SECStatus rv; rv = (*handler->ex_handler)(ss, &ss->xtnData, (PRUint16)extension->type, &extension->data); if (rv != SECSuccess) { if (!ss->ssl3.fatalAlertSent) { /* send a generic alert if the handler didn't already */ (void)SSL3_SendAlert(ss, alert_fatal, handshake_failure); } return SECFailure; } } } } return SECSuccess; }