Several optimizations
[gnutls.git] / lib / gnutls_record.c
blob8066d39d336a0961633e963c1e06911ea9d7b773
1 /*
2 * Copyright (C) 2000,2001,2002 Nikos Mavroyanopoulos
4 * This file is part of GNUTLS.
6 * GNUTLS is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * GNUTLS is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
21 #include "gnutls_int.h"
22 #include "gnutls_errors.h"
23 #include "debug.h"
24 #include "gnutls_compress.h"
25 #include "gnutls_cipher.h"
26 #include "gnutls_buffers.h"
27 #include "gnutls_handshake.h"
28 #include "gnutls_hash_int.h"
29 #include "gnutls_cipher_int.h"
30 #include "gnutls_priority.h"
31 #include "gnutls_algorithms.h"
32 #include "gnutls_db.h"
33 #include "gnutls_auth_int.h"
34 #include "gnutls_num.h"
35 #include "gnutls_record.h"
36 #include "gnutls_datum.h"
37 #include "ext_max_record.h"
38 #include <gnutls_state.h>
39 #include <gnutls_alert.h>
40 #include <gnutls_dh.h>
42 /**
43 * gnutls_protocol_get_version - Returns the version of the currently used protocol
44 * @state: is a &GNUTLS_STATE structure.
46 * Returns the version of the currently used protocol.
48 **/
49 GNUTLS_Version gnutls_protocol_get_version(GNUTLS_STATE state) {
50 return state->security_parameters.version;
53 void _gnutls_set_current_version(GNUTLS_STATE state, GNUTLS_Version version) {
54 state->security_parameters.version = version;
57 /**
58 * gnutls_transport_set_lowat - Used to set the lowat value in order for select to check for pending data.
59 * @state: is a &GNUTLS_STATE structure.
60 * @num: is the low water value.
62 * Used to set the lowat value in order for select to check
63 * if there are pending data to socket buffer. Used only
64 * if you have changed the default low water value (default is 1).
65 * Normally you will not need that function.
66 * This function is only usefull if using berkeley style sockets.
67 * Otherwise it must be called and set lowat to zero.
69 **/
70 void gnutls_transport_set_lowat(GNUTLS_STATE state, int num) {
71 state->gnutls_internals.lowat = num;
74 /**
75 * gnutls_transport_set_ptr - Used to set first argument of the transport functions
76 * @state: is a &GNUTLS_STATE structure.
77 * @ptr: is the value.
79 * Used to set the first argument of the transport function (like PUSH and
80 * PULL). In berkeley style sockets this function will set the connection
81 * handle.
83 **/
84 void gnutls_transport_set_ptr(GNUTLS_STATE state, GNUTLS_TRANSPORT_PTR ptr) {
85 state->gnutls_internals.transport_ptr = ptr;
88 /**
89 * gnutls_transport_get_ptr - Used to return the first argument of the transport functions
90 * @state: is a &GNUTLS_STATE structure.
92 * Used to get the first argument of the transport function (like PUSH and
93 * PULL). This must have been set using gnutls_transport_set_ptr().
95 **/
96 GNUTLS_TRANSPORT_PTR gnutls_transport_get_ptr(GNUTLS_STATE state) {
97 return state->gnutls_internals.transport_ptr;
101 * gnutls_bye - This function terminates the current TLS/SSL connection.
102 * @state: is a &GNUTLS_STATE structure.
103 * @how: is an integer
105 * Terminates the current TLS/SSL connection. The connection should
106 * have been initiated using gnutls_handshake().
107 * 'how' should be one of GNUTLS_SHUT_RDWR, GNUTLS_SHUT_WR.
109 * In case of GNUTLS_SHUT_RDWR then the TLS connection gets terminated and
110 * further receives and sends will be disallowed. If the return
111 * value is zero you may continue using the connection.
112 * GNUTLS_SHUT_RDWR actually sends an alert containing a close request
113 * and waits for the peer to reply with the same message.
115 * In case of GNUTLS_SHUT_WR then the TLS connection gets terminated and
116 * further sends will be disallowed. In order to reuse the connection
117 * you should wait for an EOF from the peer.
118 * GNUTLS_SHUT_WR sends an alert containing a close request.
120 * This function may also return GNUTLS_E_AGAIN, or GNUTLS_E_INTERRUPTED.
123 int gnutls_bye( GNUTLS_STATE state, GNUTLS_CloseRequest how)
125 int ret = 0, ret2 = 0;
127 switch (STATE) {
128 case STATE0:
129 case STATE60:
130 if (STATE==STATE60) {
131 ret = _gnutls_io_write_flush( state);
132 } else {
133 ret = gnutls_alert_send( state, GNUTLS_AL_WARNING, GNUTLS_A_CLOSE_NOTIFY);
134 STATE = STATE60;
137 if (ret < 0)
138 return ret;
139 case STATE61:
140 if ( how == GNUTLS_SHUT_RDWR && ret >= 0) {
141 ret2 = gnutls_recv_int( state, GNUTLS_ALERT, -1, NULL, 0);
142 if (ret2 >= 0) state->gnutls_internals.may_read = 1;
144 STATE = STATE61;
146 if (ret2 < 0)
147 return ret2;
151 STATE = STATE0;
153 state->gnutls_internals.may_write = 1;
154 return 0;
157 inline
158 static void _gnutls_session_invalidate( GNUTLS_STATE state) {
159 state->gnutls_internals.valid_connection = VALID_FALSE;
163 inline
164 static void _gnutls_session_unresumable( GNUTLS_STATE state) {
165 state->gnutls_internals.resumable = RESUME_FALSE;
168 /* returns 0 if session is valid
170 inline
171 static int _gnutls_session_is_valid( GNUTLS_STATE state) {
172 if (state->gnutls_internals.valid_connection==VALID_FALSE)
173 return GNUTLS_E_INVALID_SESSION;
175 return 0;
178 static
179 ssize_t _gnutls_create_empty_record( GNUTLS_STATE state, ContentType type,
180 opaque** erecord)
182 int cipher_size;
183 int retval;
184 int data2send;
185 uint8 headers[5];
186 GNUTLS_Version lver;
188 *erecord = NULL;
191 if (type!=GNUTLS_APPLICATION_DATA ||
192 _gnutls_cipher_is_block( gnutls_cipher_get(state))!=CIPHER_BLOCK)
193 /* alert messages and stream ciphers
194 * do not need this protection
196 return 0;
198 headers[0]=type;
200 lver = gnutls_protocol_get_version(state);
201 if (lver==GNUTLS_VERSION_UNKNOWN) {
202 gnutls_assert();
203 return GNUTLS_E_INTERNAL_ERROR;
206 headers[1]=_gnutls_version_get_major( lver);
207 headers[2]=_gnutls_version_get_minor( lver);
209 data2send = 0;
211 cipher_size = _gnutls_encrypt( state, headers, RECORD_HEADER_SIZE, NULL, 0, erecord, type, 0);
212 if (cipher_size <= 0) {
213 gnutls_assert();
214 if (cipher_size==0) cipher_size = GNUTLS_E_ENCRYPTION_FAILED;
215 return cipher_size; /* error */
218 retval = cipher_size;
220 /* increase sequence number
222 if (uint64pp( &state->connection_state.write_sequence_number) != 0) {
223 _gnutls_session_invalidate( state);
224 gnutls_assert();
225 return GNUTLS_E_RECORD_LIMIT_REACHED;
228 return retval;
231 /* This function behave exactly like write(). The only difference is
232 * that it accepts, the gnutls_state and the ContentType of data to
233 * send (if called by the user the Content is specific)
234 * It is intended to transfer data, under the current state.
236 * Oct 30 2001: Removed capability to send data more than MAX_RECORD_SIZE.
237 * This makes the function much easier to read, and more error resistant
238 * (there were cases were the old function could mess everything up).
239 * --nmav
242 ssize_t gnutls_send_int( GNUTLS_STATE state, ContentType type, HandshakeType htype, const void *_data, size_t sizeofdata)
244 uint8 *cipher;
245 int cipher_size;
246 int retval, ret;
247 int data2send;
248 uint8 headers[5];
249 const uint8 *data=_data;
250 GNUTLS_Version lver;
251 int erecord_size = 0;
252 opaque* erecord = NULL;
254 if (sizeofdata == 0 || _data==NULL) {
255 gnutls_assert();
256 return GNUTLS_E_INVALID_PARAMETERS;
259 if (type!=GNUTLS_ALERT) /* alert messages are sent anyway */
260 if ( _gnutls_session_is_valid( state) || state->gnutls_internals.may_write != 0) {
261 return GNUTLS_E_INVALID_SESSION;
266 headers[0]=type;
268 lver = gnutls_protocol_get_version(state);
269 if (lver==GNUTLS_VERSION_UNKNOWN) {
270 gnutls_assert();
271 return GNUTLS_E_INTERNAL_ERROR;
274 headers[1]=_gnutls_version_get_major( lver);
275 headers[2]=_gnutls_version_get_minor( lver);
277 _gnutls_record_log( "REC: Sending Packet[%d] %s(%d) with length: %d\n",
278 (int) uint64touint32(&state->connection_state.write_sequence_number), _gnutls_packet2str(type), type, sizeofdata);
280 if ( sizeofdata > MAX_RECORD_SIZE)
281 data2send = MAX_RECORD_SIZE;
282 else
283 data2send = sizeofdata;
285 /* Only encrypt if we don't have data to send
286 * from the previous run. - probably interrupted.
288 if (state->gnutls_internals.record_send_buffer.size > 0) {
289 ret = _gnutls_io_write_flush( state);
290 if (ret > 0) cipher_size = ret;
291 else cipher_size = 0;
293 cipher = NULL;
295 retval = state->gnutls_internals.record_send_buffer_user_size;
296 } else {
298 /* Prepend our packet with an empty record. This is to
299 * avoid the recent CBC attacks.
301 /* if this protection has been disabled
303 if (state->gnutls_internals.cbc_protection_hack!=0) {
304 erecord_size =
305 _gnutls_create_empty_record( state, type, &erecord);
306 if (erecord_size < 0) {
307 gnutls_assert();
308 return erecord_size;
312 /* now proceed to packet encryption
314 cipher_size = _gnutls_encrypt( state, headers, RECORD_HEADER_SIZE, data, data2send, &cipher, type, 1);
315 if (cipher_size <= 0) {
316 gnutls_assert();
317 if (cipher_size==0) cipher_size = GNUTLS_E_ENCRYPTION_FAILED;
318 gnutls_free( erecord);
319 return cipher_size; /* error */
322 retval = data2send;
323 state->gnutls_internals.record_send_buffer_user_size = data2send;
325 /* increase sequence number
327 if (uint64pp( &state->connection_state.write_sequence_number) != 0) {
328 _gnutls_session_invalidate( state);
329 gnutls_assert();
330 gnutls_free( erecord);
331 return GNUTLS_E_RECORD_LIMIT_REACHED;
334 ret = _gnutls_io_write_buffered2( state, erecord, erecord_size, cipher, cipher_size);
335 gnutls_free( erecord);
336 gnutls_free( cipher);
339 if ( ret != cipher_size + erecord_size) {
340 if ( ret < 0 && gnutls_error_is_fatal(ret)==0) {
341 /* If we have sent any data then return
342 * that value.
344 gnutls_assert();
345 return ret;
348 if (ret > 0) {
349 gnutls_assert();
350 ret = GNUTLS_E_UNKNOWN_ERROR;
353 _gnutls_session_unresumable( state);
354 _gnutls_session_invalidate( state);
355 gnutls_assert();
356 return ret;
359 state->gnutls_internals.record_send_buffer_user_size = 0;
361 _gnutls_record_log( "REC: Sent Packet[%d] %s(%d) with length: %d\n",
362 (int) uint64touint32(&state->connection_state.write_sequence_number), _gnutls_packet2str(type), type, cipher_size);
364 return retval;
367 /* This function is to be called if the handshake was successfully
368 * completed. This sends a Change Cipher Spec packet to the peer.
370 ssize_t _gnutls_send_change_cipher_spec( GNUTLS_STATE state, int again)
372 opaque data[1] = { GNUTLS_TYPE_CHANGE_CIPHER_SPEC };
374 _gnutls_handshake_log( "REC: Sent ChangeCipherSpec\n");
376 if (again==0)
377 return gnutls_send_int( state, GNUTLS_CHANGE_CIPHER_SPEC, -1, data, 1);
378 else {
379 return _gnutls_io_write_flush( state);
383 static int _gnutls_check_recv_type( ContentType recv_type) {
384 switch( recv_type) {
385 case GNUTLS_CHANGE_CIPHER_SPEC:
386 case GNUTLS_ALERT:
387 case GNUTLS_HANDSHAKE:
388 case GNUTLS_APPLICATION_DATA:
389 return 0;
390 default:
391 gnutls_assert();
392 return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
398 /* Checks if there are pending data into the record buffers. If there are
399 * then it copies the data.
401 static int _gnutls_check_buffers( GNUTLS_STATE state, ContentType type, opaque* data, int sizeofdata) {
402 int ret = 0, ret2=0;
403 if ( (type == GNUTLS_APPLICATION_DATA || type == GNUTLS_HANDSHAKE) && _gnutls_record_buffer_get_size(type, state) > 0) {
404 ret = _gnutls_record_buffer_get(type, state, data, sizeofdata);
405 if (ret < 0) {
406 gnutls_assert();
407 return ret;
410 /* if the buffer just got empty */
411 if (_gnutls_record_buffer_get_size(type, state)==0) {
412 if ( (ret2=_gnutls_io_clear_peeked_data( state)) < 0) {
413 gnutls_assert();
414 return ret2;
418 return ret;
421 return 0;
425 #define CHECK_RECORD_VERSION
427 /* Checks the record headers and returns the length, version and
428 * content type.
430 static int _gnutls_check_record_headers( GNUTLS_STATE state, uint8 headers[RECORD_HEADER_SIZE], ContentType type,
431 HandshakeType htype, /*output*/ ContentType *recv_type, GNUTLS_Version *version, uint16 *length, uint16* header_size) {
433 /* Read the first two bytes to determine if this is a
434 * version 2 message
437 if ( htype == GNUTLS_CLIENT_HELLO && type==GNUTLS_HANDSHAKE && headers[0] > 127) {
439 /* if msb set and expecting handshake message
440 * it should be SSL 2 hello
442 *version = GNUTLS_VERSION_UNKNOWN; /* assume unknown version */
443 *length = (((headers[0] & 0x7f) << 8)) | headers[1];
445 /* SSL 2.0 headers */
446 *header_size = 2;
447 *recv_type = GNUTLS_HANDSHAKE; /* we accept only v2 client hello
450 /* in order to assist the handshake protocol.
451 * V2 compatibility is a mess.
453 state->gnutls_internals.v2_hello = *length;
455 _gnutls_record_log( "REC: V2 packet received. Length: %d\n", *length);
457 } else {
458 /* version 3.x
460 *recv_type = headers[0];
461 #ifdef CHECK_RECORD_VERSION
462 *version = _gnutls_version_get( headers[1], headers[2]);
463 #endif
465 *length = READuint16( &headers[3]);
468 return 0;
471 /* Here we check if the advertized version is the one we
472 * negotiated in the handshake.
474 inline
475 static int _gnutls_check_record_version( GNUTLS_STATE state, HandshakeType htype, GNUTLS_Version version)
477 #ifdef CHECK_RECORD_VERSION
478 if ( (htype!=GNUTLS_CLIENT_HELLO && htype!=GNUTLS_SERVER_HELLO) && gnutls_protocol_get_version(state) != version) {
479 gnutls_assert();
481 _gnutls_record_log( "REC: INVALID VERSION PACKET: (%d) %d.%d\n", htype, _gnutls_version_get_major(version), _gnutls_version_get_minor(version));
483 return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
485 #endif
487 return 0;
490 /* This function will check if the received record type is
491 * the one we actually expecting for.
493 static int _gnutls_record_check_type( GNUTLS_STATE state, ContentType recv_type,
494 ContentType type, HandshakeType htype, opaque* data, int data_size) {
496 int ret;
498 if ( (recv_type == type) && (type == GNUTLS_APPLICATION_DATA || type == GNUTLS_HANDSHAKE)) {
499 _gnutls_record_buffer_put(type, state, (void *) data, data_size);
500 } else {
501 switch (recv_type) {
502 case GNUTLS_ALERT:
504 _gnutls_record_log( "REC: Alert[%d|%d] - %s - was received\n", data[0], data[1], gnutls_alert_get_name((int)data[1]));
506 state->gnutls_internals.last_alert = data[1];
508 /* if close notify is received and
509 * the alert is not fatal
511 if (data[1] == GNUTLS_A_CLOSE_NOTIFY && data[0] != GNUTLS_AL_FATAL) {
512 /* If we have been expecting for an alert do
515 return GNUTLS_E_INT_RET_0; /* EOF */
516 } else {
518 /* if the alert is FATAL or WARNING
519 * return the apropriate message
522 gnutls_assert();
523 ret = GNUTLS_E_WARNING_ALERT_RECEIVED;
524 if (data[0] == GNUTLS_AL_FATAL) {
525 _gnutls_session_unresumable( state);
526 _gnutls_session_invalidate( state);
528 ret = GNUTLS_E_FATAL_ALERT_RECEIVED;
531 return ret;
533 break;
535 case GNUTLS_CHANGE_CIPHER_SPEC:
536 /* this packet is now handled above */
537 gnutls_assert();
539 return GNUTLS_E_UNEXPECTED_PACKET;
541 case GNUTLS_APPLICATION_DATA:
542 /* even if data is unexpected put it into the buffer */
543 if ( (ret=_gnutls_record_buffer_put(recv_type, state, (void *) data, data_size)) < 0) {
544 gnutls_assert();
545 return ret;
548 gnutls_assert();
550 /* the got_application data is only returned
551 * if expecting client hello (for rehandshake
552 * reasons). Otherwise it is an unexpected packet
554 if (htype == GNUTLS_CLIENT_HELLO && type==GNUTLS_HANDSHAKE)
555 return GNUTLS_E_GOT_APPLICATION_DATA;
556 else return GNUTLS_E_UNEXPECTED_PACKET;
558 break;
559 case GNUTLS_HANDSHAKE:
560 /* This is only legal if HELLO_REQUEST is received - and we are a client
562 if ( state->security_parameters.entity==GNUTLS_SERVER) {
563 gnutls_assert();
564 return GNUTLS_E_UNEXPECTED_PACKET;
566 gnutls_assert();
568 return _gnutls_recv_hello_request( state, data, data_size);
570 break;
571 default:
573 _gnutls_record_log( "REC: Received Unknown packet %d expecting %d\n", recv_type, type);
575 gnutls_assert();
576 return GNUTLS_E_UNKNOWN_ERROR;
580 return 0;
584 #define MAX_EMPTY_PACKETS_SEQUENCE 4
586 /* This function behave exactly like read(). The only difference is
587 * that it accepts, the gnutls_state and the ContentType of data to
588 * send (if called by the user the Content is Userdata only)
589 * It is intended to receive data, under the current state.
591 ssize_t gnutls_recv_int( GNUTLS_STATE state, ContentType type, HandshakeType htype, char *data, size_t sizeofdata)
593 uint8 *tmpdata;
594 int tmplen;
595 GNUTLS_Version version;
596 uint8 *headers;
597 ContentType recv_type;
598 uint16 length;
599 uint8 *ciphertext;
600 uint8 *recv_data;
601 int ret, ret2;
602 uint16 header_size;
603 int empty_packet = 0;
605 begin:
607 if (empty_packet > MAX_EMPTY_PACKETS_SEQUENCE) {
608 gnutls_assert();
609 return GNUTLS_E_TOO_MANY_EMPTY_PACKETS;
612 /* default headers for TLS 1.0
614 header_size = RECORD_HEADER_SIZE;
615 ret = 0;
617 if (sizeofdata == 0 || data == NULL) {
618 return GNUTLS_E_INVALID_PARAMETERS;
621 if ( _gnutls_session_is_valid(state)!=0 || state->gnutls_internals.may_read!=0) {
622 gnutls_assert();
623 return GNUTLS_E_INVALID_SESSION;
626 /* If we have enough data in the cache do not bother receiving
627 * a new packet. (in order to flush the cache)
629 ret = _gnutls_check_buffers( state, type, data, sizeofdata);
630 if (ret != 0)
631 return ret;
634 if ( (ret = _gnutls_io_read_buffered( state, &headers, header_size, -1)) != header_size) {
635 if (ret < 0 && gnutls_error_is_fatal(ret)==0) return ret;
637 _gnutls_session_invalidate( state);
638 if (type==GNUTLS_ALERT) {
639 gnutls_assert();
640 return 0; /* we were expecting close notify */
642 _gnutls_session_unresumable( state);
643 gnutls_assert();
644 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
647 if ( (ret=_gnutls_check_record_headers( state, headers, type, htype, &recv_type, &version, &length, &header_size)) < 0) {
648 gnutls_assert();
649 return ret;
652 /* Here we check if the Type of the received packet is
653 * ok.
655 if ( (ret = _gnutls_check_recv_type( recv_type)) < 0) {
657 gnutls_assert();
658 return ret;
661 /* Here we check if the advertized version is the one we
662 * negotiated in the handshake.
664 if ( (ret=_gnutls_check_record_version( state, htype, version)) < 0) {
665 gnutls_assert();
666 _gnutls_session_invalidate( state);
667 return ret;
670 _gnutls_record_log( "REC: Expected Packet[%d] %s(%d) with length: %d\n",
671 (int) uint64touint32(&state->connection_state.read_sequence_number), _gnutls_packet2str(type), type, sizeofdata);
672 _gnutls_record_log( "REC: Received Packet[%d] %s(%d) with length: %d\n",
673 (int) uint64touint32(&state->connection_state.read_sequence_number), _gnutls_packet2str(recv_type), recv_type, length);
675 if (length > MAX_RECV_SIZE) {
677 _gnutls_record_log( "REC: FATAL ERROR: Received packet with length: %d\n", length);
679 _gnutls_session_unresumable( state);
680 _gnutls_session_invalidate( state);
681 gnutls_assert();
682 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
685 /* check if we have that data into buffer.
687 if ( (ret = _gnutls_io_read_buffered( state, &recv_data, header_size+length, recv_type)) != length+header_size) {
688 if (ret<0 && gnutls_error_is_fatal(ret)==0) return ret;
690 _gnutls_session_unresumable( state);
691 _gnutls_session_invalidate( state);
692 gnutls_assert();
693 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
696 /* ok now we are sure that we can read all the data - so
697 * move on !
699 _gnutls_io_clear_read_buffer( state);
700 ciphertext = &recv_data[header_size];
702 /* decrypt the data we got
704 tmplen = _gnutls_decrypt( state, ciphertext, length, &tmpdata, recv_type);
705 if (tmplen < 0) {
706 _gnutls_session_unresumable( state);
707 _gnutls_session_invalidate( state);
708 gnutls_assert();
709 return tmplen;
712 /* Check if this is a CHANGE_CIPHER_SPEC
714 if (type == GNUTLS_CHANGE_CIPHER_SPEC && recv_type == GNUTLS_CHANGE_CIPHER_SPEC) {
716 _gnutls_record_log( "REC: ChangeCipherSpec Packet was received\n");
718 if (tmplen!=sizeofdata) { /* sizeofdata should be 1 */
719 gnutls_assert();
720 gnutls_free(tmpdata);
721 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
723 memcpy( data, tmpdata, sizeofdata);
724 gnutls_free(tmpdata);
726 return tmplen;
729 _gnutls_record_log( "REC: Decrypted Packet[%d] %s(%d) with length: %d\n",
730 (int) uint64touint32(&state->connection_state.read_sequence_number), _gnutls_packet2str(recv_type), recv_type, tmplen);
732 /* increase sequence number */
733 if (uint64pp( &state->connection_state.read_sequence_number)!=0) {
734 _gnutls_session_invalidate( state);
735 gnutls_free(tmpdata);
736 gnutls_assert();
737 return GNUTLS_E_RECORD_LIMIT_REACHED;
740 if ( (ret=_gnutls_record_check_type( state, recv_type, type, htype, tmpdata, tmplen)) < 0) {
741 gnutls_free( tmpdata);
743 if (ret==GNUTLS_E_INT_RET_0) return 0;
745 gnutls_assert();
746 return ret;
748 gnutls_free( tmpdata);
750 /* Get Application data from buffer */
751 if ((type == GNUTLS_APPLICATION_DATA || type == GNUTLS_HANDSHAKE) && (recv_type == type)) {
753 ret = _gnutls_record_buffer_get(type, state, data, sizeofdata);
754 if (ret < 0) {
755 gnutls_assert();
756 return ret;
759 /* if the buffer just got empty */
760 if (_gnutls_record_buffer_get_size(type, state)==0) {
761 if ( (ret2 = _gnutls_io_clear_peeked_data( state)) < 0) {
762 gnutls_assert();
763 return ret2;
767 } else {
768 gnutls_assert();
769 ret = GNUTLS_E_UNEXPECTED_PACKET;
770 /* we didn't get what we wanted to
774 /* TLS 1.0 CBC protection. Read the next fragment.
776 if (ret==0) {
777 empty_packet++;
778 goto begin;
781 return ret;
785 /* Taken from libgcrypt */
787 static const char*
788 parse_version_number( const char *s, int *number )
790 int val = 0;
792 if( *s == '0' && isdigit(s[1]) )
793 return NULL; /* leading zeros are not allowed */
794 for ( ; isdigit(*s); s++ ) {
795 val *= 10;
796 val += *s - '0';
798 *number = val;
799 return val < 0? NULL : s;
803 static const char *
804 parse_version_string( const char *s, int *major, int *minor, int *micro )
806 s = parse_version_number( s, major );
807 if( !s || *s != '.' )
808 return NULL;
809 s++;
810 s = parse_version_number( s, minor );
811 if( !s || *s != '.' )
812 return NULL;
813 s++;
814 s = parse_version_number( s, micro );
815 if( !s )
816 return NULL;
817 return s; /* patchlevel */
820 /****************
821 * Check that the the version of the library is at minimum the requested one
822 * and return the version string; return NULL if the condition is not
823 * satisfied. If a NULL is passed to this function, no check is done,
824 * but the version string is simply returned.
826 const char *
827 gnutls_check_version( const char *req_version )
829 const char *ver = GNUTLS_VERSION;
830 int my_major, my_minor, my_micro;
831 int rq_major, rq_minor, rq_micro;
832 const char *my_plvl, *rq_plvl;
834 if ( !req_version )
835 return ver;
837 my_plvl = parse_version_string( ver, &my_major, &my_minor, &my_micro );
838 if ( !my_plvl )
839 return NULL; /* very strange our own version is bogus */
840 rq_plvl = parse_version_string( req_version, &rq_major, &rq_minor,
841 &rq_micro );
842 if ( !rq_plvl )
843 return NULL; /* req version string is invalid */
845 if ( my_major > rq_major
846 || (my_major == rq_major && my_minor > rq_minor)
847 || (my_major == rq_major && my_minor == rq_minor
848 && my_micro > rq_micro)
849 || (my_major == rq_major && my_minor == rq_minor
850 && my_micro == rq_micro
851 && strcmp( my_plvl, rq_plvl ) >= 0) ) {
852 return ver;
854 return NULL;
859 * gnutls_record_send - sends to the peer the specified data
860 * @state: is a &GNUTLS_STATE structure.
861 * @data: contains the data to send
862 * @sizeofdata: is the length of the data
864 * This function has the similar semantics to write(). The only
865 * difference is that is accepts a GNUTLS state, and uses different
866 * error codes.
868 * If the EINTR is returned by the internal push function (write())
869 * then GNUTLS_E_INTERRUPTED, will be returned. If GNUTLS_E_INTERRUPTED or
870 * GNUTLS_E_AGAIN is returned you must call this function again, with the
871 * same parameters. Otherwise the write operation will be
872 * corrupted and the connection will be terminated.
874 * Returns the number of bytes sent, or a negative error code.
877 ssize_t gnutls_record_send( GNUTLS_STATE state, const void *data, size_t sizeofdata) {
878 return gnutls_send_int( state, GNUTLS_APPLICATION_DATA, -1, data, sizeofdata);
882 * gnutls_record_recv - reads data from the TLS record protocol
883 * @state: is a &GNUTLS_STATE structure.
884 * @data: contains the data to send
885 * @sizeofdata: is the length of the data
887 * This function has the similar semantics to read(). The only
888 * difference is that is accepts a GNUTLS state.
889 * Also returns the number of bytes received, zero on EOF, but
890 * a negative error code in case of an error.
892 * If this function returns GNUTLS_E_REHANDSHAKE, then you may
893 * ignore this message, send an alert containing NO_RENEGOTIATION,
894 * or perform a handshake again. (only a client may receive this message)
897 ssize_t gnutls_record_recv( GNUTLS_STATE state, void *data, size_t sizeofdata) {
898 return gnutls_recv_int( state, GNUTLS_APPLICATION_DATA, -1, data, sizeofdata);
902 * gnutls_record_get_max_size - returns the maximum record size
903 * @state: is a &GNUTLS_STATE structure.
905 * This function returns the maximum record size in this connection.
906 * The maximum record size is negotiated by the client after the
907 * first handshake message.
910 size_t gnutls_record_get_max_size( GNUTLS_STATE state) {
911 return state->security_parameters.max_record_size;
916 * gnutls_record_set_max_size - sets the maximum record size
917 * @state: is a &GNUTLS_STATE structure.
918 * @size: is the new size
920 * This function sets the maximum record size in this connection.
921 * This property can only be set to clients. The server may
922 * choose not to accept the requested size.
924 * Acceptable values are 2^9, 2^10, 2^11 and 2^12.
925 * Returns 0 on success. The requested record size does not
926 * get in effect immediately. It will be used after a successful
927 * handshake.
929 * This function uses a TLS extension called 'max record size'.
930 * Not all TLS implementations use or even understand this extension.
933 ssize_t gnutls_record_set_max_size( GNUTLS_STATE state, size_t size) {
934 ssize_t new_size;
936 if (state->security_parameters.entity==GNUTLS_SERVER)
937 return GNUTLS_E_INVALID_REQUEST;
939 new_size = _gnutls_mre_record2num( size);
941 if (new_size < 0) {
942 gnutls_assert();
943 return new_size;
946 state->gnutls_internals.proposed_record_size = size;
948 return 0;