Use libtasn1 v2.4.
[gnutls.git] / lib / gnutls_record.c
blob6b8736df8c519ed10bb0e31b2ff4509b6c80b253
1 /*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
3 * 2009, 2010 Free Software Foundation, Inc.
5 * Author: Nikos Mavrogiannopoulos
7 * This file is part of GNUTLS.
9 * The GNUTLS library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1 of
12 * the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
22 * USA
26 /* Functions that are record layer specific, are included in this file.
29 #include "gnutls_int.h"
30 #include "gnutls_errors.h"
31 #include "debug.h"
32 #include "gnutls_compress.h"
33 #include "gnutls_cipher.h"
34 #include "gnutls_buffers.h"
35 #include "gnutls_handshake.h"
36 #include "gnutls_hash_int.h"
37 #include "gnutls_cipher_int.h"
38 #include "gnutls_algorithms.h"
39 #include "gnutls_db.h"
40 #include "gnutls_auth.h"
41 #include "gnutls_num.h"
42 #include "gnutls_record.h"
43 #include "gnutls_datum.h"
44 #include "ext_max_record.h"
45 #include <gnutls_state.h>
46 #include <gnutls_dh.h>
48 /**
49 * gnutls_protocol_get_version - Returns the version of the currently used protocol
50 * @session: is a #gnutls_session_t structure.
52 * Get TLS version, a #gnutls_protocol_t value.
54 * Returns: the version of the currently used protocol.
55 **/
56 gnutls_protocol_t
57 gnutls_protocol_get_version (gnutls_session_t session)
59 return session->security_parameters.version;
62 void
63 _gnutls_set_current_version (gnutls_session_t session,
64 gnutls_protocol_t version)
66 session->security_parameters.version = version;
69 /**
70 * gnutls_transport_set_lowat - Used to set the lowat value in order for select to check for pending data.
71 * @session: is a #gnutls_session_t structure.
72 * @num: is the low water value.
74 * Used to set the lowat value in order for select to check if there
75 * are pending data to socket buffer. Used only if you have changed
76 * the default low water value (default is 1). Normally you will not
77 * need that function. This function is only useful if using
78 * berkeley style sockets. Otherwise it must be called and set lowat
79 * to zero.
80 **/
81 void
82 gnutls_transport_set_lowat (gnutls_session_t session, int num)
84 session->internals.lowat = num;
87 /**
88 * gnutls_record_disable_padding - Used to disabled padding in TLS 1.0 and above
89 * @session: is a #gnutls_session_t structure.
91 * Used to disabled padding in TLS 1.0 and above. Normally you do
92 * not need to use this function, but there are buggy clients that
93 * complain if a server pads the encrypted data. This of course will
94 * disable protection against statistical attacks on the data.
96 * Normally only servers that require maximum compatibility with everything
97 * out there, need to call this function.
98 **/
99 void
100 gnutls_record_disable_padding (gnutls_session_t session)
102 session->internals.priorities.no_padding = 1;
106 * gnutls_transport_set_ptr - Used to set first argument of the transport functions
107 * @session: is a #gnutls_session_t structure.
108 * @ptr: is the value.
110 * Used to set the first argument of the transport function (like
111 * PUSH and PULL). In berkeley style sockets this function will set
112 * the connection handle.
114 void
115 gnutls_transport_set_ptr (gnutls_session_t session,
116 gnutls_transport_ptr_t ptr)
118 session->internals.transport_recv_ptr = ptr;
119 session->internals.transport_send_ptr = ptr;
124 * gnutls_transport_set_ptr2 - Used to set first argument of the transport functions
125 * @session: is a #gnutls_session_t structure.
126 * @recv_ptr: is the value for the pull function
127 * @send_ptr: is the value for the push function
129 * Used to set the first argument of the transport function (like
130 * PUSH and PULL). In berkeley style sockets this function will set
131 * the connection handle. With this function you can use two
132 * different pointers for receiving and sending.
134 void
135 gnutls_transport_set_ptr2 (gnutls_session_t session,
136 gnutls_transport_ptr_t recv_ptr,
137 gnutls_transport_ptr_t send_ptr)
139 session->internals.transport_send_ptr = send_ptr;
140 session->internals.transport_recv_ptr = recv_ptr;
144 * gnutls_transport_get_ptr - Used to return the first argument of the transport functions
145 * @session: is a #gnutls_session_t structure.
147 * Used to get the first argument of the transport function (like
148 * PUSH and PULL). This must have been set using
149 * gnutls_transport_set_ptr().
151 * Returns: first argument of the transport function.
153 gnutls_transport_ptr_t
154 gnutls_transport_get_ptr (gnutls_session_t session)
156 return session->internals.transport_recv_ptr;
160 * gnutls_transport_get_ptr2 - Used to return the first argument of the transport functions
161 * @session: is a #gnutls_session_t structure.
162 * @recv_ptr: will hold the value for the pull function
163 * @send_ptr: will hold the value for the push function
165 * Used to get the arguments of the transport functions (like PUSH
166 * and PULL). These should have been set using
167 * gnutls_transport_set_ptr2().
169 void
170 gnutls_transport_get_ptr2 (gnutls_session_t session,
171 gnutls_transport_ptr_t * recv_ptr,
172 gnutls_transport_ptr_t * send_ptr)
175 *recv_ptr = session->internals.transport_recv_ptr;
176 *send_ptr = session->internals.transport_send_ptr;
180 * gnutls_bye - terminate the current TLS/SSL connection.
181 * @session: is a #gnutls_session_t structure.
182 * @how: is an integer
184 * Terminates the current TLS/SSL connection. The connection should
185 * have been initiated using gnutls_handshake(). @how should be one
186 * of %GNUTLS_SHUT_RDWR, %GNUTLS_SHUT_WR.
188 * In case of %GNUTLS_SHUT_RDWR then the TLS connection gets
189 * terminated and further receives and sends will be disallowed. If
190 * the return value is zero you may continue using the connection.
191 * %GNUTLS_SHUT_RDWR actually sends an alert containing a close
192 * request and waits for the peer to reply with the same message.
194 * In case of %GNUTLS_SHUT_WR then the TLS connection gets terminated
195 * and further sends will be disallowed. In order to reuse the
196 * connection you should wait for an EOF from the peer.
197 * %GNUTLS_SHUT_WR sends an alert containing a close request.
199 * Note that not all implementations will properly terminate a TLS
200 * connection. Some of them, usually for performance reasons, will
201 * terminate only the underlying transport layer, thus causing a
202 * transmission error to the peer. This error cannot be
203 * distinguished from a malicious party prematurely terminating the
204 * session, thus this behavior is not recommended.
206 * This function may also return %GNUTLS_E_AGAIN or
207 * %GNUTLS_E_INTERRUPTED; cf. gnutls_record_get_direction().
209 * Returns: %GNUTLS_E_SUCCESS on success, or an error code, see
210 * function documentation for entire semantics.
213 gnutls_bye (gnutls_session_t session, gnutls_close_request_t how)
215 int ret = 0;
217 switch (STATE)
219 case STATE0:
220 case STATE60:
221 ret = _gnutls_io_write_flush (session);
222 STATE = STATE60;
223 if (ret < 0)
225 gnutls_assert ();
226 return ret;
229 case STATE61:
230 ret =
231 gnutls_alert_send (session, GNUTLS_AL_WARNING, GNUTLS_A_CLOSE_NOTIFY);
232 STATE = STATE61;
233 if (ret < 0)
235 gnutls_assert ();
236 return ret;
239 case STATE62:
240 STATE = STATE62;
241 if (how == GNUTLS_SHUT_RDWR)
245 _gnutls_io_clear_peeked_data (session);
246 ret = _gnutls_recv_int (session, GNUTLS_ALERT, -1, NULL, 0);
248 while (ret == GNUTLS_E_GOT_APPLICATION_DATA);
250 if (ret >= 0)
251 session->internals.may_not_read = 1;
253 if (ret < 0)
255 gnutls_assert ();
256 return ret;
259 STATE = STATE62;
261 break;
262 default:
263 gnutls_assert ();
264 return GNUTLS_E_INTERNAL_ERROR;
267 STATE = STATE0;
269 session->internals.may_not_write = 1;
270 return 0;
273 inline static void
274 session_invalidate (gnutls_session_t session)
276 session->internals.valid_connection = VALID_FALSE;
280 inline static void
281 session_unresumable (gnutls_session_t session)
283 session->internals.resumable = RESUME_FALSE;
286 /* returns 0 if session is valid
288 inline static int
289 session_is_valid (gnutls_session_t session)
291 if (session->internals.valid_connection == VALID_FALSE)
292 return GNUTLS_E_INVALID_SESSION;
294 return 0;
297 /* Copies the record version into the headers. The
298 * version must have 2 bytes at least.
300 inline static void
301 copy_record_version (gnutls_session_t session,
302 gnutls_handshake_description_t htype, opaque version[2])
304 gnutls_protocol_t lver;
306 if (htype != GNUTLS_HANDSHAKE_CLIENT_HELLO
307 || session->internals.default_record_version[0] == 0)
309 lver = gnutls_protocol_get_version (session);
311 version[0] = _gnutls_version_get_major (lver);
312 version[1] = _gnutls_version_get_minor (lver);
314 else
316 version[0] = session->internals.default_record_version[0];
317 version[1] = session->internals.default_record_version[1];
321 /* This function behaves exactly like write(). The only difference is
322 * that it accepts, the gnutls_session_t and the content_type_t of data to
323 * send (if called by the user the Content is specific)
324 * It is intended to transfer data, under the current session.
326 * Oct 30 2001: Removed capability to send data more than MAX_RECORD_SIZE.
327 * This makes the function much easier to read, and more error resistant
328 * (there were cases were the old function could mess everything up).
329 * --nmav
331 * This function may accept a NULL pointer for data, and 0 for size, if
332 * and only if the previous send was interrupted for some reason.
335 ssize_t
336 _gnutls_send_int (gnutls_session_t session, content_type_t type,
337 gnutls_handshake_description_t htype, const void *_data,
338 size_t sizeofdata)
340 uint8_t *cipher;
341 int cipher_size;
342 int retval, ret;
343 int data2send_size;
344 uint8_t headers[5];
345 const uint8_t *data = _data;
347 /* Do not allow null pointer if the send buffer is empty.
348 * If the previous send was interrupted then a null pointer is
349 * ok, and means to resume.
351 if (session->internals.record_send_buffer.length == 0 &&
352 (sizeofdata == 0 && _data == NULL))
354 gnutls_assert ();
355 return GNUTLS_E_INVALID_REQUEST;
358 if (type != GNUTLS_ALERT) /* alert messages are sent anyway */
359 if (session_is_valid (session) || session->internals.may_not_write != 0)
361 gnutls_assert ();
362 return GNUTLS_E_INVALID_SESSION;
365 headers[0] = type;
367 /* Use the default record version, if it is
368 * set.
370 copy_record_version (session, htype, &headers[1]);
373 _gnutls_record_log
374 ("REC[%p]: Sending Packet[%d] %s(%d) with length: %d\n", session,
375 (int) _gnutls_uint64touint32 (&session->connection_state.
376 write_sequence_number),
377 _gnutls_packet2str (type), type, (int) sizeofdata);
379 if (sizeofdata > MAX_RECORD_SEND_SIZE)
380 data2send_size = MAX_RECORD_SEND_SIZE;
381 else
382 data2send_size = sizeofdata;
384 /* Only encrypt if we don't have data to send
385 * from the previous run. - probably interrupted.
387 if (session->internals.record_send_buffer.length > 0)
389 ret = _gnutls_io_write_flush (session);
390 if (ret > 0)
391 cipher_size = ret;
392 else
393 cipher_size = 0;
395 cipher = NULL;
397 retval = session->internals.record_send_buffer_user_size;
399 else
402 /* now proceed to packet encryption
404 cipher_size = data2send_size + MAX_RECORD_OVERHEAD;
405 cipher = gnutls_malloc (cipher_size);
406 if (cipher == NULL)
408 gnutls_assert ();
409 return GNUTLS_E_MEMORY_ERROR;
412 cipher_size =
413 _gnutls_encrypt (session, headers, RECORD_HEADER_SIZE, data,
414 data2send_size, cipher, cipher_size, type,
415 (session->internals.priorities.no_padding ==
416 0) ? 1 : 0);
417 if (cipher_size <= 0)
419 gnutls_assert ();
420 if (cipher_size == 0)
421 cipher_size = GNUTLS_E_ENCRYPTION_FAILED;
422 gnutls_free (cipher);
423 return cipher_size; /* error */
426 retval = data2send_size;
427 session->internals.record_send_buffer_user_size = data2send_size;
429 /* increase sequence number
431 if (_gnutls_uint64pp
432 (&session->connection_state.write_sequence_number) != 0)
434 session_invalidate (session);
435 gnutls_assert ();
436 gnutls_free (cipher);
437 return GNUTLS_E_RECORD_LIMIT_REACHED;
440 ret = _gnutls_io_write_buffered (session, cipher, cipher_size);
441 gnutls_free (cipher);
444 if (ret != cipher_size)
446 if (ret < 0 && gnutls_error_is_fatal (ret) == 0)
448 /* If we have sent any data then just return
449 * the error value. Do not invalidate the session.
451 gnutls_assert ();
452 return ret;
455 if (ret > 0)
457 gnutls_assert ();
458 ret = GNUTLS_E_INTERNAL_ERROR;
460 session_unresumable (session);
461 session->internals.may_not_write = 1;
462 gnutls_assert ();
463 return ret;
466 session->internals.record_send_buffer_user_size = 0;
468 _gnutls_record_log ("REC[%p]: Sent Packet[%d] %s(%d) with length: %d\n",
469 session,
470 (int)
471 _gnutls_uint64touint32
472 (&session->connection_state.write_sequence_number),
473 _gnutls_packet2str (type), type, cipher_size);
475 return retval;
478 /* This function is to be called if the handshake was successfully
479 * completed. This sends a Change Cipher Spec packet to the peer.
481 ssize_t
482 _gnutls_send_change_cipher_spec (gnutls_session_t session, int again)
484 static const opaque data[1] = { GNUTLS_TYPE_CHANGE_CIPHER_SPEC };
486 _gnutls_handshake_log ("REC[%p]: Sent ChangeCipherSpec\n", session);
488 if (again == 0)
489 return _gnutls_send_int (session, GNUTLS_CHANGE_CIPHER_SPEC, -1, data, 1);
490 else
492 return _gnutls_io_write_flush (session);
496 inline static int
497 check_recv_type (content_type_t recv_type)
499 switch (recv_type)
501 case GNUTLS_CHANGE_CIPHER_SPEC:
502 case GNUTLS_ALERT:
503 case GNUTLS_HANDSHAKE:
504 case GNUTLS_APPLICATION_DATA:
505 case GNUTLS_INNER_APPLICATION:
506 return 0;
507 default:
508 gnutls_assert ();
509 return GNUTLS_A_UNEXPECTED_MESSAGE;
515 /* Checks if there are pending data in the record buffers. If there are
516 * then it copies the data.
518 static int
519 check_buffers (gnutls_session_t session, content_type_t type,
520 opaque * data, int sizeofdata)
522 if ((type == GNUTLS_APPLICATION_DATA ||
523 type == GNUTLS_HANDSHAKE ||
524 type == GNUTLS_INNER_APPLICATION)
525 && _gnutls_record_buffer_get_size (type, session) > 0)
527 int ret, ret2;
528 ret = _gnutls_record_buffer_get (type, session, data, sizeofdata);
529 if (ret < 0)
531 gnutls_assert ();
532 return ret;
535 /* if the buffer just got empty */
536 if (_gnutls_record_buffer_get_size (type, session) == 0)
538 if ((ret2 = _gnutls_io_clear_peeked_data (session)) < 0)
540 gnutls_assert ();
541 return ret2;
545 return ret;
548 return 0;
552 /* Checks the record headers and returns the length, version and
553 * content type.
555 static int
556 record_check_headers (gnutls_session_t session,
557 uint8_t headers[RECORD_HEADER_SIZE],
558 content_type_t type,
559 gnutls_handshake_description_t htype,
560 /*output */ content_type_t * recv_type,
561 opaque version[2], uint16_t * length,
562 uint16_t * header_size)
565 /* Read the first two bytes to determine if this is a
566 * version 2 message
569 if (htype == GNUTLS_HANDSHAKE_CLIENT_HELLO && type == GNUTLS_HANDSHAKE
570 && headers[0] > 127)
573 /* if msb set and expecting handshake message
574 * it should be SSL 2 hello
576 version[0] = 3; /* assume SSL 3.0 */
577 version[1] = 0;
579 *length = (((headers[0] & 0x7f) << 8)) | headers[1];
581 /* SSL 2.0 headers */
582 *header_size = 2;
583 *recv_type = GNUTLS_HANDSHAKE; /* we accept only v2 client hello
586 /* in order to assist the handshake protocol.
587 * V2 compatibility is a mess.
589 session->internals.v2_hello = *length;
591 _gnutls_record_log ("REC[%p]: V2 packet received. Length: %d\n",
592 session, *length);
595 else
597 /* version 3.x
599 *recv_type = headers[0];
600 version[0] = headers[1];
601 version[1] = headers[2];
603 /* No DECR_LEN, since headers has enough size.
605 *length = _gnutls_read_uint16 (&headers[3]);
608 return 0;
611 /* Here we check if the advertized version is the one we
612 * negotiated in the handshake.
614 inline static int
615 record_check_version (gnutls_session_t session,
616 gnutls_handshake_description_t htype, opaque version[2])
618 if (htype == GNUTLS_HANDSHAKE_CLIENT_HELLO)
620 /* Reject hello packets with major version higher than 3.
622 if (version[0] > 3)
624 gnutls_assert ();
625 _gnutls_record_log
626 ("REC[%p]: INVALID VERSION PACKET: (%d) %d.%d\n", session,
627 htype, version[0], version[1]);
628 return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
631 else if (htype != GNUTLS_HANDSHAKE_SERVER_HELLO &&
632 gnutls_protocol_get_version (session) !=
633 _gnutls_version_get (version[0], version[1]))
635 /* Reject record packets that have a different version than the
636 * one negotiated. Note that this version is not protected by any
637 * mac. I don't really think that this check serves any purpose.
639 gnutls_assert ();
640 _gnutls_record_log ("REC[%p]: INVALID VERSION PACKET: (%d) %d.%d\n",
641 session, htype, version[0], version[1]);
643 return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
646 return 0;
649 /* This function will check if the received record type is
650 * the one we actually expect.
652 static int
653 record_check_type (gnutls_session_t session,
654 content_type_t recv_type, content_type_t type,
655 gnutls_handshake_description_t htype, opaque * data,
656 int data_size)
659 int ret;
661 if ((recv_type == type)
662 && (type == GNUTLS_APPLICATION_DATA ||
663 type == GNUTLS_HANDSHAKE || type == GNUTLS_INNER_APPLICATION))
665 _gnutls_record_buffer_put (type, session, (void *) data, data_size);
667 else
669 switch (recv_type)
671 case GNUTLS_ALERT:
673 _gnutls_record_log
674 ("REC[%p]: Alert[%d|%d] - %s - was received\n", session,
675 data[0], data[1], gnutls_alert_get_name ((int) data[1]));
677 session->internals.last_alert = data[1];
679 /* if close notify is received and
680 * the alert is not fatal
682 if (data[1] == GNUTLS_A_CLOSE_NOTIFY && data[0] != GNUTLS_AL_FATAL)
684 /* If we have been expecting for an alert do
686 session->internals.read_eof = 1;
687 return GNUTLS_E_INT_RET_0; /* EOF */
689 else
692 /* if the alert is FATAL or WARNING
693 * return the apropriate message
696 gnutls_assert ();
697 ret = GNUTLS_E_WARNING_ALERT_RECEIVED;
698 if (data[0] == GNUTLS_AL_FATAL)
700 session_unresumable (session);
701 session_invalidate (session);
702 ret = GNUTLS_E_FATAL_ALERT_RECEIVED;
705 return ret;
707 break;
709 case GNUTLS_CHANGE_CIPHER_SPEC:
710 /* this packet is now handled in the recv_int()
711 * function
713 gnutls_assert ();
715 return GNUTLS_E_UNEXPECTED_PACKET;
717 case GNUTLS_APPLICATION_DATA:
718 /* even if data is unexpected put it into the buffer */
719 if ((ret =
720 _gnutls_record_buffer_put (recv_type, session,
721 (void *) data, data_size)) < 0)
723 gnutls_assert ();
724 return ret;
727 /* the got_application data is only returned
728 * if expecting client hello (for rehandshake
729 * reasons). Otherwise it is an unexpected packet
731 if (type == GNUTLS_ALERT || (htype == GNUTLS_HANDSHAKE_CLIENT_HELLO
732 && type == GNUTLS_HANDSHAKE))
733 return GNUTLS_E_GOT_APPLICATION_DATA;
734 else
736 gnutls_assert ();
737 return GNUTLS_E_UNEXPECTED_PACKET;
740 break;
741 case GNUTLS_HANDSHAKE:
742 /* This is legal if HELLO_REQUEST is received - and we are a client.
743 * If we are a server, a client may initiate a renegotiation at any time.
745 if (session->security_parameters.entity == GNUTLS_SERVER)
747 gnutls_assert ();
748 ret =
749 _gnutls_record_buffer_put (recv_type, session, (void *) data,
750 data_size);
751 if (ret < 0)
753 gnutls_assert ();
754 return ret;
756 return GNUTLS_E_REHANDSHAKE;
759 /* If we are already in a handshake then a Hello
760 * Request is illegal. But here we don't really care
761 * since this message will never make it up here.
764 /* So we accept it */
765 return _gnutls_recv_hello_request (session, data, data_size);
767 break;
768 case GNUTLS_INNER_APPLICATION:
769 /* even if data is unexpected put it into the buffer */
770 if ((ret = _gnutls_record_buffer_put (recv_type, session,
771 (void *) data,
772 data_size)) < 0)
774 gnutls_assert ();
775 return ret;
777 gnutls_assert ();
778 return GNUTLS_E_UNEXPECTED_PACKET;
779 break;
780 default:
782 _gnutls_record_log
783 ("REC[%p]: Received Unknown packet %d expecting %d\n",
784 session, recv_type, type);
786 gnutls_assert ();
787 return GNUTLS_E_INTERNAL_ERROR;
791 return 0;
796 /* This function will return the internal (per session) temporary
797 * recv buffer. If the buffer was not initialized before it will
798 * also initialize it.
800 inline static int
801 get_temp_recv_buffer (gnutls_session_t session, gnutls_datum_t * tmp)
803 size_t max_record_size;
805 if (gnutls_compression_get (session) != GNUTLS_COMP_NULL)
806 max_record_size = MAX_RECORD_RECV_SIZE + EXTRA_COMP_SIZE;
807 else
808 max_record_size = MAX_RECORD_RECV_SIZE;
810 /* We allocate MAX_RECORD_RECV_SIZE length
811 * because we cannot predict the output data by the record
812 * packet length (due to compression).
815 if (max_record_size > session->internals.recv_buffer.size ||
816 session->internals.recv_buffer.data == NULL)
819 /* Initialize the internal buffer.
821 session->internals.recv_buffer.data =
822 gnutls_realloc (session->internals.recv_buffer.data, max_record_size);
824 if (session->internals.recv_buffer.data == NULL)
826 gnutls_assert ();
827 return GNUTLS_E_MEMORY_ERROR;
830 session->internals.recv_buffer.size = max_record_size;
833 tmp->data = session->internals.recv_buffer.data;
834 tmp->size = session->internals.recv_buffer.size;
836 return 0;
840 #define MAX_EMPTY_PACKETS_SEQUENCE 4
842 /* This function behaves exactly like read(). The only difference is
843 * that it accepts the gnutls_session_t and the content_type_t of data to
844 * receive (if called by the user the Content is Userdata only)
845 * It is intended to receive data, under the current session.
847 * The gnutls_handshake_description_t was introduced to support SSL V2.0 client hellos.
849 ssize_t
850 _gnutls_recv_int (gnutls_session_t session, content_type_t type,
851 gnutls_handshake_description_t htype, opaque * data,
852 size_t sizeofdata)
854 gnutls_datum_t tmp;
855 int decrypted_length;
856 opaque version[2];
857 uint8_t *headers;
858 content_type_t recv_type;
859 uint16_t length;
860 uint8_t *ciphertext;
861 uint8_t *recv_data;
862 int ret, ret2;
863 uint16_t header_size;
864 int empty_packet = 0;
866 if (type != GNUTLS_ALERT && (sizeofdata == 0 || data == NULL))
868 return GNUTLS_E_INVALID_REQUEST;
871 begin:
873 if (empty_packet > MAX_EMPTY_PACKETS_SEQUENCE)
875 gnutls_assert ();
876 return GNUTLS_E_TOO_MANY_EMPTY_PACKETS;
879 if (session->internals.read_eof != 0)
881 /* if we have already read an EOF
883 return 0;
885 else if (session_is_valid (session) != 0
886 || session->internals.may_not_read != 0)
888 gnutls_assert ();
889 return GNUTLS_E_INVALID_SESSION;
892 /* If we have enough data in the cache do not bother receiving
893 * a new packet. (in order to flush the cache)
895 ret = check_buffers (session, type, data, sizeofdata);
896 if (ret != 0)
897 return ret;
900 /* default headers for TLS 1.0
902 header_size = RECORD_HEADER_SIZE;
904 if ((ret =
905 _gnutls_io_read_buffered (session, &headers, header_size,
906 -1)) != header_size)
908 if (ret < 0 && gnutls_error_is_fatal (ret) == 0)
909 return ret;
911 session_invalidate (session);
912 if (type == GNUTLS_ALERT)
914 gnutls_assert ();
915 return 0; /* we were expecting close notify */
917 session_unresumable (session);
918 gnutls_assert ();
919 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
922 if ((ret =
923 record_check_headers (session, headers, type, htype, &recv_type,
924 version, &length, &header_size)) < 0)
926 gnutls_assert ();
927 return ret;
930 /* Here we check if the Type of the received packet is
931 * ok.
933 if ((ret = check_recv_type (recv_type)) < 0)
935 gnutls_assert ();
936 return ret;
939 /* Here we check if the advertized version is the one we
940 * negotiated in the handshake.
942 if ((ret = record_check_version (session, htype, version)) < 0)
944 gnutls_assert ();
945 session_invalidate (session);
946 return ret;
949 _gnutls_record_log
950 ("REC[%p]: Expected Packet[%d] %s(%d) with length: %d\n", session,
951 (int) _gnutls_uint64touint32 (&session->connection_state.
952 read_sequence_number),
953 _gnutls_packet2str (type), type, (int) sizeofdata);
954 _gnutls_record_log ("REC[%p]: Received Packet[%d] %s(%d) with length: %d\n",
955 session,
956 (int)
957 _gnutls_uint64touint32 (&session->connection_state.
958 read_sequence_number),
959 _gnutls_packet2str (recv_type), recv_type, length);
961 if (length > MAX_RECV_SIZE)
963 _gnutls_record_log
964 ("REC[%p]: FATAL ERROR: Received packet with length: %d\n",
965 session, length);
967 session_unresumable (session);
968 session_invalidate (session);
969 gnutls_assert ();
970 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
973 /* check if we have that data into buffer.
975 if ((ret =
976 _gnutls_io_read_buffered (session, &recv_data,
977 header_size + length,
978 recv_type)) != header_size + length)
980 if (ret < 0 && gnutls_error_is_fatal (ret) == 0)
981 return ret;
983 session_unresumable (session);
984 session_invalidate (session);
985 gnutls_assert ();
986 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
989 /* ok now we are sure that we can read all the data - so
990 * move on !
992 _gnutls_io_clear_read_buffer (session);
993 ciphertext = &recv_data[header_size];
995 ret = get_temp_recv_buffer (session, &tmp);
996 if (ret < 0)
998 gnutls_assert ();
999 return ret;
1002 /* decrypt the data we got.
1004 ret =
1005 _gnutls_decrypt (session, ciphertext, length, tmp.data, tmp.size,
1006 recv_type);
1007 if (ret < 0)
1009 session_unresumable (session);
1010 session_invalidate (session);
1011 gnutls_assert ();
1012 return ret;
1014 decrypted_length = ret;
1016 /* Check if this is a CHANGE_CIPHER_SPEC
1018 if (type == GNUTLS_CHANGE_CIPHER_SPEC &&
1019 recv_type == GNUTLS_CHANGE_CIPHER_SPEC)
1022 _gnutls_record_log
1023 ("REC[%p]: ChangeCipherSpec Packet was received\n", session);
1025 if ((size_t) ret != sizeofdata)
1026 { /* sizeofdata should be 1 */
1027 gnutls_assert ();
1028 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1030 memcpy (data, tmp.data, sizeofdata);
1032 return ret;
1035 _gnutls_record_log
1036 ("REC[%p]: Decrypted Packet[%d] %s(%d) with length: %d\n", session,
1037 (int) _gnutls_uint64touint32 (&session->connection_state.
1038 read_sequence_number),
1039 _gnutls_packet2str (recv_type), recv_type, decrypted_length);
1041 /* increase sequence number
1043 if (_gnutls_uint64pp (&session->connection_state.read_sequence_number) != 0)
1045 session_invalidate (session);
1046 gnutls_assert ();
1047 return GNUTLS_E_RECORD_LIMIT_REACHED;
1050 ret =
1051 record_check_type (session, recv_type, type, htype, tmp.data,
1052 decrypted_length);
1053 if (ret < 0)
1055 if (ret == GNUTLS_E_INT_RET_0)
1056 return 0;
1057 gnutls_assert ();
1058 return ret;
1061 /* Get Application data from buffer
1063 if ((recv_type == type) &&
1064 (type == GNUTLS_APPLICATION_DATA ||
1065 type == GNUTLS_HANDSHAKE || type == GNUTLS_INNER_APPLICATION))
1068 ret = _gnutls_record_buffer_get (type, session, data, sizeofdata);
1069 if (ret < 0)
1071 gnutls_assert ();
1072 return ret;
1075 /* if the buffer just got empty
1077 if (_gnutls_record_buffer_get_size (type, session) == 0)
1079 if ((ret2 = _gnutls_io_clear_peeked_data (session)) < 0)
1081 gnutls_assert ();
1082 return ret2;
1086 else
1088 gnutls_assert ();
1089 return GNUTLS_E_UNEXPECTED_PACKET;
1090 /* we didn't get what we wanted to
1094 /* (originally for) TLS 1.0 CBC protection.
1095 * Actually this code is called if we just received
1096 * an empty packet. An empty TLS packet is usually
1097 * sent to protect some vulnerabilities in the CBC mode.
1098 * In that case we go to the beginning and start reading
1099 * the next packet.
1101 if (ret == 0)
1103 empty_packet++;
1104 goto begin;
1107 return ret;
1112 * gnutls_record_send - sends to the peer the specified data
1113 * @session: is a #gnutls_session_t structure.
1114 * @data: contains the data to send
1115 * @sizeofdata: is the length of the data
1117 * This function has the similar semantics with send(). The only
1118 * difference is that it accepts a GnuTLS session, and uses different
1119 * error codes.
1121 * Note that if the send buffer is full, send() will block this
1122 * function. See the send() documentation for full information. You
1123 * can replace the default push function by using
1124 * gnutls_transport_set_ptr2() with a call to send() with a
1125 * MSG_DONTWAIT flag if blocking is a problem.
1127 * If the EINTR is returned by the internal push function (the
1128 * default is send()} then %GNUTLS_E_INTERRUPTED will be returned. If
1129 * %GNUTLS_E_INTERRUPTED or %GNUTLS_E_AGAIN is returned, you must
1130 * call this function again, with the same parameters; alternatively
1131 * you could provide a %NULL pointer for data, and 0 for
1132 * size. cf. gnutls_record_get_direction().
1134 * Returns: the number of bytes sent, or a negative error code. The
1135 * number of bytes sent might be less than @sizeofdata. The maximum
1136 * number of bytes this function can send in a single call depends on
1137 * the negotiated maximum record size.
1139 ssize_t
1140 gnutls_record_send (gnutls_session_t session, const void *data,
1141 size_t sizeofdata)
1143 return _gnutls_send_int (session, GNUTLS_APPLICATION_DATA, -1, data,
1144 sizeofdata);
1148 * gnutls_record_recv - reads data from the TLS record protocol
1149 * @session: is a #gnutls_session_t structure.
1150 * @data: the buffer that the data will be read into
1151 * @sizeofdata: the number of requested bytes
1153 * This function has the similar semantics with recv(). The only
1154 * difference is that it accepts a GnuTLS session, and uses different
1155 * error codes.
1157 * In the special case that a server requests a renegotiation, the
1158 * client may receive an error code of %GNUTLS_E_REHANDSHAKE. This
1159 * message may be simply ignored, replied with an alert
1160 * %GNUTLS_A_NO_RENEGOTIATION, or replied with a new handshake,
1161 * depending on the client's will.
1163 * If %EINTR is returned by the internal push function (the default
1164 * is recv()) then %GNUTLS_E_INTERRUPTED will be returned. If
1165 * %GNUTLS_E_INTERRUPTED or %GNUTLS_E_AGAIN is returned, you must
1166 * call this function again to get the data. See also
1167 * gnutls_record_get_direction().
1169 * A server may also receive %GNUTLS_E_REHANDSHAKE when a client has
1170 * initiated a handshake. In that case the server can only initiate a
1171 * handshake or terminate the connection.
1173 * Returns: the number of bytes received and zero on EOF. A negative
1174 * error code is returned in case of an error. The number of bytes
1175 * received might be less than @sizeofdata.
1177 ssize_t
1178 gnutls_record_recv (gnutls_session_t session, void *data, size_t sizeofdata)
1180 return _gnutls_recv_int (session, GNUTLS_APPLICATION_DATA, -1, data,
1181 sizeofdata);
1185 * gnutls_record_get_max_size - returns the maximum record size
1186 * @session: is a #gnutls_session_t structure.
1188 * Get the record size. The maximum record size is negotiated by the
1189 * client after the first handshake message.
1191 * Returns: The maximum record packet size in this connection.
1193 size_t
1194 gnutls_record_get_max_size (gnutls_session_t session)
1196 /* Recv will hold the negotiated max record size
1197 * always.
1199 return session->security_parameters.max_record_recv_size;
1204 * gnutls_record_set_max_size - sets the maximum record size
1205 * @session: is a #gnutls_session_t structure.
1206 * @size: is the new size
1208 * This function sets the maximum record packet size in this
1209 * connection. This property can only be set to clients. The server
1210 * may choose not to accept the requested size.
1212 * Acceptable values are 512(=2^9), 1024(=2^10), 2048(=2^11) and
1213 * 4096(=2^12). The requested record size does get in effect
1214 * immediately only while sending data. The receive part will take
1215 * effect after a successful handshake.
1217 * This function uses a TLS extension called 'max record size'. Not
1218 * all TLS implementations use or even understand this extension.
1220 * Returns: On success, %GNUTLS_E_SUCCESS (zero) is returned,
1221 * otherwise an error code is returned.
1223 ssize_t
1224 gnutls_record_set_max_size (gnutls_session_t session, size_t size)
1226 ssize_t new_size;
1228 if (session->security_parameters.entity == GNUTLS_SERVER)
1229 return GNUTLS_E_INVALID_REQUEST;
1231 new_size = _gnutls_mre_record2num (size);
1233 if (new_size < 0)
1235 gnutls_assert ();
1236 return new_size;
1239 session->security_parameters.max_record_send_size = size;
1241 session->internals.proposed_record_size = size;
1243 return 0;