00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "gnutls_int.h"
00029 #include "gnutls_errors.h"
00030 #include "debug.h"
00031 #include "gnutls_cipher.h"
00032 #include "gnutls_buffers.h"
00033 #include "gnutls_handshake.h"
00034 #include "gnutls_hash_int.h"
00035 #include "gnutls_cipher_int.h"
00036 #include "gnutls_algorithms.h"
00037 #include "gnutls_auth_int.h"
00038 #include "gnutls_num.h"
00039 #include "gnutls_record.h"
00040 #include "gnutls_datum.h"
00041 #include "ext_max_record.h"
00042 #include <gnutls_state.h>
00043 #include <gnutls_dh.h>
00044
00051 enum MHD_GNUTLS_Protocol
00052 MHD__gnutls_protocol_get_version (MHD_gtls_session_t session)
00053 {
00054 return session->security_parameters.version;
00055 }
00056
00057 void
00058 MHD_gtls_set_current_version (MHD_gtls_session_t session,
00059 enum MHD_GNUTLS_Protocol version)
00060 {
00061 session->security_parameters.version = version;
00062 }
00063
00076 void
00077 MHD__gnutls_transport_set_lowat (MHD_gtls_session_t session, int num)
00078 {
00079 session->internals.lowat = num;
00080 }
00081
00091 void
00092 MHD__gnutls_transport_set_ptr (MHD_gtls_session_t session,
00093 MHD_gnutls_transport_ptr_t ptr)
00094 {
00095 session->internals.transport_recv_ptr = ptr;
00096 session->internals.transport_send_ptr = ptr;
00097 }
00098
00132 int
00133 MHD__gnutls_bye (MHD_gtls_session_t session, MHD_gnutls_close_request_t how)
00134 {
00135 int ret = 0;
00136
00137 switch (STATE)
00138 {
00139 case STATE0:
00140 case STATE60:
00141 ret = MHD_gtls_io_write_flush (session);
00142 STATE = STATE60;
00143 if (ret < 0)
00144 {
00145 MHD_gnutls_assert ();
00146 return ret;
00147 }
00148
00149 case STATE61:
00150 ret =
00151 MHD__gnutls_alert_send (session, GNUTLS_AL_WARNING,
00152 GNUTLS_A_CLOSE_NOTIFY);
00153 STATE = STATE61;
00154 if (ret < 0)
00155 {
00156 MHD_gnutls_assert ();
00157 return ret;
00158 }
00159
00160 case STATE62:
00161 STATE = STATE62;
00162 if (how == GNUTLS_SHUT_RDWR)
00163 {
00164 do
00165 {
00166 MHD_gtls_io_clear_peeked_data (session);
00167 ret = MHD_gtls_recv_int (session, GNUTLS_ALERT, -1, NULL, 0);
00168 }
00169 while (ret == GNUTLS_E_GOT_APPLICATION_DATA);
00170
00171 if (ret >= 0)
00172 session->internals.may_not_read = 1;
00173
00174 if (ret < 0)
00175 {
00176 MHD_gnutls_assert ();
00177 return ret;
00178 }
00179 }
00180 STATE = STATE62;
00181
00182 break;
00183 default:
00184 MHD_gnutls_assert ();
00185 return GNUTLS_E_INTERNAL_ERROR;
00186 }
00187
00188 STATE = STATE0;
00189
00190 session->internals.may_not_write = 1;
00191 return 0;
00192 }
00193
00194 inline static void
00195 session_invalidate (MHD_gtls_session_t session)
00196 {
00197 session->internals.valid_connection = VALID_FALSE;
00198 }
00199
00200 inline static void
00201 session_unresumable (MHD_gtls_session_t session)
00202 {
00203 session->internals.resumable = RESUME_FALSE;
00204 }
00205
00206
00207
00208 inline static int
00209 session_is_valid (MHD_gtls_session_t session)
00210 {
00211 if (session->internals.valid_connection == VALID_FALSE)
00212 return GNUTLS_E_INVALID_SESSION;
00213
00214 return 0;
00215 }
00216
00217
00218
00219
00220 inline static void
00221 copy_record_version (MHD_gtls_session_t session,
00222 MHD_gnutls_handshake_description_t htype,
00223 opaque version[2])
00224 {
00225 enum MHD_GNUTLS_Protocol lver;
00226
00227 if (htype != GNUTLS_HANDSHAKE_CLIENT_HELLO
00228 || session->internals.default_record_version[0] == 0)
00229 {
00230 lver = MHD__gnutls_protocol_get_version (session);
00231
00232 version[0] = MHD_gtls_version_get_major (lver);
00233 version[1] = MHD_gtls_version_get_minor (lver);
00234 }
00235 else
00236 {
00237 version[0] = session->internals.default_record_version[0];
00238 version[1] = session->internals.default_record_version[1];
00239 }
00240 }
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256 ssize_t
00257 MHD_gtls_send_int (MHD_gtls_session_t session,
00258 content_type_t type,
00259 MHD_gnutls_handshake_description_t htype,
00260 const void *_data, size_t sizeofdata)
00261 {
00262 uint8_t *cipher;
00263 int cipher_size;
00264 int retval, ret;
00265 int data2send_size;
00266 uint8_t headers[5];
00267 const uint8_t *data = _data;
00268
00269
00270
00271
00272
00273 if (session->internals.record_send_buffer.length == 0 && (sizeofdata == 0
00274 && _data == NULL))
00275 {
00276 MHD_gnutls_assert ();
00277 return GNUTLS_E_INVALID_REQUEST;
00278 }
00279
00280 if (type != GNUTLS_ALERT)
00281 if (session_is_valid (session) || session->internals.may_not_write != 0)
00282 {
00283 MHD_gnutls_assert ();
00284 return GNUTLS_E_INVALID_SESSION;
00285 }
00286
00287 headers[0] = type;
00288
00289
00290
00291
00292 copy_record_version (session, htype, &headers[1]);
00293
00294 MHD__gnutls_record_log
00295 ("REC[%x]: Sending Packet[%d] %s(%d) with length: %d\n", session,
00296 (int) MHD_gtls_uint64touint32 (&session->connection_state.
00297 write_sequence_number),
00298 MHD__gnutls_packet2str (type), type, sizeofdata);
00299
00300 if (sizeofdata > MAX_RECORD_SEND_SIZE)
00301 data2send_size = MAX_RECORD_SEND_SIZE;
00302 else
00303 data2send_size = sizeofdata;
00304
00305
00306
00307
00308 if (session->internals.record_send_buffer.length > 0)
00309 {
00310 ret = MHD_gtls_io_write_flush (session);
00311 if (ret > 0)
00312 cipher_size = ret;
00313 else
00314 cipher_size = 0;
00315
00316 cipher = NULL;
00317
00318 retval = session->internals.record_send_buffer_user_size;
00319 }
00320 else
00321 {
00322
00323
00324 cipher_size = data2send_size + MAX_RECORD_OVERHEAD;
00325 cipher = MHD_gnutls_malloc (cipher_size);
00326 if (cipher == NULL)
00327 {
00328 MHD_gnutls_assert ();
00329 return GNUTLS_E_MEMORY_ERROR;
00330 }
00331
00332 cipher_size =
00333 MHD_gtls_encrypt (session, headers, RECORD_HEADER_SIZE, data,
00334 data2send_size, cipher, cipher_size, type,
00335 (session->internals.priorities.no_padding ==
00336 0) ? 1 : 0);
00337 if (cipher_size <= 0)
00338 {
00339 MHD_gnutls_assert ();
00340 if (cipher_size == 0)
00341 cipher_size = GNUTLS_E_ENCRYPTION_FAILED;
00342 MHD_gnutls_free (cipher);
00343 return cipher_size;
00344 }
00345
00346 retval = data2send_size;
00347 session->internals.record_send_buffer_user_size = data2send_size;
00348
00349
00350
00351 if (MHD_gtls_uint64pp
00352 (&session->connection_state.write_sequence_number) != 0)
00353 {
00354 session_invalidate (session);
00355 MHD_gnutls_assert ();
00356 MHD_gnutls_free (cipher);
00357 return GNUTLS_E_RECORD_LIMIT_REACHED;
00358 }
00359
00360 ret = MHD_gtls_io_write_buffered (session, cipher, cipher_size);
00361 MHD_gnutls_free (cipher);
00362 }
00363
00364 if (ret != cipher_size)
00365 {
00366 if (ret < 0 && MHD_gtls_error_is_fatal (ret) == 0)
00367 {
00368
00369
00370
00371 MHD_gnutls_assert ();
00372 return ret;
00373 }
00374
00375 if (ret > 0)
00376 {
00377 MHD_gnutls_assert ();
00378 ret = GNUTLS_E_INTERNAL_ERROR;
00379 }
00380 session_unresumable (session);
00381 session->internals.may_not_write = 1;
00382 MHD_gnutls_assert ();
00383 return ret;
00384 }
00385
00386 session->internals.record_send_buffer_user_size = 0;
00387
00388 MHD__gnutls_record_log ("REC[%x]: Sent Packet[%d] %s(%d) with length: %d\n",
00389 session,
00390 (int)
00391 MHD_gtls_uint64touint32
00392 (&session->connection_state.write_sequence_number),
00393 MHD__gnutls_packet2str (type), type, cipher_size);
00394
00395 return retval;
00396 }
00397
00398
00399
00400
00401 ssize_t
00402 MHD_gtls_send_change_cipher_spec (MHD_gtls_session_t session, int again)
00403 {
00404 static const opaque data[1] = {
00405 GNUTLS_TYPE_CHANGE_CIPHER_SPEC
00406 };
00407
00408 MHD__gnutls_handshake_log ("REC[%x]: Sent ChangeCipherSpec\n", session);
00409
00410 if (again == 0)
00411 return MHD_gtls_send_int (session, GNUTLS_CHANGE_CIPHER_SPEC, -1, data,
00412 1);
00413 else
00414 {
00415 return MHD_gtls_io_write_flush (session);
00416 }
00417 }
00418
00419 inline static int
00420 check_recv_type (content_type_t recv_type)
00421 {
00422 switch (recv_type)
00423 {
00424 case GNUTLS_CHANGE_CIPHER_SPEC:
00425 case GNUTLS_ALERT:
00426 case GNUTLS_HANDSHAKE:
00427 case GNUTLS_APPLICATION_DATA:
00428 case GNUTLS_INNER_APPLICATION:
00429 return 0;
00430 default:
00431 MHD_gnutls_assert ();
00432 return GNUTLS_A_UNEXPECTED_MESSAGE;
00433 }
00434
00435 }
00436
00437
00438
00439
00440 static int
00441 check_buffers (MHD_gtls_session_t session,
00442 content_type_t type, opaque * data, int sizeofdata)
00443 {
00444 if ((type == GNUTLS_APPLICATION_DATA || type == GNUTLS_HANDSHAKE || type
00445 == GNUTLS_INNER_APPLICATION)
00446 && MHD_gnutls_record_buffer_get_size (type, session) > 0)
00447 {
00448 int ret, ret2;
00449 ret = MHD_gtls_record_buffer_get (type, session, data, sizeofdata);
00450 if (ret < 0)
00451 {
00452 MHD_gnutls_assert ();
00453 return ret;
00454 }
00455
00456
00457 if (MHD_gnutls_record_buffer_get_size (type, session) == 0)
00458 {
00459 if ((ret2 = MHD_gtls_io_clear_peeked_data (session)) < 0)
00460 {
00461 MHD_gnutls_assert ();
00462 return ret2;
00463 }
00464 }
00465
00466 return ret;
00467 }
00468
00469 return 0;
00470 }
00471
00472
00473
00474
00475 static int
00476 record_check_headers (MHD_gtls_session_t session,
00477 uint8_t headers[RECORD_HEADER_SIZE],
00478 content_type_t type,
00479 MHD_gnutls_handshake_description_t htype,
00480 content_type_t * recv_type,
00481 opaque version[2],
00482 uint16_t * length, uint16_t * header_size)
00483 {
00484
00485
00486
00487
00488
00489 if (htype == GNUTLS_HANDSHAKE_CLIENT_HELLO && type == GNUTLS_HANDSHAKE
00490 && headers[0] > 127)
00491 {
00492
00493
00494
00495
00496 version[0] = 3;
00497 version[1] = 0;
00498
00499 *length = (((headers[0] & 0x7f) << 8)) | headers[1];
00500
00501
00502 *header_size = 2;
00503 *recv_type = GNUTLS_HANDSHAKE;
00504
00505
00506
00507
00508
00509 session->internals.v2_hello = *length;
00510
00511 MHD__gnutls_record_log ("REC[%x]: V2 packet received. Length: %d\n",
00512 session, *length);
00513
00514 }
00515 else
00516 {
00517
00518 *recv_type = headers[0];
00519 version[0] = headers[1];
00520 version[1] = headers[2];
00521
00522
00523
00524 *length = MHD_gtls_read_uint16 (&headers[3]);
00525 }
00526
00527 return 0;
00528 }
00529
00530
00531
00532
00533 inline static int
00534 record_check_version (MHD_gtls_session_t session,
00535 MHD_gnutls_handshake_description_t htype,
00536 opaque version[2])
00537 {
00538 if (htype == GNUTLS_HANDSHAKE_CLIENT_HELLO)
00539 {
00540
00541
00542 if (version[0] > 3)
00543 {
00544 MHD_gnutls_assert ();
00545 MHD__gnutls_record_log
00546 ("REC[%x]: INVALID VERSION PACKET: (%d) %d.%d\n", session,
00547 htype, version[0], version[1]);
00548 return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
00549 }
00550 }
00551 else if (htype != GNUTLS_HANDSHAKE_SERVER_HELLO
00552 && MHD__gnutls_protocol_get_version (session)
00553 != MHD_gtls_version_get (version[0], version[1]))
00554 {
00555
00556
00557
00558
00559 MHD_gnutls_assert ();
00560 MHD__gnutls_record_log ("REC[%x]: INVALID VERSION PACKET: (%d) %d.%d\n",
00561 session, htype, version[0], version[1]);
00562
00563 return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
00564 }
00565
00566 return 0;
00567 }
00568
00569
00570
00571
00572 static int
00573 record_check_type (MHD_gtls_session_t session,
00574 content_type_t recv_type,
00575 content_type_t type,
00576 MHD_gnutls_handshake_description_t htype,
00577 opaque * data, int data_size)
00578 {
00579
00580 int ret;
00581
00582 if ((recv_type == type) && (type == GNUTLS_APPLICATION_DATA || type
00583 == GNUTLS_HANDSHAKE
00584 || type == GNUTLS_INNER_APPLICATION))
00585 {
00586 MHD_gnutls_record_buffer_put (type, session, (void *) data, data_size);
00587 }
00588 else
00589 {
00590 switch (recv_type)
00591 {
00592 case GNUTLS_ALERT:
00593
00594 MHD__gnutls_record_log
00595 ("REC[%x]: Alert[%d|%d] - %s - was received\n", session,
00596 data[0], data[1], MHD__gnutls_alert_get_name ((int) data[1]));
00597
00598 session->internals.last_alert = data[1];
00599 session->internals.last_alert_level = data[0];
00600
00601
00602
00603
00604 if (data[1] == GNUTLS_A_CLOSE_NOTIFY && data[0] != GNUTLS_AL_FATAL)
00605 {
00606
00607
00608 session->internals.read_eof = 1;
00609 return GNUTLS_E_INT_RET_0;
00610 }
00611 else
00612 {
00613
00614
00615
00616
00617 MHD_gnutls_assert ();
00618 ret = GNUTLS_E_WARNING_ALERT_RECEIVED;
00619 if (data[0] == GNUTLS_AL_FATAL)
00620 {
00621 session_unresumable (session);
00622 session_invalidate (session);
00623 ret = GNUTLS_E_FATAL_ALERT_RECEIVED;
00624 }
00625
00626 return ret;
00627 }
00628 break;
00629
00630 case GNUTLS_CHANGE_CIPHER_SPEC:
00631
00632
00633
00634 MHD_gnutls_assert ();
00635
00636 return GNUTLS_E_UNEXPECTED_PACKET;
00637
00638 case GNUTLS_APPLICATION_DATA:
00639
00640 if ((ret =
00641 MHD_gnutls_record_buffer_put (recv_type, session,
00642 (void *) data, data_size)) < 0)
00643 {
00644 MHD_gnutls_assert ();
00645 return ret;
00646 }
00647
00648
00649
00650
00651
00652 if (type == GNUTLS_ALERT || (htype == GNUTLS_HANDSHAKE_CLIENT_HELLO
00653 && type == GNUTLS_HANDSHAKE))
00654 return GNUTLS_E_GOT_APPLICATION_DATA;
00655 else
00656 {
00657 MHD_gnutls_assert ();
00658 return GNUTLS_E_UNEXPECTED_PACKET;
00659 }
00660
00661 break;
00662 case GNUTLS_HANDSHAKE:
00663
00664
00665
00666 if (session->security_parameters.entity == GNUTLS_SERVER)
00667 {
00668 MHD_gnutls_assert ();
00669 return GNUTLS_E_REHANDSHAKE;
00670 }
00671
00672
00673
00674
00675
00676
00677
00678 return MHD_gtls_recv_hello_request (session, data, data_size);
00679
00680 break;
00681 case GNUTLS_INNER_APPLICATION:
00682
00683 if ((ret =
00684 MHD_gnutls_record_buffer_put (recv_type, session,
00685 (void *) data, data_size)) < 0)
00686 {
00687 MHD_gnutls_assert ();
00688 return ret;
00689 }
00690 MHD_gnutls_assert ();
00691 return GNUTLS_E_UNEXPECTED_PACKET;
00692 break;
00693 default:
00694
00695 MHD__gnutls_record_log
00696 ("REC[%x]: Received Unknown packet %d expecting %d\n",
00697 session, recv_type, type);
00698
00699 MHD_gnutls_assert ();
00700 return GNUTLS_E_INTERNAL_ERROR;
00701 }
00702 }
00703
00704 return 0;
00705
00706 }
00707
00708
00709
00710
00711
00712 inline static int
00713 get_temp_recv_buffer (MHD_gtls_session_t session, MHD_gnutls_datum_t * tmp)
00714 {
00715 size_t max_record_size;
00716
00717 max_record_size = MAX_RECORD_RECV_SIZE;
00718
00719
00720
00721
00722
00723
00724 if (max_record_size > session->internals.recv_buffer.size
00725 || session->internals.recv_buffer.data == NULL)
00726 {
00727
00728
00729
00730 session->internals.recv_buffer.data
00731 =
00732 MHD_gnutls_realloc (session->internals.recv_buffer.data,
00733 max_record_size);
00734
00735 if (session->internals.recv_buffer.data == NULL)
00736 {
00737 MHD_gnutls_assert ();
00738 return GNUTLS_E_MEMORY_ERROR;
00739 }
00740
00741 session->internals.recv_buffer.size = max_record_size;
00742 }
00743
00744 tmp->data = session->internals.recv_buffer.data;
00745 tmp->size = session->internals.recv_buffer.size;
00746
00747 return 0;
00748 }
00749
00750 #define MAX_EMPTY_PACKETS_SEQUENCE 4
00751
00752
00753
00754
00755
00756
00757
00758
00759 ssize_t
00760 MHD_gtls_recv_int (MHD_gtls_session_t session,
00761 content_type_t type,
00762 MHD_gnutls_handshake_description_t htype,
00763 opaque * data, size_t sizeofdata)
00764 {
00765 MHD_gnutls_datum_t tmp;
00766 int decrypted_length;
00767 opaque version[2];
00768 uint8_t *headers;
00769 content_type_t recv_type;
00770 uint16_t length;
00771 uint8_t *ciphertext;
00772 uint8_t *recv_data;
00773 int ret, ret2;
00774 uint16_t header_size;
00775 int empty_packet = 0;
00776
00777 if (type != GNUTLS_ALERT && (sizeofdata == 0 || data == NULL))
00778 {
00779 return GNUTLS_E_INVALID_REQUEST;
00780 }
00781
00782 begin:
00783
00784 if (empty_packet > MAX_EMPTY_PACKETS_SEQUENCE)
00785 {
00786 MHD_gnutls_assert ();
00787 return GNUTLS_E_TOO_MANY_EMPTY_PACKETS;
00788 }
00789
00790 if (session->internals.read_eof != 0)
00791 {
00792
00793
00794 return 0;
00795 }
00796 else if (session_is_valid (session) != 0 || session->internals.may_not_read
00797 != 0)
00798 {
00799 MHD_gnutls_assert ();
00800 return GNUTLS_E_INVALID_SESSION;
00801 }
00802
00803
00804
00805
00806 ret = check_buffers (session, type, data, sizeofdata);
00807 if (ret != 0)
00808 return ret;
00809
00810
00811
00812 header_size = RECORD_HEADER_SIZE;
00813
00814 if ((ret = MHD_gtls_io_read_buffered (session, &headers, header_size, -1))
00815 != header_size)
00816 {
00817 if (ret < 0 && MHD_gtls_error_is_fatal (ret) == 0)
00818 return ret;
00819
00820 session_invalidate (session);
00821 if (type == GNUTLS_ALERT)
00822 {
00823 MHD_gnutls_assert ();
00824 return 0;
00825 }
00826 session_unresumable (session);
00827 MHD_gnutls_assert ();
00828 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
00829 }
00830
00831 if ((ret = record_check_headers (session, headers, type, htype, &recv_type,
00832 version, &length, &header_size)) < 0)
00833 {
00834 MHD_gnutls_assert ();
00835 return ret;
00836 }
00837
00838
00839
00840
00841 if ((ret = check_recv_type (recv_type)) < 0)
00842 {
00843 MHD_gnutls_assert ();
00844 return ret;
00845 }
00846
00847
00848
00849
00850 if ((ret = record_check_version (session, htype, version)) < 0)
00851 {
00852 MHD_gnutls_assert ();
00853 session_invalidate (session);
00854 return ret;
00855 }
00856
00857 MHD__gnutls_record_log
00858 ("REC[%x]: Expected Packet[%d] %s(%d) with length: %d\n", session,
00859 (int) MHD_gtls_uint64touint32 (&session->connection_state.
00860 read_sequence_number),
00861 MHD__gnutls_packet2str (type), type, sizeofdata);
00862 MHD__gnutls_record_log
00863 ("REC[%x]: Received Packet[%d] %s(%d) with length: %d\n", session,
00864 (int) MHD_gtls_uint64touint32 (&session->connection_state.
00865 read_sequence_number),
00866 MHD__gnutls_packet2str (recv_type), recv_type, length);
00867
00868 if (length > MAX_RECV_SIZE)
00869 {
00870 MHD__gnutls_record_log
00871 ("REC[%x]: FATAL ERROR: Received packet with length: %d\n",
00872 session, length);
00873
00874 session_unresumable (session);
00875 session_invalidate (session);
00876 MHD_gnutls_assert ();
00877 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
00878 }
00879
00880
00881
00882 if ((ret = MHD_gtls_io_read_buffered (session, &recv_data,
00883 header_size + length, recv_type))
00884 != header_size + length)
00885 {
00886 if (ret < 0 && MHD_gtls_error_is_fatal (ret) == 0)
00887 return ret;
00888
00889 session_unresumable (session);
00890 session_invalidate (session);
00891 MHD_gnutls_assert ();
00892 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
00893 }
00894
00895
00896
00897
00898 MHD_gtls_io_clear_read_buffer (session);
00899 ciphertext = &recv_data[header_size];
00900
00901 ret = get_temp_recv_buffer (session, &tmp);
00902 if (ret < 0)
00903 {
00904 MHD_gnutls_assert ();
00905 return ret;
00906 }
00907
00908
00909 ret = MHD_gtls_decrypt (session, ciphertext, length, tmp.data, tmp.size,
00910 recv_type);
00911 if (ret < 0)
00912 {
00913 session_unresumable (session);
00914 session_invalidate (session);
00915 MHD_gnutls_assert ();
00916 return ret;
00917 }
00918 decrypted_length = ret;
00919
00920
00921
00922 if (type == GNUTLS_CHANGE_CIPHER_SPEC && recv_type
00923 == GNUTLS_CHANGE_CIPHER_SPEC)
00924 {
00925
00926 MHD__gnutls_record_log
00927 ("REC[%x]: ChangeCipherSpec Packet was received\n", session);
00928
00929 if ((size_t) ret != sizeofdata)
00930 {
00931 MHD_gnutls_assert ();
00932 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
00933 }
00934 memcpy (data, tmp.data, sizeofdata);
00935
00936 return ret;
00937 }
00938
00939 MHD__gnutls_record_log
00940 ("REC[%x]: Decrypted Packet[%d] %s(%d) with length: %d\n", session,
00941 (int) MHD_gtls_uint64touint32 (&session->connection_state.
00942 read_sequence_number),
00943 MHD__gnutls_packet2str (recv_type), recv_type, decrypted_length);
00944
00945
00946
00947 if (MHD_gtls_uint64pp (&session->connection_state.read_sequence_number) !=
00948 0)
00949 {
00950 session_invalidate (session);
00951 MHD_gnutls_assert ();
00952 return GNUTLS_E_RECORD_LIMIT_REACHED;
00953 }
00954
00955
00956 ret = record_check_type (session, recv_type, type, htype, tmp.data,
00957 decrypted_length);
00958 if (ret < 0)
00959 {
00960 if (ret == GNUTLS_E_INT_RET_0)
00961 return 0;
00962 MHD_gnutls_assert ();
00963 return ret;
00964 }
00965
00966
00967
00968 if ((recv_type == type) && (type == GNUTLS_APPLICATION_DATA || type
00969 == GNUTLS_HANDSHAKE
00970 || type == GNUTLS_INNER_APPLICATION))
00971 {
00972
00973 ret = MHD_gtls_record_buffer_get (type, session, data, sizeofdata);
00974 if (ret < 0)
00975 {
00976 MHD_gnutls_assert ();
00977 return ret;
00978 }
00979
00980
00981
00982 if (MHD_gnutls_record_buffer_get_size (type, session) == 0)
00983 {
00984 if ((ret2 = MHD_gtls_io_clear_peeked_data (session)) < 0)
00985 {
00986 MHD_gnutls_assert ();
00987 return ret2;
00988 }
00989 }
00990 }
00991 else
00992 {
00993 MHD_gnutls_assert ();
00994 return GNUTLS_E_UNEXPECTED_PACKET;
00995
00996
00997 }
00998
00999
01000
01001
01002
01003
01004
01005
01006 if (ret == 0)
01007 {
01008 empty_packet++;
01009 goto begin;
01010 }
01011
01012 return ret;
01013 }
01014
01043 ssize_t
01044 MHD__gnutls_record_send (MHD_gtls_session_t session,
01045 const void *data, size_t sizeofdata)
01046 {
01047 return MHD_gtls_send_int (session, GNUTLS_APPLICATION_DATA, -1, data,
01048 sizeofdata);
01049 }
01050
01081 ssize_t
01082 MHD__gnutls_record_recv (MHD_gtls_session_t session, void *data,
01083 size_t sizeofdata)
01084 {
01085 return MHD_gtls_recv_int (session, GNUTLS_APPLICATION_DATA, -1, data,
01086 sizeofdata);
01087 }