int ssl3_read_app_data(SSL *ssl, int *out_got_handshake, uint8_t *buf, int len, int peek) { assert(!SSL_in_init(ssl)); assert(ssl->s3->initial_handshake_complete); *out_got_handshake = 0; SSL3_RECORD *rr = &ssl->s3->rrec; for (;;) { /* A previous iteration may have read a partial handshake message. Do not * allow more app data in that case. */ int has_hs_data = ssl->init_buf != NULL && ssl->init_buf->length > 0; /* Get new packet if necessary. */ if (rr->length == 0 && !has_hs_data) { int ret = ssl3_get_record(ssl); if (ret <= 0) { return ret; } } if (has_hs_data || rr->type == SSL3_RT_HANDSHAKE) { /* Post-handshake data prior to TLS 1.3 is always renegotiation, which we * never accept as a server. Otherwise |ssl3_get_message| will send * |SSL_R_EXCESSIVE_MESSAGE_SIZE|. */ if (ssl->server && ssl3_protocol_version(ssl) < TLS1_3_VERSION) { ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_NO_RENEGOTIATION); OPENSSL_PUT_ERROR(SSL, SSL_R_NO_RENEGOTIATION); return -1; } /* Parse post-handshake handshake messages. */ int ret = ssl3_get_message(ssl, -1, ssl_dont_hash_message); if (ret <= 0) { return ret; } *out_got_handshake = 1; return -1; } if (rr->type != SSL3_RT_APPLICATION_DATA) { OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); return -1; } if (rr->length != 0) { return consume_record(ssl, buf, len, peek); } /* Discard empty records and loop again. */ } }
int ssl3_get_finished(SSL *s, int a, int b) { int al,i,ok; long n; unsigned char *p; /* the mac has already been generated when we received the * change cipher spec message and is in s->s3->tmp.peer_finish_md */ n=ssl3_get_message(s, a, b, SSL3_MT_FINISHED, 64, /* should actually be 36+4 :-) */ &ok); if (!ok) return((int)n); /* If this occurs, we have missed a message */ if (!s->s3->change_cipher_spec) { al=SSL_AD_UNEXPECTED_MESSAGE; SSLerr(SSL_F_SSL3_GET_FINISHED,SSL_R_GOT_A_FIN_BEFORE_A_CCS); goto f_err; } s->s3->change_cipher_spec=0; p = (unsigned char *)s->init_buf->data; i = s->s3->tmp.peer_finish_md_len; if (i != n) { al=SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_FINISHED,SSL_R_BAD_DIGEST_LENGTH); goto f_err; } if (memcmp(p, s->s3->tmp.peer_finish_md, i) != 0) { al=SSL_AD_DECRYPT_ERROR; SSLerr(SSL_F_SSL3_GET_FINISHED,SSL_R_DIGEST_CHECK_FAILED); goto f_err; } return(1); f_err: ssl3_send_alert(s,SSL3_AL_FATAL,al); return(0); }