+/*
+ * ossl_statem_client_read_transition() encapsulates the logic for the allowed
+ * handshake state transitions when a TLS1.3 client is reading messages from the
+ * server. The message type that the server has sent is provided in |mt|. The
+ * current state is in |s->statem.hand_state|.
+ *
+ * Return values are 1 for success (transition allowed) and 0 on error
+ * (transition not allowed)
+ */
+static int ossl_statem_client13_read_transition(SSL *s, int mt)
+{
+ OSSL_STATEM *st = &s->statem;
+
+ /*
+ * TODO(TLS1.3): This is still based on the TLSv1.2 state machine. Over time
+ * we will update this to look more like real TLSv1.3
+ */
+
+ /*
+ * Note: There is no case for TLS_ST_CW_CLNT_HELLO, because we haven't
+ * yet negotiated TLSv1.3 at that point so that is handled by
+ * ossl_statem_client_read_transition()
+ */
+
+ switch (st->hand_state) {
+ default:
+ break;
+
+ case TLS_ST_CR_SRVR_HELLO:
+ if (mt == SSL3_MT_ENCRYPTED_EXTENSIONS) {
+ st->hand_state = TLS_ST_CR_ENCRYPTED_EXTENSIONS;
+ return 1;
+ }
+ break;
+
+ case TLS_ST_CR_ENCRYPTED_EXTENSIONS:
+ if (s->hit) {
+ if (mt == SSL3_MT_FINISHED) {
+ st->hand_state = TLS_ST_CR_FINISHED;
+ return 1;
+ }
+ } else {
+ if (mt == SSL3_MT_CERTIFICATE_REQUEST) {
+ st->hand_state = TLS_ST_CR_CERT_REQ;
+ return 1;
+ }
+ if (mt == SSL3_MT_CERTIFICATE) {
+ st->hand_state = TLS_ST_CR_CERT;
+ return 1;
+ }
+ }
+ break;
+
+ case TLS_ST_CR_CERT_REQ:
+ if (mt == SSL3_MT_CERTIFICATE) {
+ st->hand_state = TLS_ST_CR_CERT;
+ return 1;
+ }
+ break;
+
+ case TLS_ST_CR_CERT:
+ if (mt == SSL3_MT_FINISHED) {
+ st->hand_state = TLS_ST_CR_FINISHED;
+ return 1;
+ }
+ break;
+
+ }
+
+ /* No valid transition found */
+ return 0;
+}
+