static int extend_handshake_buffer(SSL *ssl, size_t length) { if (!BUF_MEM_reserve(ssl->init_buf, length)) { return -1; } while (ssl->init_buf->length < length) { int ret = ssl3_read_bytes(ssl, SSL3_RT_HANDSHAKE, (uint8_t *)ssl->init_buf->data + ssl->init_buf->length, length - ssl->init_buf->length, 0); if (ret <= 0) { return ret; } ssl->init_buf->length += (size_t)ret; } return 1; }
int ssl3_read_change_cipher_spec(SSL *ssl) { uint8_t byte; int ret = ssl3_read_bytes(ssl, SSL3_RT_CHANGE_CIPHER_SPEC, &byte, 1 /* len */, 0 /* no peek */); if (ret <= 0) { return ret; } assert(ret == 1); if (ssl->s3->rrec.length != 0 || byte != SSL3_MT_CCS) { OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_CHANGE_CIPHER_SPEC); ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); return -1; } if (ssl->msg_callback != NULL) { ssl->msg_callback(0, ssl->version, SSL3_RT_CHANGE_CIPHER_SPEC, &byte, 1, ssl, ssl->msg_callback_arg); } return 1; }
void ssl3_read_close_notify(SSL *ssl) { ssl3_read_bytes(ssl, 0, NULL, 0, 0); }
int ssl3_read_app_data(SSL *ssl, uint8_t *buf, int len, int peek) { return ssl3_read_bytes(ssl, SSL3_RT_APPLICATION_DATA, buf, len, peek); }
int ssl3_read_app_data(SSL *ssl, uint8_t *buf, int len, int peek) { assert(!SSL_in_init(ssl)); return ssl3_read_bytes(ssl, SSL3_RT_APPLICATION_DATA, buf, len, peek); }
/* Obtain handshake message of message type |msg_type| (any if |msg_type| == -1), * maximum acceptable body length |max|. The first four bytes (msg_type and * length) are read in state |header_state|, the body is read in state * |body_state|. */ long ssl3_get_message(SSL *ssl, int header_state, int body_state, int msg_type, long max, enum ssl_hash_message_t hash_message, int *ok) { uint8_t *p; unsigned long l; long n; int al; if (ssl->s3->tmp.reuse_message) { /* A ssl_dont_hash_message call cannot be combined with reuse_message; the * ssl_dont_hash_message would have to have been applied to the previous * call. */ assert(hash_message == ssl_hash_message); ssl->s3->tmp.reuse_message = 0; if (msg_type >= 0 && ssl->s3->tmp.message_type != msg_type) { al = SSL_AD_UNEXPECTED_MESSAGE; OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE); goto f_err; } *ok = 1; ssl->state = body_state; ssl->init_msg = (uint8_t *)ssl->init_buf->data + 4; ssl->init_num = (int)ssl->s3->tmp.message_size; return ssl->init_num; } p = (uint8_t *)ssl->init_buf->data; if (ssl->state == header_state) { assert(ssl->init_num < 4); for (;;) { while (ssl->init_num < 4) { int bytes_read = ssl3_read_bytes( ssl, SSL3_RT_HANDSHAKE, &p[ssl->init_num], 4 - ssl->init_num, 0); if (bytes_read <= 0) { *ok = 0; return bytes_read; } ssl->init_num += bytes_read; } static const uint8_t kHelloRequest[4] = {SSL3_MT_HELLO_REQUEST, 0, 0, 0}; if (ssl->server || memcmp(p, kHelloRequest, sizeof(kHelloRequest)) != 0) { break; } /* The server may always send 'Hello Request' messages -- we are doing * a handshake anyway now, so ignore them if their format is correct. * Does not count for 'Finished' MAC. */ ssl->init_num = 0; if (ssl->msg_callback) { ssl->msg_callback(0, ssl->version, SSL3_RT_HANDSHAKE, p, 4, ssl, ssl->msg_callback_arg); } } /* ssl->init_num == 4 */ if (msg_type >= 0 && *p != msg_type) { al = SSL_AD_UNEXPECTED_MESSAGE; OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE); goto f_err; } ssl->s3->tmp.message_type = *(p++); n2l3(p, l); if (l > (unsigned long)max) { al = SSL_AD_ILLEGAL_PARAMETER; OPENSSL_PUT_ERROR(SSL, SSL_R_EXCESSIVE_MESSAGE_SIZE); goto f_err; } if (l && !BUF_MEM_grow_clean(ssl->init_buf, l + 4)) { OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); goto err; } ssl->s3->tmp.message_size = l; ssl->state = body_state; ssl->init_msg = (uint8_t *)ssl->init_buf->data + 4; ssl->init_num = 0; } /* next state (body_state) */ p = ssl->init_msg; n = ssl->s3->tmp.message_size - ssl->init_num; while (n > 0) { int bytes_read = ssl3_read_bytes(ssl, SSL3_RT_HANDSHAKE, &p[ssl->init_num], n, 0); if (bytes_read <= 0) { ssl->rwstate = SSL_READING; *ok = 0; return bytes_read; } ssl->init_num += bytes_read; n -= bytes_read; } /* Feed this message into MAC computation. */ if (hash_message == ssl_hash_message && !ssl3_hash_current_message(ssl)) { goto err; } if (ssl->msg_callback) { ssl->msg_callback(0, ssl->version, SSL3_RT_HANDSHAKE, ssl->init_buf->data, (size_t)ssl->init_num + 4, ssl, ssl->msg_callback_arg); } *ok = 1; return ssl->init_num; f_err: ssl3_send_alert(ssl, SSL3_AL_FATAL, al); err: *ok = 0; return -1; }
int ssl3_read_app_data(SSL *ssl, uint8_t *buf, int len, int peek) { assert(!SSL_in_init(ssl)); assert(ssl->s3->initial_handshake_complete); return ssl3_read_bytes(ssl, SSL3_RT_APPLICATION_DATA, buf, len, peek); }
/* Obtain handshake message of message type 'mt' (any if mt == -1), * maximum acceptable body length 'max'. * The first four bytes (msg_type and length) are read in state 'st1', * the body is read in state 'stn'. */ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) { unsigned char *p; unsigned long l; long n; int i,al; if (s->s3->tmp.reuse_message) { s->s3->tmp.reuse_message=0; if ((mt >= 0) && (s->s3->tmp.message_type != mt)) { al=SSL_AD_UNEXPECTED_MESSAGE; SSLerr(SSL_F_SSL3_GET_MESSAGE,SSL_R_UNEXPECTED_MESSAGE); goto f_err; } *ok=1; return((int)s->s3->tmp.message_size); } p=(unsigned char *)s->init_buf->data; if (s->state == st1) /* s->init_num < 4 */ { int skip_message; do { while (s->init_num < 4) { i=ssl3_read_bytes(s,SSL3_RT_HANDSHAKE,&p[s->init_num], 4 - s->init_num, 0); if (i <= 0) { s->rwstate=SSL_READING; *ok = 0; return i; } s->init_num+=i; } skip_message = 0; if (!s->server) if (p[0] == SSL3_MT_HELLO_REQUEST) /* The server may always send 'Hello Request' messages -- * we are doing a handshake anyway now, so ignore them * if their format is correct. Does not count for * 'Finished' MAC. */ if (p[1] == 0 && p[2] == 0 &&p[3] == 0) skip_message = 1; } while (skip_message); /* s->init_num == 4 */ if ((mt >= 0) && (*p != mt)) { al=SSL_AD_UNEXPECTED_MESSAGE; SSLerr(SSL_F_SSL3_GET_MESSAGE,SSL_R_UNEXPECTED_MESSAGE); goto f_err; } if ((mt < 0) && (*p == SSL3_MT_CLIENT_HELLO) && (st1 == SSL3_ST_SR_CERT_A) && (stn == SSL3_ST_SR_CERT_B)) { /* At this point we have got an MS SGC second client * hello (maybe we should always allow the client to * start a new handshake?). We need to restart the mac. * Don't increment {num,total}_renegotiations because * we have not completed the handshake. */ ssl3_init_finished_mac(s); } ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, 4); s->s3->tmp.message_type= *(p++); n2l3(p,l); if (l > (unsigned long)max) { al=SSL_AD_ILLEGAL_PARAMETER; SSLerr(SSL_F_SSL3_GET_MESSAGE,SSL_R_EXCESSIVE_MESSAGE_SIZE); goto f_err; } if (l && !BUF_MEM_grow(s->init_buf,(int)l)) { SSLerr(SSL_F_SSL3_GET_MESSAGE,ERR_R_BUF_LIB); goto err; } s->s3->tmp.message_size=l; s->state=stn; s->init_num=0; } /* next state (stn) */ p=(unsigned char *)s->init_buf->data; n=s->s3->tmp.message_size; while (n > 0) { i=ssl3_read_bytes(s,SSL3_RT_HANDSHAKE,&p[s->init_num],n,0); if (i <= 0) { s->rwstate=SSL_READING; *ok = 0; return i; } s->init_num += i; n -= i; } ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, s->init_num); *ok=1; return s->init_num; f_err: ssl3_send_alert(s,SSL3_AL_FATAL,al); err: *ok=0; return(-1); }