Imported Upstream version 3.3.5
[platform/upstream/gnutls.git] / lib / gnutls_record.c
1 /*
2  * Copyright (C) 2000-2013 Free Software Foundation, Inc.
3  * Copyright (C) 2012,2013 Nikos Mavrogiannopoulos
4  *
5  * Author: Nikos Mavrogiannopoulos
6  *
7  * This file is part of GnuTLS.
8  *
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.
13  *
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.
18  *
19  * You should have received a copy of the GNU Lesser General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>
21  *
22  */
23
24 /* Functions that are record layer specific, are included in this file.
25  */
26
27 /* allocate this many bytes more when encrypting or decrypting, to
28  * compensate for broken backends such as cryptodev.
29  */
30 #define CIPHER_SLACK_SIZE 32
31
32 #include "gnutls_int.h"
33 #include "gnutls_errors.h"
34 #include "debug.h"
35 #include "gnutls_compress.h"
36 #include "gnutls_cipher.h"
37 #include "gnutls_buffers.h"
38 #include "gnutls_mbuffers.h"
39 #include "gnutls_handshake.h"
40 #include "gnutls_hash_int.h"
41 #include "gnutls_cipher_int.h"
42 #include "algorithms.h"
43 #include "gnutls_db.h"
44 #include "gnutls_auth.h"
45 #include "gnutls_num.h"
46 #include "gnutls_record.h"
47 #include "gnutls_datum.h"
48 #include "gnutls_constate.h"
49 #include "ext/max_record.h"
50 #include <ext/heartbeat.h>
51 #include <gnutls_state.h>
52 #include <gnutls_dtls.h>
53 #include <gnutls_dh.h>
54 #include <random.h>
55
56 struct tls_record_st {
57         uint16_t header_size;
58         uint8_t version[2];
59         uint64 sequence;        /* DTLS */
60         uint16_t length;
61         uint16_t packet_size;   /* header_size + length */
62         content_type_t type;
63         uint16_t epoch;         /* valid in DTLS only */
64         unsigned v2:1;          /* whether an SSLv2 client hello */
65         /* the data */
66 };
67
68 /**
69  * gnutls_record_disable_padding:  
70  * @session: is a #gnutls_session_t structure.
71  *
72  * Used to disabled padding in TLS 1.0 and above.  Normally you do not
73  * need to use this function, but there are buggy clients that
74  * complain if a server pads the encrypted data.  This of course will
75  * disable protection against statistical attacks on the data.
76  *
77  * This functions is defunt since 3.1.7. Random padding is disabled
78  * by default unless requested using gnutls_range_send_message().
79  *
80  **/
81 void gnutls_record_disable_padding(gnutls_session_t session)
82 {
83         return;
84 }
85
86 /**
87  * gnutls_record_set_max_empty_records:
88  * @session: is a #gnutls_session_t structure.
89  * @i: is the desired value of maximum empty records that can be accepted in a row.
90  *
91  * Used to set the maximum number of empty fragments that can be accepted
92  * in a row. Accepting many empty fragments is useful for receiving length-hidden
93  * content, where empty fragments filled with pad are sent to hide the real
94  * length of a message. However, a malicious peer could send empty fragments to
95  * mount a DoS attack, so as a safety measure, a maximum number of empty fragments
96  * is accepted by default. If you know your application must accept a given number
97  * of empty fragments in a row, you can use this function to set the desired value.
98  **/
99 void
100 gnutls_record_set_max_empty_records(gnutls_session_t session,
101                                     const unsigned int i)
102 {
103         session->internals.priorities.max_empty_records = i;
104 }
105
106 /**
107  * gnutls_transport_set_ptr:
108  * @session: is a #gnutls_session_t structure.
109  * @ptr: is the value.
110  *
111  * Used to set the first argument of the transport function (for push
112  * and pull callbacks). In berkeley style sockets this function will set the
113  * connection descriptor.
114  * 
115  **/
116 void
117 gnutls_transport_set_ptr(gnutls_session_t session,
118                          gnutls_transport_ptr_t ptr)
119 {
120         session->internals.transport_recv_ptr = ptr;
121         session->internals.transport_send_ptr = ptr;
122 }
123
124 /**
125  * gnutls_transport_set_ptr2:
126  * @session: is a #gnutls_session_t structure.
127  * @recv_ptr: is the value for the pull function
128  * @send_ptr: is the value for the push function
129  *
130  * Used to set the first argument of the transport function (for push
131  * and pull callbacks). In berkeley style sockets this function will set the
132  * connection descriptor.  With this function you can use two different
133  * pointers for receiving and sending.
134  **/
135 void
136 gnutls_transport_set_ptr2(gnutls_session_t session,
137                           gnutls_transport_ptr_t recv_ptr,
138                           gnutls_transport_ptr_t send_ptr)
139 {
140         session->internals.transport_send_ptr = send_ptr;
141         session->internals.transport_recv_ptr = recv_ptr;
142 }
143
144 /**
145  * gnutls_transport_set_int2:
146  * @session: is a #gnutls_session_t structure.
147  * @recv_int: is the value for the pull function
148  * @send_int: is the value for the push function
149  *
150  * Used to set the first argument of the transport function (for push
151  * and pull callbacks), when using the berkeley style sockets. 
152  * With this function you can set two different
153  * pointers for receiving and sending.
154  *
155  * Since: 3.1.9
156  **/
157 void
158 gnutls_transport_set_int2(gnutls_session_t session,
159                           int recv_int, int send_int)
160 {
161         session->internals.transport_send_ptr =
162             (gnutls_transport_ptr_t) (long) send_int;
163         session->internals.transport_recv_ptr =
164             (gnutls_transport_ptr_t) (long) recv_int;
165 }
166
167 #if 0
168 /* this will be a macro */
169 /**
170  * gnutls_transport_set_int:
171  * @session: is a #gnutls_session_t structure.
172  * @i: is the value.
173  *
174  * Used to set the first argument of the transport function (for push
175  * and pull callbacks) for berkeley style sockets.
176  *
177  * Since: 3.1.9
178  * 
179  **/
180 void gnutls_transport_set_int(gnutls_session_t session, int i)
181 {
182         session->internals.transport_recv_ptr =
183             (gnutls_transport_ptr_t) (long) i;
184         session->internals.transport_send_ptr =
185             (gnutls_transport_ptr_t) (long) i;
186 }
187 #endif
188
189 /**
190  * gnutls_transport_get_ptr:
191  * @session: is a #gnutls_session_t structure.
192  *
193  * Used to get the first argument of the transport function (like
194  * PUSH and PULL).  This must have been set using
195  * gnutls_transport_set_ptr().
196  *
197  * Returns: The first argument of the transport function.
198  **/
199 gnutls_transport_ptr_t gnutls_transport_get_ptr(gnutls_session_t session)
200 {
201         return session->internals.transport_recv_ptr;
202 }
203
204 /**
205  * gnutls_transport_get_ptr2:
206  * @session: is a #gnutls_session_t structure.
207  * @recv_ptr: will hold the value for the pull function
208  * @send_ptr: will hold the value for the push function
209  *
210  * Used to get the arguments of the transport functions (like PUSH
211  * and PULL).  These should have been set using
212  * gnutls_transport_set_ptr2().
213  **/
214 void
215 gnutls_transport_get_ptr2(gnutls_session_t session,
216                           gnutls_transport_ptr_t * recv_ptr,
217                           gnutls_transport_ptr_t * send_ptr)
218 {
219
220         *recv_ptr = session->internals.transport_recv_ptr;
221         *send_ptr = session->internals.transport_send_ptr;
222 }
223
224 /**
225  * gnutls_transport_get_int2:
226  * @session: is a #gnutls_session_t structure.
227  * @recv_int: will hold the value for the pull function
228  * @send_int: will hold the value for the push function
229  *
230  * Used to get the arguments of the transport functions (like PUSH
231  * and PULL).  These should have been set using
232  * gnutls_transport_set_int2().
233  *
234  * Since: 3.1.9
235  **/
236 void
237 gnutls_transport_get_int2(gnutls_session_t session,
238                           int *recv_int, int *send_int)
239 {
240
241         *recv_int = (long) session->internals.transport_recv_ptr;
242         *send_int = (long) session->internals.transport_send_ptr;
243 }
244
245 /**
246  * gnutls_transport_get_int:
247  * @session: is a #gnutls_session_t structure.
248  *
249  * Used to get the first argument of the transport function (like
250  * PUSH and PULL).  This must have been set using
251  * gnutls_transport_set_int().
252  *
253  * Returns: The first argument of the transport function.
254  *
255  * Since: 3.1.9
256  **/
257 int gnutls_transport_get_int(gnutls_session_t session)
258 {
259         return (long) session->internals.transport_recv_ptr;
260 }
261
262 /**
263  * gnutls_bye:
264  * @session: is a #gnutls_session_t structure.
265  * @how: is an integer
266  *
267  * Terminates the current TLS/SSL connection. The connection should
268  * have been initiated using gnutls_handshake().  @how should be one
269  * of %GNUTLS_SHUT_RDWR, %GNUTLS_SHUT_WR.
270  *
271  * In case of %GNUTLS_SHUT_RDWR the TLS session gets
272  * terminated and further receives and sends will be disallowed.  If
273  * the return value is zero you may continue using the underlying
274  * transport layer. %GNUTLS_SHUT_RDWR sends an alert containing a close
275  * request and waits for the peer to reply with the same message.
276  *
277  * In case of %GNUTLS_SHUT_WR the TLS session gets terminated
278  * and further sends will be disallowed. In order to reuse the
279  * connection you should wait for an EOF from the peer.
280  * %GNUTLS_SHUT_WR sends an alert containing a close request.
281  *
282  * Note that not all implementations will properly terminate a TLS
283  * connection.  Some of them, usually for performance reasons, will
284  * terminate only the underlying transport layer, and thus not
285  * distinguishing between a malicious party prematurely terminating 
286  * the connection and normal termination. 
287  *
288  * This function may also return %GNUTLS_E_AGAIN or
289  * %GNUTLS_E_INTERRUPTED; cf.  gnutls_record_get_direction().
290  *
291  * Returns: %GNUTLS_E_SUCCESS on success, or an error code, see
292  *   function documentation for entire semantics.
293  **/
294 int gnutls_bye(gnutls_session_t session, gnutls_close_request_t how)
295 {
296         int ret = 0;
297
298         switch (STATE) {
299         case STATE0:
300         case STATE60:
301                 ret = _gnutls_io_write_flush(session);
302                 STATE = STATE60;
303                 if (ret < 0) {
304                         gnutls_assert();
305                         return ret;
306                 }
307                 /* fallthrough */
308         case STATE61:
309                 ret =
310                     gnutls_alert_send(session, GNUTLS_AL_WARNING,
311                                       GNUTLS_A_CLOSE_NOTIFY);
312                 STATE = STATE61;
313                 if (ret < 0) {
314                         gnutls_assert();
315                         return ret;
316                 }
317
318         case STATE62:
319                 STATE = STATE62;
320                 if (how == GNUTLS_SHUT_RDWR) {
321                         do {
322                                 ret =
323                                     _gnutls_recv_int(session, GNUTLS_ALERT,
324                                                      -1, NULL, NULL, 0, NULL,
325                                                      session->internals.
326                                                      record_timeout_ms);
327                         }
328                         while (ret == GNUTLS_E_GOT_APPLICATION_DATA);
329
330                         if (ret >= 0)
331                                 session->internals.may_not_read = 1;
332
333                         if (ret < 0) {
334                                 gnutls_assert();
335                                 return ret;
336                         }
337                 }
338                 STATE = STATE62;
339
340                 break;
341         default:
342                 gnutls_assert();
343                 return GNUTLS_E_INTERNAL_ERROR;
344         }
345
346         STATE = STATE0;
347
348         session->internals.may_not_write = 1;
349         return 0;
350 }
351
352 inline static void session_invalidate(gnutls_session_t session)
353 {
354         session->internals.invalid_connection = 1;
355 }
356
357
358 inline static void session_unresumable(gnutls_session_t session)
359 {
360         session->internals.resumable = RESUME_FALSE;
361 }
362
363 /* returns 0 if session is valid
364  */
365 inline static int session_is_valid(gnutls_session_t session)
366 {
367         if (session->internals.invalid_connection != 0)
368                 return GNUTLS_E_INVALID_SESSION;
369
370         return 0;
371 }
372
373 /* Copies the record version into the headers. The 
374  * version must have 2 bytes at least.
375  */
376 inline static void
377 copy_record_version(gnutls_session_t session,
378                     gnutls_handshake_description_t htype,
379                     uint8_t version[2])
380 {
381         const version_entry_st *lver;
382
383         if (session->internals.initial_negotiation_completed
384             || htype != GNUTLS_HANDSHAKE_CLIENT_HELLO
385             || session->internals.default_record_version[0] == 0) {
386                 lver = get_version(session);
387
388                 version[0] = lver->major;
389                 version[1] = lver->minor;
390         } else {
391                 version[0] = session->internals.default_record_version[0];
392                 version[1] = session->internals.default_record_version[1];
393         }
394 }
395
396 /* Increments the sequence value
397  */
398 inline static int
399 sequence_increment(gnutls_session_t session, uint64 * value)
400 {
401         if (IS_DTLS(session)) {
402                 return _gnutls_uint48pp(value);
403         } else {
404                 return _gnutls_uint64pp(value);
405         }
406 }
407
408 /* This function behaves exactly like write(). The only difference is
409  * that it accepts, the gnutls_session_t and the content_type_t of data to
410  * send (if called by the user the Content is specific)
411  * It is intended to transfer data, under the current session.    
412  *
413  * @type: The content type to send
414  * @htype: If this is a handshake message then the handshake type
415  * @epoch_rel: %EPOCH_READ_* or %EPOCH_WRITE_*
416  * @data: the data to be sent
417  * @data_size: the size of the @data
418  * @min_pad: the minimum required padding
419  * @mflags: zero or %MBUFFER_FLUSH
420  *
421  * Oct 30 2001: Removed capability to send data more than MAX_RECORD_SIZE.
422  * This makes the function much easier to read, and more error resistant
423  * (there were cases were the old function could mess everything up).
424  * --nmav
425  *
426  * This function may accept a NULL pointer for data, and 0 for size, if
427  * and only if the previous send was interrupted for some reason.
428  *
429  */
430 ssize_t
431 _gnutls_send_tlen_int(gnutls_session_t session, content_type_t type,
432                       gnutls_handshake_description_t htype,
433                       unsigned int epoch_rel, const void *_data,
434                       size_t data_size, size_t min_pad,
435                       unsigned int mflags)
436 {
437         mbuffer_st *bufel;
438         ssize_t cipher_size;
439         int retval, ret;
440         int send_data_size;
441         uint8_t *headers;
442         int header_size;
443         const uint8_t *data = _data;
444         record_parameters_st *record_params;
445         size_t max_send_size;
446         record_state_st *record_state;
447
448         ret = _gnutls_epoch_get(session, epoch_rel, &record_params);
449         if (ret < 0)
450                 return gnutls_assert_val(ret);
451
452         /* Safeguard against processing data with an incomplete cipher state. */
453         if (!record_params->initialized)
454                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
455
456         record_state = &record_params->write;
457
458         /* Do not allow null pointer if the send buffer is empty.
459          * If the previous send was interrupted then a null pointer is
460          * ok, and means to resume.
461          */
462         if (session->internals.record_send_buffer.byte_length == 0 &&
463             (data_size == 0 && _data == NULL)) {
464                 gnutls_assert();
465                 return GNUTLS_E_INVALID_REQUEST;
466         }
467
468         if (type != GNUTLS_ALERT)       /* alert messages are sent anyway */
469                 if (session_is_valid(session)
470                     || session->internals.may_not_write != 0) {
471                         gnutls_assert();
472                         return GNUTLS_E_INVALID_SESSION;
473                 }
474
475         max_send_size = max_user_send_size(session, record_params);
476
477         if (data_size > max_send_size) {
478                 if (IS_DTLS(session))
479                         return gnutls_assert_val(GNUTLS_E_LARGE_PACKET);
480
481                 send_data_size = max_send_size;
482         } else
483                 send_data_size = data_size;
484
485         /* Only encrypt if we don't have data to send 
486          * from the previous run. - probably interrupted.
487          */
488         if (mflags != 0
489             && session->internals.record_send_buffer.byte_length > 0) {
490                 ret = _gnutls_io_write_flush(session);
491                 if (ret > 0)
492                         cipher_size = ret;
493                 else
494                         cipher_size = 0;
495
496                 retval = session->internals.record_send_buffer_user_size;
497         } else {
498                 if (unlikely((send_data_size == 0 && min_pad == 0)))
499                         return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
500
501                 /* now proceed to packet encryption
502                  */
503                 cipher_size = MAX_RECORD_SEND_SIZE(session);
504
505                 bufel = _mbuffer_alloc_align16(cipher_size + CIPHER_SLACK_SIZE, 
506                         get_total_headers2(session, record_params));
507                 if (bufel == NULL)
508                         return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
509
510                 headers = _mbuffer_get_uhead_ptr(bufel);
511                 headers[0] = type;
512                 /* Use the default record version, if it is
513                  * set. */
514                 copy_record_version(session, htype, &headers[1]);
515                 /* Adjust header length and add sequence for DTLS */
516                 if (IS_DTLS(session))
517                         memcpy(&headers[3],
518                                &record_state->sequence_number.i, 8);
519
520                 _gnutls_record_log
521                     ("REC[%p]: Preparing Packet %s(%d) with length: %d and min pad: %d\n",
522                      session, _gnutls_packet2str(type), type,
523                      (int) data_size, (int) min_pad);
524
525                 header_size = RECORD_HEADER_SIZE(session);
526                 _mbuffer_set_udata_size(bufel, cipher_size);
527                 _mbuffer_set_uhead_size(bufel, header_size);
528
529                 ret =
530                     _gnutls_encrypt(session,
531                                     data, send_data_size, min_pad,
532                                     bufel, type, record_params);
533                 if (ret <= 0) {
534                         gnutls_assert();
535                         if (ret == 0)
536                                 ret = GNUTLS_E_ENCRYPTION_FAILED;
537                         gnutls_free(bufel);
538                         return ret;     /* error */
539                 }
540
541                 cipher_size = _mbuffer_get_udata_size(bufel);
542                 retval = send_data_size;
543                 session->internals.record_send_buffer_user_size =
544                     send_data_size;
545
546                 /* increase sequence number
547                  */
548                 if (sequence_increment
549                     (session, &record_state->sequence_number) != 0) {
550                         session_invalidate(session);
551                         gnutls_free(bufel);
552                         return
553                             gnutls_assert_val
554                             (GNUTLS_E_RECORD_LIMIT_REACHED);
555                 }
556
557                 ret = _gnutls_io_write_buffered(session, bufel, mflags);
558         }
559
560         if (ret != cipher_size) {
561                 /* If we have sent any data then just return
562                  * the error value. Do not invalidate the session.
563                  */
564                 if (ret < 0 && gnutls_error_is_fatal(ret) == 0)
565                         return gnutls_assert_val(ret);
566
567                 if (ret > 0)
568                         ret = gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
569
570                 session_unresumable(session);
571                 session->internals.may_not_write = 1;
572                 return gnutls_assert_val(ret);
573         }
574
575         session->internals.record_send_buffer_user_size = 0;
576
577         _gnutls_record_log
578             ("REC[%p]: Sent Packet[%d] %s(%d) in epoch %d and length: %d\n",
579              session, (unsigned int)
580              _gnutls_uint64touint32(&record_state->sequence_number),
581              _gnutls_packet2str(type), type, (int) record_params->epoch,
582              (int) cipher_size);
583
584         return retval;
585 }
586
587 inline static int
588 check_recv_type(gnutls_session_t session, content_type_t recv_type)
589 {
590         switch (recv_type) {
591         case GNUTLS_CHANGE_CIPHER_SPEC:
592         case GNUTLS_ALERT:
593         case GNUTLS_HANDSHAKE:
594         case GNUTLS_HEARTBEAT:
595         case GNUTLS_APPLICATION_DATA:
596                 return 0;
597         default:
598                 gnutls_assert();
599                 _gnutls_audit_log(session,
600                                   "Received record packet of unknown type %u\n",
601                                   (unsigned int) recv_type);
602                 return GNUTLS_E_UNEXPECTED_PACKET;
603         }
604
605 }
606
607
608 /* Checks if there are pending data in the record buffers. If there are
609  * then it copies the data.
610  */
611 static int
612 check_buffers(gnutls_session_t session, content_type_t type,
613               uint8_t * data, int data_size, void *seq)
614 {
615         if ((type == GNUTLS_APPLICATION_DATA ||
616              type == GNUTLS_HANDSHAKE || type == GNUTLS_CHANGE_CIPHER_SPEC)
617             && _gnutls_record_buffer_get_size(session) > 0) {
618                 int ret;
619                 ret =
620                     _gnutls_record_buffer_get(type, session, data,
621                                               data_size, seq);
622                 if (ret < 0) {
623                         if (IS_DTLS(session)) {
624                                 if (ret == GNUTLS_E_UNEXPECTED_PACKET) {
625                                         ret = GNUTLS_E_AGAIN;
626                                 }
627                         }
628                         gnutls_assert();
629                         return ret;
630                 }
631
632                 return ret;
633         }
634
635         return 0;
636 }
637
638 /* Checks and retrieves any pending data in the application data record buffers.
639  */
640 static int
641 check_packet_buffers(gnutls_session_t session, content_type_t type,
642                      gnutls_packet_t *packet)
643 {
644         if (_gnutls_record_buffer_get_size(session) > 0) {
645                 int ret;
646                 ret =
647                     _gnutls_record_buffer_get_packet(type, session,
648                                                      packet);
649                 if (ret < 0) {
650                         if (IS_DTLS(session)) {
651                                 if (ret == GNUTLS_E_UNEXPECTED_PACKET) {
652                                         ret = GNUTLS_E_AGAIN;
653                                 }
654                         }
655                         gnutls_assert();
656                         return ret;
657                 }
658
659                 return ret;
660         }
661
662         *packet = NULL;
663         return 0;
664 }
665
666
667
668 /* Here we check if the advertized version is the one we
669  * negotiated in the handshake.
670  */
671 inline static int
672 record_check_version(gnutls_session_t session,
673                      gnutls_handshake_description_t htype,
674                      uint8_t version[2])
675 {
676         const version_entry_st *vers = get_version(session);
677         int diff = 0;
678
679         if (vers->major != version[0] || vers->minor != version[1])
680                 diff = 1;
681
682         if (!IS_DTLS(session)) {
683                 if (htype == GNUTLS_HANDSHAKE_CLIENT_HELLO ||
684                     htype == GNUTLS_HANDSHAKE_SERVER_HELLO) {
685                         if (version[0] != 3) {
686                                 gnutls_assert();
687                                 _gnutls_record_log
688                                     ("REC[%p]: INVALID VERSION PACKET: (%d) %d.%d\n",
689                                      session, htype, version[0],
690                                      version[1]);
691                                 return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
692                         }
693                 } else if (diff != 0) {
694                         /* Reject record packets that have a different version than the
695                          * one negotiated. Note that this version is not protected by any
696                          * mac. I don't really think that this check serves any purpose.
697                          */
698                         gnutls_assert();
699                         _gnutls_record_log
700                             ("REC[%p]: INVALID VERSION PACKET: (%d) %d.%d\n",
701                              session, htype, version[0], version[1]);
702
703                         return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
704                 }
705         } else {                /* DTLS */
706
707                 /* In DTLS the only information we have here is whether we
708                  * expect a handshake message or not.
709                  */
710                 if (htype == (gnutls_handshake_description_t) - 1) {
711                         if (diff) {
712                                 /* Reject record packets that have a different version than the
713                                  * one negotiated. Note that this version is not protected by any
714                                  * mac. I don't really think that this check serves any purpose.
715                                  */
716                                 gnutls_assert();
717                                 _gnutls_record_log
718                                     ("REC[%p]: INVALID VERSION PACKET: (%d) %d.%d\n",
719                                      session, htype, version[0],
720                                      version[1]);
721
722                                 return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
723                         }
724                 } else if (vers->id > GNUTLS_DTLS1_0 && version[0] > 254) {
725                         gnutls_assert();
726                         _gnutls_record_log
727                             ("REC[%p]: INVALID DTLS VERSION PACKET: (%d) %d.%d\n",
728                              session, htype, version[0], version[1]);
729                         return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
730                 } else if (vers->id == GNUTLS_DTLS0_9 && version[0] > 1) {
731                         gnutls_assert();
732                         _gnutls_record_log
733                             ("REC[%p]: INVALID DTLS VERSION PACKET: (%d) %d.%d\n",
734                              session, htype, version[0], version[1]);
735                         return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
736                 }
737         }
738
739         return 0;
740 }
741
742 /* This function will check if the received record type is
743  * the one we actually expect and adds it to the proper
744  * buffer. The bufel will be deinitialized after calling
745  * this function, even if it fails.
746  */
747 static int
748 record_add_to_buffers(gnutls_session_t session,
749                       struct tls_record_st *recv, content_type_t type,
750                       gnutls_handshake_description_t htype,
751                       uint64 * seq, mbuffer_st * bufel)
752 {
753
754         int ret;
755
756         if ((recv->type == type)
757             && (type == GNUTLS_APPLICATION_DATA ||
758                 type == GNUTLS_CHANGE_CIPHER_SPEC ||
759                 type == GNUTLS_HANDSHAKE)) {
760                 _gnutls_record_buffer_put(session, type, seq, bufel);
761
762                 /* if we received application data as expected then we
763                  * deactivate the async timer */
764                 _dtls_async_timer_delete(session);
765         } else {
766                 /* if the expected type is different than the received 
767                  */
768                 switch (recv->type) {
769                 case GNUTLS_ALERT:
770                         if (bufel->msg.size < 2) {
771                                 ret =
772                                     gnutls_assert_val
773                                     (GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
774                                 goto unexpected_packet;
775                         }
776
777                         _gnutls_record_log
778                             ("REC[%p]: Alert[%d|%d] - %s - was received\n",
779                              session, bufel->msg.data[0],
780                              bufel->msg.data[1],
781                              gnutls_alert_get_name((int) bufel->msg.
782                                                    data[1]));
783
784                         session->internals.last_alert = bufel->msg.data[1];
785
786                         /* if close notify is received and
787                          * the alert is not fatal
788                          */
789                         if (bufel->msg.data[1] == GNUTLS_A_CLOSE_NOTIFY
790                             && bufel->msg.data[0] != GNUTLS_AL_FATAL) {
791                                 /* If we have been expecting for an alert do 
792                                  */
793                                 session->internals.read_eof = 1;
794                                 ret = GNUTLS_E_SESSION_EOF;
795                                 goto cleanup;
796                         } else {
797                                 /* if the alert is FATAL or WARNING
798                                  * return the apropriate message
799                                  */
800
801                                 gnutls_assert();
802                                 ret = GNUTLS_E_WARNING_ALERT_RECEIVED;
803                                 if (bufel->msg.data[0] == GNUTLS_AL_FATAL) {
804                                         session_unresumable(session);
805                                         session_invalidate(session);
806                                         ret =
807                                             gnutls_assert_val
808                                             (GNUTLS_E_FATAL_ALERT_RECEIVED);
809                                 }
810                                 goto cleanup;
811                         }
812                         break;
813
814                 case GNUTLS_CHANGE_CIPHER_SPEC:
815                         if (!(IS_DTLS(session))) {
816                                 ret = gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET);
817                                 goto cleanup;
818                         }
819
820                         _gnutls_record_buffer_put(session, recv->type, seq,
821                                                   bufel);
822
823                         break;
824
825 #ifdef ENABLE_HEARTBEAT
826                 case GNUTLS_HEARTBEAT:
827                         ret = _gnutls_heartbeat_handle(session, bufel);
828                         goto cleanup;
829 #endif
830
831                 case GNUTLS_APPLICATION_DATA:
832                         if (session->internals.
833                             initial_negotiation_completed == 0) {
834                                 ret =
835                                     gnutls_assert_val
836                                     (GNUTLS_E_UNEXPECTED_PACKET);
837                                 goto unexpected_packet;
838                         }
839
840
841                         /* the got_application data is only returned
842                          * if expecting client hello (for rehandshake
843                          * reasons). Otherwise it is an unexpected packet
844                          */
845                         if (type == GNUTLS_ALERT
846                             || (htype == GNUTLS_HANDSHAKE_CLIENT_HELLO
847                                 && type == GNUTLS_HANDSHAKE)) {
848                                 /* even if data is unexpected put it into the buffer */
849                                 _gnutls_record_buffer_put(session, recv->type,
850                                                           seq, bufel);
851                                 return
852                                     gnutls_assert_val
853                                     (GNUTLS_E_GOT_APPLICATION_DATA);
854                         } else {
855                                 ret =
856                                     gnutls_assert_val
857                                     (GNUTLS_E_UNEXPECTED_PACKET);
858                                 goto unexpected_packet;
859                         }
860
861                         break;
862
863                 case GNUTLS_HANDSHAKE:
864                         /* In DTLS we might receive a handshake replay from the peer to indicate
865                          * the our last TLS handshake messages were not received.
866                          */
867                         if (IS_DTLS(session)) {
868                                 if (type == GNUTLS_CHANGE_CIPHER_SPEC) {
869                                         ret =
870                                             gnutls_assert_val
871                                             (GNUTLS_E_UNEXPECTED_PACKET);
872                                         goto unexpected_packet;
873                                 }
874
875                                 if (_dtls_is_async(session)
876                                     && _dtls_async_timer_active(session)) {
877                                         if (session->security_parameters.
878                                             entity == GNUTLS_SERVER
879                                             && bufel->htype ==
880                                             GNUTLS_HANDSHAKE_CLIENT_HELLO)
881                                         {
882                                                 /* client requested rehandshake. Delete the timer */
883                                                 _dtls_async_timer_delete
884                                                     (session);
885                                         } else {
886                                                 session->internals.
887                                                     recv_state =
888                                                     RECV_STATE_DTLS_RETRANSMIT;
889                                                 ret =
890                                                     _dtls_retransmit
891                                                     (session);
892                                                 if (ret == 0) {
893                                                         session->internals.
894                                                             recv_state =
895                                                             RECV_STATE_0;
896                                                         ret =
897                                                             gnutls_assert_val
898                                                             (GNUTLS_E_AGAIN);
899                                                         goto unexpected_packet;
900                                                 }
901                                                 goto cleanup;
902                                         }
903                                 }
904                         }
905
906                         /* This is legal if HELLO_REQUEST is received - and we are a client.
907                          * If we are a server, a client may initiate a renegotiation at any time.
908                          */
909                         if (session->security_parameters.entity ==
910                             GNUTLS_SERVER
911                             && bufel->htype ==
912                             GNUTLS_HANDSHAKE_CLIENT_HELLO) {
913                                 gnutls_assert();
914                                 _gnutls_record_buffer_put(session,
915                                                               recv->type,
916                                                               seq, bufel);
917                                 return GNUTLS_E_REHANDSHAKE;
918                         }
919
920                         /* If we are already in a handshake then a Hello
921                          * Request is illegal. But here we don't really care
922                          * since this message will never make it up here.
923                          */
924
925                         /* So we accept it, if it is a Hello. If not, this will
926                          * fail and trigger flight retransmissions after some time. */
927                         ret =
928                             _gnutls_recv_hello_request(session,
929                                                        bufel->msg.data,
930                                                        bufel->msg.size);
931                         goto unexpected_packet;
932
933                         break;
934                 default:
935
936                         _gnutls_record_log
937                             ("REC[%p]: Received unexpected packet %d (%s) expecting %d (%s)\n",
938                              session, recv->type,
939                              _gnutls_packet2str(recv->type), type,
940                              _gnutls_packet2str(type));
941
942                         gnutls_assert();
943                         ret = GNUTLS_E_UNEXPECTED_PACKET;
944                         goto unexpected_packet;
945                 }
946         }
947
948         return 0;
949
950       unexpected_packet:
951         if (IS_DTLS(session) && ret != GNUTLS_E_REHANDSHAKE) {
952                 _mbuffer_xfree(&bufel);
953                 RETURN_DTLS_EAGAIN_OR_TIMEOUT(session, ret);
954         }
955
956       cleanup:
957         _mbuffer_xfree(&bufel);
958         return ret;
959
960 }
961
962
963 /* Checks the record headers and returns the length, version and
964  * content type.
965  */
966 static void
967 record_read_headers(gnutls_session_t session,
968                     uint8_t headers[MAX_RECORD_HEADER_SIZE],
969                     content_type_t type,
970                     gnutls_handshake_description_t htype,
971                     struct tls_record_st *record)
972 {
973
974         /* Read the first two bytes to determine if this is a 
975          * version 2 message 
976          */
977
978         if (htype == GNUTLS_HANDSHAKE_CLIENT_HELLO
979             && type == GNUTLS_HANDSHAKE && headers[0] > 127
980             && !(IS_DTLS(session))) {
981
982                 /* if msb set and expecting handshake message
983                  * it should be SSL 2 hello 
984                  */
985                 record->version[0] = 3; /* assume SSL 3.0 */
986                 record->version[1] = 0;
987
988                 record->length = (((headers[0] & 0x7f) << 8)) | headers[1];
989
990                 /* SSL 2.0 headers */
991                 record->header_size = record->packet_size = 2;
992                 record->type = GNUTLS_HANDSHAKE;        /* we accept only v2 client hello
993                                                          */
994
995                 /* in order to assist the handshake protocol.
996                  * V2 compatibility is a mess.
997                  */
998                 record->v2 = 1;
999                 record->epoch = 0;
1000                 memset(&record->sequence, 0, sizeof(record->sequence));
1001
1002                 _gnutls_record_log
1003                     ("REC[%p]: SSL 2.0 %s packet received. Length: %d\n",
1004                      session, _gnutls_packet2str(record->type),
1005                      record->length);
1006
1007         } else {
1008                 /* dtls version 1.0 and TLS version 1.x */
1009                 record->v2 = 0;
1010
1011                 record->type = headers[0];
1012                 record->version[0] = headers[1];
1013                 record->version[1] = headers[2];
1014
1015                 if (IS_DTLS(session)) {
1016                         memcpy(record->sequence.i, &headers[3], 8);
1017                         record->length = _gnutls_read_uint16(&headers[11]);
1018                         record->epoch =
1019                             _gnutls_read_uint16(record->sequence.i);
1020                 } else {
1021                         memset(&record->sequence, 0,
1022                                sizeof(record->sequence));
1023                         record->length = _gnutls_read_uint16(&headers[3]);
1024                         record->epoch = 0;
1025                 }
1026
1027                 _gnutls_record_log
1028                     ("REC[%p]: SSL %d.%d %s packet received. Epoch %d, length: %d\n",
1029                      session, (int) record->version[0],
1030                      (int) record->version[1],
1031                      _gnutls_packet2str(record->type), (int) record->epoch,
1032                      record->length);
1033
1034         }
1035
1036         record->packet_size += record->length;
1037 }
1038
1039
1040 static int recv_headers(gnutls_session_t session, 
1041                         record_parameters_st *record_params,
1042                         content_type_t type,
1043                         gnutls_handshake_description_t htype,
1044                         struct tls_record_st *record, unsigned int *ms)
1045 {
1046         int ret;
1047         gnutls_datum_t raw;     /* raw headers */
1048         /* Read the headers.
1049          */
1050         record->header_size = record->packet_size =
1051             RECORD_HEADER_SIZE(session);
1052
1053         ret =
1054             _gnutls_io_read_buffered(session, record->header_size, -1, ms);
1055         if (ret != record->header_size) {
1056                 if (ret < 0 && gnutls_error_is_fatal(ret) == 0)
1057                         return ret;
1058
1059                 if (ret > 0)
1060                         ret = GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1061                 else if (ret == 0)
1062                         ret = GNUTLS_E_PREMATURE_TERMINATION;
1063
1064                 return gnutls_assert_val(ret);
1065         }
1066
1067         ret = _mbuffer_linearize_align16(&session->internals.record_recv_buffer, 
1068                 get_total_headers2(session, record_params));
1069         if (ret < 0)
1070                 return gnutls_assert_val(ret);
1071
1072         _mbuffer_head_get_first(&session->internals.record_recv_buffer,
1073                                 &raw);
1074         if (raw.size < RECORD_HEADER_SIZE(session))
1075                 return
1076                     gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
1077
1078         record_read_headers(session, raw.data, type, htype, record);
1079
1080         /* Check if the DTLS epoch is valid */
1081         if (IS_DTLS(session)) {
1082                 if (_gnutls_epoch_is_valid(session, record->epoch) == 0) {
1083                         _gnutls_audit_log(session,
1084                                           "Discarded message[%u] with invalid epoch %u.\n",
1085                                           (unsigned int)
1086                                           _gnutls_uint64touint32(&record->
1087                                                                  sequence),
1088                                           (unsigned int) record->sequence.
1089                                           i[0] * 256 +
1090                                           (unsigned int) record->sequence.
1091                                           i[1]);
1092                         gnutls_assert();
1093                         /* doesn't matter, just a fatal error */
1094                         return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1095                 }
1096         }
1097
1098         /* Here we check if the Type of the received packet is
1099          * ok. 
1100          */
1101         if ((ret = check_recv_type(session, record->type)) < 0)
1102                 return gnutls_assert_val(ret);
1103
1104         /* Here we check if the advertized version is the one we
1105          * negotiated in the handshake.
1106          */
1107         if ((ret =
1108              record_check_version(session, htype, record->version)) < 0)
1109                 return gnutls_assert_val(ret);
1110
1111         if (record->length > max_record_recv_size(session)) {
1112                 _gnutls_audit_log
1113                     (session, "Received packet with illegal length: %u\n",
1114                      (unsigned int) record->length);
1115                 return
1116                     gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);
1117         }
1118
1119         _gnutls_record_log
1120             ("REC[%p]: Expected Packet %s(%d)\n", session,
1121              _gnutls_packet2str(type), type);
1122         _gnutls_record_log
1123             ("REC[%p]: Received Packet %s(%d) with length: %d\n", session,
1124              _gnutls_packet2str(record->type), record->type,
1125              record->length);
1126
1127
1128         return 0;
1129 }
1130
1131 /* @ms: is the number of milliseconds to wait for data. Use zero for indefinite.
1132  *
1133  * This will receive record layer packets and add them to 
1134  * application_data_buffer and handshake_data_buffer.
1135  *
1136  * If the htype is not -1 then handshake timeouts
1137  * will be enforced.
1138  */
1139 ssize_t
1140 _gnutls_recv_in_buffers(gnutls_session_t session, content_type_t type,
1141                         gnutls_handshake_description_t htype,
1142                         unsigned int ms)
1143 {
1144         uint64 *packet_sequence;
1145         gnutls_datum_t ciphertext;
1146         mbuffer_st *bufel = NULL, *decrypted = NULL;
1147         gnutls_datum_t t;
1148         int ret;
1149         unsigned int empty_fragments = 0;
1150         record_parameters_st *record_params;
1151         record_state_st *record_state;
1152         struct tls_record_st record;
1153
1154       begin:
1155
1156         if (empty_fragments >
1157             session->internals.priorities.max_empty_records) {
1158                 gnutls_assert();
1159                 return GNUTLS_E_TOO_MANY_EMPTY_PACKETS;
1160         }
1161
1162         if (session->internals.read_eof != 0) {
1163                 /* if we have already read an EOF
1164                  */
1165                 return 0;
1166         } else if (session_is_valid(session) != 0
1167                    || session->internals.may_not_read != 0)
1168                 return gnutls_assert_val(GNUTLS_E_INVALID_SESSION);
1169
1170         /* get the record state parameters */
1171         ret =
1172             _gnutls_epoch_get(session, EPOCH_READ_CURRENT, &record_params);
1173         if (ret < 0)
1174                 return gnutls_assert_val(ret);
1175
1176         /* Safeguard against processing data with an incomplete cipher state. */
1177         if (!record_params->initialized)
1178                 return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
1179
1180         record_state = &record_params->read;
1181
1182         /* receive headers */
1183         ret = recv_headers(session, record_params, type, htype, &record, &ms);
1184         if (ret < 0) {
1185                 ret = gnutls_assert_val_fatal(ret);
1186                 goto recv_error;
1187         }
1188
1189         if (IS_DTLS(session))
1190                 packet_sequence = &record.sequence;
1191         else
1192                 packet_sequence = &record_state->sequence_number;
1193
1194         /* Read the packet data and insert it to record_recv_buffer.
1195          */
1196         ret =
1197             _gnutls_io_read_buffered(session, record.packet_size,
1198                                      record.type, &ms);
1199         if (ret != record.packet_size) {
1200                 gnutls_assert();
1201                 goto recv_error;
1202         }
1203
1204         /* ok now we are sure that we have read all the data - so
1205          * move on !
1206          */
1207         ret = _mbuffer_linearize_align16(&session->internals.record_recv_buffer, 
1208                 get_total_headers2(session, record_params));
1209         if (ret < 0)
1210                 return gnutls_assert_val(ret);
1211
1212         bufel =
1213             _mbuffer_head_get_first(&session->internals.record_recv_buffer,
1214                                     NULL);
1215         if (bufel == NULL)
1216                 return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
1217
1218         /* We allocate the maximum possible to allow few compressed bytes to expand to a
1219          * full record. Moreover we add space for any pad and the MAC (in case
1220          * they are encrypted).
1221          */
1222         ret = max_decrypted_size(session) + MAX_PAD_SIZE + MAX_HASH_SIZE;
1223         decrypted = _mbuffer_alloc_align16(ret, 0);
1224         if (decrypted == NULL)
1225                 return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
1226
1227         _mbuffer_set_udata_size(decrypted, ret);
1228         ciphertext.data =
1229             (uint8_t *) _mbuffer_get_udata_ptr(bufel) + record.header_size;
1230         ciphertext.size = record.length;
1231
1232         /* decrypt the data we got. 
1233          */
1234         t.data = _mbuffer_get_udata_ptr(decrypted);
1235         t.size = _mbuffer_get_udata_size(decrypted);
1236         ret =
1237             _gnutls_decrypt(session, &ciphertext, &t,
1238                             record.type, record_params, packet_sequence);
1239         if (ret >= 0)
1240                 _mbuffer_set_udata_size(decrypted, ret);
1241
1242         _mbuffer_head_remove_bytes(&session->internals.record_recv_buffer,
1243                                    record.header_size + record.length);
1244         if (ret < 0) {
1245                 gnutls_assert();
1246                 _gnutls_audit_log(session,
1247                                   "Discarded message[%u] due to invalid decryption\n",
1248                                   (unsigned int)
1249                                   _gnutls_uint64touint32(packet_sequence));
1250                 goto sanity_check_error;
1251         }
1252
1253         /* check for duplicates. We check after the message
1254          * is processed and authenticated to avoid someone
1255          * messing with our windows.
1256          */
1257         if (IS_DTLS(session)
1258             && session->internals.no_replay_protection == 0) {
1259                 ret = _dtls_record_check(record_params, packet_sequence);
1260                 if (ret < 0) {
1261                         _gnutls_record_log
1262                             ("REC[%p]: Discarded duplicate message[%u.%u]: %s\n",
1263                              session,
1264                              (unsigned int) record.sequence.i[0] * 256 +
1265                              (unsigned int) record.sequence.i[1],
1266                              (unsigned int)
1267                              _gnutls_uint64touint32(packet_sequence),
1268                              _gnutls_packet2str(record.type));
1269                         goto sanity_check_error;
1270                 }
1271                 _gnutls_record_log
1272                     ("REC[%p]: Decrypted Packet[%u.%u] %s(%d) with length: %d\n",
1273                      session,
1274                      (unsigned int) record.sequence.i[0] * 256 +
1275                      (unsigned int) record.sequence.i[1],
1276                      (unsigned int)
1277                      _gnutls_uint64touint32(packet_sequence),
1278                      _gnutls_packet2str(record.type), record.type,
1279                      (int) _mbuffer_get_udata_size(decrypted));
1280         } else {
1281                 _gnutls_record_log
1282                     ("REC[%p]: Decrypted Packet[%u] %s(%d) with length: %d\n",
1283                      session,
1284                      (unsigned int)
1285                      _gnutls_uint64touint32(packet_sequence),
1286                      _gnutls_packet2str(record.type), record.type,
1287                      (int) _mbuffer_get_udata_size(decrypted));
1288         }
1289
1290         /* increase sequence number 
1291          */
1292         if (!IS_DTLS(session)
1293             && sequence_increment(session,
1294                                   &record_state->sequence_number) != 0) {
1295                 session_invalidate(session);
1296                 gnutls_assert();
1297                 ret = GNUTLS_E_RECORD_LIMIT_REACHED;
1298                 goto sanity_check_error;
1299         }
1300
1301 /* (originally for) TLS 1.0 CBC protection. 
1302  * Actually this code is called if we just received
1303  * an empty packet. An empty TLS packet is usually
1304  * sent to protect some vulnerabilities in the CBC mode.
1305  * In that case we go to the beginning and start reading
1306  * the next packet.
1307  */
1308         if (_mbuffer_get_udata_size(decrypted) == 0) {
1309                 _mbuffer_xfree(&decrypted);
1310                 empty_fragments++;
1311                 goto begin;
1312         }
1313
1314         if (record.v2) {
1315                 decrypted->htype = GNUTLS_HANDSHAKE_CLIENT_HELLO_V2;
1316         } else {
1317                 uint8_t *p = _mbuffer_get_udata_ptr(decrypted);
1318                 decrypted->htype = p[0];
1319         }
1320
1321         ret =
1322             record_add_to_buffers(session, &record, type, htype,
1323                                   packet_sequence, decrypted);
1324
1325         /* decrypted is now either deinitialized or buffered somewhere else */
1326
1327         if (ret < 0)
1328                 return gnutls_assert_val(ret);
1329
1330         return ret;
1331
1332       discard:
1333         session->internals.dtls.packets_dropped++;
1334
1335         /* discard the whole received fragment. */
1336         bufel =
1337             _mbuffer_head_pop_first(&session->internals.
1338                                     record_recv_buffer);
1339         _mbuffer_xfree(&bufel);
1340         return gnutls_assert_val(GNUTLS_E_AGAIN);
1341
1342       sanity_check_error:
1343         if (IS_DTLS(session)) {
1344                 session->internals.dtls.packets_dropped++;
1345                 ret = gnutls_assert_val(GNUTLS_E_AGAIN);
1346                 goto cleanup;
1347         }
1348
1349         session_unresumable(session);
1350         session_invalidate(session);
1351
1352       cleanup:
1353         _mbuffer_xfree(&decrypted);
1354         return ret;
1355
1356       recv_error:
1357         if (ret < 0
1358             && (gnutls_error_is_fatal(ret) == 0
1359                 || ret == GNUTLS_E_TIMEDOUT))
1360                 return ret;
1361
1362         if (type == GNUTLS_ALERT) {     /* we were expecting close notify */
1363                 session_invalidate(session);
1364                 gnutls_assert();
1365                 return 0;
1366         }
1367
1368         if (IS_DTLS(session)) {
1369                 goto discard;
1370         }
1371
1372         session_invalidate(session);
1373         session_unresumable(session);
1374
1375         if (ret == 0)
1376                 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1377         else
1378                 return ret;
1379 }
1380
1381 /* This function behaves exactly like read(). The only difference is
1382  * that it accepts the gnutls_session_t and the content_type_t of data to
1383  * receive (if called by the user the Content is Userdata only)
1384  * It is intended to receive data, under the current session.
1385  *
1386  * The gnutls_handshake_description_t was introduced to support SSL V2.0 client hellos.
1387  */
1388 ssize_t
1389 _gnutls_recv_int(gnutls_session_t session, content_type_t type,
1390                  gnutls_handshake_description_t htype,
1391                  gnutls_packet_t *packet,
1392                  uint8_t * data, size_t data_size, void *seq,
1393                  unsigned int ms)
1394 {
1395         int ret;
1396
1397         if (packet == NULL && (type != GNUTLS_ALERT && type != GNUTLS_HEARTBEAT)
1398             && (data_size == 0 || data == NULL))
1399                 return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
1400
1401         if (session->internals.read_eof != 0) {
1402                 /* if we have already read an EOF
1403                  */
1404                 return 0;
1405         } else if (session_is_valid(session) != 0
1406                    || session->internals.may_not_read != 0) {
1407                 gnutls_assert();
1408                 return GNUTLS_E_INVALID_SESSION;
1409         }
1410
1411         switch (session->internals.recv_state) {
1412         case RECV_STATE_DTLS_RETRANSMIT:
1413                 ret = _dtls_retransmit(session);
1414                 if (ret < 0)
1415                         return gnutls_assert_val(ret);
1416
1417                 session->internals.recv_state = RECV_STATE_0;
1418         case RECV_STATE_0:
1419
1420                 _dtls_async_timer_check(session);
1421
1422                 if (packet == NULL) {
1423                         /* If we have enough data in the cache do not bother receiving
1424                          * a new packet. (in order to flush the cache)
1425                          */
1426                         ret = check_buffers(session, type, data, data_size, seq);
1427                         if (ret != 0)
1428                                 return ret;
1429
1430                         ret = _gnutls_recv_in_buffers(session, type, htype, ms);
1431                         if (ret < 0 && ret != GNUTLS_E_SESSION_EOF)
1432                                 return gnutls_assert_val(ret);
1433
1434                         return check_buffers(session, type, data, data_size, seq);
1435                 } else {
1436                         ret = check_packet_buffers(session, type, packet);
1437                         if (ret != 0)
1438                                 return ret;
1439
1440                         ret = _gnutls_recv_in_buffers(session, type, -1, ms);
1441                         if (ret < 0 && ret != GNUTLS_E_SESSION_EOF)
1442                                 return gnutls_assert_val(ret);
1443
1444                         return check_packet_buffers(session, type, packet);
1445                 }
1446         default:
1447                 return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
1448         }
1449 }
1450
1451 /**
1452  * gnutls_packet_get:
1453  * @packet: is a #gnutls_packet_t structure.
1454  * @data: will contain the data present in the @packet structure (may be %NULL)
1455  * @sequence: the 8-bytes of the packet sequence number (may be %NULL)
1456  *
1457  * This function returns the data and sequence number associated with
1458  * the received packet.
1459  *
1460  * Since: 3.3.5
1461  **/
1462
1463 void gnutls_packet_get(gnutls_packet_t packet, gnutls_datum_t *data, unsigned char *sequence)
1464 {
1465         if (unlikely(packet == NULL)) {
1466                 gnutls_assert();
1467                 if (data) {
1468                         data->data = NULL;
1469                         data->size = 0;
1470                 }
1471         }
1472
1473         if (sequence) {
1474                 memcpy(sequence, packet->record_sequence.i, 8);
1475         }
1476
1477         if (data) {
1478                 data->size = packet->msg.size - packet->mark;
1479                 data->data = packet->msg.data + packet->mark;
1480         }
1481 }
1482
1483 /**
1484  * gnutls_packet_deinit:
1485  * @packet: is a pointer to a #gnutls_packet_st structure.
1486  *
1487  * This function will deinitialize all data associated with
1488  * the received packet.
1489  *
1490  * Since: 3.3.5
1491  **/
1492 void gnutls_packet_deinit(gnutls_packet_t packet)
1493 {
1494         gnutls_free(packet);
1495 }
1496
1497 /**
1498  * gnutls_record_recv_packet:
1499  * @session: is a #gnutls_session_t structure.
1500  * @packet: the structure that will hold the packet data
1501  *
1502  * This is a lower-level function thatn gnutls_record_recv() and allows
1503  * to directly receive the whole decrypted packet. That avoids a
1504  * memory copy, and is mostly applicable to applications seeking high
1505  * performance.
1506  *
1507  * The received packet is accessed using gnutls_packet_get() and 
1508  * must be deinitialized using gnutls_packet_deinit(). The returned
1509  * packet will be %NULL if the return value is zero (EOF).
1510  *
1511  * Returns: The number of bytes received and zero on EOF (for stream
1512  * connections).  A negative error code is returned in case of an error.  
1513  *
1514  * Since: 3.3.5
1515  **/
1516 ssize_t
1517 gnutls_record_recv_packet(gnutls_session_t session, 
1518                           gnutls_packet_t *packet)
1519 {
1520         return _gnutls_recv_int(session, GNUTLS_APPLICATION_DATA, -1, packet,
1521                                 NULL, 0, NULL,
1522                                 session->internals.record_timeout_ms);
1523 }
1524
1525 /**
1526  * gnutls_record_send:
1527  * @session: is a #gnutls_session_t structure.
1528  * @data: contains the data to send
1529  * @data_size: is the length of the data
1530  *
1531  * This function has the similar semantics with send().  The only
1532  * difference is that it accepts a GnuTLS session, and uses different
1533  * error codes.
1534  * Note that if the send buffer is full, send() will block this
1535  * function.  See the send() documentation for more information.  
1536  *
1537  * You can replace the default push function which is send(), by using
1538  * gnutls_transport_set_push_function().
1539  *
1540  * If the EINTR is returned by the internal push function 
1541  * then %GNUTLS_E_INTERRUPTED will be returned. If
1542  * %GNUTLS_E_INTERRUPTED or %GNUTLS_E_AGAIN is returned, you must
1543  * call this function again, with the exact same parameters; alternatively
1544  * you could provide a %NULL pointer for data, and 0 for
1545  * size. cf. gnutls_record_get_direction(). 
1546  *
1547  * Note that in DTLS this function will return the %GNUTLS_E_LARGE_PACKET
1548  * error code if the send data exceed the data MTU value - as returned
1549  * by gnutls_dtls_get_data_mtu(). The errno value EMSGSIZE
1550  * also maps to %GNUTLS_E_LARGE_PACKET. 
1551  * Note that since 3.2.13 this function can be called under cork in DTLS
1552  * mode, and will refuse to send data over the MTU size by returning
1553  * %GNUTLS_E_LARGE_PACKET.
1554  *
1555  * Returns: The number of bytes sent, or a negative error code.  The
1556  *   number of bytes sent might be less than @data_size.  The maximum
1557  *   number of bytes this function can send in a single call depends
1558  *   on the negotiated maximum record size.
1559  **/
1560 ssize_t
1561 gnutls_record_send(gnutls_session_t session, const void *data,
1562                    size_t data_size)
1563 {
1564         if (session->internals.record_flush_mode == RECORD_FLUSH) {
1565                 return _gnutls_send_int(session, GNUTLS_APPLICATION_DATA,
1566                                         -1, EPOCH_WRITE_CURRENT, data,
1567                                         data_size, MBUFFER_FLUSH);
1568         } else {                /* GNUTLS_CORKED */
1569
1570                 int ret;
1571
1572                 if (IS_DTLS(session)) {
1573                         if (data_size + session->internals.record_presend_buffer.length >
1574                                 gnutls_dtls_get_data_mtu(session)) {
1575                                 return gnutls_assert_val(GNUTLS_E_LARGE_PACKET);
1576                         }
1577                 }
1578
1579                 ret =
1580                     _gnutls_buffer_append_data(&session->internals.
1581                                                record_presend_buffer, data,
1582                                                data_size);
1583                 if (ret < 0)
1584                         return gnutls_assert_val(ret);
1585
1586                 return data_size;
1587         }
1588 }
1589
1590 /**
1591  * gnutls_cork:
1592  * @session: is a #gnutls_session_t structure.
1593  *
1594  * If called gnutls_record_send() will no longer send partial records.
1595  * All queued records will be sent when gnutls_uncork() is called, or
1596  * when the maximum record size is reached.
1597  *
1598  * This function is safe to use with DTLS after GnuTLS 3.3.0.
1599  *
1600  * Since: 3.1.9
1601  **/
1602 void gnutls_record_cork(gnutls_session_t session)
1603 {
1604         session->internals.record_flush_mode = RECORD_CORKED;
1605 }
1606
1607 /**
1608  * gnutls_uncork:
1609  * @session: is a #gnutls_session_t structure.
1610  * @flags: Could be zero or %GNUTLS_RECORD_WAIT
1611  *
1612  * This resets the effect of gnutls_cork(), and flushes any pending
1613  * data. If the %GNUTLS_RECORD_WAIT flag is specified then this
1614  * function will block until the data is sent or a fatal error
1615  * occurs (i.e., the function will retry on %GNUTLS_E_AGAIN and
1616  * %GNUTLS_E_INTERRUPTED).
1617  *
1618  * If the flag %GNUTLS_RECORD_WAIT is not specified and the function
1619  * is interrupted then the %GNUTLS_E_AGAIN or %GNUTLS_E_INTERRUPTED
1620  * errors will be returned. To obtain the data left in the corked
1621  * buffer use gnutls_record_check_corked().
1622  *
1623  * Returns: On success the number of transmitted data is returned, or 
1624  * otherwise a negative error code. 
1625  *
1626  * Since: 3.1.9
1627  **/
1628 int gnutls_record_uncork(gnutls_session_t session, unsigned int flags)
1629 {
1630         int ret;
1631         ssize_t total = 0;
1632
1633         if (session->internals.record_flush_mode == RECORD_FLUSH)
1634                 return 0;       /* nothing to be done */
1635
1636         session->internals.record_flush_mode = RECORD_FLUSH;
1637
1638         while (session->internals.record_presend_buffer.length > 0) {
1639                 if (flags == GNUTLS_RECORD_WAIT) {
1640                         do {
1641                                 ret =
1642                                     gnutls_record_send(session,
1643                                                        session->internals.
1644                                                        record_presend_buffer.
1645                                                        data,
1646                                                        session->internals.
1647                                                        record_presend_buffer.
1648                                                        length);
1649                         }
1650                         while (ret < 0 && (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED));
1651                 } else {
1652                         ret =
1653                             gnutls_record_send(session,
1654                                                session->internals.
1655                                                record_presend_buffer.data,
1656                                                session->internals.
1657                                                record_presend_buffer.
1658                                                length);
1659                 }
1660                 if (ret < 0)
1661                         goto fail;
1662
1663                 session->internals.record_presend_buffer.data += ret;
1664                 session->internals.record_presend_buffer.length -= ret;
1665                 total += ret;
1666         }
1667
1668         return total;
1669
1670       fail:
1671         session->internals.record_flush_mode = RECORD_CORKED;
1672         return ret;
1673 }
1674
1675 /**
1676  * gnutls_record_recv:
1677  * @session: is a #gnutls_session_t structure.
1678  * @data: the buffer that the data will be read into
1679  * @data_size: the number of requested bytes
1680  *
1681  * This function has the similar semantics with recv().  The only
1682  * difference is that it accepts a GnuTLS session, and uses different
1683  * error codes.
1684  * In the special case that a server requests a renegotiation, the
1685  * client may receive an error code of %GNUTLS_E_REHANDSHAKE.  This
1686  * message may be simply ignored, replied with an alert
1687  * %GNUTLS_A_NO_RENEGOTIATION, or replied with a new handshake,
1688  * depending on the client's will.
1689  * If %EINTR is returned by the internal push function (the default
1690  * is recv()) then %GNUTLS_E_INTERRUPTED will be returned.  If
1691  * %GNUTLS_E_INTERRUPTED or %GNUTLS_E_AGAIN is returned, you must
1692  * call this function again to get the data.  See also
1693  * gnutls_record_get_direction().
1694  * A server may also receive %GNUTLS_E_REHANDSHAKE when a client has
1695  * initiated a handshake. In that case the server can only initiate a
1696  * handshake or terminate the connection.
1697  *
1698  * Returns: The number of bytes received and zero on EOF (for stream
1699  * connections).  A negative error code is returned in case of an error.  
1700  * The number of bytes received might be less than the requested @data_size.
1701  **/
1702 ssize_t
1703 gnutls_record_recv(gnutls_session_t session, void *data, size_t data_size)
1704 {
1705         return _gnutls_recv_int(session, GNUTLS_APPLICATION_DATA, -1, NULL,
1706                                 data, data_size, NULL,
1707                                 session->internals.record_timeout_ms);
1708 }
1709
1710 /**
1711  * gnutls_record_recv_seq:
1712  * @session: is a #gnutls_session_t structure.
1713  * @data: the buffer that the data will be read into
1714  * @data_size: the number of requested bytes
1715  * @seq: is the packet's 64-bit sequence number. Should have space for 8 bytes.
1716  *
1717  * This function is the same as gnutls_record_recv(), except that
1718  * it returns in addition to data, the sequence number of the data.
1719  * This is useful in DTLS where record packets might be received
1720  * out-of-order. The returned 8-byte sequence number is an
1721  * integer in big-endian format and should be
1722  * treated as a unique message identification. 
1723  *
1724  * Returns: The number of bytes received and zero on EOF.  A negative
1725  *   error code is returned in case of an error.  The number of bytes
1726  *   received might be less than @data_size.
1727  *
1728  * Since: 3.0
1729  **/
1730 ssize_t
1731 gnutls_record_recv_seq(gnutls_session_t session, void *data,
1732                        size_t data_size, unsigned char *seq)
1733 {
1734         return _gnutls_recv_int(session, GNUTLS_APPLICATION_DATA, -1, NULL,
1735                                 data, data_size, seq,
1736                                 session->internals.record_timeout_ms);
1737 }
1738
1739 /**
1740  * gnutls_record_set_timeout:
1741  * @session: is a #gnutls_session_t structure.
1742  * @ms: is a timeout value in milliseconds
1743  *
1744  * This function sets the receive timeout for the record layer
1745  * to the provided value. Use an @ms value of zero to disable
1746  * timeout (the default).
1747  *
1748  * Since: 3.1.7
1749  **/
1750 void gnutls_record_set_timeout(gnutls_session_t session, unsigned int ms)
1751 {
1752         session->internals.record_timeout_ms = ms;
1753 }