*** empty log message ***
[gnutls.git] / lib / gnutls_record.c
blob7ef793f27c06066b62e3c5a5862b2e543555d23d
1 /*
2 * Copyright (C) 2000,2001,2002 Nikos Mavroyanopoulos
4 * This file is part of GNUTLS.
6 * The GNUTLS library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "gnutls_int.h"
23 #include "gnutls_errors.h"
24 #include "debug.h"
25 #include "gnutls_compress.h"
26 #include "gnutls_cipher.h"
27 #include "gnutls_buffers.h"
28 #include "gnutls_handshake.h"
29 #include "gnutls_hash_int.h"
30 #include "gnutls_cipher_int.h"
31 #include "gnutls_priority.h"
32 #include "gnutls_algorithms.h"
33 #include "gnutls_db.h"
34 #include "gnutls_auth_int.h"
35 #include "gnutls_num.h"
36 #include "gnutls_record.h"
37 #include "gnutls_datum.h"
38 #include "ext_max_record.h"
39 #include <gnutls_state.h>
40 #include <gnutls_alert.h>
41 #include <gnutls_dh.h>
43 /**
44 * gnutls_protocol_get_version - Returns the version of the currently used protocol
45 * @state: is a &GNUTLS_STATE structure.
47 * Returns the version of the currently used protocol.
49 **/
50 GNUTLS_Version gnutls_protocol_get_version(GNUTLS_STATE state) {
51 return state->security_parameters.version;
54 void _gnutls_set_current_version(GNUTLS_STATE state, GNUTLS_Version version) {
55 state->security_parameters.version = version;
58 /**
59 * gnutls_transport_set_lowat - Used to set the lowat value in order for select to check for pending data.
60 * @state: is a &GNUTLS_STATE structure.
61 * @num: is the low water value.
63 * Used to set the lowat value in order for select to check
64 * if there are pending data to socket buffer. Used only
65 * if you have changed the default low water value (default is 1).
66 * Normally you will not need that function.
67 * This function is only usefull if using berkeley style sockets.
68 * Otherwise it must be called and set lowat to zero.
70 **/
71 void gnutls_transport_set_lowat(GNUTLS_STATE state, int num) {
72 state->gnutls_internals.lowat = num;
75 /**
76 * gnutls_transport_set_ptr - Used to set first argument of the transport functions
77 * @state: is a &GNUTLS_STATE structure.
78 * @ptr: is the value.
80 * Used to set the first argument of the transport function (like PUSH and
81 * PULL). In berkeley style sockets this function will set the connection
82 * handle.
84 **/
85 void gnutls_transport_set_ptr(GNUTLS_STATE state, GNUTLS_TRANSPORT_PTR ptr) {
86 state->gnutls_internals.transport_ptr = ptr;
89 /**
90 * gnutls_transport_get_ptr - Used to return the first argument of the transport functions
91 * @state: is a &GNUTLS_STATE structure.
93 * Used to get the first argument of the transport function (like PUSH and
94 * PULL). This must have been set using gnutls_transport_set_ptr().
96 **/
97 GNUTLS_TRANSPORT_PTR gnutls_transport_get_ptr(GNUTLS_STATE state) {
98 return state->gnutls_internals.transport_ptr;
102 * gnutls_bye - This function terminates the current TLS/SSL connection.
103 * @state: is a &GNUTLS_STATE structure.
104 * @how: is an integer
106 * Terminates the current TLS/SSL connection. The connection should
107 * have been initiated using gnutls_handshake().
108 * 'how' should be one of GNUTLS_SHUT_RDWR, GNUTLS_SHUT_WR.
110 * In case of GNUTLS_SHUT_RDWR then the TLS connection gets terminated and
111 * further receives and sends will be disallowed. If the return
112 * value is zero you may continue using the connection.
113 * GNUTLS_SHUT_RDWR actually sends an alert containing a close request
114 * and waits for the peer to reply with the same message.
116 * In case of GNUTLS_SHUT_WR then the TLS connection gets terminated and
117 * further sends will be disallowed. In order to reuse the connection
118 * you should wait for an EOF from the peer.
119 * GNUTLS_SHUT_WR sends an alert containing a close request.
121 * This function may also return GNUTLS_E_AGAIN, or GNUTLS_E_INTERRUPTED.
124 int gnutls_bye( GNUTLS_STATE state, GNUTLS_CloseRequest how)
126 int ret = 0, ret2 = 0;
128 switch (STATE) {
129 case STATE0:
130 case STATE60:
131 if (STATE==STATE60) {
132 ret = _gnutls_io_write_flush( state);
133 } else {
134 ret = gnutls_alert_send( state, GNUTLS_AL_WARNING, GNUTLS_A_CLOSE_NOTIFY);
135 STATE = STATE60;
138 if (ret < 0)
139 return ret;
140 case STATE61:
141 if ( how == GNUTLS_SHUT_RDWR && ret >= 0) {
142 ret2 = gnutls_recv_int( state, GNUTLS_ALERT, -1, NULL, 0);
143 if (ret2 >= 0) state->gnutls_internals.may_read = 1;
145 STATE = STATE61;
147 if (ret2 < 0)
148 return ret2;
152 STATE = STATE0;
154 state->gnutls_internals.may_write = 1;
155 return 0;
158 inline
159 static void _gnutls_session_invalidate( GNUTLS_STATE state) {
160 state->gnutls_internals.valid_connection = VALID_FALSE;
164 inline
165 static void _gnutls_session_unresumable( GNUTLS_STATE state) {
166 state->gnutls_internals.resumable = RESUME_FALSE;
169 /* returns 0 if session is valid
171 inline
172 static int _gnutls_session_is_valid( GNUTLS_STATE state) {
173 if (state->gnutls_internals.valid_connection==VALID_FALSE)
174 return GNUTLS_E_INVALID_SESSION;
176 return 0;
179 static
180 ssize_t _gnutls_create_empty_record( GNUTLS_STATE state, ContentType type,
181 opaque* erecord, int erecord_size)
183 int cipher_size;
184 int retval;
185 int data2send;
186 uint8 headers[5];
187 GNUTLS_Version lver;
189 if (type!=GNUTLS_APPLICATION_DATA ||
190 _gnutls_cipher_is_block( gnutls_cipher_get(state))!=CIPHER_BLOCK)
191 /* alert messages and stream ciphers
192 * do not need this protection
194 return 0;
196 headers[0]=type;
198 lver = gnutls_protocol_get_version(state);
199 if (lver==GNUTLS_VERSION_UNKNOWN) {
200 gnutls_assert();
201 return GNUTLS_E_INTERNAL_ERROR;
204 headers[1]=_gnutls_version_get_major( lver);
205 headers[2]=_gnutls_version_get_minor( lver);
207 data2send = 0;
209 cipher_size = _gnutls_encrypt( state, headers, RECORD_HEADER_SIZE, NULL, 0, erecord, erecord_size, type, 0);
210 if (cipher_size <= 0) {
211 gnutls_assert();
212 if (cipher_size==0) cipher_size = GNUTLS_E_ENCRYPTION_FAILED;
213 return cipher_size; /* error */
216 retval = cipher_size;
218 /* increase sequence number
220 if (_gnutls_uint64pp( &state->connection_state.write_sequence_number) != 0) {
221 _gnutls_session_invalidate( state);
222 gnutls_assert();
223 return GNUTLS_E_RECORD_LIMIT_REACHED;
226 return retval;
229 /* This function behave exactly like write(). The only difference is
230 * that it accepts, the gnutls_state and the ContentType of data to
231 * send (if called by the user the Content is specific)
232 * It is intended to transfer data, under the current state.
234 * Oct 30 2001: Removed capability to send data more than MAX_RECORD_SIZE.
235 * This makes the function much easier to read, and more error resistant
236 * (there were cases were the old function could mess everything up).
237 * --nmav
240 ssize_t gnutls_send_int( GNUTLS_STATE state, ContentType type, HandshakeType htype, const void *_data, size_t sizeofdata)
242 uint8 *cipher;
243 int cipher_size;
244 int retval, ret;
245 int data2send_size;
246 uint8 headers[5];
247 const uint8 *data=_data;
248 GNUTLS_Version lver;
249 int erecord_size = 0;
250 opaque* erecord = NULL;
252 if (sizeofdata == 0 || _data==NULL) {
253 gnutls_assert();
254 return GNUTLS_E_INVALID_PARAMETERS;
257 if (type!=GNUTLS_ALERT) /* alert messages are sent anyway */
258 if ( _gnutls_session_is_valid( state) || state->gnutls_internals.may_write != 0) {
259 return GNUTLS_E_INVALID_SESSION;
264 headers[0]=type;
266 lver = gnutls_protocol_get_version(state);
267 if (lver==GNUTLS_VERSION_UNKNOWN) {
268 gnutls_assert();
269 return GNUTLS_E_INTERNAL_ERROR;
272 headers[1]=_gnutls_version_get_major( lver);
273 headers[2]=_gnutls_version_get_minor( lver);
275 _gnutls_record_log( "REC: Sending Packet[%d] %s(%d) with length: %d\n",
276 (int) _gnutls_uint64touint32(&state->connection_state.write_sequence_number), _gnutls_packet2str(type), type, sizeofdata);
278 if ( sizeofdata > MAX_RECORD_SIZE)
279 data2send_size = MAX_RECORD_SIZE;
280 else
281 data2send_size = sizeofdata;
283 /* Only encrypt if we don't have data to send
284 * from the previous run. - probably interrupted.
286 if (state->gnutls_internals.record_send_buffer.size > 0) {
287 ret = _gnutls_io_write_flush( state);
288 if (ret > 0) cipher_size = ret;
289 else cipher_size = 0;
291 cipher = NULL;
293 retval = state->gnutls_internals.record_send_buffer_user_size;
294 } else {
296 /* Prepend our packet with an empty record. This is to
297 * avoid the recent CBC attacks.
299 /* if this protection has been disabled
301 if (state->gnutls_internals.cbc_protection_hack!=0) {
302 erecord_size = MAX_RECORD_OVERHEAD;
303 erecord = gnutls_alloca( erecord_size);
304 if (erecord==NULL) {
305 gnutls_assert();
306 return GNUTLS_E_MEMORY_ERROR;
309 erecord_size =
310 _gnutls_create_empty_record( state, type, erecord, erecord_size);
311 if (erecord_size < 0) {
312 gnutls_assert();
313 return erecord_size;
317 /* now proceed to packet encryption
319 cipher_size = data2send_size + MAX_RECORD_OVERHEAD;
320 cipher = gnutls_alloca( cipher_size);
321 if (cipher==NULL) {
322 gnutls_assert();
323 return GNUTLS_E_MEMORY_ERROR;
326 cipher_size = _gnutls_encrypt( state, headers, RECORD_HEADER_SIZE, data, data2send_size, cipher,
327 cipher_size, type, 1);
328 if (cipher_size <= 0) {
329 gnutls_assert();
330 if (cipher_size==0) cipher_size = GNUTLS_E_ENCRYPTION_FAILED;
331 gnutls_afree( erecord);
332 gnutls_afree( cipher);
333 return cipher_size; /* error */
336 retval = data2send_size;
337 state->gnutls_internals.record_send_buffer_user_size = data2send_size;
339 /* increase sequence number
341 if (_gnutls_uint64pp( &state->connection_state.write_sequence_number) != 0) {
342 _gnutls_session_invalidate( state);
343 gnutls_assert();
344 gnutls_afree( erecord);
345 gnutls_afree( cipher);
346 return GNUTLS_E_RECORD_LIMIT_REACHED;
349 ret = _gnutls_io_write_buffered2( state, erecord, erecord_size, cipher, cipher_size);
350 gnutls_afree( erecord);
351 gnutls_afree( cipher);
354 if ( ret != cipher_size + erecord_size) {
355 if ( ret < 0 && gnutls_error_is_fatal(ret)==0) {
356 /* If we have sent any data then return
357 * that value.
359 gnutls_assert();
360 return ret;
363 if (ret > 0) {
364 gnutls_assert();
365 ret = GNUTLS_E_UNKNOWN_ERROR;
368 _gnutls_session_unresumable( state);
369 _gnutls_session_invalidate( state);
370 gnutls_assert();
371 return ret;
374 state->gnutls_internals.record_send_buffer_user_size = 0;
376 _gnutls_record_log( "REC: Sent Packet[%d] %s(%d) with length: %d\n",
377 (int) _gnutls_uint64touint32(&state->connection_state.write_sequence_number), _gnutls_packet2str(type), type, cipher_size);
379 return retval;
382 /* This function is to be called if the handshake was successfully
383 * completed. This sends a Change Cipher Spec packet to the peer.
385 ssize_t _gnutls_send_change_cipher_spec( GNUTLS_STATE state, int again)
387 opaque data[1] = { GNUTLS_TYPE_CHANGE_CIPHER_SPEC };
389 _gnutls_handshake_log( "REC: Sent ChangeCipherSpec\n");
391 if (again==0)
392 return gnutls_send_int( state, GNUTLS_CHANGE_CIPHER_SPEC, -1, data, 1);
393 else {
394 return _gnutls_io_write_flush( state);
398 static int _gnutls_check_recv_type( ContentType recv_type) {
399 switch( recv_type) {
400 case GNUTLS_CHANGE_CIPHER_SPEC:
401 case GNUTLS_ALERT:
402 case GNUTLS_HANDSHAKE:
403 case GNUTLS_APPLICATION_DATA:
404 return 0;
405 default:
406 gnutls_assert();
407 return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
413 /* Checks if there are pending data into the record buffers. If there are
414 * then it copies the data.
416 static int _gnutls_check_buffers( GNUTLS_STATE state, ContentType type, opaque* data, int sizeofdata) {
417 int ret = 0, ret2=0;
418 if ( (type == GNUTLS_APPLICATION_DATA || type == GNUTLS_HANDSHAKE) && _gnutls_record_buffer_get_size(type, state) > 0) {
419 ret = _gnutls_record_buffer_get(type, state, data, sizeofdata);
420 if (ret < 0) {
421 gnutls_assert();
422 return ret;
425 /* if the buffer just got empty */
426 if (_gnutls_record_buffer_get_size(type, state)==0) {
427 if ( (ret2=_gnutls_io_clear_peeked_data( state)) < 0) {
428 gnutls_assert();
429 return ret2;
433 return ret;
436 return 0;
440 #define CHECK_RECORD_VERSION
442 /* Checks the record headers and returns the length, version and
443 * content type.
445 static int _gnutls_check_record_headers( GNUTLS_STATE state, uint8 headers[RECORD_HEADER_SIZE], ContentType type,
446 HandshakeType htype, /*output*/ ContentType *recv_type, GNUTLS_Version *version, uint16 *length, uint16* header_size) {
448 /* Read the first two bytes to determine if this is a
449 * version 2 message
452 if ( htype == GNUTLS_CLIENT_HELLO && type==GNUTLS_HANDSHAKE && headers[0] > 127) {
454 /* if msb set and expecting handshake message
455 * it should be SSL 2 hello
457 *version = GNUTLS_VERSION_UNKNOWN; /* assume unknown version */
458 *length = (((headers[0] & 0x7f) << 8)) | headers[1];
460 /* SSL 2.0 headers */
461 *header_size = 2;
462 *recv_type = GNUTLS_HANDSHAKE; /* we accept only v2 client hello
465 /* in order to assist the handshake protocol.
466 * V2 compatibility is a mess.
468 state->gnutls_internals.v2_hello = *length;
470 _gnutls_record_log( "REC: V2 packet received. Length: %d\n", *length);
472 } else {
473 /* version 3.x
475 *recv_type = headers[0];
476 #ifdef CHECK_RECORD_VERSION
477 *version = _gnutls_version_get( headers[1], headers[2]);
478 #endif
480 /* No DECR_LEN, since headers has enough size.
482 *length = _gnutls_read_uint16( &headers[3]);
485 return 0;
488 /* Here we check if the advertized version is the one we
489 * negotiated in the handshake.
491 inline
492 static int _gnutls_check_record_version( GNUTLS_STATE state, HandshakeType htype, GNUTLS_Version version)
494 #ifdef CHECK_RECORD_VERSION
495 if ( (htype!=GNUTLS_CLIENT_HELLO && htype!=GNUTLS_SERVER_HELLO) && gnutls_protocol_get_version(state) != version) {
496 gnutls_assert();
498 _gnutls_record_log( "REC: INVALID VERSION PACKET: (%d) %d.%d\n", htype, _gnutls_version_get_major(version), _gnutls_version_get_minor(version));
500 return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
502 #endif
504 return 0;
507 /* This function will check if the received record type is
508 * the one we actually expecting for.
510 static int _gnutls_record_check_type( GNUTLS_STATE state, ContentType recv_type,
511 ContentType type, HandshakeType htype, opaque* data, int data_size) {
513 int ret;
515 if ( (recv_type == type) && (type == GNUTLS_APPLICATION_DATA || type == GNUTLS_HANDSHAKE)) {
516 _gnutls_record_buffer_put(type, state, (void *) data, data_size);
517 } else {
518 switch (recv_type) {
519 case GNUTLS_ALERT:
521 _gnutls_record_log( "REC: Alert[%d|%d] - %s - was received\n", data[0], data[1], gnutls_alert_get_name((int)data[1]));
523 state->gnutls_internals.last_alert = data[1];
525 /* if close notify is received and
526 * the alert is not fatal
528 if (data[1] == GNUTLS_A_CLOSE_NOTIFY && data[0] != GNUTLS_AL_FATAL) {
529 /* If we have been expecting for an alert do
532 return GNUTLS_E_INT_RET_0; /* EOF */
533 } else {
535 /* if the alert is FATAL or WARNING
536 * return the apropriate message
539 gnutls_assert();
540 ret = GNUTLS_E_WARNING_ALERT_RECEIVED;
541 if (data[0] == GNUTLS_AL_FATAL) {
542 _gnutls_session_unresumable( state);
543 _gnutls_session_invalidate( state);
545 ret = GNUTLS_E_FATAL_ALERT_RECEIVED;
548 return ret;
550 break;
552 case GNUTLS_CHANGE_CIPHER_SPEC:
553 /* this packet is now handled above */
554 gnutls_assert();
556 return GNUTLS_E_UNEXPECTED_PACKET;
558 case GNUTLS_APPLICATION_DATA:
559 /* even if data is unexpected put it into the buffer */
560 if ( (ret=_gnutls_record_buffer_put(recv_type, state, (void *) data, data_size)) < 0) {
561 gnutls_assert();
562 return ret;
565 gnutls_assert();
567 /* the got_application data is only returned
568 * if expecting client hello (for rehandshake
569 * reasons). Otherwise it is an unexpected packet
571 if (htype == GNUTLS_CLIENT_HELLO && type==GNUTLS_HANDSHAKE)
572 return GNUTLS_E_GOT_APPLICATION_DATA;
573 else return GNUTLS_E_UNEXPECTED_PACKET;
575 break;
576 case GNUTLS_HANDSHAKE:
577 /* This is only legal if HELLO_REQUEST is received - and we are a client
579 if ( state->security_parameters.entity==GNUTLS_SERVER) {
580 gnutls_assert();
581 return GNUTLS_E_UNEXPECTED_PACKET;
583 gnutls_assert();
585 return _gnutls_recv_hello_request( state, data, data_size);
587 break;
588 default:
590 _gnutls_record_log( "REC: Received Unknown packet %d expecting %d\n", recv_type, type);
592 gnutls_assert();
593 return GNUTLS_E_UNKNOWN_ERROR;
597 return 0;
601 #define MAX_EMPTY_PACKETS_SEQUENCE 4
603 /* This function behave exactly like read(). The only difference is
604 * that it accepts, the gnutls_state and the ContentType of data to
605 * send (if called by the user the Content is Userdata only)
606 * It is intended to receive data, under the current state.
608 ssize_t gnutls_recv_int( GNUTLS_STATE state, ContentType type, HandshakeType htype, char *data, size_t sizeofdata)
610 uint8 *tmpdata;
611 int tmplen;
612 GNUTLS_Version version;
613 uint8 *headers;
614 ContentType recv_type;
615 uint16 length;
616 uint8 *ciphertext;
617 uint8 *recv_data;
618 int ret, ret2;
619 uint16 header_size;
620 int empty_packet = 0;
622 begin:
624 if (empty_packet > MAX_EMPTY_PACKETS_SEQUENCE) {
625 gnutls_assert();
626 return GNUTLS_E_TOO_MANY_EMPTY_PACKETS;
629 /* default headers for TLS 1.0
631 header_size = RECORD_HEADER_SIZE;
632 ret = 0;
634 if (sizeofdata == 0 || data == NULL) {
635 return GNUTLS_E_INVALID_PARAMETERS;
638 if ( _gnutls_session_is_valid(state)!=0 || state->gnutls_internals.may_read!=0) {
639 gnutls_assert();
640 return GNUTLS_E_INVALID_SESSION;
643 /* If we have enough data in the cache do not bother receiving
644 * a new packet. (in order to flush the cache)
646 ret = _gnutls_check_buffers( state, type, data, sizeofdata);
647 if (ret != 0)
648 return ret;
651 if ( (ret = _gnutls_io_read_buffered( state, &headers, header_size, -1)) != header_size) {
652 if (ret < 0 && gnutls_error_is_fatal(ret)==0) return ret;
654 _gnutls_session_invalidate( state);
655 if (type==GNUTLS_ALERT) {
656 gnutls_assert();
657 return 0; /* we were expecting close notify */
659 _gnutls_session_unresumable( state);
660 gnutls_assert();
661 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
664 if ( (ret=_gnutls_check_record_headers( state, headers, type, htype, &recv_type, &version, &length, &header_size)) < 0) {
665 gnutls_assert();
666 return ret;
669 /* Here we check if the Type of the received packet is
670 * ok.
672 if ( (ret = _gnutls_check_recv_type( recv_type)) < 0) {
674 gnutls_assert();
675 return ret;
678 /* Here we check if the advertized version is the one we
679 * negotiated in the handshake.
681 if ( (ret=_gnutls_check_record_version( state, htype, version)) < 0) {
682 gnutls_assert();
683 _gnutls_session_invalidate( state);
684 return ret;
687 _gnutls_record_log( "REC: Expected Packet[%d] %s(%d) with length: %d\n",
688 (int) _gnutls_uint64touint32(&state->connection_state.read_sequence_number), _gnutls_packet2str(type), type, sizeofdata);
689 _gnutls_record_log( "REC: Received Packet[%d] %s(%d) with length: %d\n",
690 (int) _gnutls_uint64touint32(&state->connection_state.read_sequence_number), _gnutls_packet2str(recv_type), recv_type, length);
692 if (length > MAX_RECV_SIZE) {
694 _gnutls_record_log( "REC: FATAL ERROR: Received packet with length: %d\n", length);
696 _gnutls_session_unresumable( state);
697 _gnutls_session_invalidate( state);
698 gnutls_assert();
699 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
702 /* check if we have that data into buffer.
704 if ( (ret = _gnutls_io_read_buffered( state, &recv_data, header_size+length, recv_type)) != length+header_size) {
705 if (ret<0 && gnutls_error_is_fatal(ret)==0) return ret;
707 _gnutls_session_unresumable( state);
708 _gnutls_session_invalidate( state);
709 gnutls_assert();
710 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
713 /* ok now we are sure that we can read all the data - so
714 * move on !
716 _gnutls_io_clear_read_buffer( state);
717 ciphertext = &recv_data[header_size];
719 /* decrypt the data we got
721 tmplen = length + MAX_RECORD_OVERHEAD;
722 tmpdata = gnutls_alloca( tmplen);
723 if (tmpdata==NULL) {
724 gnutls_assert();
725 return GNUTLS_E_MEMORY_ERROR;
728 tmplen = _gnutls_decrypt( state, ciphertext, length, tmpdata, tmplen, recv_type);
729 if (tmplen < 0) {
730 _gnutls_session_unresumable( state);
731 _gnutls_session_invalidate( state);
732 gnutls_afree(tmpdata);
733 gnutls_assert();
734 return tmplen;
737 /* Check if this is a CHANGE_CIPHER_SPEC
739 if (type == GNUTLS_CHANGE_CIPHER_SPEC && recv_type == GNUTLS_CHANGE_CIPHER_SPEC) {
741 _gnutls_record_log( "REC: ChangeCipherSpec Packet was received\n");
743 if (tmplen!=sizeofdata) { /* sizeofdata should be 1 */
744 gnutls_assert();
745 gnutls_afree(tmpdata);
746 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
748 memcpy( data, tmpdata, sizeofdata);
749 gnutls_afree(tmpdata);
751 return tmplen;
754 _gnutls_record_log( "REC: Decrypted Packet[%d] %s(%d) with length: %d\n",
755 (int) _gnutls_uint64touint32(&state->connection_state.read_sequence_number), _gnutls_packet2str(recv_type), recv_type, tmplen);
757 /* increase sequence number */
758 if (_gnutls_uint64pp( &state->connection_state.read_sequence_number)!=0) {
759 _gnutls_session_invalidate( state);
760 gnutls_afree(tmpdata);
761 gnutls_assert();
762 return GNUTLS_E_RECORD_LIMIT_REACHED;
765 if ( (ret=_gnutls_record_check_type( state, recv_type, type, htype, tmpdata, tmplen)) < 0) {
766 gnutls_afree(tmpdata);
768 if (ret==GNUTLS_E_INT_RET_0) return 0;
770 gnutls_assert();
771 return ret;
773 gnutls_afree(tmpdata);
775 /* Get Application data from buffer */
776 if ((type == GNUTLS_APPLICATION_DATA || type == GNUTLS_HANDSHAKE) && (recv_type == type)) {
778 ret = _gnutls_record_buffer_get(type, state, data, sizeofdata);
779 if (ret < 0) {
780 gnutls_assert();
781 return ret;
784 /* if the buffer just got empty */
785 if (_gnutls_record_buffer_get_size(type, state)==0) {
786 if ( (ret2 = _gnutls_io_clear_peeked_data( state)) < 0) {
787 gnutls_assert();
788 return ret2;
792 } else {
793 gnutls_assert();
794 ret = GNUTLS_E_UNEXPECTED_PACKET;
795 /* we didn't get what we wanted to
799 /* TLS 1.0 CBC protection. Read the next fragment.
801 if (ret==0) {
802 empty_packet++;
803 goto begin;
806 return ret;
810 /* Taken from libgcrypt */
812 static const char*
813 parse_version_number( const char *s, int *number )
815 int val = 0;
817 if( *s == '0' && isdigit(s[1]) )
818 return NULL; /* leading zeros are not allowed */
819 for ( ; isdigit(*s); s++ ) {
820 val *= 10;
821 val += *s - '0';
823 *number = val;
824 return val < 0? NULL : s;
828 static const char *
829 parse_version_string( const char *s, int *major, int *minor, int *micro )
831 s = parse_version_number( s, major );
832 if( !s || *s != '.' )
833 return NULL;
834 s++;
835 s = parse_version_number( s, minor );
836 if( !s || *s != '.' )
837 return NULL;
838 s++;
839 s = parse_version_number( s, micro );
840 if( !s )
841 return NULL;
842 return s; /* patchlevel */
845 /****************
846 * Check that the the version of the library is at minimum the requested one
847 * and return the version string; return NULL if the condition is not
848 * satisfied. If a NULL is passed to this function, no check is done,
849 * but the version string is simply returned.
851 const char *
852 gnutls_check_version( const char *req_version )
854 const char *ver = GNUTLS_VERSION;
855 int my_major, my_minor, my_micro;
856 int rq_major, rq_minor, rq_micro;
857 const char *my_plvl, *rq_plvl;
859 if ( !req_version )
860 return ver;
862 my_plvl = parse_version_string( ver, &my_major, &my_minor, &my_micro );
863 if ( !my_plvl )
864 return NULL; /* very strange our own version is bogus */
865 rq_plvl = parse_version_string( req_version, &rq_major, &rq_minor,
866 &rq_micro );
867 if ( !rq_plvl )
868 return NULL; /* req version string is invalid */
870 if ( my_major > rq_major
871 || (my_major == rq_major && my_minor > rq_minor)
872 || (my_major == rq_major && my_minor == rq_minor
873 && my_micro > rq_micro)
874 || (my_major == rq_major && my_minor == rq_minor
875 && my_micro == rq_micro
876 && strcmp( my_plvl, rq_plvl ) >= 0) ) {
877 return ver;
879 return NULL;
884 * gnutls_record_send - sends to the peer the specified data
885 * @state: is a &GNUTLS_STATE structure.
886 * @data: contains the data to send
887 * @sizeofdata: is the length of the data
889 * This function has the similar semantics to write(). The only
890 * difference is that is accepts a GNUTLS state, and uses different
891 * error codes.
893 * If the EINTR is returned by the internal push function (write())
894 * then GNUTLS_E_INTERRUPTED, will be returned. If GNUTLS_E_INTERRUPTED or
895 * GNUTLS_E_AGAIN is returned you must call this function again, with the
896 * same parameters. Otherwise the write operation will be
897 * corrupted and the connection will be terminated.
899 * Returns the number of bytes sent, or a negative error code.
902 ssize_t gnutls_record_send( GNUTLS_STATE state, const void *data, size_t sizeofdata) {
903 return gnutls_send_int( state, GNUTLS_APPLICATION_DATA, -1, data, sizeofdata);
907 * gnutls_record_recv - reads data from the TLS record protocol
908 * @state: is a &GNUTLS_STATE structure.
909 * @data: contains the data to send
910 * @sizeofdata: is the length of the data
912 * This function has the similar semantics to read(). The only
913 * difference is that is accepts a GNUTLS state.
914 * Also returns the number of bytes received, zero on EOF, but
915 * a negative error code in case of an error.
917 * If this function returns GNUTLS_E_REHANDSHAKE, then you may
918 * ignore this message, send an alert containing NO_RENEGOTIATION,
919 * or perform a handshake again. (only a client may receive this message)
922 ssize_t gnutls_record_recv( GNUTLS_STATE state, void *data, size_t sizeofdata) {
923 return gnutls_recv_int( state, GNUTLS_APPLICATION_DATA, -1, data, sizeofdata);
927 * gnutls_record_get_max_size - returns the maximum record size
928 * @state: is a &GNUTLS_STATE structure.
930 * This function returns the maximum record size in this connection.
931 * The maximum record size is negotiated by the client after the
932 * first handshake message.
935 size_t gnutls_record_get_max_size( GNUTLS_STATE state) {
936 return state->security_parameters.max_record_size;
941 * gnutls_record_set_max_size - sets the maximum record size
942 * @state: is a &GNUTLS_STATE structure.
943 * @size: is the new size
945 * This function sets the maximum record size in this connection.
946 * This property can only be set to clients. The server may
947 * choose not to accept the requested size.
949 * Acceptable values are 2^9, 2^10, 2^11 and 2^12.
950 * Returns 0 on success. The requested record size does not
951 * get in effect immediately. It will be used after a successful
952 * handshake.
954 * This function uses a TLS extension called 'max record size'.
955 * Not all TLS implementations use or even understand this extension.
958 ssize_t gnutls_record_set_max_size( GNUTLS_STATE state, size_t size) {
959 ssize_t new_size;
961 if (state->security_parameters.entity==GNUTLS_SERVER)
962 return GNUTLS_E_INVALID_REQUEST;
964 new_size = _gnutls_mre_record2num( size);
966 if (new_size < 0) {
967 gnutls_assert();
968 return new_size;
971 state->gnutls_internals.proposed_record_size = size;
973 return 0;