Tizen 2.0 Release
[external/libgnutls26.git] / lib / gnutls_record.c
1 /*
2  * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
3  * 2009, 2010 Free Software Foundation, Inc.
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
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
22  * USA
23  *
24  */
25
26 /* Functions that are record layer specific, are included in this file.
27  */
28
29 #include "gnutls_int.h"
30 #include "gnutls_errors.h"
31 #include "debug.h"
32 #include "gnutls_compress.h"
33 #include "gnutls_cipher.h"
34 #include "gnutls_buffers.h"
35 #include "gnutls_mbuffers.h"
36 #include "gnutls_handshake.h"
37 #include "gnutls_hash_int.h"
38 #include "gnutls_cipher_int.h"
39 #include "gnutls_algorithms.h"
40 #include "gnutls_db.h"
41 #include "gnutls_auth.h"
42 #include "gnutls_num.h"
43 #include "gnutls_record.h"
44 #include "gnutls_datum.h"
45 #include "gnutls_constate.h"
46 #include "ext_max_record.h"
47 #include <gnutls_state.h>
48 #include <gnutls_dh.h>
49
50 void
51 _gnutls_transport_set_lowat (gnutls_session_t session, int num);
52
53 /**
54  * gnutls_protocol_get_version:
55  * @session: is a #gnutls_session_t structure.
56  *
57  * Get TLS version, a #gnutls_protocol_t value.
58  *
59  * Returns: the version of the currently used protocol.
60  **/
61 gnutls_protocol_t
62 gnutls_protocol_get_version (gnutls_session_t session)
63 {
64   return session->security_parameters.version;
65 }
66
67 void
68 _gnutls_set_current_version (gnutls_session_t session,
69                              gnutls_protocol_t version)
70 {
71   session->security_parameters.version = version;
72 }
73
74 /* Added to avoid issue in C++ interface not being able to
75  * call deprecated functions.
76  */
77 void
78 _gnutls_transport_set_lowat (gnutls_session_t session, int num)
79 {
80   session->internals.lowat = num;
81 }
82
83 /**
84  * gnutls_transport_set_lowat:
85  * @session: is a #gnutls_session_t structure.
86  * @num: is the low water value.
87  *
88  * Used to set the lowat value in order for select to check if there
89  * are pending data to socket buffer. Used only if you have changed
90  * the default low water value (default is 1).  Normally you will not
91  * need that function.  This function is only useful if using
92  * berkeley style sockets.  Otherwise it must be called and set lowat
93  * to zero.
94  **/
95 void
96 gnutls_transport_set_lowat (gnutls_session_t session, int num)
97 {
98   _gnutls_transport_set_lowat(session, num);
99 }
100
101 /**
102  * gnutls_record_disable_padding:
103  * @session: is a #gnutls_session_t structure.
104  *
105  * Used to disabled padding in TLS 1.0 and above.  Normally you do not
106  * need to use this function, but there are buggy clients that
107  * complain if a server pads the encrypted data.  This of course will
108  * disable protection against statistical attacks on the data.
109  *
110  * Normally only servers that require maximum compatibility with everything
111  * out there, need to call this function.
112  **/
113 void
114 gnutls_record_disable_padding (gnutls_session_t session)
115 {
116   session->internals.priorities.no_padding = 1;
117 }
118
119 /**
120  * gnutls_transport_set_ptr:
121  * @session: is a #gnutls_session_t structure.
122  * @ptr: is the value.
123  *
124  * Used to set the first argument of the transport function (like PUSH
125  * and PULL).  In berkeley style sockets this function will set the
126  * connection handle.
127  **/
128 void
129 gnutls_transport_set_ptr (gnutls_session_t session,
130                           gnutls_transport_ptr_t ptr)
131 {
132   session->internals.transport_recv_ptr = ptr;
133   session->internals.transport_send_ptr = ptr;
134 }
135
136 /**
137  * gnutls_transport_set_ptr2:
138  * @session: is a #gnutls_session_t structure.
139  * @recv_ptr: is the value for the pull function
140  * @send_ptr: is the value for the push function
141  *
142  * Used to set the first argument of the transport function (like PUSH
143  * and PULL). In berkeley style sockets this function will set the
144  * connection handle.  With this function you can use two different
145  * pointers for receiving and sending.
146  **/
147 void
148 gnutls_transport_set_ptr2 (gnutls_session_t session,
149                            gnutls_transport_ptr_t recv_ptr,
150                            gnutls_transport_ptr_t send_ptr)
151 {
152   session->internals.transport_send_ptr = send_ptr;
153   session->internals.transport_recv_ptr = recv_ptr;
154 }
155
156 /**
157  * gnutls_transport_get_ptr:
158  * @session: is a #gnutls_session_t structure.
159  *
160  * Used to get the first argument of the transport function (like
161  * PUSH and PULL).  This must have been set using
162  * gnutls_transport_set_ptr().
163  *
164  * Returns: first argument of the transport function.
165  **/
166 gnutls_transport_ptr_t
167 gnutls_transport_get_ptr (gnutls_session_t session)
168 {
169   return session->internals.transport_recv_ptr;
170 }
171
172 /**
173  * gnutls_transport_get_ptr2:
174  * @session: is a #gnutls_session_t structure.
175  * @recv_ptr: will hold the value for the pull function
176  * @send_ptr: will hold the value for the push function
177  *
178  * Used to get the arguments of the transport functions (like PUSH
179  * and PULL).  These should have been set using
180  * gnutls_transport_set_ptr2().
181  **/
182 void
183 gnutls_transport_get_ptr2 (gnutls_session_t session,
184                            gnutls_transport_ptr_t * recv_ptr,
185                            gnutls_transport_ptr_t * send_ptr)
186 {
187
188   *recv_ptr = session->internals.transport_recv_ptr;
189   *send_ptr = session->internals.transport_send_ptr;
190 }
191
192 /**
193  * gnutls_bye:
194  * @session: is a #gnutls_session_t structure.
195  * @how: is an integer
196  *
197  * Terminates the current TLS/SSL connection. The connection should
198  * have been initiated using gnutls_handshake().  @how should be one
199  * of %GNUTLS_SHUT_RDWR, %GNUTLS_SHUT_WR.
200  *
201  * In case of %GNUTLS_SHUT_RDWR then the TLS connection gets
202  * terminated and further receives and sends will be disallowed.  If
203  * the return value is zero you may continue using the connection.
204  * %GNUTLS_SHUT_RDWR actually sends an alert containing a close
205  * request and waits for the peer to reply with the same message.
206  *
207  * In case of %GNUTLS_SHUT_WR then the TLS connection gets terminated
208  * and further sends will be disallowed. In order to reuse the
209  * connection you should wait for an EOF from the peer.
210  * %GNUTLS_SHUT_WR sends an alert containing a close request.
211  *
212  * Note that not all implementations will properly terminate a TLS
213  * connection.  Some of them, usually for performance reasons, will
214  * terminate only the underlying transport layer, thus causing a
215  * transmission error to the peer.  This error cannot be
216  * distinguished from a malicious party prematurely terminating the
217  * session, thus this behavior is not recommended.
218  *
219  * This function may also return %GNUTLS_E_AGAIN or
220  * %GNUTLS_E_INTERRUPTED; cf.  gnutls_record_get_direction().
221  *
222  * Returns: %GNUTLS_E_SUCCESS on success, or an error code, see
223  *   function documentation for entire semantics.
224  **/
225 int
226 gnutls_bye (gnutls_session_t session, gnutls_close_request_t how)
227 {
228   int ret = 0;
229
230   switch (STATE)
231     {
232     case STATE0:
233     case STATE60:
234       ret = _gnutls_io_write_flush (session);
235       STATE = STATE60;
236       if (ret < 0)
237         {
238           gnutls_assert ();
239           return ret;
240         }
241
242     case STATE61:
243       ret =
244         gnutls_alert_send (session, GNUTLS_AL_WARNING, GNUTLS_A_CLOSE_NOTIFY);
245       STATE = STATE61;
246       if (ret < 0)
247         {
248           gnutls_assert ();
249           return ret;
250         }
251
252     case STATE62:
253       STATE = STATE62;
254       if (how == GNUTLS_SHUT_RDWR)
255         {
256           do
257             {
258               _gnutls_io_clear_peeked_data (session);
259               ret = _gnutls_recv_int (session, GNUTLS_ALERT, -1, NULL, 0);
260             }
261           while (ret == GNUTLS_E_GOT_APPLICATION_DATA);
262
263           if (ret >= 0)
264             session->internals.may_not_read = 1;
265
266           if (ret < 0)
267             {
268               gnutls_assert ();
269               return ret;
270             }
271         }
272       STATE = STATE62;
273
274       break;
275     default:
276       gnutls_assert ();
277       return GNUTLS_E_INTERNAL_ERROR;
278     }
279
280   STATE = STATE0;
281
282   session->internals.may_not_write = 1;
283   return 0;
284 }
285
286 inline static void
287 session_invalidate (gnutls_session_t session)
288 {
289   session->internals.invalid_connection = 1;
290 }
291
292
293 inline static void
294 session_unresumable (gnutls_session_t session)
295 {
296   session->internals.resumable = RESUME_FALSE;
297 }
298
299 /* returns 0 if session is valid
300  */
301 inline static int
302 session_is_valid (gnutls_session_t session)
303 {
304   if (session->internals.invalid_connection != 0)
305     return GNUTLS_E_INVALID_SESSION;
306
307   return 0;
308 }
309
310 /* Copies the record version into the headers. The 
311  * version must have 2 bytes at least.
312  */
313 inline static void
314 copy_record_version (gnutls_session_t session,
315                      gnutls_handshake_description_t htype, opaque version[2])
316 {
317   gnutls_protocol_t lver;
318
319   if (session->internals.initial_negotiation_completed || htype != GNUTLS_HANDSHAKE_CLIENT_HELLO
320       || session->internals.default_record_version[0] == 0)
321     {
322       lver = gnutls_protocol_get_version (session);
323
324       version[0] = _gnutls_version_get_major (lver);
325       version[1] = _gnutls_version_get_minor (lver);
326     }
327   else
328     {
329       version[0] = session->internals.default_record_version[0];
330       version[1] = session->internals.default_record_version[1];
331     }
332 }
333
334 /* This function behaves exactly like write(). The only difference is
335  * that it accepts, the gnutls_session_t and the content_type_t of data to
336  * send (if called by the user the Content is specific)
337  * It is intended to transfer data, under the current session.    
338  *
339  * Oct 30 2001: Removed capability to send data more than MAX_RECORD_SIZE.
340  * This makes the function much easier to read, and more error resistant
341  * (there were cases were the old function could mess everything up).
342  * --nmav
343  *
344  * This function may accept a NULL pointer for data, and 0 for size, if
345  * and only if the previous send was interrupted for some reason.
346  *
347  */
348 ssize_t
349 _gnutls_send_int (gnutls_session_t session, content_type_t type,
350                   gnutls_handshake_description_t htype,
351                   unsigned int epoch_rel, const void *_data,
352                   size_t sizeofdata, unsigned int mflags)
353 {
354   mbuffer_st *bufel;
355   ssize_t cipher_size;
356   int retval, ret;
357   int data2send_size;
358   uint8_t headers[5];
359   const uint8_t *data = _data;
360   record_parameters_st *record_params;
361   record_state_st *record_state;
362
363   ret = _gnutls_epoch_get (session, epoch_rel, &record_params);
364   if (ret < 0)
365     {
366       gnutls_assert ();
367       return ret;
368     }
369
370   /* Safeguard against processing data with an incomplete cipher state. */
371   if (!record_params->initialized)
372     {
373       gnutls_assert ();
374       return GNUTLS_E_INVALID_REQUEST;
375     }
376
377   record_state = &record_params->write;
378
379   /* Do not allow null pointer if the send buffer is empty.
380    * If the previous send was interrupted then a null pointer is
381    * ok, and means to resume.
382    */
383   if (session->internals.record_send_buffer.byte_length == 0 &&
384       (sizeofdata == 0 && _data == NULL))
385     {
386       gnutls_assert ();
387       return GNUTLS_E_INVALID_REQUEST;
388     }
389
390   if (type != GNUTLS_ALERT)     /* alert messages are sent anyway */
391     if (session_is_valid (session) || session->internals.may_not_write != 0)
392       {
393         gnutls_assert ();
394         return GNUTLS_E_INVALID_SESSION;
395       }
396
397   headers[0] = type;
398
399   /* Use the default record version, if it is
400    * set.
401    */
402   copy_record_version (session, htype, &headers[1]);
403
404
405   _gnutls_record_log
406     ("REC[%p]: Sending Packet[%d] %s(%d) with length: %d\n", session,
407      (int) _gnutls_uint64touint32 (&record_state->sequence_number),
408      _gnutls_packet2str (type), type, (int) sizeofdata);
409
410   if (sizeofdata > MAX_RECORD_SEND_SIZE)
411     data2send_size = MAX_RECORD_SEND_SIZE;
412   else
413     data2send_size = sizeofdata;
414
415   /* Only encrypt if we don't have data to send 
416    * from the previous run. - probably interrupted.
417    */
418   if (mflags != 0 && session->internals.record_send_buffer.byte_length > 0)
419     {
420       ret = _gnutls_io_write_flush (session);
421       if (ret > 0)
422         cipher_size = ret;
423       else
424         cipher_size = 0;
425
426       retval = session->internals.record_send_buffer_user_size;
427     }
428   else
429     {
430
431       /* now proceed to packet encryption
432        */
433       cipher_size = data2send_size + MAX_RECORD_OVERHEAD;
434       bufel = _mbuffer_alloc (cipher_size, cipher_size);
435       if (bufel == NULL)
436         {
437           gnutls_assert ();
438           return GNUTLS_E_MEMORY_ERROR;
439         }
440
441       cipher_size =
442         _gnutls_encrypt (session, headers, RECORD_HEADER_SIZE, data,
443                          data2send_size, _mbuffer_get_udata_ptr (bufel),
444                          cipher_size, type,
445                          (session->internals.priorities.no_padding ==
446                           0) ? 1 : 0, record_params);
447       if (cipher_size <= 0)
448         {
449           gnutls_assert ();
450           if (cipher_size == 0)
451             cipher_size = GNUTLS_E_ENCRYPTION_FAILED;
452           gnutls_free (bufel);
453           return cipher_size;   /* error */
454         }
455
456       retval = data2send_size;
457       session->internals.record_send_buffer_user_size = data2send_size;
458
459       /* increase sequence number
460        */
461       if (_gnutls_uint64pp (&record_state->sequence_number) != 0)
462         {
463           session_invalidate (session);
464           gnutls_assert ();
465           gnutls_free (bufel);
466           return GNUTLS_E_RECORD_LIMIT_REACHED;
467         }
468
469       _mbuffer_set_udata_size (bufel, cipher_size);
470       ret = _gnutls_io_write_buffered (session, bufel, mflags);
471     }
472
473   if (ret != cipher_size)
474     {
475       if (ret < 0 && gnutls_error_is_fatal (ret) == 0)
476         {
477           /* If we have sent any data then just return
478            * the error value. Do not invalidate the session.
479            */
480           gnutls_assert ();
481           return ret;
482         }
483
484       if (ret > 0)
485         {
486           gnutls_assert ();
487           ret = GNUTLS_E_INTERNAL_ERROR;
488         }
489       session_unresumable (session);
490       session->internals.may_not_write = 1;
491       gnutls_assert ();
492       return ret;
493     }
494
495   session->internals.record_send_buffer_user_size = 0;
496
497   _gnutls_record_log ("REC[%p]: Sent Packet[%d] %s(%d) with length: %d\n",
498                       session,
499                       (int)
500                       _gnutls_uint64touint32
501                       (&record_state->sequence_number),
502                       _gnutls_packet2str (type), type, (int) cipher_size);
503
504   return retval;
505 }
506
507 /* This function is to be called if the handshake was successfully 
508  * completed. This sends a Change Cipher Spec packet to the peer.
509  */
510 ssize_t
511 _gnutls_send_change_cipher_spec (gnutls_session_t session, int again)
512 {
513   static const opaque data[1] = { GNUTLS_TYPE_CHANGE_CIPHER_SPEC };
514
515   _gnutls_handshake_log ("REC[%p]: Sent ChangeCipherSpec\n", session);
516
517   if (again == 0)
518     return _gnutls_send_int (session, GNUTLS_CHANGE_CIPHER_SPEC, -1,
519                              EPOCH_WRITE_CURRENT, data, 1, MBUFFER_FLUSH);
520   else
521     {
522       return _gnutls_io_write_flush (session);
523     }
524 }
525
526 inline static int
527 check_recv_type (content_type_t recv_type)
528 {
529   switch (recv_type)
530     {
531     case GNUTLS_CHANGE_CIPHER_SPEC:
532     case GNUTLS_ALERT:
533     case GNUTLS_HANDSHAKE:
534     case GNUTLS_APPLICATION_DATA:
535     case GNUTLS_INNER_APPLICATION:
536       return 0;
537     default:
538       gnutls_assert ();
539       return GNUTLS_E_UNEXPECTED_PACKET;
540     }
541
542 }
543
544
545 /* Checks if there are pending data in the record buffers. If there are
546  * then it copies the data.
547  */
548 static int
549 check_buffers (gnutls_session_t session, content_type_t type,
550                opaque * data, int sizeofdata)
551 {
552   if ((type == GNUTLS_APPLICATION_DATA ||
553        type == GNUTLS_HANDSHAKE ||
554        type == GNUTLS_INNER_APPLICATION)
555       && _gnutls_record_buffer_get_size (type, session) > 0)
556     {
557       int ret, ret2;
558       ret = _gnutls_record_buffer_get (type, session, data, sizeofdata);
559       if (ret < 0)
560         {
561           gnutls_assert ();
562           return ret;
563         }
564
565       /* if the buffer just got empty */
566       if (_gnutls_record_buffer_get_size (type, session) == 0)
567         {
568           if ((ret2 = _gnutls_io_clear_peeked_data (session)) < 0)
569             {
570               gnutls_assert ();
571               return ret2;
572             }
573         }
574
575       return ret;
576     }
577
578   return 0;
579 }
580
581
582 /* Checks the record headers and returns the length, version and
583  * content type.
584  */
585 static int
586 record_check_headers (gnutls_session_t session,
587                       uint8_t headers[RECORD_HEADER_SIZE],
588                       content_type_t type,
589                       gnutls_handshake_description_t htype,
590                       /*output */ content_type_t * recv_type,
591                       opaque version[2], uint16_t * length,
592                       uint16_t * header_size)
593 {
594
595   /* Read the first two bytes to determine if this is a 
596    * version 2 message 
597    */
598
599   if (htype == GNUTLS_HANDSHAKE_CLIENT_HELLO && type == GNUTLS_HANDSHAKE
600       && headers[0] > 127)
601     {
602
603       /* if msb set and expecting handshake message
604        * it should be SSL 2 hello 
605        */
606       version[0] = 3;           /* assume SSL 3.0 */
607       version[1] = 0;
608
609       *length = (((headers[0] & 0x7f) << 8)) | headers[1];
610
611       /* SSL 2.0 headers */
612       *header_size = 2;
613       *recv_type = GNUTLS_HANDSHAKE;    /* we accept only v2 client hello
614                                          */
615
616       /* in order to assist the handshake protocol.
617        * V2 compatibility is a mess.
618        */
619       session->internals.v2_hello = *length;
620
621       _gnutls_record_log ("REC[%p]: V2 packet received. Length: %d\n",
622                           session, *length);
623
624     }
625   else
626     {
627       /* version 3.x 
628        */
629       *recv_type = headers[0];
630       version[0] = headers[1];
631       version[1] = headers[2];
632
633       /* No DECR_LEN, since headers has enough size. 
634        */
635       *length = _gnutls_read_uint16 (&headers[3]);
636     }
637
638   return 0;
639 }
640
641 /* Here we check if the advertized version is the one we
642  * negotiated in the handshake.
643  */
644 inline static int
645 record_check_version (gnutls_session_t session,
646                       gnutls_handshake_description_t htype, opaque version[2])
647 {
648   if (htype == GNUTLS_HANDSHAKE_CLIENT_HELLO)
649     {
650       /* Reject hello packets with major version higher than 3.
651        */
652       if (version[0] > 3)
653         {
654           gnutls_assert ();
655           _gnutls_record_log
656             ("REC[%p]: INVALID VERSION PACKET: (%d) %d.%d\n", session,
657              htype, version[0], version[1]);
658           return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
659         }
660     }
661   else if (htype != GNUTLS_HANDSHAKE_SERVER_HELLO &&
662            gnutls_protocol_get_version (session) !=
663            _gnutls_version_get (version[0], version[1]))
664     {
665       /* Reject record packets that have a different version than the
666        * one negotiated. Note that this version is not protected by any
667        * mac. I don't really think that this check serves any purpose.
668        */
669       gnutls_assert ();
670       _gnutls_record_log ("REC[%p]: INVALID VERSION PACKET: (%d) %d.%d\n",
671                           session, htype, version[0], version[1]);
672
673       return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
674     }
675
676   return 0;
677 }
678
679 /* This function will check if the received record type is
680  * the one we actually expect.
681  */
682 static int
683 record_check_type (gnutls_session_t session,
684                    content_type_t recv_type, content_type_t type,
685                    gnutls_handshake_description_t htype, opaque * data,
686                    int data_size)
687 {
688
689   int ret;
690
691   if ((recv_type == type)
692       && (type == GNUTLS_APPLICATION_DATA ||
693           type == GNUTLS_HANDSHAKE || type == GNUTLS_INNER_APPLICATION))
694     {
695       _gnutls_record_buffer_put (type, session, (void *) data, data_size);
696     }
697   else
698     {
699       switch (recv_type)
700         {
701         case GNUTLS_ALERT:
702
703           _gnutls_record_log
704             ("REC[%p]: Alert[%d|%d] - %s - was received\n", session,
705              data[0], data[1], gnutls_alert_get_name ((int) data[1]));
706
707           session->internals.last_alert = data[1];
708
709           /* if close notify is received and
710            * the alert is not fatal
711            */
712           if (data[1] == GNUTLS_A_CLOSE_NOTIFY && data[0] != GNUTLS_AL_FATAL)
713             {
714               /* If we have been expecting for an alert do 
715                */
716               session->internals.read_eof = 1;
717               return GNUTLS_E_INT_RET_0;        /* EOF */
718             }
719           else
720             {
721
722               /* if the alert is FATAL or WARNING
723                * return the apropriate message
724                */
725
726               gnutls_assert ();
727               ret = GNUTLS_E_WARNING_ALERT_RECEIVED;
728               if (data[0] == GNUTLS_AL_FATAL)
729                 {
730                   session_unresumable (session);
731                   session_invalidate (session);
732                   ret = GNUTLS_E_FATAL_ALERT_RECEIVED;
733                 }
734
735               return ret;
736             }
737           break;
738
739         case GNUTLS_CHANGE_CIPHER_SPEC:
740           /* this packet is now handled in the recv_int()
741            * function
742            */
743           gnutls_assert ();
744
745           return GNUTLS_E_UNEXPECTED_PACKET;
746
747         case GNUTLS_APPLICATION_DATA:
748           if (session->internals.initial_negotiation_completed == 0)
749             {
750               return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET);
751             }
752
753           /* even if data is unexpected put it into the buffer */
754           if ((ret =
755                _gnutls_record_buffer_put (recv_type, session,
756                                           (void *) data, data_size)) < 0)
757             {
758               gnutls_assert ();
759               return ret;
760             }
761
762           /* the got_application data is only returned
763            * if expecting client hello (for rehandshake
764            * reasons). Otherwise it is an unexpected packet
765            */
766           if (type == GNUTLS_ALERT || (htype == GNUTLS_HANDSHAKE_CLIENT_HELLO
767                                        && type == GNUTLS_HANDSHAKE))
768             return GNUTLS_E_GOT_APPLICATION_DATA;
769           else
770             {
771               gnutls_assert ();
772               return GNUTLS_E_UNEXPECTED_PACKET;
773             }
774
775           break;
776         case GNUTLS_HANDSHAKE:
777           /* This is legal if HELLO_REQUEST is received - and we are a client.
778            * If we are a server, a client may initiate a renegotiation at any time.
779            */
780           if (session->security_parameters.entity == GNUTLS_SERVER)
781             {
782               gnutls_assert ();
783               ret =
784                 _gnutls_record_buffer_put (recv_type, session, (void *) data,
785                                            data_size);
786               if (ret < 0)
787                 {
788                   gnutls_assert ();
789                   return ret;
790                 }
791               return GNUTLS_E_REHANDSHAKE;
792             }
793
794           /* If we are already in a handshake then a Hello
795            * Request is illegal. But here we don't really care
796            * since this message will never make it up here.
797            */
798
799           /* So we accept it */
800           return _gnutls_recv_hello_request (session, data, data_size);
801
802           break;
803         case GNUTLS_INNER_APPLICATION:
804           /* even if data is unexpected put it into the buffer */
805           if ((ret = _gnutls_record_buffer_put (recv_type, session,
806                                                 (void *) data,
807                                                 data_size)) < 0)
808             {
809               gnutls_assert ();
810               return ret;
811             }
812           gnutls_assert ();
813           return GNUTLS_E_UNEXPECTED_PACKET;
814           break;
815         default:
816
817           _gnutls_record_log
818             ("REC[%p]: Received Unknown packet %d expecting %d\n",
819              session, recv_type, type);
820
821           gnutls_assert ();
822           return GNUTLS_E_INTERNAL_ERROR;
823         }
824     }
825
826   return 0;
827
828 }
829
830
831 /* This function will return the internal (per session) temporary
832  * recv buffer. If the buffer was not initialized before it will
833  * also initialize it.
834  */
835 inline static int
836 get_temp_recv_buffer (gnutls_session_t session, gnutls_datum_t * tmp)
837 {
838   size_t max_record_size;
839
840   if (gnutls_compression_get (session) != GNUTLS_COMP_NULL ||
841       session->internals.priorities.allow_large_records != 0)
842     max_record_size = MAX_RECORD_RECV_SIZE + EXTRA_COMP_SIZE;
843   else
844     max_record_size = MAX_RECORD_RECV_SIZE;
845
846   /* We allocate MAX_RECORD_RECV_SIZE length
847    * because we cannot predict the output data by the record
848    * packet length (due to compression).
849    */
850
851   if (max_record_size > session->internals.recv_buffer.size ||
852       session->internals.recv_buffer.data == NULL)
853     {
854
855       /* Initialize the internal buffer.
856        */
857       session->internals.recv_buffer.data =
858         gnutls_realloc (session->internals.recv_buffer.data, max_record_size);
859
860       if (session->internals.recv_buffer.data == NULL)
861         {
862           gnutls_assert ();
863           return GNUTLS_E_MEMORY_ERROR;
864         }
865
866       session->internals.recv_buffer.size = max_record_size;
867     }
868
869   tmp->data = session->internals.recv_buffer.data;
870   tmp->size = session->internals.recv_buffer.size;
871
872   return 0;
873 }
874
875
876 #define MAX_EMPTY_PACKETS_SEQUENCE 4
877
878 /* This function behaves exactly like read(). The only difference is
879  * that it accepts the gnutls_session_t and the content_type_t of data to
880  * receive (if called by the user the Content is Userdata only)
881  * It is intended to receive data, under the current session.
882  *
883  * The gnutls_handshake_description_t was introduced to support SSL V2.0 client hellos.
884  */
885 ssize_t
886 _gnutls_recv_int (gnutls_session_t session, content_type_t type,
887                   gnutls_handshake_description_t htype,
888                   opaque * data, size_t sizeofdata)
889 {
890   int decrypted_length;
891   opaque version[2];
892   content_type_t recv_type;
893   uint16_t length;
894   uint8_t *ciphertext;
895   int ret, ret2;
896   uint16_t header_size;
897   int empty_packet = 0;
898   gnutls_datum_t data_enc, tmp;
899   record_parameters_st *record_params;
900   record_state_st *record_state;
901
902   ret = _gnutls_epoch_get (session, EPOCH_READ_CURRENT, &record_params);
903   if (ret < 0)
904     {
905       gnutls_assert ();
906       return ret;
907     }
908
909   /* Safeguard against processing data with an incomplete cipher state. */
910   if (!record_params->initialized)
911     {
912       gnutls_assert ();
913       return GNUTLS_E_INVALID_REQUEST;
914     }
915
916   record_state = &record_params->read;
917
918   if (type != GNUTLS_ALERT && (sizeofdata == 0 || data == NULL))
919     {
920       return GNUTLS_E_INVALID_REQUEST;
921     }
922
923 begin:
924
925   if (empty_packet > MAX_EMPTY_PACKETS_SEQUENCE)
926     {
927       gnutls_assert ();
928       return GNUTLS_E_TOO_MANY_EMPTY_PACKETS;
929     }
930
931   if (session->internals.read_eof != 0)
932     {
933       /* if we have already read an EOF
934        */
935       return 0;
936     }
937   else if (session_is_valid (session) != 0
938            || session->internals.may_not_read != 0)
939     {
940       gnutls_assert ();
941       return GNUTLS_E_INVALID_SESSION;
942     }
943
944 /* If we have enough data in the cache do not bother receiving
945  * a new packet. (in order to flush the cache)
946  */
947   ret = check_buffers (session, type, data, sizeofdata);
948   if (ret != 0)
949     return ret;
950
951
952 /* default headers for TLS 1.0
953  */
954   header_size = RECORD_HEADER_SIZE;
955
956   if ((ret =
957        _gnutls_io_read_buffered (session, header_size, -1)) != header_size)
958     {
959       if (ret < 0 && gnutls_error_is_fatal (ret) == 0)
960         return ret;
961
962       session_invalidate (session);
963       if (type == GNUTLS_ALERT)
964         {
965           gnutls_assert ();
966           return 0;             /* we were expecting close notify */
967         }
968       session_unresumable (session);
969       gnutls_assert ();
970       return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
971     }
972
973   ret = _mbuffer_linearize (&session->internals.record_recv_buffer);
974   if (ret != 0)
975     {
976       gnutls_assert ();
977       return ret;
978     }
979
980   _mbuffer_get_first (&session->internals.record_recv_buffer, &data_enc);
981
982   if ((ret =
983        record_check_headers (session, data_enc.data, type, htype, &recv_type,
984                              version, &length, &header_size)) < 0)
985     {
986       gnutls_assert ();
987       return ret;
988     }
989
990 /* Here we check if the Type of the received packet is
991  * ok. 
992  */
993   if ((ret = check_recv_type (recv_type)) < 0)
994     {
995       gnutls_assert ();
996       return ret;
997     }
998
999 /* Here we check if the advertized version is the one we
1000  * negotiated in the handshake.
1001  */
1002   if ((ret = record_check_version (session, htype, version)) < 0)
1003     {
1004       gnutls_assert ();
1005       session_invalidate (session);
1006       return ret;
1007     }
1008
1009   _gnutls_record_log
1010     ("REC[%p]: Expected Packet[%d] %s(%d) with length: %d\n", session,
1011      (int) _gnutls_uint64touint32 (&record_state->sequence_number),
1012      _gnutls_packet2str (type), type, (int) sizeofdata);
1013   _gnutls_record_log ("REC[%p]: Received Packet[%d] %s(%d) with length: %d\n",
1014                       session,
1015                       (int)
1016                       _gnutls_uint64touint32 (&record_state->sequence_number),
1017                       _gnutls_packet2str (recv_type), recv_type, length);
1018
1019   if (length > MAX_RECV_SIZE)
1020     {
1021       _gnutls_record_log
1022         ("REC[%p]: FATAL ERROR: Received packet with length: %d\n",
1023          session, length);
1024
1025       session_unresumable (session);
1026       session_invalidate (session);
1027       gnutls_assert ();
1028       return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1029     }
1030
1031 /* check if we have that data into buffer. 
1032  */
1033   if ((ret =
1034        _gnutls_io_read_buffered (session, header_size + length,
1035                                  recv_type)) != header_size + length)
1036     {
1037       if (ret < 0 && gnutls_error_is_fatal (ret) == 0)
1038         return ret;
1039
1040       session_unresumable (session);
1041       session_invalidate (session);
1042       gnutls_assert ();
1043       return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1044     }
1045
1046 /* ok now we are sure that we can read all the data - so
1047  * move on !
1048  */
1049
1050   ret = _mbuffer_linearize (&session->internals.record_recv_buffer);
1051   if (ret != 0)
1052     {
1053       gnutls_assert ();
1054       return ret;
1055     }
1056   _mbuffer_get_first (&session->internals.record_recv_buffer, &data_enc);
1057   ciphertext = &data_enc.data[header_size];
1058
1059   ret = get_temp_recv_buffer (session, &tmp);
1060   if (ret < 0)
1061     {
1062       gnutls_assert ();
1063       return ret;
1064     }
1065
1066 /* decrypt the data we got. 
1067  */
1068   ret =
1069     _gnutls_decrypt (session, ciphertext, length, tmp.data, tmp.size,
1070                      recv_type, record_params);
1071   if (ret < 0)
1072     {
1073       session_unresumable (session);
1074       session_invalidate (session);
1075       gnutls_assert ();
1076       return ret;
1077     }
1078   _mbuffer_remove_bytes (&session->internals.record_recv_buffer,
1079                          header_size + length);
1080   decrypted_length = ret;
1081
1082 /* Check if this is a CHANGE_CIPHER_SPEC
1083  */
1084   if (type == GNUTLS_CHANGE_CIPHER_SPEC &&
1085       recv_type == GNUTLS_CHANGE_CIPHER_SPEC)
1086     {
1087
1088       _gnutls_record_log
1089         ("REC[%p]: ChangeCipherSpec Packet was received\n", session);
1090
1091       if ((size_t) ret != sizeofdata)
1092         {                       /* sizeofdata should be 1 */
1093           gnutls_assert ();
1094           return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1095         }
1096       memcpy (data, tmp.data, sizeofdata);
1097
1098       return ret;
1099     }
1100
1101   _gnutls_record_log
1102     ("REC[%p]: Decrypted Packet[%d] %s(%d) with length: %d\n", session,
1103      (int) _gnutls_uint64touint32 (&record_state->sequence_number),
1104      _gnutls_packet2str (recv_type), recv_type, decrypted_length);
1105
1106 /* increase sequence number 
1107  */
1108   if (_gnutls_uint64pp (&record_state->sequence_number) != 0)
1109     {
1110       session_invalidate (session);
1111       gnutls_assert ();
1112       return GNUTLS_E_RECORD_LIMIT_REACHED;
1113     }
1114
1115   ret =
1116     record_check_type (session, recv_type, type, htype, tmp.data,
1117                        decrypted_length);
1118   if (ret < 0)
1119     {
1120       if (ret == GNUTLS_E_INT_RET_0)
1121         return 0;
1122       gnutls_assert ();
1123       return ret;
1124     }
1125
1126 /* Get Application data from buffer 
1127  */
1128   if ((recv_type == type) &&
1129       (type == GNUTLS_APPLICATION_DATA ||
1130        type == GNUTLS_HANDSHAKE || type == GNUTLS_INNER_APPLICATION))
1131     {
1132
1133       ret = _gnutls_record_buffer_get (type, session, data, sizeofdata);
1134       if (ret < 0)
1135         {
1136           gnutls_assert ();
1137           return ret;
1138         }
1139
1140       /* if the buffer just got empty 
1141        */
1142       if (_gnutls_record_buffer_get_size (type, session) == 0)
1143         {
1144           if ((ret2 = _gnutls_io_clear_peeked_data (session)) < 0)
1145             {
1146               gnutls_assert ();
1147               return ret2;
1148             }
1149         }
1150     }
1151   else
1152     {
1153       gnutls_assert ();
1154       return GNUTLS_E_UNEXPECTED_PACKET;
1155       /* we didn't get what we wanted to 
1156        */
1157     }
1158
1159 /* (originally for) TLS 1.0 CBC protection. 
1160  * Actually this code is called if we just received
1161  * an empty packet. An empty TLS packet is usually
1162  * sent to protect some vulnerabilities in the CBC mode.
1163  * In that case we go to the beginning and start reading
1164  * the next packet.
1165  */
1166   if (ret == 0)
1167     {
1168       empty_packet++;
1169       goto begin;
1170     }
1171
1172   return ret;
1173 }
1174
1175
1176 /**
1177  * gnutls_record_send:
1178  * @session: is a #gnutls_session_t structure.
1179  * @data: contains the data to send
1180  * @sizeofdata: is the length of the data
1181  *
1182  * This function has the similar semantics with send().  The only
1183  * difference is that it accepts a GnuTLS session, and uses different
1184  * error codes.
1185  *
1186  * Note that if the send buffer is full, send() will block this
1187  * function.  See the send() documentation for full information.  You
1188  * can replace the default push function by using
1189  * gnutls_transport_set_ptr2() with a call to send() with a
1190  * MSG_DONTWAIT flag if blocking is a problem.
1191  *
1192  * If the EINTR is returned by the internal push function (the
1193  * default is send()} then %GNUTLS_E_INTERRUPTED will be returned. If
1194  * %GNUTLS_E_INTERRUPTED or %GNUTLS_E_AGAIN is returned, you must
1195  * call this function again, with the same parameters; alternatively
1196  * you could provide a %NULL pointer for data, and 0 for
1197  * size. cf. gnutls_record_get_direction().
1198  *
1199  * Returns: the number of bytes sent, or a negative error code.  The
1200  *   number of bytes sent might be less than @sizeofdata.  The maximum
1201  *   number of bytes this function can send in a single call depends
1202  *   on the negotiated maximum record size.
1203   **/
1204 ssize_t
1205 gnutls_record_send (gnutls_session_t session, const void *data,
1206                     size_t sizeofdata)
1207 {
1208   return _gnutls_send_int (session, GNUTLS_APPLICATION_DATA, -1,
1209                            EPOCH_WRITE_CURRENT, data, sizeofdata,
1210                            MBUFFER_FLUSH);
1211 }
1212
1213 /**
1214  * gnutls_record_recv:
1215  * @session: is a #gnutls_session_t structure.
1216  * @data: the buffer that the data will be read into
1217  * @sizeofdata: the number of requested bytes
1218  *
1219  * This function has the similar semantics with recv().  The only
1220  * difference is that it accepts a GnuTLS session, and uses different
1221  * error codes.
1222  *
1223  * In the special case that a server requests a renegotiation, the
1224  * client may receive an error code of %GNUTLS_E_REHANDSHAKE.  This
1225  * message may be simply ignored, replied with an alert
1226  * %GNUTLS_A_NO_RENEGOTIATION, or replied with a new handshake,
1227  * depending on the client's will.
1228  *
1229  * If %EINTR is returned by the internal push function (the default
1230  * is recv()) then %GNUTLS_E_INTERRUPTED will be returned.  If
1231  * %GNUTLS_E_INTERRUPTED or %GNUTLS_E_AGAIN is returned, you must
1232  * call this function again to get the data.  See also
1233  * gnutls_record_get_direction().
1234  *
1235  * A server may also receive %GNUTLS_E_REHANDSHAKE when a client has
1236  * initiated a handshake. In that case the server can only initiate a
1237  * handshake or terminate the connection.
1238  *
1239  * Returns: the number of bytes received and zero on EOF.  A negative
1240  *   error code is returned in case of an error.  The number of bytes
1241  *   received might be less than @sizeofdata.
1242  **/
1243 ssize_t
1244 gnutls_record_recv (gnutls_session_t session, void *data, size_t sizeofdata)
1245 {
1246   return _gnutls_recv_int (session, GNUTLS_APPLICATION_DATA, -1, data,
1247                            sizeofdata);
1248 }