Add.
[gnutls.git] / lib / gnutls_record.c
blob62df8715174d32eef232f3a976fdb9090aafcbf5
1 /*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GNUTLS.
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
25 /* Functions that are record layer specific, are included in this file.
28 #include "gnutls_int.h"
29 #include "gnutls_errors.h"
30 #include "debug.h"
31 #include "gnutls_compress.h"
32 #include "gnutls_cipher.h"
33 #include "gnutls_buffers.h"
34 #include "gnutls_handshake.h"
35 #include "gnutls_hash_int.h"
36 #include "gnutls_cipher_int.h"
37 #include "gnutls_algorithms.h"
38 #include "gnutls_db.h"
39 #include "gnutls_auth.h"
40 #include "gnutls_num.h"
41 #include "gnutls_record.h"
42 #include "gnutls_datum.h"
43 #include "ext_max_record.h"
44 #include <gnutls_state.h>
45 #include <gnutls_dh.h>
47 /**
48 * gnutls_protocol_get_version - Returns the version of the currently used protocol
49 * @session: is a #gnutls_session_t structure.
51 * Get TLS version, a #gnutls_protocol_t value.
53 * Returns: the version of the currently used protocol.
54 **/
55 gnutls_protocol_t
56 gnutls_protocol_get_version (gnutls_session_t session)
58 return session->security_parameters.version;
61 void
62 _gnutls_set_current_version (gnutls_session_t session,
63 gnutls_protocol_t version)
65 session->security_parameters.version = version;
68 /**
69 * gnutls_transport_set_lowat - Used to set the lowat value in order for select to check for pending data.
70 * @session: is a #gnutls_session_t structure.
71 * @num: is the low water value.
73 * Used to set the lowat value in order for select to check if there
74 * are pending data to socket buffer. Used only if you have changed
75 * the default low water value (default is 1). Normally you will not
76 * need that function. This function is only useful if using
77 * berkeley style sockets. Otherwise it must be called and set lowat
78 * to zero.
79 **/
80 void
81 gnutls_transport_set_lowat (gnutls_session_t session, int num)
83 session->internals.lowat = num;
86 /**
87 * gnutls_record_disable_padding - Used to disabled padding in TLS 1.0 and above
88 * @session: is a #gnutls_session_t structure.
90 * Used to disabled padding in TLS 1.0 and above. Normally you do
91 * not need to use this function, but there are buggy clients that
92 * complain if a server pads the encrypted data. This of course will
93 * disable protection against statistical attacks on the data.
95 * Normally only servers that require maximum compatibility with everything
96 * out there, need to call this function.
97 **/
98 void
99 gnutls_record_disable_padding (gnutls_session_t session)
101 session->internals.priorities.no_padding = 1;
105 * gnutls_transport_set_ptr - Used to set first argument of the transport functions
106 * @session: is a #gnutls_session_t structure.
107 * @ptr: is the value.
109 * Used to set the first argument of the transport function (like
110 * PUSH and PULL). In berkeley style sockets this function will set
111 * the connection handle.
113 void
114 gnutls_transport_set_ptr (gnutls_session_t session,
115 gnutls_transport_ptr_t ptr)
117 session->internals.transport_recv_ptr = ptr;
118 session->internals.transport_send_ptr = ptr;
123 * gnutls_transport_set_ptr2 - Used to set first argument of the transport functions
124 * @session: is a #gnutls_session_t structure.
125 * @recv_ptr: is the value for the pull function
126 * @send_ptr: is the value for the push function
128 * Used to set the first argument of the transport function (like
129 * PUSH and PULL). In berkeley style sockets this function will set
130 * the connection handle. With this function you can use two
131 * different pointers for receiving and sending.
133 void
134 gnutls_transport_set_ptr2 (gnutls_session_t session,
135 gnutls_transport_ptr_t recv_ptr,
136 gnutls_transport_ptr_t send_ptr)
138 session->internals.transport_send_ptr = send_ptr;
139 session->internals.transport_recv_ptr = recv_ptr;
143 * gnutls_transport_get_ptr - Used to return the first argument of the transport functions
144 * @session: is a #gnutls_session_t structure.
146 * Used to get the first argument of the transport function (like
147 * PUSH and PULL). This must have been set using
148 * gnutls_transport_set_ptr().
150 * Returns: first argument of the transport function.
152 gnutls_transport_ptr_t
153 gnutls_transport_get_ptr (gnutls_session_t session)
155 return session->internals.transport_recv_ptr;
159 * gnutls_transport_get_ptr2 - Used to return the first argument of the transport functions
160 * @session: is a #gnutls_session_t structure.
161 * @recv_ptr: will hold the value for the pull function
162 * @send_ptr: will hold the value for the push function
164 * Used to get the arguments of the transport functions (like PUSH
165 * and PULL). These should have been set using
166 * gnutls_transport_set_ptr2().
168 void
169 gnutls_transport_get_ptr2 (gnutls_session_t session,
170 gnutls_transport_ptr_t * recv_ptr,
171 gnutls_transport_ptr_t * send_ptr)
174 *recv_ptr = session->internals.transport_recv_ptr;
175 *send_ptr = session->internals.transport_send_ptr;
179 * gnutls_bye - terminate the current TLS/SSL connection.
180 * @session: is a #gnutls_session_t structure.
181 * @how: is an integer
183 * Terminates the current TLS/SSL connection. The connection should
184 * have been initiated using gnutls_handshake(). @how should be one
185 * of %GNUTLS_SHUT_RDWR, %GNUTLS_SHUT_WR.
187 * In case of %GNUTLS_SHUT_RDWR then the TLS connection gets
188 * terminated and further receives and sends will be disallowed. If
189 * the return value is zero you may continue using the connection.
190 * %GNUTLS_SHUT_RDWR actually sends an alert containing a close
191 * request and waits for the peer to reply with the same message.
193 * In case of %GNUTLS_SHUT_WR then the TLS connection gets terminated
194 * and further sends will be disallowed. In order to reuse the
195 * connection you should wait for an EOF from the peer.
196 * %GNUTLS_SHUT_WR sends an alert containing a close request.
198 * Note that not all implementations will properly terminate a TLS
199 * connection. Some of them, usually for performance reasons, will
200 * terminate only the underlying transport layer, thus causing a
201 * transmission error to the peer. This error cannot be
202 * distinguished from a malicious party prematurely terminating the
203 * session, thus this behavior is not recommended.
205 * This function may also return %GNUTLS_E_AGAIN or
206 * %GNUTLS_E_INTERRUPTED; cf. gnutls_record_get_direction().
208 * Returns: %GNUTLS_E_SUCCESS on success, or an error code, see
209 * function documentation for entire semantics.
212 gnutls_bye (gnutls_session_t session, gnutls_close_request_t how)
214 int ret = 0;
216 switch (STATE)
218 case STATE0:
219 case STATE60:
220 ret = _gnutls_io_write_flush (session);
221 STATE = STATE60;
222 if (ret < 0)
224 gnutls_assert ();
225 return ret;
228 case STATE61:
229 ret =
230 gnutls_alert_send (session, GNUTLS_AL_WARNING, GNUTLS_A_CLOSE_NOTIFY);
231 STATE = STATE61;
232 if (ret < 0)
234 gnutls_assert ();
235 return ret;
238 case STATE62:
239 STATE = STATE62;
240 if (how == GNUTLS_SHUT_RDWR)
244 _gnutls_io_clear_peeked_data (session);
245 ret = _gnutls_recv_int (session, GNUTLS_ALERT, -1, NULL, 0);
247 while (ret == GNUTLS_E_GOT_APPLICATION_DATA);
249 if (ret >= 0)
250 session->internals.may_not_read = 1;
252 if (ret < 0)
254 gnutls_assert ();
255 return ret;
258 STATE = STATE62;
260 break;
261 default:
262 gnutls_assert ();
263 return GNUTLS_E_INTERNAL_ERROR;
266 STATE = STATE0;
268 session->internals.may_not_write = 1;
269 return 0;
272 inline static void
273 session_invalidate (gnutls_session_t session)
275 session->internals.valid_connection = VALID_FALSE;
279 inline static void
280 session_unresumable (gnutls_session_t session)
282 session->internals.resumable = RESUME_FALSE;
285 /* returns 0 if session is valid
287 inline static int
288 session_is_valid (gnutls_session_t session)
290 if (session->internals.valid_connection == VALID_FALSE)
291 return GNUTLS_E_INVALID_SESSION;
293 return 0;
296 /* Copies the record version into the headers. The
297 * version must have 2 bytes at least.
299 inline static void
300 copy_record_version (gnutls_session_t session,
301 gnutls_handshake_description_t htype, opaque version[2])
303 gnutls_protocol_t lver;
305 if (htype != GNUTLS_HANDSHAKE_CLIENT_HELLO
306 || session->internals.default_record_version[0] == 0)
308 lver = gnutls_protocol_get_version (session);
310 version[0] = _gnutls_version_get_major (lver);
311 version[1] = _gnutls_version_get_minor (lver);
313 else
315 version[0] = session->internals.default_record_version[0];
316 version[1] = session->internals.default_record_version[1];
320 /* This function behaves exactly like write(). The only difference is
321 * that it accepts, the gnutls_session_t and the content_type_t of data to
322 * send (if called by the user the Content is specific)
323 * It is intended to transfer data, under the current session.
325 * Oct 30 2001: Removed capability to send data more than MAX_RECORD_SIZE.
326 * This makes the function much easier to read, and more error resistant
327 * (there were cases were the old function could mess everything up).
328 * --nmav
330 * This function may accept a NULL pointer for data, and 0 for size, if
331 * and only if the previous send was interrupted for some reason.
334 ssize_t
335 _gnutls_send_int (gnutls_session_t session, content_type_t type,
336 gnutls_handshake_description_t htype, const void *_data,
337 size_t sizeofdata)
339 uint8_t *cipher;
340 int cipher_size;
341 int retval, ret;
342 int data2send_size;
343 uint8_t headers[5];
344 const uint8_t *data = _data;
346 /* Do not allow null pointer if the send buffer is empty.
347 * If the previous send was interrupted then a null pointer is
348 * ok, and means to resume.
350 if (session->internals.record_send_buffer.length == 0 &&
351 (sizeofdata == 0 && _data == NULL))
353 gnutls_assert ();
354 return GNUTLS_E_INVALID_REQUEST;
357 if (type != GNUTLS_ALERT) /* alert messages are sent anyway */
358 if (session_is_valid (session) || session->internals.may_not_write != 0)
360 gnutls_assert ();
361 return GNUTLS_E_INVALID_SESSION;
364 headers[0] = type;
366 /* Use the default record version, if it is
367 * set.
369 copy_record_version (session, htype, &headers[1]);
372 _gnutls_record_log
373 ("REC[%p]: Sending Packet[%d] %s(%d) with length: %d\n", session,
374 (int) _gnutls_uint64touint32 (&session->connection_state.
375 write_sequence_number),
376 _gnutls_packet2str (type), type, (int)sizeofdata);
378 if (sizeofdata > MAX_RECORD_SEND_SIZE)
379 data2send_size = MAX_RECORD_SEND_SIZE;
380 else
381 data2send_size = sizeofdata;
383 /* Only encrypt if we don't have data to send
384 * from the previous run. - probably interrupted.
386 if (session->internals.record_send_buffer.length > 0)
388 ret = _gnutls_io_write_flush (session);
389 if (ret > 0)
390 cipher_size = ret;
391 else
392 cipher_size = 0;
394 cipher = NULL;
396 retval = session->internals.record_send_buffer_user_size;
398 else
401 /* now proceed to packet encryption
403 cipher_size = data2send_size + MAX_RECORD_OVERHEAD;
404 cipher = gnutls_malloc (cipher_size);
405 if (cipher == NULL)
407 gnutls_assert ();
408 return GNUTLS_E_MEMORY_ERROR;
411 cipher_size =
412 _gnutls_encrypt (session, headers, RECORD_HEADER_SIZE, data,
413 data2send_size, cipher, cipher_size, type,
414 (session->internals.priorities.no_padding ==
415 0) ? 1 : 0);
416 if (cipher_size <= 0)
418 gnutls_assert ();
419 if (cipher_size == 0)
420 cipher_size = GNUTLS_E_ENCRYPTION_FAILED;
421 gnutls_free (cipher);
422 return cipher_size; /* error */
425 retval = data2send_size;
426 session->internals.record_send_buffer_user_size = data2send_size;
428 /* increase sequence number
430 if (_gnutls_uint64pp
431 (&session->connection_state.write_sequence_number) != 0)
433 session_invalidate (session);
434 gnutls_assert ();
435 gnutls_free (cipher);
436 return GNUTLS_E_RECORD_LIMIT_REACHED;
439 ret = _gnutls_io_write_buffered (session, cipher, cipher_size);
440 gnutls_free (cipher);
443 if (ret != cipher_size)
445 if (ret < 0 && gnutls_error_is_fatal (ret) == 0)
447 /* If we have sent any data then just return
448 * the error value. Do not invalidate the session.
450 gnutls_assert ();
451 return ret;
454 if (ret > 0)
456 gnutls_assert ();
457 ret = GNUTLS_E_INTERNAL_ERROR;
459 session_unresumable (session);
460 session->internals.may_not_write = 1;
461 gnutls_assert ();
462 return ret;
465 session->internals.record_send_buffer_user_size = 0;
467 _gnutls_record_log ("REC[%p]: Sent Packet[%d] %s(%d) with length: %d\n",
468 session,
469 (int)
470 _gnutls_uint64touint32
471 (&session->connection_state.write_sequence_number),
472 _gnutls_packet2str (type), type, cipher_size);
474 return retval;
477 /* This function is to be called if the handshake was successfully
478 * completed. This sends a Change Cipher Spec packet to the peer.
480 ssize_t
481 _gnutls_send_change_cipher_spec (gnutls_session_t session, int again)
483 static const opaque data[1] = { GNUTLS_TYPE_CHANGE_CIPHER_SPEC };
485 _gnutls_handshake_log ("REC[%p]: Sent ChangeCipherSpec\n", session);
487 if (again == 0)
488 return _gnutls_send_int (session, GNUTLS_CHANGE_CIPHER_SPEC, -1, data, 1);
489 else
491 return _gnutls_io_write_flush (session);
495 inline static int
496 check_recv_type (content_type_t recv_type)
498 switch (recv_type)
500 case GNUTLS_CHANGE_CIPHER_SPEC:
501 case GNUTLS_ALERT:
502 case GNUTLS_HANDSHAKE:
503 case GNUTLS_APPLICATION_DATA:
504 case GNUTLS_INNER_APPLICATION:
505 return 0;
506 default:
507 gnutls_assert ();
508 return GNUTLS_A_UNEXPECTED_MESSAGE;
514 /* Checks if there are pending data in the record buffers. If there are
515 * then it copies the data.
517 static int
518 check_buffers (gnutls_session_t session, content_type_t type,
519 opaque * data, int sizeofdata)
521 if ((type == GNUTLS_APPLICATION_DATA ||
522 type == GNUTLS_HANDSHAKE ||
523 type == GNUTLS_INNER_APPLICATION)
524 && _gnutls_record_buffer_get_size (type, session) > 0)
526 int ret, ret2;
527 ret = _gnutls_record_buffer_get (type, session, data, sizeofdata);
528 if (ret < 0)
530 gnutls_assert ();
531 return ret;
534 /* if the buffer just got empty */
535 if (_gnutls_record_buffer_get_size (type, session) == 0)
537 if ((ret2 = _gnutls_io_clear_peeked_data (session)) < 0)
539 gnutls_assert ();
540 return ret2;
544 return ret;
547 return 0;
551 /* Checks the record headers and returns the length, version and
552 * content type.
554 static int
555 record_check_headers (gnutls_session_t session,
556 uint8_t headers[RECORD_HEADER_SIZE],
557 content_type_t type,
558 gnutls_handshake_description_t htype,
559 /*output */ content_type_t * recv_type,
560 opaque version[2], uint16_t * length,
561 uint16_t * header_size)
564 /* Read the first two bytes to determine if this is a
565 * version 2 message
568 if (htype == GNUTLS_HANDSHAKE_CLIENT_HELLO && type == GNUTLS_HANDSHAKE
569 && headers[0] > 127)
572 /* if msb set and expecting handshake message
573 * it should be SSL 2 hello
575 version[0] = 3; /* assume SSL 3.0 */
576 version[1] = 0;
578 *length = (((headers[0] & 0x7f) << 8)) | headers[1];
580 /* SSL 2.0 headers */
581 *header_size = 2;
582 *recv_type = GNUTLS_HANDSHAKE; /* we accept only v2 client hello
585 /* in order to assist the handshake protocol.
586 * V2 compatibility is a mess.
588 session->internals.v2_hello = *length;
590 _gnutls_record_log ("REC[%p]: V2 packet received. Length: %d\n",
591 session, *length);
594 else
596 /* version 3.x
598 *recv_type = headers[0];
599 version[0] = headers[1];
600 version[1] = headers[2];
602 /* No DECR_LEN, since headers has enough size.
604 *length = _gnutls_read_uint16 (&headers[3]);
607 return 0;
610 /* Here we check if the advertized version is the one we
611 * negotiated in the handshake.
613 inline static int
614 record_check_version (gnutls_session_t session,
615 gnutls_handshake_description_t htype, opaque version[2])
617 if (htype == GNUTLS_HANDSHAKE_CLIENT_HELLO)
619 /* Reject hello packets with major version higher than 3.
621 if (version[0] > 3)
623 gnutls_assert ();
624 _gnutls_record_log
625 ("REC[%p]: INVALID VERSION PACKET: (%d) %d.%d\n", session,
626 htype, version[0], version[1]);
627 return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
630 else if (htype != GNUTLS_HANDSHAKE_SERVER_HELLO &&
631 gnutls_protocol_get_version (session) !=
632 _gnutls_version_get (version[0], version[1]))
634 /* Reject record packets that have a different version than the
635 * one negotiated. Note that this version is not protected by any
636 * mac. I don't really think that this check serves any purpose.
638 gnutls_assert ();
639 _gnutls_record_log ("REC[%p]: INVALID VERSION PACKET: (%d) %d.%d\n",
640 session, htype, version[0], version[1]);
642 return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
645 return 0;
648 /* This function will check if the received record type is
649 * the one we actually expect.
651 static int
652 record_check_type (gnutls_session_t session,
653 content_type_t recv_type, content_type_t type,
654 gnutls_handshake_description_t htype, opaque * data,
655 int data_size)
658 int ret;
660 if ((recv_type == type)
661 && (type == GNUTLS_APPLICATION_DATA ||
662 type == GNUTLS_HANDSHAKE || type == GNUTLS_INNER_APPLICATION))
664 _gnutls_record_buffer_put (type, session, (void *) data, data_size);
666 else
668 switch (recv_type)
670 case GNUTLS_ALERT:
672 _gnutls_record_log
673 ("REC[%p]: Alert[%d|%d] - %s - was received\n", session,
674 data[0], data[1], gnutls_alert_get_name ((int) data[1]));
676 session->internals.last_alert = data[1];
678 /* if close notify is received and
679 * the alert is not fatal
681 if (data[1] == GNUTLS_A_CLOSE_NOTIFY && data[0] != GNUTLS_AL_FATAL)
683 /* If we have been expecting for an alert do
685 session->internals.read_eof = 1;
686 return GNUTLS_E_INT_RET_0; /* EOF */
688 else
691 /* if the alert is FATAL or WARNING
692 * return the apropriate message
695 gnutls_assert ();
696 ret = GNUTLS_E_WARNING_ALERT_RECEIVED;
697 if (data[0] == GNUTLS_AL_FATAL)
699 session_unresumable (session);
700 session_invalidate (session);
701 ret = GNUTLS_E_FATAL_ALERT_RECEIVED;
704 return ret;
706 break;
708 case GNUTLS_CHANGE_CIPHER_SPEC:
709 /* this packet is now handled in the recv_int()
710 * function
712 gnutls_assert ();
714 return GNUTLS_E_UNEXPECTED_PACKET;
716 case GNUTLS_APPLICATION_DATA:
717 /* even if data is unexpected put it into the buffer */
718 if ((ret =
719 _gnutls_record_buffer_put (recv_type, session,
720 (void *) data, data_size)) < 0)
722 gnutls_assert ();
723 return ret;
726 /* the got_application data is only returned
727 * if expecting client hello (for rehandshake
728 * reasons). Otherwise it is an unexpected packet
730 if (type == GNUTLS_ALERT || (htype == GNUTLS_HANDSHAKE_CLIENT_HELLO
731 && type == GNUTLS_HANDSHAKE))
732 return GNUTLS_E_GOT_APPLICATION_DATA;
733 else
735 gnutls_assert ();
736 return GNUTLS_E_UNEXPECTED_PACKET;
739 break;
740 case GNUTLS_HANDSHAKE:
741 /* This is legal if HELLO_REQUEST is received - and we are a client.
742 * If we are a server, a client may initiate a renegotiation at any time.
744 if (session->security_parameters.entity == GNUTLS_SERVER)
746 gnutls_assert ();
747 ret = _gnutls_record_buffer_put (recv_type, session, (void *) data, data_size);
748 if (ret < 0)
750 gnutls_assert();
751 return ret;
753 return GNUTLS_E_REHANDSHAKE;
756 /* If we are already in a handshake then a Hello
757 * Request is illegal. But here we don't really care
758 * since this message will never make it up here.
761 /* So we accept it */
762 return _gnutls_recv_hello_request (session, data, data_size);
764 break;
765 case GNUTLS_INNER_APPLICATION:
766 /* even if data is unexpected put it into the buffer */
767 if ((ret = _gnutls_record_buffer_put (recv_type, session,
768 (void *) data,
769 data_size)) < 0)
771 gnutls_assert ();
772 return ret;
774 gnutls_assert ();
775 return GNUTLS_E_UNEXPECTED_PACKET;
776 break;
777 default:
779 _gnutls_record_log
780 ("REC[%p]: Received Unknown packet %d expecting %d\n",
781 session, recv_type, type);
783 gnutls_assert ();
784 return GNUTLS_E_INTERNAL_ERROR;
788 return 0;
793 /* This function will return the internal (per session) temporary
794 * recv buffer. If the buffer was not initialized before it will
795 * also initialize it.
797 inline static int
798 get_temp_recv_buffer (gnutls_session_t session, gnutls_datum_t * tmp)
800 size_t max_record_size;
802 if (gnutls_compression_get (session) != GNUTLS_COMP_NULL)
803 max_record_size = MAX_RECORD_RECV_SIZE + EXTRA_COMP_SIZE;
804 else
805 max_record_size = MAX_RECORD_RECV_SIZE;
807 /* We allocate MAX_RECORD_RECV_SIZE length
808 * because we cannot predict the output data by the record
809 * packet length (due to compression).
812 if (max_record_size > session->internals.recv_buffer.size ||
813 session->internals.recv_buffer.data == NULL)
816 /* Initialize the internal buffer.
818 session->internals.recv_buffer.data =
819 gnutls_realloc (session->internals.recv_buffer.data, max_record_size);
821 if (session->internals.recv_buffer.data == NULL)
823 gnutls_assert ();
824 return GNUTLS_E_MEMORY_ERROR;
827 session->internals.recv_buffer.size = max_record_size;
830 tmp->data = session->internals.recv_buffer.data;
831 tmp->size = session->internals.recv_buffer.size;
833 return 0;
837 #define MAX_EMPTY_PACKETS_SEQUENCE 4
839 /* This function behaves exactly like read(). The only difference is
840 * that it accepts the gnutls_session_t and the content_type_t of data to
841 * receive (if called by the user the Content is Userdata only)
842 * It is intended to receive data, under the current session.
844 * The gnutls_handshake_description_t was introduced to support SSL V2.0 client hellos.
846 ssize_t
847 _gnutls_recv_int (gnutls_session_t session, content_type_t type,
848 gnutls_handshake_description_t htype, opaque * data,
849 size_t sizeofdata)
851 gnutls_datum_t tmp;
852 int decrypted_length;
853 opaque version[2];
854 uint8_t *headers;
855 content_type_t recv_type;
856 uint16_t length;
857 uint8_t *ciphertext;
858 uint8_t *recv_data;
859 int ret, ret2;
860 uint16_t header_size;
861 int empty_packet = 0;
863 if (type != GNUTLS_ALERT && (sizeofdata == 0 || data == NULL))
865 return GNUTLS_E_INVALID_REQUEST;
868 begin:
870 if (empty_packet > MAX_EMPTY_PACKETS_SEQUENCE)
872 gnutls_assert ();
873 return GNUTLS_E_TOO_MANY_EMPTY_PACKETS;
876 if (session->internals.read_eof != 0)
878 /* if we have already read an EOF
880 return 0;
882 else if (session_is_valid (session) != 0
883 || session->internals.may_not_read != 0)
885 gnutls_assert ();
886 return GNUTLS_E_INVALID_SESSION;
889 /* If we have enough data in the cache do not bother receiving
890 * a new packet. (in order to flush the cache)
892 ret = check_buffers (session, type, data, sizeofdata);
893 if (ret != 0)
894 return ret;
897 /* default headers for TLS 1.0
899 header_size = RECORD_HEADER_SIZE;
901 if ((ret =
902 _gnutls_io_read_buffered (session, &headers, header_size,
903 -1)) != header_size)
905 if (ret < 0 && gnutls_error_is_fatal (ret) == 0)
906 return ret;
908 session_invalidate (session);
909 if (type == GNUTLS_ALERT)
911 gnutls_assert ();
912 return 0; /* we were expecting close notify */
914 session_unresumable (session);
915 gnutls_assert ();
916 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
919 if ((ret =
920 record_check_headers (session, headers, type, htype, &recv_type,
921 version, &length, &header_size)) < 0)
923 gnutls_assert ();
924 return ret;
927 /* Here we check if the Type of the received packet is
928 * ok.
930 if ((ret = check_recv_type (recv_type)) < 0)
932 gnutls_assert ();
933 return ret;
936 /* Here we check if the advertized version is the one we
937 * negotiated in the handshake.
939 if ((ret = record_check_version (session, htype, version)) < 0)
941 gnutls_assert ();
942 session_invalidate (session);
943 return ret;
946 _gnutls_record_log
947 ("REC[%p]: Expected Packet[%d] %s(%d) with length: %d\n", session,
948 (int) _gnutls_uint64touint32 (&session->connection_state.
949 read_sequence_number),
950 _gnutls_packet2str (type), type, (int)sizeofdata);
951 _gnutls_record_log ("REC[%p]: Received Packet[%d] %s(%d) with length: %d\n",
952 session,
953 (int)
954 _gnutls_uint64touint32 (&session->connection_state.
955 read_sequence_number),
956 _gnutls_packet2str (recv_type), recv_type, length);
958 if (length > MAX_RECV_SIZE)
960 _gnutls_record_log
961 ("REC[%p]: FATAL ERROR: Received packet with length: %d\n",
962 session, length);
964 session_unresumable (session);
965 session_invalidate (session);
966 gnutls_assert ();
967 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
970 /* check if we have that data into buffer.
972 if ((ret =
973 _gnutls_io_read_buffered (session, &recv_data,
974 header_size + length,
975 recv_type)) != header_size + length)
977 if (ret < 0 && gnutls_error_is_fatal (ret) == 0)
978 return ret;
980 session_unresumable (session);
981 session_invalidate (session);
982 gnutls_assert ();
983 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
986 /* ok now we are sure that we can read all the data - so
987 * move on !
989 _gnutls_io_clear_read_buffer (session);
990 ciphertext = &recv_data[header_size];
992 ret = get_temp_recv_buffer (session, &tmp);
993 if (ret < 0)
995 gnutls_assert ();
996 return ret;
999 /* decrypt the data we got.
1001 ret =
1002 _gnutls_decrypt (session, ciphertext, length, tmp.data, tmp.size,
1003 recv_type);
1004 if (ret < 0)
1006 session_unresumable (session);
1007 session_invalidate (session);
1008 gnutls_assert ();
1009 return ret;
1011 decrypted_length = ret;
1013 /* Check if this is a CHANGE_CIPHER_SPEC
1015 if (type == GNUTLS_CHANGE_CIPHER_SPEC &&
1016 recv_type == GNUTLS_CHANGE_CIPHER_SPEC)
1019 _gnutls_record_log
1020 ("REC[%p]: ChangeCipherSpec Packet was received\n", session);
1022 if ((size_t) ret != sizeofdata)
1023 { /* sizeofdata should be 1 */
1024 gnutls_assert ();
1025 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1027 memcpy (data, tmp.data, sizeofdata);
1029 return ret;
1032 _gnutls_record_log
1033 ("REC[%p]: Decrypted Packet[%d] %s(%d) with length: %d\n", session,
1034 (int) _gnutls_uint64touint32 (&session->connection_state.
1035 read_sequence_number),
1036 _gnutls_packet2str (recv_type), recv_type, decrypted_length);
1038 /* increase sequence number
1040 if (_gnutls_uint64pp (&session->connection_state.read_sequence_number) != 0)
1042 session_invalidate (session);
1043 gnutls_assert ();
1044 return GNUTLS_E_RECORD_LIMIT_REACHED;
1047 ret =
1048 record_check_type (session, recv_type, type, htype, tmp.data,
1049 decrypted_length);
1050 if (ret < 0)
1052 if (ret == GNUTLS_E_INT_RET_0)
1053 return 0;
1054 gnutls_assert ();
1055 return ret;
1058 /* Get Application data from buffer
1060 if ((recv_type == type) &&
1061 (type == GNUTLS_APPLICATION_DATA ||
1062 type == GNUTLS_HANDSHAKE || type == GNUTLS_INNER_APPLICATION))
1065 ret = _gnutls_record_buffer_get (type, session, data, sizeofdata);
1066 if (ret < 0)
1068 gnutls_assert ();
1069 return ret;
1072 /* if the buffer just got empty
1074 if (_gnutls_record_buffer_get_size (type, session) == 0)
1076 if ((ret2 = _gnutls_io_clear_peeked_data (session)) < 0)
1078 gnutls_assert ();
1079 return ret2;
1083 else
1085 gnutls_assert ();
1086 return GNUTLS_E_UNEXPECTED_PACKET;
1087 /* we didn't get what we wanted to
1091 /* (originally for) TLS 1.0 CBC protection.
1092 * Actually this code is called if we just received
1093 * an empty packet. An empty TLS packet is usually
1094 * sent to protect some vulnerabilities in the CBC mode.
1095 * In that case we go to the beginning and start reading
1096 * the next packet.
1098 if (ret == 0)
1100 empty_packet++;
1101 goto begin;
1104 return ret;
1109 * gnutls_record_send - sends to the peer the specified data
1110 * @session: is a #gnutls_session_t structure.
1111 * @data: contains the data to send
1112 * @sizeofdata: is the length of the data
1114 * This function has the similar semantics with send(). The only
1115 * difference is that it accepts a GnuTLS session, and uses different
1116 * error codes.
1118 * Note that if the send buffer is full, send() will block this
1119 * function. See the send() documentation for full information. You
1120 * can replace the default push function by using
1121 * gnutls_transport_set_ptr2() with a call to send() with a
1122 * MSG_DONTWAIT flag if blocking is a problem.
1124 * If the EINTR is returned by the internal push function (the
1125 * default is send()} then %GNUTLS_E_INTERRUPTED will be returned. If
1126 * %GNUTLS_E_INTERRUPTED or %GNUTLS_E_AGAIN is returned, you must
1127 * call this function again, with the same parameters; alternatively
1128 * you could provide a %NULL pointer for data, and 0 for
1129 * size. cf. gnutls_record_get_direction().
1131 * Returns: the number of bytes sent, or a negative error code. The
1132 * number of bytes sent might be less than @sizeofdata. The maximum
1133 * number of bytes this function can send in a single call depends on
1134 * the negotiated maximum record size.
1136 ssize_t
1137 gnutls_record_send (gnutls_session_t session, const void *data,
1138 size_t sizeofdata)
1140 return _gnutls_send_int (session, GNUTLS_APPLICATION_DATA, -1, data,
1141 sizeofdata);
1145 * gnutls_record_recv - reads data from the TLS record protocol
1146 * @session: is a #gnutls_session_t structure.
1147 * @data: the buffer that the data will be read into
1148 * @sizeofdata: the number of requested bytes
1150 * This function has the similar semantics with recv(). The only
1151 * difference is that it accepts a GnuTLS session, and uses different
1152 * error codes.
1154 * In the special case that a server requests a renegotiation, the
1155 * client may receive an error code of %GNUTLS_E_REHANDSHAKE. This
1156 * message may be simply ignored, replied with an alert
1157 * %GNUTLS_A_NO_RENEGOTIATION, or replied with a new handshake,
1158 * depending on the client's will.
1160 * If %EINTR is returned by the internal push function (the default
1161 * is recv()) then %GNUTLS_E_INTERRUPTED will be returned. If
1162 * %GNUTLS_E_INTERRUPTED or %GNUTLS_E_AGAIN is returned, you must
1163 * call this function again to get the data. See also
1164 * gnutls_record_get_direction().
1166 * A server may also receive %GNUTLS_E_REHANDSHAKE when a client has
1167 * initiated a handshake. In that case the server can only initiate a
1168 * handshake or terminate the connection.
1170 * Returns: the number of bytes received and zero on EOF. A negative
1171 * error code is returned in case of an error. The number of bytes
1172 * received might be less than @sizeofdata.
1174 ssize_t
1175 gnutls_record_recv (gnutls_session_t session, void *data, size_t sizeofdata)
1177 return _gnutls_recv_int (session, GNUTLS_APPLICATION_DATA, -1, data,
1178 sizeofdata);
1182 * gnutls_record_get_max_size - returns the maximum record size
1183 * @session: is a #gnutls_session_t structure.
1185 * Get the record size. The maximum record size is negotiated by the
1186 * client after the first handshake message.
1188 * Returns: The maximum record packet size in this connection.
1190 size_t
1191 gnutls_record_get_max_size (gnutls_session_t session)
1193 /* Recv will hold the negotiated max record size
1194 * always.
1196 return session->security_parameters.max_record_recv_size;
1201 * gnutls_record_set_max_size - sets the maximum record size
1202 * @session: is a #gnutls_session_t structure.
1203 * @size: is the new size
1205 * This function sets the maximum record packet size in this
1206 * connection. This property can only be set to clients. The server
1207 * may choose not to accept the requested size.
1209 * Acceptable values are 512(=2^9), 1024(=2^10), 2048(=2^11) and
1210 * 4096(=2^12). The requested record size does get in effect
1211 * immediately only while sending data. The receive part will take
1212 * effect after a successful handshake.
1214 * This function uses a TLS extension called 'max record size'. Not
1215 * all TLS implementations use or even understand this extension.
1217 * Returns: On success, %GNUTLS_E_SUCCESS (zero) is returned,
1218 * otherwise an error code is returned.
1220 ssize_t
1221 gnutls_record_set_max_size (gnutls_session_t session, size_t size)
1223 ssize_t new_size;
1225 if (session->security_parameters.entity == GNUTLS_SERVER)
1226 return GNUTLS_E_INVALID_REQUEST;
1228 new_size = _gnutls_mre_record2num (size);
1230 if (new_size < 0)
1232 gnutls_assert ();
1233 return new_size;
1236 session->security_parameters.max_record_send_size = size;
1238 session->internals.proposed_record_size = size;
1240 return 0;