2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
3 * 2009, 2010, 2011 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,
26 /* Functions that are record layer specific, are included in this file.
29 #include "gnutls_int.h"
30 #include "gnutls_errors.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_dtls.h>
49 #include <gnutls_dh.h>
52 * gnutls_protocol_get_version:
53 * @session: is a #gnutls_session_t structure.
55 * Get TLS version, a #gnutls_protocol_t value.
57 * Returns: the version of the currently used protocol.
60 gnutls_protocol_get_version (gnutls_session_t session
)
62 return session
->security_parameters
.version
;
66 _gnutls_set_current_version (gnutls_session_t session
,
67 gnutls_protocol_t version
)
69 session
->security_parameters
.version
= version
;
73 * gnutls_transport_set_lowat:
74 * @session: is a #gnutls_session_t structure.
75 * @num: is the low water value.
77 * Used to set the lowat value in order for select to check if there
78 * are pending data to socket buffer. Used only if you have changed
79 * the default low water value (default is 1). Normally you will not
80 * need that function. This function is only useful if using
81 * berkeley style sockets. Otherwise it must be called and set lowat
85 gnutls_transport_set_lowat (gnutls_session_t session
, int num
)
87 session
->internals
.lowat
= num
;
91 * gnutls_record_disable_padding:
92 * @session: is a #gnutls_session_t structure.
94 * Used to disabled padding in TLS 1.0 and above. Normally you do not
95 * need to use this function, but there are buggy clients that
96 * complain if a server pads the encrypted data. This of course will
97 * disable protection against statistical attacks on the data.
99 * Normally only servers that require maximum compatibility with everything
100 * out there, need to call this function.
103 gnutls_record_disable_padding (gnutls_session_t session
)
105 session
->internals
.priorities
.no_padding
= 1;
109 * gnutls_transport_set_ptr:
110 * @session: is a #gnutls_session_t structure.
111 * @ptr: is the value.
113 * Used to set the first argument of the transport function (like PUSH
114 * and PULL). In berkeley style sockets this function will set the
118 gnutls_transport_set_ptr (gnutls_session_t session
,
119 gnutls_transport_ptr_t ptr
)
121 session
->internals
.transport_recv_ptr
= ptr
;
122 session
->internals
.transport_send_ptr
= ptr
;
126 * gnutls_transport_set_ptr2:
127 * @session: is a #gnutls_session_t structure.
128 * @recv_ptr: is the value for the pull function
129 * @send_ptr: is the value for the push function
131 * Used to set the first argument of the transport function (like PUSH
132 * and PULL). In berkeley style sockets this function will set the
133 * connection handle. With this function you can use two different
134 * pointers for receiving and sending.
137 gnutls_transport_set_ptr2 (gnutls_session_t session
,
138 gnutls_transport_ptr_t recv_ptr
,
139 gnutls_transport_ptr_t send_ptr
)
141 session
->internals
.transport_send_ptr
= send_ptr
;
142 session
->internals
.transport_recv_ptr
= recv_ptr
;
146 * gnutls_transport_get_ptr:
147 * @session: is a #gnutls_session_t structure.
149 * Used to get the first argument of the transport function (like
150 * PUSH and PULL). This must have been set using
151 * gnutls_transport_set_ptr().
153 * Returns: first argument of the transport function.
155 gnutls_transport_ptr_t
156 gnutls_transport_get_ptr (gnutls_session_t session
)
158 return session
->internals
.transport_recv_ptr
;
162 * gnutls_transport_get_ptr2:
163 * @session: is a #gnutls_session_t structure.
164 * @recv_ptr: will hold the value for the pull function
165 * @send_ptr: will hold the value for the push function
167 * Used to get the arguments of the transport functions (like PUSH
168 * and PULL). These should have been set using
169 * gnutls_transport_set_ptr2().
172 gnutls_transport_get_ptr2 (gnutls_session_t session
,
173 gnutls_transport_ptr_t
* recv_ptr
,
174 gnutls_transport_ptr_t
* send_ptr
)
177 *recv_ptr
= session
->internals
.transport_recv_ptr
;
178 *send_ptr
= session
->internals
.transport_send_ptr
;
183 * @session: is a #gnutls_session_t structure.
184 * @how: is an integer
186 * Terminates the current TLS/SSL connection. The connection should
187 * have been initiated using gnutls_handshake(). @how should be one
188 * of %GNUTLS_SHUT_RDWR, %GNUTLS_SHUT_WR.
190 * In case of %GNUTLS_SHUT_RDWR then the TLS connection gets
191 * terminated and further receives and sends will be disallowed. If
192 * the return value is zero you may continue using the connection.
193 * %GNUTLS_SHUT_RDWR actually sends an alert containing a close
194 * request and waits for the peer to reply with the same message.
196 * In case of %GNUTLS_SHUT_WR then the TLS connection gets terminated
197 * and further sends will be disallowed. In order to reuse the
198 * connection you should wait for an EOF from the peer.
199 * %GNUTLS_SHUT_WR sends an alert containing a close request.
201 * Note that not all implementations will properly terminate a TLS
202 * connection. Some of them, usually for performance reasons, will
203 * terminate only the underlying transport layer, thus causing a
204 * transmission error to the peer. This error cannot be
205 * distinguished from a malicious party prematurely terminating the
206 * session, thus this behavior is not recommended.
208 * This function may also return %GNUTLS_E_AGAIN or
209 * %GNUTLS_E_INTERRUPTED; cf. gnutls_record_get_direction().
211 * Returns: %GNUTLS_E_SUCCESS on success, or an error code, see
212 * function documentation for entire semantics.
215 gnutls_bye (gnutls_session_t session
, gnutls_close_request_t how
)
223 ret
= _gnutls_io_write_flush (session
);
233 gnutls_alert_send (session
, GNUTLS_AL_WARNING
, GNUTLS_A_CLOSE_NOTIFY
);
243 if (how
== GNUTLS_SHUT_RDWR
)
247 _gnutls_io_clear_peeked_data (session
);
248 ret
= _gnutls_recv_int (session
, GNUTLS_ALERT
, -1, NULL
, 0, NULL
);
250 while (ret
== GNUTLS_E_GOT_APPLICATION_DATA
);
253 session
->internals
.may_not_read
= 1;
266 return GNUTLS_E_INTERNAL_ERROR
;
271 session
->internals
.may_not_write
= 1;
276 session_invalidate (gnutls_session_t session
)
278 session
->internals
.invalid_connection
= 1;
283 session_unresumable (gnutls_session_t session
)
285 session
->internals
.resumable
= RESUME_FALSE
;
288 /* returns 0 if session is valid
291 session_is_valid (gnutls_session_t session
)
293 if (session
->internals
.invalid_connection
!= 0)
294 return GNUTLS_E_INVALID_SESSION
;
299 /* Copies the record version into the headers. The
300 * version must have 2 bytes at least.
303 copy_record_version (gnutls_session_t session
,
304 gnutls_handshake_description_t htype
, opaque version
[2])
306 gnutls_protocol_t lver
;
308 if (htype
!= GNUTLS_HANDSHAKE_CLIENT_HELLO
309 || session
->internals
.default_record_version
[0] == 0)
311 lver
= gnutls_protocol_get_version (session
);
313 version
[0] = _gnutls_version_get_major (lver
);
314 version
[1] = _gnutls_version_get_minor (lver
);
318 version
[0] = session
->internals
.default_record_version
[0];
319 version
[1] = session
->internals
.default_record_version
[1];
323 /* Increments the sequence value
326 sequence_increment (gnutls_session_t session
,
329 if (_gnutls_is_dtls(session
))
331 return _gnutls_uint48pp(value
);
335 return _gnutls_uint64pp(value
);
339 /* This function behaves exactly like write(). The only difference is
340 * that it accepts, the gnutls_session_t and the content_type_t of data to
341 * send (if called by the user the Content is specific)
342 * It is intended to transfer data, under the current session.
344 * Oct 30 2001: Removed capability to send data more than MAX_RECORD_SIZE.
345 * This makes the function much easier to read, and more error resistant
346 * (there were cases were the old function could mess everything up).
349 * This function may accept a NULL pointer for data, and 0 for size, if
350 * and only if the previous send was interrupted for some reason.
354 _gnutls_send_int (gnutls_session_t session
, content_type_t type
,
355 gnutls_handshake_description_t htype
,
356 unsigned int epoch_rel
, const void *_data
,
357 size_t data_size
, unsigned int mflags
)
363 uint8_t headers
[MAX_RECORD_HEADER_SIZE
];
365 const uint8_t *data
= _data
;
366 record_parameters_st
*record_params
;
367 record_state_st
*record_state
;
369 ret
= _gnutls_epoch_get (session
, epoch_rel
, &record_params
);
376 /* Safeguard against processing data with an incomplete cipher state. */
377 if (!record_params
->initialized
)
380 return GNUTLS_E_INVALID_REQUEST
;
383 record_state
= &record_params
->write
;
385 /* Do not allow null pointer if the send buffer is empty.
386 * If the previous send was interrupted then a null pointer is
387 * ok, and means to resume.
389 if (session
->internals
.record_send_buffer
.byte_length
== 0 &&
390 (data_size
== 0 && _data
== NULL
))
393 return GNUTLS_E_INVALID_REQUEST
;
396 if (type
!= GNUTLS_ALERT
) /* alert messages are sent anyway */
397 if (session_is_valid (session
) || session
->internals
.may_not_write
!= 0)
400 return GNUTLS_E_INVALID_SESSION
;
405 /* Use the default record version, if it is
408 copy_record_version (session
, htype
, &headers
[1]);
410 header_size
= RECORD_HEADER_SIZE(session
);
411 /* Adjust header length and add sequence for DTLS */
412 if (IS_DTLS(session
))
413 memcpy(&headers
[3], &record_state
->sequence_number
.i
, 8);
416 ("REC[%p]: Preparing Packet %s(%d) with length: %d\n", session
,
417 _gnutls_packet2str (type
), type
, (int) data_size
);
419 if (data_size
> MAX_RECORD_SEND_SIZE(session
))
420 data2send_size
= MAX_RECORD_SEND_SIZE(session
);
422 data2send_size
= data_size
;
424 /* Only encrypt if we don't have data to send
425 * from the previous run. - probably interrupted.
427 if (mflags
!= 0 && session
->internals
.record_send_buffer
.byte_length
> 0)
429 ret
= _gnutls_io_write_flush (session
);
435 retval
= session
->internals
.record_send_buffer_user_size
;
440 /* now proceed to packet encryption
442 cipher_size
= data2send_size
+ MAX_RECORD_OVERHEAD
;
443 bufel
= _mbuffer_alloc (cipher_size
, cipher_size
);
447 return GNUTLS_E_MEMORY_ERROR
;
451 _gnutls_encrypt (session
, headers
, header_size
, data
,
452 data2send_size
, _mbuffer_get_udata_ptr (bufel
),
453 cipher_size
, type
, record_params
);
454 if (cipher_size
<= 0)
457 if (cipher_size
== 0)
458 cipher_size
= GNUTLS_E_ENCRYPTION_FAILED
;
460 return cipher_size
; /* error */
463 retval
= data2send_size
;
464 session
->internals
.record_send_buffer_user_size
= data2send_size
;
466 /* increase sequence number
468 if (sequence_increment (session
, &record_state
->sequence_number
) != 0)
470 session_invalidate (session
);
473 return GNUTLS_E_RECORD_LIMIT_REACHED
;
476 _mbuffer_set_udata_size (bufel
, cipher_size
);
477 ret
= _gnutls_io_write_buffered (session
, bufel
, mflags
);
480 if (ret
!= cipher_size
)
482 if (ret
< 0 && gnutls_error_is_fatal (ret
) == 0)
484 /* If we have sent any data then just return
485 * the error value. Do not invalidate the session.
494 ret
= GNUTLS_E_INTERNAL_ERROR
;
496 session_unresumable (session
);
497 session
->internals
.may_not_write
= 1;
502 session
->internals
.record_send_buffer_user_size
= 0;
504 _gnutls_record_log ("REC[%p]: Sent Packet[%d] %s(%d) with length: %d\n",
507 _gnutls_uint64touint32
508 (&record_state
->sequence_number
),
509 _gnutls_packet2str (type
), type
, (int) cipher_size
);
515 check_recv_type (content_type_t recv_type
)
519 case GNUTLS_CHANGE_CIPHER_SPEC
:
521 case GNUTLS_HANDSHAKE
:
522 case GNUTLS_APPLICATION_DATA
:
523 case GNUTLS_INNER_APPLICATION
:
527 _gnutls_audit_log("Received record packet of unknown type %u\n", (unsigned int)recv_type
);
528 return GNUTLS_E_UNEXPECTED_PACKET
;
534 /* Checks if there are pending data in the record buffers. If there are
535 * then it copies the data.
538 check_buffers (gnutls_session_t session
, content_type_t type
,
539 opaque
* data
, int data_size
)
541 if ((type
== GNUTLS_APPLICATION_DATA
||
542 type
== GNUTLS_HANDSHAKE
||
543 type
== GNUTLS_INNER_APPLICATION
)
544 && _gnutls_record_buffer_get_size (type
, session
) > 0)
547 ret
= _gnutls_record_buffer_get (type
, session
, data
, data_size
);
554 /* if the buffer just got empty */
555 if (_gnutls_record_buffer_get_size (type
, session
) == 0)
557 if ((ret2
= _gnutls_io_clear_peeked_data (session
)) < 0)
572 /* Here we check if the advertized version is the one we
573 * negotiated in the handshake.
576 record_check_version (gnutls_session_t session
,
577 gnutls_handshake_description_t htype
, opaque version
[2])
579 if (htype
== GNUTLS_HANDSHAKE_CLIENT_HELLO
)
581 /* Reject hello packets with major version higher than 3.
583 if (!(IS_DTLS(session
)) && version
[0] > 3)
587 ("REC[%p]: INVALID VERSION PACKET: (%d) %d.%d\n", session
,
588 htype
, version
[0], version
[1]);
589 return GNUTLS_E_UNSUPPORTED_VERSION_PACKET
;
592 else if (htype
!= GNUTLS_HANDSHAKE_SERVER_HELLO
&&
593 gnutls_protocol_get_version (session
) !=
594 _gnutls_version_get (version
[0], version
[1]))
596 /* Reject record packets that have a different version than the
597 * one negotiated. Note that this version is not protected by any
598 * mac. I don't really think that this check serves any purpose.
601 _gnutls_record_log ("REC[%p]: INVALID VERSION PACKET: (%d) %d.%d\n",
602 session
, htype
, version
[0], version
[1]);
604 return GNUTLS_E_UNSUPPORTED_VERSION_PACKET
;
610 /* This function will check if the received record type is
611 * the one we actually expect and adds it to the proper
615 record_add_to_buffers (gnutls_session_t session
,
616 content_type_t recv_type
, content_type_t type
,
617 gnutls_handshake_description_t htype
, opaque
* data
,
623 if ((recv_type
== type
)
624 && (type
== GNUTLS_APPLICATION_DATA
||
625 type
== GNUTLS_HANDSHAKE
|| type
== GNUTLS_INNER_APPLICATION
))
627 _gnutls_record_buffer_put (type
, session
, (void *) data
, data_size
);
636 ("REC[%p]: Alert[%d|%d] - %s - was received\n", session
,
637 data
[0], data
[1], gnutls_alert_get_name ((int) data
[1]));
639 session
->internals
.last_alert
= data
[1];
641 /* if close notify is received and
642 * the alert is not fatal
644 if (data
[1] == GNUTLS_A_CLOSE_NOTIFY
&& data
[0] != GNUTLS_AL_FATAL
)
646 /* If we have been expecting for an alert do
648 session
->internals
.read_eof
= 1;
649 return GNUTLS_E_INT_RET_0
; /* EOF */
654 /* if the alert is FATAL or WARNING
655 * return the apropriate message
659 ret
= GNUTLS_E_WARNING_ALERT_RECEIVED
;
660 if (data
[0] == GNUTLS_AL_FATAL
)
662 session_unresumable (session
);
663 session_invalidate (session
);
664 ret
= GNUTLS_E_FATAL_ALERT_RECEIVED
;
671 case GNUTLS_CHANGE_CIPHER_SPEC
:
672 /* this packet is now handled in the recv_int()
677 return GNUTLS_E_UNEXPECTED_PACKET
;
679 case GNUTLS_APPLICATION_DATA
:
680 /* even if data is unexpected put it into the buffer */
682 _gnutls_record_buffer_put (recv_type
, session
,
683 (void *) data
, data_size
)) < 0)
689 /* the got_application data is only returned
690 * if expecting client hello (for rehandshake
691 * reasons). Otherwise it is an unexpected packet
693 if (type
== GNUTLS_ALERT
|| (htype
== GNUTLS_HANDSHAKE_CLIENT_HELLO
694 && type
== GNUTLS_HANDSHAKE
))
695 return GNUTLS_E_GOT_APPLICATION_DATA
;
699 return GNUTLS_E_UNEXPECTED_PACKET
;
703 case GNUTLS_HANDSHAKE
:
704 /* This is legal if HELLO_REQUEST is received - and we are a client.
705 * If we are a server, a client may initiate a renegotiation at any time.
707 if (session
->security_parameters
.entity
== GNUTLS_SERVER
)
711 _gnutls_record_buffer_put (recv_type
, session
, (void *) data
,
718 return GNUTLS_E_REHANDSHAKE
;
721 /* If we are already in a handshake then a Hello
722 * Request is illegal. But here we don't really care
723 * since this message will never make it up here.
726 /* So we accept it */
727 return _gnutls_recv_hello_request (session
, data
, data_size
);
730 case GNUTLS_INNER_APPLICATION
:
731 /* even if data is unexpected put it into the buffer */
732 if ((ret
= _gnutls_record_buffer_put (recv_type
, session
,
740 return GNUTLS_E_UNEXPECTED_PACKET
;
745 ("REC[%p]: Received Unknown packet %d expecting %d\n",
746 session
, recv_type
, type
);
749 return GNUTLS_E_INTERNAL_ERROR
;
758 /* This function will return the internal (per session) temporary
759 * recv buffer. If the buffer was not initialized before it will
760 * also initialize it.
763 get_temp_recv_buffer (gnutls_session_t session
, gnutls_datum_t
* tmp
)
765 size_t max_record_size
;
767 if (gnutls_compression_get (session
) != GNUTLS_COMP_NULL
||
768 session
->internals
.priorities
.allow_large_records
!= 0)
769 max_record_size
= MAX_RECORD_RECV_SIZE(session
) + EXTRA_COMP_SIZE
;
771 max_record_size
= MAX_RECORD_RECV_SIZE(session
);
773 /* We allocate MAX_RECORD_RECV_SIZE length
774 * because we cannot predict the output data by the record
775 * packet length (due to compression).
778 if (max_record_size
> session
->internals
.recv_buffer
.size
||
779 session
->internals
.recv_buffer
.data
== NULL
)
782 /* Initialize the internal buffer.
784 session
->internals
.recv_buffer
.data
=
785 gnutls_realloc (session
->internals
.recv_buffer
.data
, max_record_size
);
787 if (session
->internals
.recv_buffer
.data
== NULL
)
790 return GNUTLS_E_MEMORY_ERROR
;
793 session
->internals
.recv_buffer
.size
= max_record_size
;
796 tmp
->data
= session
->internals
.recv_buffer
.data
;
797 tmp
->size
= session
->internals
.recv_buffer
.size
;
802 struct tls_record_st
{
803 uint16_t header_size
;
805 uint64 sequence
; /* DTLS */
807 uint16_t packet_size
; /* header_size + length */
813 /* Checks the record headers and returns the length, version and
817 record_read_headers (gnutls_session_t session
,
818 uint8_t headers
[MAX_RECORD_HEADER_SIZE
],
820 gnutls_handshake_description_t htype
,
821 struct tls_record_st
* record
)
824 /* Read the first two bytes to determine if this is a
828 if (htype
== GNUTLS_HANDSHAKE_CLIENT_HELLO
&& type
== GNUTLS_HANDSHAKE
829 && headers
[0] > 127 && !(IS_DTLS(session
)))
832 /* if msb set and expecting handshake message
833 * it should be SSL 2 hello
835 record
->version
[0] = 3; /* assume SSL 3.0 */
836 record
->version
[1] = 0;
838 record
->length
= (((headers
[0] & 0x7f) << 8)) | headers
[1];
840 /* SSL 2.0 headers */
841 record
->header_size
= 2;
842 record
->type
= GNUTLS_HANDSHAKE
; /* we accept only v2 client hello
845 /* in order to assist the handshake protocol.
846 * V2 compatibility is a mess.
848 session
->internals
.v2_hello
= record
->length
;
850 _gnutls_record_log ("REC[%p]: V2 packet received. Length: %d\n",
851 session
, record
->length
);
856 /* dtls version 1.0 and TLS version 1.x */
857 record
->type
= headers
[0];
858 record
->version
[0] = headers
[1];
859 record
->version
[1] = headers
[2];
863 memcpy(record
->sequence
.i
, &headers
[3], 8);
864 record
->length
= _gnutls_read_uint16 (&headers
[11]);
867 record
->length
= _gnutls_read_uint16 (&headers
[3]);
870 record
->packet_size
+= record
->length
;
874 static int recv_headers( gnutls_session_t session
, content_type_t type
,
875 gnutls_handshake_description_t htype
, struct tls_record_st
* record
)
880 record
->header_size
= record
->packet_size
= RECORD_HEADER_SIZE(session
);
883 _gnutls_io_read_buffered (session
, record
->header_size
, -1)) != record
->header_size
)
886 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH
;
889 ret
= _mbuffer_linearize (&session
->internals
.record_recv_buffer
);
896 _mbuffer_get_first (&session
->internals
.record_recv_buffer
, &record
->data
);
898 record_read_headers (session
, record
->data
.data
, type
, htype
, record
);
900 /* Check if the DTLS epoch is valid */
901 if (IS_DTLS(session
))
903 uint16_t epoch
= _gnutls_read_uint16(record
->sequence
.i
);
905 if (_gnutls_epoch_is_valid(session
, epoch
) == 0)
907 _gnutls_audit_log("Discarded message[%u] with invalid epoch 0x%.2x%.2x.\n",
908 (unsigned int)_gnutls_uint64touint32 (&record
->sequence
), (int)record
->sequence
.i
[0],
909 (int)record
->sequence
.i
[1]);
911 /* doesn't matter, just a fatal error */
912 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH
;
916 /* Here we check if the Type of the received packet is
919 if ((ret
= check_recv_type (record
->type
)) < 0)
925 /* Here we check if the advertized version is the one we
926 * negotiated in the handshake.
928 if ((ret
= record_check_version (session
, htype
, record
->version
)) < 0)
934 if (record
->length
> MAX_RECV_SIZE(session
))
937 ("Received packet with illegal length: %u\n", (unsigned int)record
->length
);
939 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH
;
943 ("REC[%p]: Expected Packet %s(%d)\n", session
,
944 _gnutls_packet2str (type
), type
);
945 _gnutls_record_log ("REC[%p]: Received Packet %s(%d) with length: %d\n",
947 _gnutls_packet2str (record
->type
), record
->type
, record
->length
);
953 #define MAX_EMPTY_PACKETS_SEQUENCE 4
955 /* This function behaves exactly like read(). The only difference is
956 * that it accepts the gnutls_session_t and the content_type_t of data to
957 * receive (if called by the user the Content is Userdata only)
958 * It is intended to receive data, under the current session.
960 * The gnutls_handshake_description_t was introduced to support SSL V2.0 client hellos.
963 _gnutls_recv_int (gnutls_session_t session
, content_type_t type
,
964 gnutls_handshake_description_t htype
,
965 opaque
* data
, size_t data_size
, void* seq
)
967 uint64
*packet_sequence
;
970 int empty_packet
= 0;
971 gnutls_datum_t decrypted
;
972 record_parameters_st
*record_params
;
973 record_state_st
*record_state
;
974 struct tls_record_st record
;
976 memset(&record
, 0, sizeof(record
));
978 if (type
!= GNUTLS_ALERT
&& (data_size
== 0 || data
== NULL
))
980 return GNUTLS_E_INVALID_REQUEST
;
985 if (empty_packet
> MAX_EMPTY_PACKETS_SEQUENCE
)
988 return GNUTLS_E_TOO_MANY_EMPTY_PACKETS
;
991 if (session
->internals
.read_eof
!= 0)
993 /* if we have already read an EOF
997 else if (session_is_valid (session
) != 0
998 || session
->internals
.may_not_read
!= 0)
1001 return GNUTLS_E_INVALID_SESSION
;
1004 /* If we have enough data in the cache do not bother receiving
1005 * a new packet. (in order to flush the cache)
1007 ret
= check_buffers (session
, type
, data
, data_size
);
1011 ret
= recv_headers(session
, type
, htype
, &record
);
1018 /* get the record state parameters */
1019 ret
= _gnutls_epoch_get (session
, EPOCH_READ_CURRENT
, &record_params
);
1021 return gnutls_assert_val (ret
);
1023 /* Safeguard against processing data with an incomplete cipher state. */
1024 if (!record_params
->initialized
)
1025 return gnutls_assert_val (GNUTLS_E_INTERNAL_ERROR
);
1027 record_state
= &record_params
->read
;
1029 /* Check if the DTLS epoch is valid */
1030 if (IS_DTLS(session
))
1031 packet_sequence
= &record
.sequence
;
1033 packet_sequence
= &record_state
->sequence_number
;
1036 memcpy(seq
, packet_sequence
, 8);
1038 /* Read the packet data and insert it to record_recv_buffer.
1041 _gnutls_io_read_buffered (session
, record
.packet_size
,
1043 if (ret
!= record
.packet_size
)
1049 /* ok now we are sure that we have read all the data - so
1052 ret
= _mbuffer_linearize (&session
->internals
.record_recv_buffer
);
1058 _mbuffer_get_first (&session
->internals
.record_recv_buffer
, &record
.data
);
1059 ciphertext
= &record
.data
.data
[record
.header_size
];
1061 ret
= get_temp_recv_buffer (session
, &decrypted
);
1068 /* decrypt the data we got.
1071 _gnutls_decrypt (session
, ciphertext
, record
.length
, decrypted
.data
, decrypted
.size
,
1072 record
.type
, record_params
, packet_sequence
);
1073 decrypted
.size
= ret
;
1078 goto sanity_check_error
;
1081 /* remove the decrypted packet from buffers */
1082 _mbuffer_remove_bytes (&session
->internals
.record_recv_buffer
,
1083 record
.packet_size
);
1085 /* check for duplicates. We check after the message
1086 * is processed and authenticated to avoid someone
1087 * messing with our windows.
1089 if (IS_DTLS(session
))
1091 ret
= _dtls_record_check(session
, packet_sequence
);
1094 _gnutls_audit_log("Discarded duplicate message[%u]\n",
1095 (unsigned int) _gnutls_uint64touint32 (packet_sequence
));
1100 /* Check if this is a CHANGE_CIPHER_SPEC
1102 if (type
== GNUTLS_CHANGE_CIPHER_SPEC
&& type
== record
.type
)
1106 ("REC[%p]: ChangeCipherSpec Packet was received\n", session
);
1108 if ((size_t) decrypted
.size
!= data_size
)
1109 { /* data_size should be 1 */
1111 ret
= GNUTLS_E_UNEXPECTED_PACKET_LENGTH
;
1112 goto sanity_check_error
;
1114 data
[0] = decrypted
.data
[0];
1120 ("REC[%p]: Decrypted Packet[%d] %s(%d) with length: %d\n", session
,
1121 (int) _gnutls_uint64touint32 (packet_sequence
),
1122 _gnutls_packet2str (record
.type
), record
.type
, decrypted
.size
);
1124 /* increase sequence number
1126 if (!IS_DTLS(session
) && sequence_increment (session
, &record_state
->sequence_number
) != 0)
1128 session_invalidate (session
);
1130 return GNUTLS_E_RECORD_LIMIT_REACHED
;
1134 record_add_to_buffers (session
, record
.type
, type
, htype
, decrypted
.data
, decrypted
.size
);
1137 if (ret
== GNUTLS_E_INT_RET_0
)
1143 /* Get Application data from buffer
1145 if ((record
.type
== type
) &&
1146 (type
== GNUTLS_APPLICATION_DATA
||
1147 type
== GNUTLS_HANDSHAKE
|| type
== GNUTLS_INNER_APPLICATION
))
1150 ret
= _gnutls_record_buffer_get (type
, session
, data
, data_size
);
1157 /* if the buffer just got empty
1159 if (_gnutls_record_buffer_get_size (type
, session
) == 0)
1161 if ((ret2
= _gnutls_io_clear_peeked_data (session
)) < 0)
1171 return GNUTLS_E_UNEXPECTED_PACKET
;
1172 /* we didn't get what we wanted to
1176 /* (originally for) TLS 1.0 CBC protection.
1177 * Actually this code is called if we just received
1178 * an empty packet. An empty TLS packet is usually
1179 * sent to protect some vulnerabilities in the CBC mode.
1180 * In that case we go to the beginning and start reading
1192 _mbuffer_remove_bytes (&session
->internals
.record_recv_buffer
,
1193 record
.packet_size
);
1195 return GNUTLS_E_AGAIN
;
1198 if (IS_DTLS(session
))
1200 _gnutls_audit_log("Discarded message[%u] due to invalid decryption\n",
1201 (unsigned int)_gnutls_uint64touint32 (packet_sequence
));
1204 session_unresumable (session
);
1205 session_invalidate (session
);
1209 if (gnutls_error_is_fatal (ret
) == 0)
1212 if (IS_DTLS(session
))
1217 session_invalidate (session
);
1218 if (type
== GNUTLS_ALERT
) /* we were expecting close notify */
1223 session_unresumable (session
);
1226 return GNUTLS_E_PREMATURE_TERMINATION
;
1233 * gnutls_record_send:
1234 * @session: is a #gnutls_session_t structure.
1235 * @data: contains the data to send
1236 * @data_size: is the length of the data
1238 * This function has the similar semantics with send(). The only
1239 * difference is that it accepts a GnuTLS session, and uses different
1242 * Note that if the send buffer is full, send() will block this
1243 * function. See the send() documentation for full information. You
1244 * can replace the default push function by using
1245 * gnutls_transport_set_ptr2() with a call to send() with a
1246 * MSG_DONTWAIT flag if blocking is a problem.
1248 * If the EINTR is returned by the internal push function (the
1249 * default is send()} then %GNUTLS_E_INTERRUPTED will be returned. If
1250 * %GNUTLS_E_INTERRUPTED or %GNUTLS_E_AGAIN is returned, you must
1251 * call this function again, with the same parameters; alternatively
1252 * you could provide a %NULL pointer for data, and 0 for
1253 * size. cf. gnutls_record_get_direction().
1255 * Returns: the number of bytes sent, or a negative error code. The
1256 * number of bytes sent might be less than @data_size. The maximum
1257 * number of bytes this function can send in a single call depends
1258 * on the negotiated maximum record size.
1261 gnutls_record_send (gnutls_session_t session
, const void *data
,
1264 return _gnutls_send_int (session
, GNUTLS_APPLICATION_DATA
, -1,
1265 EPOCH_WRITE_CURRENT
, data
, data_size
,
1270 * gnutls_record_recv:
1271 * @session: is a #gnutls_session_t structure.
1272 * @data: the buffer that the data will be read into
1273 * @data_size: the number of requested bytes
1275 * This function has the similar semantics with recv(). The only
1276 * difference is that it accepts a GnuTLS session, and uses different
1279 * In the special case that a server requests a renegotiation, the
1280 * client may receive an error code of %GNUTLS_E_REHANDSHAKE. This
1281 * message may be simply ignored, replied with an alert
1282 * %GNUTLS_A_NO_RENEGOTIATION, or replied with a new handshake,
1283 * depending on the client's will.
1285 * If %EINTR is returned by the internal push function (the default
1286 * is recv()) then %GNUTLS_E_INTERRUPTED will be returned. If
1287 * %GNUTLS_E_INTERRUPTED or %GNUTLS_E_AGAIN is returned, you must
1288 * call this function again to get the data. See also
1289 * gnutls_record_get_direction().
1291 * A server may also receive %GNUTLS_E_REHANDSHAKE when a client has
1292 * initiated a handshake. In that case the server can only initiate a
1293 * handshake or terminate the connection.
1295 * Returns: the number of bytes received and zero on EOF. A negative
1296 * error code is returned in case of an error. The number of bytes
1297 * received might be less than @data_size.
1300 gnutls_record_recv (gnutls_session_t session
, void *data
, size_t data_size
)
1302 return _gnutls_recv_int (session
, GNUTLS_APPLICATION_DATA
, -1, data
,
1307 * gnutls_record_recv_seq:
1308 * @session: is a #gnutls_session_t structure.
1309 * @data: the buffer that the data will be read into
1310 * @data_size: the number of requested bytes
1311 * @seq: is the packet's 64-bit sequence number.
1313 * This function is the same as gnutls_record_recv(), except that
1314 * it returns in addition to data, the sequence number of the data.
1315 * This is useful in DTLS where record packets might be received
1318 * In DTLS the least significant 48-bits are a unique sequence
1319 * number, per handshake. If your application is using TLS re-handshakes
1320 * then the full 64-bits should be used as a unique sequence.
1322 * Returns: the number of bytes received and zero on EOF. A negative
1323 * error code is returned in case of an error. The number of bytes
1324 * received might be less than @data_size.
1327 gnutls_record_recv_seq (gnutls_session_t session
, void *data
, size_t data_size
,
1328 unsigned char seq
[8])
1330 return _gnutls_recv_int (session
, GNUTLS_APPLICATION_DATA
, -1, data
,