removed keyid_t types.
[gnutls.git] / lib / gnutls_record.c
blob37ef582efaadfba0f558a8f465f11a044ca5fb2d
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 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_mbuffers.h"
36 #include "gnutls_handshake.h"
37 #include "gnutls_hash_int.h"
38 #include "gnutls_cipher_int.h"
39 #include "gnutls_algorithms.h"
40 #include "gnutls_db.h"
41 #include "gnutls_auth.h"
42 #include "gnutls_num.h"
43 #include "gnutls_record.h"
44 #include "gnutls_datum.h"
45 #include "gnutls_constate.h"
46 #include "ext_max_record.h"
47 #include <gnutls_state.h>
48 #include <gnutls_dh.h>
50 void
51 _gnutls_transport_set_lowat (gnutls_session_t session, int num);
53 /**
54 * gnutls_protocol_get_version:
55 * @session: is a #gnutls_session_t structure.
57 * Get TLS version, a #gnutls_protocol_t value.
59 * Returns: the version of the currently used protocol.
60 **/
61 gnutls_protocol_t
62 gnutls_protocol_get_version (gnutls_session_t session)
64 return session->security_parameters.version;
67 void
68 _gnutls_set_current_version (gnutls_session_t session,
69 gnutls_protocol_t version)
71 session->security_parameters.version = version;
74 /* Added to avoid issue in C++ interface not being able to
75 * call deprecated functions.
77 void
78 _gnutls_transport_set_lowat (gnutls_session_t session, int num)
80 session->internals.lowat = num;
83 /**
84 * gnutls_transport_set_lowat:
85 * @session: is a #gnutls_session_t structure.
86 * @num: is the low water value.
88 * Used to set the lowat value in order for select to check if there
89 * are pending data to socket buffer. Used only if you have changed
90 * the default low water value (default is 1). Normally you will not
91 * need that function. This function is only useful if using
92 * berkeley style sockets. Otherwise it must be called and set lowat
93 * to zero.
94 **/
95 void
96 gnutls_transport_set_lowat (gnutls_session_t session, int num)
98 _gnutls_transport_set_lowat(session, num);
102 * gnutls_record_disable_padding:
103 * @session: is a #gnutls_session_t structure.
105 * Used to disabled padding in TLS 1.0 and above. Normally you do not
106 * need to use this function, but there are buggy clients that
107 * complain if a server pads the encrypted data. This of course will
108 * disable protection against statistical attacks on the data.
110 * Normally only servers that require maximum compatibility with everything
111 * out there, need to call this function.
113 void
114 gnutls_record_disable_padding (gnutls_session_t session)
116 session->internals.priorities.no_padding = 1;
120 * gnutls_transport_set_ptr:
121 * @session: is a #gnutls_session_t structure.
122 * @ptr: is the value.
124 * Used to set the first argument of the transport function (like PUSH
125 * and PULL). In berkeley style sockets this function will set the
126 * connection handle.
128 void
129 gnutls_transport_set_ptr (gnutls_session_t session,
130 gnutls_transport_ptr_t ptr)
132 session->internals.transport_recv_ptr = ptr;
133 session->internals.transport_send_ptr = ptr;
137 * gnutls_transport_set_ptr2:
138 * @session: is a #gnutls_session_t structure.
139 * @recv_ptr: is the value for the pull function
140 * @send_ptr: is the value for the push function
142 * Used to set the first argument of the transport function (like PUSH
143 * and PULL). In berkeley style sockets this function will set the
144 * connection handle. With this function you can use two different
145 * pointers for receiving and sending.
147 void
148 gnutls_transport_set_ptr2 (gnutls_session_t session,
149 gnutls_transport_ptr_t recv_ptr,
150 gnutls_transport_ptr_t send_ptr)
152 session->internals.transport_send_ptr = send_ptr;
153 session->internals.transport_recv_ptr = recv_ptr;
157 * gnutls_transport_get_ptr:
158 * @session: is a #gnutls_session_t structure.
160 * Used to get the first argument of the transport function (like
161 * PUSH and PULL). This must have been set using
162 * gnutls_transport_set_ptr().
164 * Returns: first argument of the transport function.
166 gnutls_transport_ptr_t
167 gnutls_transport_get_ptr (gnutls_session_t session)
169 return session->internals.transport_recv_ptr;
173 * gnutls_transport_get_ptr2:
174 * @session: is a #gnutls_session_t structure.
175 * @recv_ptr: will hold the value for the pull function
176 * @send_ptr: will hold the value for the push function
178 * Used to get the arguments of the transport functions (like PUSH
179 * and PULL). These should have been set using
180 * gnutls_transport_set_ptr2().
182 void
183 gnutls_transport_get_ptr2 (gnutls_session_t session,
184 gnutls_transport_ptr_t * recv_ptr,
185 gnutls_transport_ptr_t * send_ptr)
188 *recv_ptr = session->internals.transport_recv_ptr;
189 *send_ptr = session->internals.transport_send_ptr;
193 * gnutls_bye:
194 * @session: is a #gnutls_session_t structure.
195 * @how: is an integer
197 * Terminates the current TLS/SSL connection. The connection should
198 * have been initiated using gnutls_handshake(). @how should be one
199 * of %GNUTLS_SHUT_RDWR, %GNUTLS_SHUT_WR.
201 * In case of %GNUTLS_SHUT_RDWR then the TLS connection gets
202 * terminated and further receives and sends will be disallowed. If
203 * the return value is zero you may continue using the connection.
204 * %GNUTLS_SHUT_RDWR actually sends an alert containing a close
205 * request and waits for the peer to reply with the same message.
207 * In case of %GNUTLS_SHUT_WR then the TLS connection gets terminated
208 * and further sends will be disallowed. In order to reuse the
209 * connection you should wait for an EOF from the peer.
210 * %GNUTLS_SHUT_WR sends an alert containing a close request.
212 * Note that not all implementations will properly terminate a TLS
213 * connection. Some of them, usually for performance reasons, will
214 * terminate only the underlying transport layer, thus causing a
215 * transmission error to the peer. This error cannot be
216 * distinguished from a malicious party prematurely terminating the
217 * session, thus this behavior is not recommended.
219 * This function may also return %GNUTLS_E_AGAIN or
220 * %GNUTLS_E_INTERRUPTED; cf. gnutls_record_get_direction().
222 * Returns: %GNUTLS_E_SUCCESS on success, or an error code, see
223 * function documentation for entire semantics.
226 gnutls_bye (gnutls_session_t session, gnutls_close_request_t how)
228 int ret = 0;
230 switch (STATE)
232 case STATE0:
233 case STATE60:
234 ret = _gnutls_io_write_flush (session);
235 STATE = STATE60;
236 if (ret < 0)
238 gnutls_assert ();
239 return ret;
242 case STATE61:
243 ret =
244 gnutls_alert_send (session, GNUTLS_AL_WARNING, GNUTLS_A_CLOSE_NOTIFY);
245 STATE = STATE61;
246 if (ret < 0)
248 gnutls_assert ();
249 return ret;
252 case STATE62:
253 STATE = STATE62;
254 if (how == GNUTLS_SHUT_RDWR)
258 _gnutls_io_clear_peeked_data (session);
259 ret = _gnutls_recv_int (session, GNUTLS_ALERT, -1, NULL, 0);
261 while (ret == GNUTLS_E_GOT_APPLICATION_DATA);
263 if (ret >= 0)
264 session->internals.may_not_read = 1;
266 if (ret < 0)
268 gnutls_assert ();
269 return ret;
272 STATE = STATE62;
274 break;
275 default:
276 gnutls_assert ();
277 return GNUTLS_E_INTERNAL_ERROR;
280 STATE = STATE0;
282 session->internals.may_not_write = 1;
283 return 0;
286 inline static void
287 session_invalidate (gnutls_session_t session)
289 session->internals.invalid_connection = 1;
293 inline static void
294 session_unresumable (gnutls_session_t session)
296 session->internals.resumable = RESUME_FALSE;
299 /* returns 0 if session is valid
301 inline static int
302 session_is_valid (gnutls_session_t session)
304 if (session->internals.invalid_connection != 0)
305 return GNUTLS_E_INVALID_SESSION;
307 return 0;
310 /* Copies the record version into the headers. The
311 * version must have 2 bytes at least.
313 inline static void
314 copy_record_version (gnutls_session_t session,
315 gnutls_handshake_description_t htype, opaque version[2])
317 gnutls_protocol_t lver;
319 if (session->internals.initial_negotiation_completed || htype != GNUTLS_HANDSHAKE_CLIENT_HELLO
320 || session->internals.default_record_version[0] == 0)
322 lver = gnutls_protocol_get_version (session);
324 version[0] = _gnutls_version_get_major (lver);
325 version[1] = _gnutls_version_get_minor (lver);
327 else
329 version[0] = session->internals.default_record_version[0];
330 version[1] = session->internals.default_record_version[1];
334 /* This function behaves exactly like write(). The only difference is
335 * that it accepts, the gnutls_session_t and the content_type_t of data to
336 * send (if called by the user the Content is specific)
337 * It is intended to transfer data, under the current session.
339 * Oct 30 2001: Removed capability to send data more than MAX_RECORD_SIZE.
340 * This makes the function much easier to read, and more error resistant
341 * (there were cases were the old function could mess everything up).
342 * --nmav
344 * This function may accept a NULL pointer for data, and 0 for size, if
345 * and only if the previous send was interrupted for some reason.
348 ssize_t
349 _gnutls_send_int (gnutls_session_t session, content_type_t type,
350 gnutls_handshake_description_t htype,
351 unsigned int epoch_rel, const void *_data,
352 size_t sizeofdata, unsigned int mflags)
354 mbuffer_st *bufel;
355 size_t cipher_size;
356 int retval, ret;
357 int data2send_size;
358 uint8_t headers[5];
359 const uint8_t *data = _data;
360 record_parameters_st *record_params;
361 record_state_st *record_state;
363 ret = _gnutls_epoch_get (session, epoch_rel, &record_params);
364 if (ret < 0)
366 gnutls_assert ();
367 return ret;
370 /* Safeguard against processing data with an incomplete cipher state. */
371 if (!record_params->initialized)
373 gnutls_assert ();
374 return GNUTLS_E_INVALID_REQUEST;
377 record_state = &record_params->write;
379 /* Do not allow null pointer if the send buffer is empty.
380 * If the previous send was interrupted then a null pointer is
381 * ok, and means to resume.
383 if (session->internals.record_send_buffer.byte_length == 0 &&
384 (sizeofdata == 0 && _data == NULL))
386 gnutls_assert ();
387 return GNUTLS_E_INVALID_REQUEST;
390 if (type != GNUTLS_ALERT) /* alert messages are sent anyway */
391 if (session_is_valid (session) || session->internals.may_not_write != 0)
393 gnutls_assert ();
394 return GNUTLS_E_INVALID_SESSION;
397 headers[0] = type;
399 /* Use the default record version, if it is
400 * set.
402 copy_record_version (session, htype, &headers[1]);
405 _gnutls_record_log
406 ("REC[%p]: Sending Packet[%d] %s(%d) with length: %d\n", session,
407 (int) _gnutls_uint64touint32 (&record_state->sequence_number),
408 _gnutls_packet2str (type), type, (int) sizeofdata);
410 if (sizeofdata > MAX_RECORD_SEND_SIZE)
411 data2send_size = MAX_RECORD_SEND_SIZE;
412 else
413 data2send_size = sizeofdata;
415 /* Only encrypt if we don't have data to send
416 * from the previous run. - probably interrupted.
418 if (mflags != 0 && session->internals.record_send_buffer.byte_length > 0)
420 ret = _gnutls_io_write_flush (session);
421 if (ret > 0)
422 cipher_size = ret;
423 else
424 cipher_size = 0;
426 retval = session->internals.record_send_buffer_user_size;
428 else
431 /* now proceed to packet encryption
433 cipher_size = data2send_size + MAX_RECORD_OVERHEAD;
434 bufel = _mbuffer_alloc (cipher_size, cipher_size);
435 if (bufel == NULL)
437 gnutls_assert ();
438 return GNUTLS_E_MEMORY_ERROR;
441 cipher_size =
442 _gnutls_encrypt (session, headers, RECORD_HEADER_SIZE, data,
443 data2send_size, _mbuffer_get_udata_ptr (bufel),
444 cipher_size, type,
445 (session->internals.priorities.no_padding ==
446 0) ? 1 : 0, record_params);
447 if (cipher_size <= 0)
449 gnutls_assert ();
450 if (cipher_size == 0)
451 cipher_size = GNUTLS_E_ENCRYPTION_FAILED;
452 gnutls_free (bufel);
453 return cipher_size; /* error */
456 retval = data2send_size;
457 session->internals.record_send_buffer_user_size = data2send_size;
459 /* increase sequence number
461 if (_gnutls_uint64pp (&record_state->sequence_number) != 0)
463 session_invalidate (session);
464 gnutls_assert ();
465 gnutls_free (bufel);
466 return GNUTLS_E_RECORD_LIMIT_REACHED;
469 _mbuffer_set_udata_size (bufel, cipher_size);
470 ret = _gnutls_io_write_buffered (session, bufel, mflags);
473 if (ret != cipher_size)
475 if (ret < 0 && gnutls_error_is_fatal (ret) == 0)
477 /* If we have sent any data then just return
478 * the error value. Do not invalidate the session.
480 gnutls_assert ();
481 return ret;
484 if (ret > 0)
486 gnutls_assert ();
487 ret = GNUTLS_E_INTERNAL_ERROR;
489 session_unresumable (session);
490 session->internals.may_not_write = 1;
491 gnutls_assert ();
492 return ret;
495 session->internals.record_send_buffer_user_size = 0;
497 _gnutls_record_log ("REC[%p]: Sent Packet[%d] %s(%d) with length: %d\n",
498 session,
499 (int)
500 _gnutls_uint64touint32
501 (&record_state->sequence_number),
502 _gnutls_packet2str (type), type, (int) cipher_size);
504 return retval;
507 /* This function is to be called if the handshake was successfully
508 * completed. This sends a Change Cipher Spec packet to the peer.
510 ssize_t
511 _gnutls_send_change_cipher_spec (gnutls_session_t session, int again)
513 static const opaque data[1] = { GNUTLS_TYPE_CHANGE_CIPHER_SPEC };
515 _gnutls_handshake_log ("REC[%p]: Sent ChangeCipherSpec\n", session);
517 if (again == 0)
518 return _gnutls_send_int (session, GNUTLS_CHANGE_CIPHER_SPEC, -1,
519 EPOCH_WRITE_CURRENT, data, 1, MBUFFER_FLUSH);
520 else
522 return _gnutls_io_write_flush (session);
526 inline static int
527 check_recv_type (content_type_t recv_type)
529 switch (recv_type)
531 case GNUTLS_CHANGE_CIPHER_SPEC:
532 case GNUTLS_ALERT:
533 case GNUTLS_HANDSHAKE:
534 case GNUTLS_APPLICATION_DATA:
535 case GNUTLS_INNER_APPLICATION:
536 return 0;
537 default:
538 gnutls_assert ();
539 return GNUTLS_E_UNEXPECTED_PACKET;
545 /* Checks if there are pending data in the record buffers. If there are
546 * then it copies the data.
548 static int
549 check_buffers (gnutls_session_t session, content_type_t type,
550 opaque * data, int sizeofdata)
552 if ((type == GNUTLS_APPLICATION_DATA ||
553 type == GNUTLS_HANDSHAKE ||
554 type == GNUTLS_INNER_APPLICATION)
555 && _gnutls_record_buffer_get_size (type, session) > 0)
557 int ret, ret2;
558 ret = _gnutls_record_buffer_get (type, session, data, sizeofdata);
559 if (ret < 0)
561 gnutls_assert ();
562 return ret;
565 /* if the buffer just got empty */
566 if (_gnutls_record_buffer_get_size (type, session) == 0)
568 if ((ret2 = _gnutls_io_clear_peeked_data (session)) < 0)
570 gnutls_assert ();
571 return ret2;
575 return ret;
578 return 0;
582 /* Checks the record headers and returns the length, version and
583 * content type.
585 static int
586 record_check_headers (gnutls_session_t session,
587 uint8_t headers[RECORD_HEADER_SIZE],
588 content_type_t type,
589 gnutls_handshake_description_t htype,
590 /*output */ content_type_t * recv_type,
591 opaque version[2], uint16_t * length,
592 uint16_t * header_size)
595 /* Read the first two bytes to determine if this is a
596 * version 2 message
599 if (htype == GNUTLS_HANDSHAKE_CLIENT_HELLO && type == GNUTLS_HANDSHAKE
600 && headers[0] > 127)
603 /* if msb set and expecting handshake message
604 * it should be SSL 2 hello
606 version[0] = 3; /* assume SSL 3.0 */
607 version[1] = 0;
609 *length = (((headers[0] & 0x7f) << 8)) | headers[1];
611 /* SSL 2.0 headers */
612 *header_size = 2;
613 *recv_type = GNUTLS_HANDSHAKE; /* we accept only v2 client hello
616 /* in order to assist the handshake protocol.
617 * V2 compatibility is a mess.
619 session->internals.v2_hello = *length;
621 _gnutls_record_log ("REC[%p]: V2 packet received. Length: %d\n",
622 session, *length);
625 else
627 /* version 3.x
629 *recv_type = headers[0];
630 version[0] = headers[1];
631 version[1] = headers[2];
633 /* No DECR_LEN, since headers has enough size.
635 *length = _gnutls_read_uint16 (&headers[3]);
638 return 0;
641 /* Here we check if the advertized version is the one we
642 * negotiated in the handshake.
644 inline static int
645 record_check_version (gnutls_session_t session,
646 gnutls_handshake_description_t htype, opaque version[2])
648 if (htype == GNUTLS_HANDSHAKE_CLIENT_HELLO)
650 /* Reject hello packets with major version higher than 3.
652 if (version[0] > 3)
654 gnutls_assert ();
655 _gnutls_record_log
656 ("REC[%p]: INVALID VERSION PACKET: (%d) %d.%d\n", session,
657 htype, version[0], version[1]);
658 return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
661 else if (htype != GNUTLS_HANDSHAKE_SERVER_HELLO &&
662 gnutls_protocol_get_version (session) !=
663 _gnutls_version_get (version[0], version[1]))
665 /* Reject record packets that have a different version than the
666 * one negotiated. Note that this version is not protected by any
667 * mac. I don't really think that this check serves any purpose.
669 gnutls_assert ();
670 _gnutls_record_log ("REC[%p]: INVALID VERSION PACKET: (%d) %d.%d\n",
671 session, htype, version[0], version[1]);
673 return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
676 return 0;
679 /* This function will check if the received record type is
680 * the one we actually expect.
682 static int
683 record_check_type (gnutls_session_t session,
684 content_type_t recv_type, content_type_t type,
685 gnutls_handshake_description_t htype, opaque * data,
686 int data_size)
689 int ret;
691 if ((recv_type == type)
692 && (type == GNUTLS_APPLICATION_DATA ||
693 type == GNUTLS_HANDSHAKE || type == GNUTLS_INNER_APPLICATION))
695 _gnutls_record_buffer_put (type, session, (void *) data, data_size);
697 else
699 switch (recv_type)
701 case GNUTLS_ALERT:
703 _gnutls_record_log
704 ("REC[%p]: Alert[%d|%d] - %s - was received\n", session,
705 data[0], data[1], gnutls_alert_get_name ((int) data[1]));
707 session->internals.last_alert = data[1];
709 /* if close notify is received and
710 * the alert is not fatal
712 if (data[1] == GNUTLS_A_CLOSE_NOTIFY && data[0] != GNUTLS_AL_FATAL)
714 /* If we have been expecting for an alert do
716 session->internals.read_eof = 1;
717 return GNUTLS_E_INT_RET_0; /* EOF */
719 else
722 /* if the alert is FATAL or WARNING
723 * return the apropriate message
726 gnutls_assert ();
727 ret = GNUTLS_E_WARNING_ALERT_RECEIVED;
728 if (data[0] == GNUTLS_AL_FATAL)
730 session_unresumable (session);
731 session_invalidate (session);
732 ret = GNUTLS_E_FATAL_ALERT_RECEIVED;
735 return ret;
737 break;
739 case GNUTLS_CHANGE_CIPHER_SPEC:
740 /* this packet is now handled in the recv_int()
741 * function
743 gnutls_assert ();
745 return GNUTLS_E_UNEXPECTED_PACKET;
747 case GNUTLS_APPLICATION_DATA:
748 if (session->internals.initial_negotiation_completed == 0)
750 return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET);
753 /* even if data is unexpected put it into the buffer */
754 if ((ret =
755 _gnutls_record_buffer_put (recv_type, session,
756 (void *) data, data_size)) < 0)
758 gnutls_assert ();
759 return ret;
762 /* the got_application data is only returned
763 * if expecting client hello (for rehandshake
764 * reasons). Otherwise it is an unexpected packet
766 if (type == GNUTLS_ALERT || (htype == GNUTLS_HANDSHAKE_CLIENT_HELLO
767 && type == GNUTLS_HANDSHAKE))
768 return GNUTLS_E_GOT_APPLICATION_DATA;
769 else
771 gnutls_assert ();
772 return GNUTLS_E_UNEXPECTED_PACKET;
775 break;
776 case GNUTLS_HANDSHAKE:
777 /* This is legal if HELLO_REQUEST is received - and we are a client.
778 * If we are a server, a client may initiate a renegotiation at any time.
780 if (session->security_parameters.entity == GNUTLS_SERVER)
782 gnutls_assert ();
783 ret =
784 _gnutls_record_buffer_put (recv_type, session, (void *) data,
785 data_size);
786 if (ret < 0)
788 gnutls_assert ();
789 return ret;
791 return GNUTLS_E_REHANDSHAKE;
794 /* If we are already in a handshake then a Hello
795 * Request is illegal. But here we don't really care
796 * since this message will never make it up here.
799 /* So we accept it */
800 return _gnutls_recv_hello_request (session, data, data_size);
802 break;
803 case GNUTLS_INNER_APPLICATION:
804 /* even if data is unexpected put it into the buffer */
805 if ((ret = _gnutls_record_buffer_put (recv_type, session,
806 (void *) data,
807 data_size)) < 0)
809 gnutls_assert ();
810 return ret;
812 gnutls_assert ();
813 return GNUTLS_E_UNEXPECTED_PACKET;
814 break;
815 default:
817 _gnutls_record_log
818 ("REC[%p]: Received Unknown packet %d expecting %d\n",
819 session, recv_type, type);
821 gnutls_assert ();
822 return GNUTLS_E_INTERNAL_ERROR;
826 return 0;
831 /* This function will return the internal (per session) temporary
832 * recv buffer. If the buffer was not initialized before it will
833 * also initialize it.
835 inline static int
836 get_temp_recv_buffer (gnutls_session_t session, gnutls_datum_t * tmp)
838 size_t max_record_size;
840 if (gnutls_compression_get (session) != GNUTLS_COMP_NULL ||
841 session->internals.priorities.allow_large_records != 0)
842 max_record_size = MAX_RECORD_RECV_SIZE + EXTRA_COMP_SIZE;
843 else
844 max_record_size = MAX_RECORD_RECV_SIZE;
846 /* We allocate MAX_RECORD_RECV_SIZE length
847 * because we cannot predict the output data by the record
848 * packet length (due to compression).
851 if (max_record_size > session->internals.recv_buffer.size ||
852 session->internals.recv_buffer.data == NULL)
855 /* Initialize the internal buffer.
857 session->internals.recv_buffer.data =
858 gnutls_realloc (session->internals.recv_buffer.data, max_record_size);
860 if (session->internals.recv_buffer.data == NULL)
862 gnutls_assert ();
863 return GNUTLS_E_MEMORY_ERROR;
866 session->internals.recv_buffer.size = max_record_size;
869 tmp->data = session->internals.recv_buffer.data;
870 tmp->size = session->internals.recv_buffer.size;
872 return 0;
876 #define MAX_EMPTY_PACKETS_SEQUENCE 4
878 /* This function behaves exactly like read(). The only difference is
879 * that it accepts the gnutls_session_t and the content_type_t of data to
880 * receive (if called by the user the Content is Userdata only)
881 * It is intended to receive data, under the current session.
883 * The gnutls_handshake_description_t was introduced to support SSL V2.0 client hellos.
885 ssize_t
886 _gnutls_recv_int (gnutls_session_t session, content_type_t type,
887 gnutls_handshake_description_t htype,
888 opaque * data, size_t sizeofdata)
890 int decrypted_length;
891 opaque version[2];
892 content_type_t recv_type;
893 uint16_t length;
894 uint8_t *ciphertext;
895 int ret, ret2;
896 uint16_t header_size;
897 int empty_packet = 0;
898 gnutls_datum_t data_enc, tmp;
899 record_parameters_st *record_params;
900 record_state_st *record_state;
902 ret = _gnutls_epoch_get (session, EPOCH_READ_CURRENT, &record_params);
903 if (ret < 0)
905 gnutls_assert ();
906 return ret;
909 /* Safeguard against processing data with an incomplete cipher state. */
910 if (!record_params->initialized)
912 gnutls_assert ();
913 return GNUTLS_E_INVALID_REQUEST;
916 record_state = &record_params->read;
918 if (type != GNUTLS_ALERT && (sizeofdata == 0 || data == NULL))
920 return GNUTLS_E_INVALID_REQUEST;
923 begin:
925 if (empty_packet > MAX_EMPTY_PACKETS_SEQUENCE)
927 gnutls_assert ();
928 return GNUTLS_E_TOO_MANY_EMPTY_PACKETS;
931 if (session->internals.read_eof != 0)
933 /* if we have already read an EOF
935 return 0;
937 else if (session_is_valid (session) != 0
938 || session->internals.may_not_read != 0)
940 gnutls_assert ();
941 return GNUTLS_E_INVALID_SESSION;
944 /* If we have enough data in the cache do not bother receiving
945 * a new packet. (in order to flush the cache)
947 ret = check_buffers (session, type, data, sizeofdata);
948 if (ret != 0)
949 return ret;
952 /* default headers for TLS 1.0
954 header_size = RECORD_HEADER_SIZE;
956 if ((ret =
957 _gnutls_io_read_buffered (session, header_size, -1)) != header_size)
959 if (ret < 0 && gnutls_error_is_fatal (ret) == 0)
960 return ret;
962 session_invalidate (session);
963 if (type == GNUTLS_ALERT)
965 gnutls_assert ();
966 return 0; /* we were expecting close notify */
968 session_unresumable (session);
969 gnutls_assert ();
970 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
973 ret = _mbuffer_linearize (&session->internals.record_recv_buffer);
974 if (ret != 0)
976 gnutls_assert ();
977 return ret;
980 _mbuffer_get_first (&session->internals.record_recv_buffer, &data_enc);
982 if ((ret =
983 record_check_headers (session, data_enc.data, type, htype, &recv_type,
984 version, &length, &header_size)) < 0)
986 gnutls_assert ();
987 return ret;
990 /* Here we check if the Type of the received packet is
991 * ok.
993 if ((ret = check_recv_type (recv_type)) < 0)
995 gnutls_assert ();
996 return ret;
999 /* Here we check if the advertized version is the one we
1000 * negotiated in the handshake.
1002 if ((ret = record_check_version (session, htype, version)) < 0)
1004 gnutls_assert ();
1005 session_invalidate (session);
1006 return ret;
1009 _gnutls_record_log
1010 ("REC[%p]: Expected Packet[%d] %s(%d) with length: %d\n", session,
1011 (int) _gnutls_uint64touint32 (&record_state->sequence_number),
1012 _gnutls_packet2str (type), type, (int) sizeofdata);
1013 _gnutls_record_log ("REC[%p]: Received Packet[%d] %s(%d) with length: %d\n",
1014 session,
1015 (int)
1016 _gnutls_uint64touint32 (&record_state->sequence_number),
1017 _gnutls_packet2str (recv_type), recv_type, length);
1019 if (length > MAX_RECV_SIZE)
1021 _gnutls_record_log
1022 ("REC[%p]: FATAL ERROR: Received packet with length: %d\n",
1023 session, length);
1025 session_unresumable (session);
1026 session_invalidate (session);
1027 gnutls_assert ();
1028 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1031 /* check if we have that data into buffer.
1033 if ((ret =
1034 _gnutls_io_read_buffered (session, header_size + length,
1035 recv_type)) != header_size + length)
1037 if (ret < 0 && gnutls_error_is_fatal (ret) == 0)
1038 return ret;
1040 session_unresumable (session);
1041 session_invalidate (session);
1042 gnutls_assert ();
1043 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1046 /* ok now we are sure that we can read all the data - so
1047 * move on !
1050 ret = _mbuffer_linearize (&session->internals.record_recv_buffer);
1051 if (ret != 0)
1053 gnutls_assert ();
1054 return ret;
1056 _mbuffer_get_first (&session->internals.record_recv_buffer, &data_enc);
1057 ciphertext = &data_enc.data[header_size];
1059 ret = get_temp_recv_buffer (session, &tmp);
1060 if (ret < 0)
1062 gnutls_assert ();
1063 return ret;
1066 /* decrypt the data we got.
1068 ret =
1069 _gnutls_decrypt (session, ciphertext, length, tmp.data, tmp.size,
1070 recv_type, record_params);
1071 if (ret < 0)
1073 session_unresumable (session);
1074 session_invalidate (session);
1075 gnutls_assert ();
1076 return ret;
1078 _mbuffer_remove_bytes (&session->internals.record_recv_buffer,
1079 header_size + length);
1080 decrypted_length = ret;
1082 /* Check if this is a CHANGE_CIPHER_SPEC
1084 if (type == GNUTLS_CHANGE_CIPHER_SPEC &&
1085 recv_type == GNUTLS_CHANGE_CIPHER_SPEC)
1088 _gnutls_record_log
1089 ("REC[%p]: ChangeCipherSpec Packet was received\n", session);
1091 if ((size_t) ret != sizeofdata)
1092 { /* sizeofdata should be 1 */
1093 gnutls_assert ();
1094 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1096 memcpy (data, tmp.data, sizeofdata);
1098 return ret;
1101 _gnutls_record_log
1102 ("REC[%p]: Decrypted Packet[%d] %s(%d) with length: %d\n", session,
1103 (int) _gnutls_uint64touint32 (&record_state->sequence_number),
1104 _gnutls_packet2str (recv_type), recv_type, decrypted_length);
1106 /* increase sequence number
1108 if (_gnutls_uint64pp (&record_state->sequence_number) != 0)
1110 session_invalidate (session);
1111 gnutls_assert ();
1112 return GNUTLS_E_RECORD_LIMIT_REACHED;
1115 ret =
1116 record_check_type (session, recv_type, type, htype, tmp.data,
1117 decrypted_length);
1118 if (ret < 0)
1120 if (ret == GNUTLS_E_INT_RET_0)
1121 return 0;
1122 gnutls_assert ();
1123 return ret;
1126 /* Get Application data from buffer
1128 if ((recv_type == type) &&
1129 (type == GNUTLS_APPLICATION_DATA ||
1130 type == GNUTLS_HANDSHAKE || type == GNUTLS_INNER_APPLICATION))
1133 ret = _gnutls_record_buffer_get (type, session, data, sizeofdata);
1134 if (ret < 0)
1136 gnutls_assert ();
1137 return ret;
1140 /* if the buffer just got empty
1142 if (_gnutls_record_buffer_get_size (type, session) == 0)
1144 if ((ret2 = _gnutls_io_clear_peeked_data (session)) < 0)
1146 gnutls_assert ();
1147 return ret2;
1151 else
1153 gnutls_assert ();
1154 return GNUTLS_E_UNEXPECTED_PACKET;
1155 /* we didn't get what we wanted to
1159 /* (originally for) TLS 1.0 CBC protection.
1160 * Actually this code is called if we just received
1161 * an empty packet. An empty TLS packet is usually
1162 * sent to protect some vulnerabilities in the CBC mode.
1163 * In that case we go to the beginning and start reading
1164 * the next packet.
1166 if (ret == 0)
1168 empty_packet++;
1169 goto begin;
1172 return ret;
1177 * gnutls_record_send:
1178 * @session: is a #gnutls_session_t structure.
1179 * @data: contains the data to send
1180 * @sizeofdata: is the length of the data
1182 * This function has the similar semantics with send(). The only
1183 * difference is that it accepts a GnuTLS session, and uses different
1184 * error codes.
1186 * Note that if the send buffer is full, send() will block this
1187 * function. See the send() documentation for full information. You
1188 * can replace the default push function by using
1189 * gnutls_transport_set_ptr2() with a call to send() with a
1190 * MSG_DONTWAIT flag if blocking is a problem.
1192 * If the EINTR is returned by the internal push function (the
1193 * default is send()} then %GNUTLS_E_INTERRUPTED will be returned. If
1194 * %GNUTLS_E_INTERRUPTED or %GNUTLS_E_AGAIN is returned, you must
1195 * call this function again, with the same parameters; alternatively
1196 * you could provide a %NULL pointer for data, and 0 for
1197 * size. cf. gnutls_record_get_direction().
1199 * Returns: the number of bytes sent, or a negative error code. The
1200 * number of bytes sent might be less than @sizeofdata. The maximum
1201 * number of bytes this function can send in a single call depends
1202 * on the negotiated maximum record size.
1204 ssize_t
1205 gnutls_record_send (gnutls_session_t session, const void *data,
1206 size_t sizeofdata)
1208 return _gnutls_send_int (session, GNUTLS_APPLICATION_DATA, -1,
1209 EPOCH_WRITE_CURRENT, data, sizeofdata,
1210 MBUFFER_FLUSH);
1214 * gnutls_record_recv:
1215 * @session: is a #gnutls_session_t structure.
1216 * @data: the buffer that the data will be read into
1217 * @sizeofdata: the number of requested bytes
1219 * This function has the similar semantics with recv(). The only
1220 * difference is that it accepts a GnuTLS session, and uses different
1221 * error codes.
1223 * In the special case that a server requests a renegotiation, the
1224 * client may receive an error code of %GNUTLS_E_REHANDSHAKE. This
1225 * message may be simply ignored, replied with an alert
1226 * %GNUTLS_A_NO_RENEGOTIATION, or replied with a new handshake,
1227 * depending on the client's will.
1229 * If %EINTR is returned by the internal push function (the default
1230 * is recv()) then %GNUTLS_E_INTERRUPTED will be returned. If
1231 * %GNUTLS_E_INTERRUPTED or %GNUTLS_E_AGAIN is returned, you must
1232 * call this function again to get the data. See also
1233 * gnutls_record_get_direction().
1235 * A server may also receive %GNUTLS_E_REHANDSHAKE when a client has
1236 * initiated a handshake. In that case the server can only initiate a
1237 * handshake or terminate the connection.
1239 * Returns: the number of bytes received and zero on EOF. A negative
1240 * error code is returned in case of an error. The number of bytes
1241 * received might be less than @sizeofdata.
1243 ssize_t
1244 gnutls_record_recv (gnutls_session_t session, void *data, size_t sizeofdata)
1246 return _gnutls_recv_int (session, GNUTLS_APPLICATION_DATA, -1, data,
1247 sizeofdata);