N_("The server name sent was not recognized")),
ALERT_ENTRY(GNUTLS_A_UNKNOWN_PSK_IDENTITY,
N_("The SRP/PSK username is missing or not known")),
+ ALERT_ENTRY(GNUTLS_A_MISSING_EXTENSION,
+ N_("An extension was expected but was not seen")),
ALERT_ENTRY(GNUTLS_A_NO_APPLICATION_PROTOCOL,
N_
("No supported application protocol could be negotiated")),
ret = GNUTLS_A_UNSUPPORTED_EXTENSION;
_level = GNUTLS_AL_FATAL;
break;
+ case GNUTLS_E_MISSING_EXTENSION:
+ ret = GNUTLS_A_MISSING_EXTENSION;
+ _level = GNUTLS_AL_FATAL;
+ break;
case GNUTLS_E_USER_ERROR:
ret = GNUTLS_A_USER_CANCELED;
_level = GNUTLS_AL_FATAL;
GNUTLS_E_INAPPROPRIATE_FALLBACK),
ERROR_ENTRY(N_("An illegal TLS extension was received."),
GNUTLS_E_RECEIVED_ILLEGAL_EXTENSION),
+ ERROR_ENTRY(N_("An required TLS extension was received."),
+ GNUTLS_E_MISSING_EXTENSION),
ERROR_ENTRY(N_("A TLS fatal alert has been received."),
GNUTLS_E_FATAL_ALERT_RECEIVED),
ERROR_ENTRY(N_("An unexpected TLS packet was received."),
return gnutls_assert_val(GNUTLS_E_NO_COMMON_KEY_SHARE);
}
+ session->internals.hsk_flags |= HSK_KEY_SHARE_RECEIVED;
} else { /* Client */
ver = get_version(session);
if (unlikely(ver == NULL || ver->key_shares == 0))
#define HSK_PSK_KE_MODE_DHE_PSK (1<<14) /* server: whether PSK with DH is selected
* client: whether PSK with DH is allowed
*/
-#define HSK_PSK_SELECTED (1<<15)
+#define HSK_PSK_SELECTED (1<<15) /* server: whether PSK was selected, either for resumption or not;
+ * on resumption session->internals.resumed will be set as well.
+ * client: the same */
#define HSK_KEY_SHARE_SENT (1<<16) /* server: key share was sent to client */
-#define HSK_KEY_SHARE_RECEIVED (1<<17) /* client: key share was received */
+#define HSK_KEY_SHARE_RECEIVED (1<<17) /* client: key share was received
+ * server: key share was received and accepted */
#define HSK_TLS13_TICKET_SENT (1<<18) /* client: sent a ticket under TLS1.3;
* server: a ticket was sent to client.
*/
return sret;
}
+/* Associates the right credential types for the session, and
+ * performs sanity checks. */
static int set_auth_types(gnutls_session_t session)
{
const version_entry_st *ver = get_version(session);
gnutls_kx_algorithm_t kx;
- kx = session->security_parameters.cs->kx_algorithm;
- if (kx == 0 && ver->tls13_sem) {
- /* if we are resuming then the KX seen doesn't match the original */
+ /* sanity check:
+ * we see TLS1.3 negotiated but no key share was sent */
+ if (ver->tls13_sem) {
+ if (unlikely(!(session->internals.hsk_flags & HSK_PSK_KE_MODE_PSK) &&
+ !(session->internals.hsk_flags & HSK_KEY_SHARE_RECEIVED))) {
+ return gnutls_assert_val(GNUTLS_E_MISSING_EXTENSION);
+ }
+
+ /* Under TLS1.3 this returns a KX which matches the negotiated
+ * groups from the key shares; if we are resuming then the KX seen
+ * here doesn't match the original session. */
if (session->internals.resumed == RESUME_FALSE)
kx = gnutls_kx_get(session);
+ else
+ kx = GNUTLS_KX_UNKNOWN;
+ } else {
+ /* TLS1.2 or earlier, kx is associated with ciphersuite */
+ kx = session->security_parameters.cs->kx_algorithm;
}
- if (kx) {
+ if (kx != GNUTLS_KX_UNKNOWN) {
session->security_parameters.server_auth_type = _gnutls_map_kx_get_cred(kx, 1);
session->security_parameters.client_auth_type = _gnutls_map_kx_get_cred(kx, 0);
- } else if (session->internals.resumed == RESUME_FALSE) {
- return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
+ } else if (unlikely(session->internals.resumed == RESUME_FALSE)) {
+ /* Here we can only arrive if something we received
+ * prevented the session from completing. */
+ return gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);
}
return 0;
* @GNUTLS_A_EXPORT_RESTRICTION: Export restriction.
* @GNUTLS_A_PROTOCOL_VERSION: Error in protocol version.
* @GNUTLS_A_INSUFFICIENT_SECURITY: Insufficient security.
- * @GNUTLS_A_USER_CANCELED: User canceled.
* @GNUTLS_A_INTERNAL_ERROR: Internal error.
* @GNUTLS_A_INAPPROPRIATE_FALLBACK: Inappropriate fallback,
+ * @GNUTLS_A_USER_CANCELED: User canceled.
* @GNUTLS_A_NO_RENEGOTIATION: No renegotiation is allowed.
- * @GNUTLS_A_CERTIFICATE_UNOBTAINABLE: Could not retrieve the
- * specified certificate.
+ * @GNUTLS_A_MISSING_EXTENSION: An extension was expected but was not seen
* @GNUTLS_A_UNSUPPORTED_EXTENSION: An unsupported extension was
* sent.
+ * @GNUTLS_A_CERTIFICATE_UNOBTAINABLE: Could not retrieve the
+ * specified certificate.
* @GNUTLS_A_UNRECOGNIZED_NAME: The server name sent was not
* recognized.
* @GNUTLS_A_UNKNOWN_PSK_IDENTITY: The SRP/PSK username is missing
GNUTLS_A_INAPPROPRIATE_FALLBACK = 86,
GNUTLS_A_USER_CANCELED = 90,
GNUTLS_A_NO_RENEGOTIATION = 100,
+ GNUTLS_A_MISSING_EXTENSION = 109,
GNUTLS_A_UNSUPPORTED_EXTENSION = 110,
GNUTLS_A_CERTIFICATE_UNOBTAINABLE = 111,
GNUTLS_A_UNRECOGNIZED_NAME = 112,
#define GNUTLS_E_REAUTH_REQUEST -424
#define GNUTLS_E_TOO_MANY_MATCHES -425
#define GNUTLS_E_CRL_VERIFICATION_ERROR -426
+#define GNUTLS_E_MISSING_EXTENSION -427
#define GNUTLS_E_UNIMPLEMENTED_FEATURE -1250