2 * Copyright (C) 2000,2001,2002 Nikos Mavroyanopoulos
4 * This file is part of GNUTLS.
6 * GNUTLS is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * GNUTLS 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
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
21 #include "gnutls_int.h"
22 #include "gnutls_errors.h"
24 #include "gnutls_compress.h"
25 #include "gnutls_cipher.h"
26 #include "gnutls_buffers.h"
27 #include "gnutls_handshake.h"
28 #include "gnutls_hash_int.h"
29 #include "gnutls_cipher_int.h"
30 #include "gnutls_priority.h"
31 #include "gnutls_algorithms.h"
32 #include "gnutls_db.h"
33 #include "gnutls_auth_int.h"
34 #include "gnutls_num.h"
35 #include "gnutls_record.h"
36 #include "gnutls_datum.h"
37 #include "ext_max_record.h"
38 #include <gnutls_state.h>
39 #include <gnutls_alert.h>
40 #include <gnutls_dh.h>
43 * gnutls_protocol_get_version - Returns the version of the currently used protocol
44 * @state: is a &GNUTLS_STATE structure.
46 * Returns the version of the currently used protocol.
49 GNUTLS_Version
gnutls_protocol_get_version(GNUTLS_STATE state
) {
50 return state
->security_parameters
.version
;
53 void _gnutls_set_current_version(GNUTLS_STATE state
, GNUTLS_Version version
) {
54 state
->security_parameters
.version
= version
;
58 * gnutls_transport_set_lowat - Used to set the lowat value in order for select to check for pending data.
59 * @state: is a &GNUTLS_STATE structure.
60 * @num: is the low water value.
62 * Used to set the lowat value in order for select to check
63 * if there are pending data to socket buffer. Used only
64 * if you have changed the default low water value (default is 1).
65 * Normally you will not need that function.
66 * This function is only usefull if using berkeley style sockets.
67 * Otherwise it must be called and set lowat to zero.
70 void gnutls_transport_set_lowat(GNUTLS_STATE state
, int num
) {
71 state
->gnutls_internals
.lowat
= num
;
75 * gnutls_transport_set_ptr - Used to set first argument of the transport functions
76 * @state: is a &GNUTLS_STATE structure.
79 * Used to set the first argument of the transport function (like PUSH and
80 * PULL). In berkeley style sockets this function will set the connection
84 void gnutls_transport_set_ptr(GNUTLS_STATE state
, GNUTLS_TRANSPORT_PTR ptr
) {
85 state
->gnutls_internals
.transport_ptr
= ptr
;
89 * gnutls_transport_get_ptr - Used to return the first argument of the transport functions
90 * @state: is a &GNUTLS_STATE structure.
92 * Used to get the first argument of the transport function (like PUSH and
93 * PULL). This must have been set using gnutls_transport_set_ptr().
96 GNUTLS_TRANSPORT_PTR
gnutls_transport_get_ptr(GNUTLS_STATE state
) {
97 return state
->gnutls_internals
.transport_ptr
;
101 * gnutls_bye - This function terminates the current TLS/SSL connection.
102 * @state: is a &GNUTLS_STATE structure.
103 * @how: is an integer
105 * Terminates the current TLS/SSL connection. The connection should
106 * have been initiated using gnutls_handshake().
107 * 'how' should be one of GNUTLS_SHUT_RDWR, GNUTLS_SHUT_WR.
109 * In case of GNUTLS_SHUT_RDWR then the TLS connection gets terminated and
110 * further receives and sends will be disallowed. If the return
111 * value is zero you may continue using the connection.
112 * GNUTLS_SHUT_RDWR actually sends an alert containing a close request
113 * and waits for the peer to reply with the same message.
115 * In case of GNUTLS_SHUT_WR then the TLS connection gets terminated and
116 * further sends will be disallowed. In order to reuse the connection
117 * you should wait for an EOF from the peer.
118 * GNUTLS_SHUT_WR sends an alert containing a close request.
120 * This function may also return GNUTLS_E_AGAIN, or GNUTLS_E_INTERRUPTED.
123 int gnutls_bye( GNUTLS_STATE state
, GNUTLS_CloseRequest how
)
125 int ret
= 0, ret2
= 0;
130 if (STATE
==STATE60
) {
131 ret
= _gnutls_io_write_flush( state
);
133 ret
= gnutls_alert_send( state
, GNUTLS_AL_WARNING
, GNUTLS_A_CLOSE_NOTIFY
);
140 if ( how
== GNUTLS_SHUT_RDWR
&& ret
>= 0) {
141 ret2
= gnutls_recv_int( state
, GNUTLS_ALERT
, -1, NULL
, 0);
142 if (ret2
>= 0) state
->gnutls_internals
.may_read
= 1;
153 state
->gnutls_internals
.may_write
= 1;
158 static void _gnutls_session_invalidate( GNUTLS_STATE state
) {
159 state
->gnutls_internals
.valid_connection
= VALID_FALSE
;
164 static void _gnutls_session_unresumable( GNUTLS_STATE state
) {
165 state
->gnutls_internals
.resumable
= RESUME_FALSE
;
168 /* returns 0 if session is valid
171 static int _gnutls_session_is_valid( GNUTLS_STATE state
) {
172 if (state
->gnutls_internals
.valid_connection
==VALID_FALSE
)
173 return GNUTLS_E_INVALID_SESSION
;
179 ssize_t
_gnutls_create_empty_record( GNUTLS_STATE state
, ContentType type
,
191 if (type
!=GNUTLS_APPLICATION_DATA
||
192 _gnutls_cipher_is_block( gnutls_cipher_get(state
))!=CIPHER_BLOCK
)
193 /* alert messages and stream ciphers
194 * do not need this protection
200 lver
= gnutls_protocol_get_version(state
);
201 if (lver
==GNUTLS_VERSION_UNKNOWN
) {
203 return GNUTLS_E_INTERNAL_ERROR
;
206 headers
[1]=_gnutls_version_get_major( lver
);
207 headers
[2]=_gnutls_version_get_minor( lver
);
211 cipher_size
= _gnutls_encrypt( state
, headers
, RECORD_HEADER_SIZE
, NULL
, 0, erecord
, type
, 0);
212 if (cipher_size
<= 0) {
214 if (cipher_size
==0) cipher_size
= GNUTLS_E_ENCRYPTION_FAILED
;
215 return cipher_size
; /* error */
218 retval
= cipher_size
;
220 /* increase sequence number
222 if (uint64pp( &state
->connection_state
.write_sequence_number
) != 0) {
223 _gnutls_session_invalidate( state
);
225 return GNUTLS_E_RECORD_LIMIT_REACHED
;
231 /* This function behave exactly like write(). The only difference is
232 * that it accepts, the gnutls_state and the ContentType of data to
233 * send (if called by the user the Content is specific)
234 * It is intended to transfer data, under the current state.
236 * Oct 30 2001: Removed capability to send data more than MAX_RECORD_SIZE.
237 * This makes the function much easier to read, and more error resistant
238 * (there were cases were the old function could mess everything up).
242 ssize_t
gnutls_send_int( GNUTLS_STATE state
, ContentType type
, HandshakeType htype
, const void *_data
, size_t sizeofdata
)
249 const uint8
*data
=_data
;
251 int erecord_size
= 0;
252 opaque
* erecord
= NULL
;
254 if (sizeofdata
== 0 || _data
==NULL
) {
256 return GNUTLS_E_INVALID_PARAMETERS
;
259 if (type
!=GNUTLS_ALERT
) /* alert messages are sent anyway */
260 if ( _gnutls_session_is_valid( state
) || state
->gnutls_internals
.may_write
!= 0) {
261 return GNUTLS_E_INVALID_SESSION
;
268 lver
= gnutls_protocol_get_version(state
);
269 if (lver
==GNUTLS_VERSION_UNKNOWN
) {
271 return GNUTLS_E_INTERNAL_ERROR
;
274 headers
[1]=_gnutls_version_get_major( lver
);
275 headers
[2]=_gnutls_version_get_minor( lver
);
277 _gnutls_record_log( "REC: Sending Packet[%d] %s(%d) with length: %d\n",
278 (int) uint64touint32(&state
->connection_state
.write_sequence_number
), _gnutls_packet2str(type
), type
, sizeofdata
);
280 if ( sizeofdata
> MAX_RECORD_SIZE
)
281 data2send
= MAX_RECORD_SIZE
;
283 data2send
= sizeofdata
;
285 /* Only encrypt if we don't have data to send
286 * from the previous run. - probably interrupted.
288 if (state
->gnutls_internals
.record_send_buffer
.size
> 0) {
289 ret
= _gnutls_io_write_flush( state
);
290 if (ret
> 0) cipher_size
= ret
;
291 else cipher_size
= 0;
295 retval
= state
->gnutls_internals
.record_send_buffer_user_size
;
298 /* Prepend our packet with an empty record. This is to
299 * avoid the recent CBC attacks.
301 /* if this protection has been disabled
303 if (state
->gnutls_internals
.cbc_protection_hack
!=0) {
305 _gnutls_create_empty_record( state
, type
, &erecord
);
306 if (erecord_size
< 0) {
312 /* now proceed to packet encryption
314 cipher_size
= _gnutls_encrypt( state
, headers
, RECORD_HEADER_SIZE
, data
, data2send
, &cipher
, type
, 1);
315 if (cipher_size
<= 0) {
317 if (cipher_size
==0) cipher_size
= GNUTLS_E_ENCRYPTION_FAILED
;
318 gnutls_free( erecord
);
319 return cipher_size
; /* error */
323 state
->gnutls_internals
.record_send_buffer_user_size
= data2send
;
325 /* increase sequence number
327 if (uint64pp( &state
->connection_state
.write_sequence_number
) != 0) {
328 _gnutls_session_invalidate( state
);
330 gnutls_free( erecord
);
331 return GNUTLS_E_RECORD_LIMIT_REACHED
;
334 ret
= _gnutls_io_write_buffered2( state
, erecord
, erecord_size
, cipher
, cipher_size
);
335 gnutls_free( erecord
);
336 gnutls_free( cipher
);
339 if ( ret
!= cipher_size
+ erecord_size
) {
340 if ( ret
< 0 && gnutls_error_is_fatal(ret
)==0) {
341 /* If we have sent any data then return
350 ret
= GNUTLS_E_UNKNOWN_ERROR
;
353 _gnutls_session_unresumable( state
);
354 _gnutls_session_invalidate( state
);
359 state
->gnutls_internals
.record_send_buffer_user_size
= 0;
361 _gnutls_record_log( "REC: Sent Packet[%d] %s(%d) with length: %d\n",
362 (int) uint64touint32(&state
->connection_state
.write_sequence_number
), _gnutls_packet2str(type
), type
, cipher_size
);
367 /* This function is to be called if the handshake was successfully
368 * completed. This sends a Change Cipher Spec packet to the peer.
370 ssize_t
_gnutls_send_change_cipher_spec( GNUTLS_STATE state
, int again
)
372 opaque data
[1] = { GNUTLS_TYPE_CHANGE_CIPHER_SPEC
};
374 _gnutls_handshake_log( "REC: Sent ChangeCipherSpec\n");
377 return gnutls_send_int( state
, GNUTLS_CHANGE_CIPHER_SPEC
, -1, data
, 1);
379 return _gnutls_io_write_flush( state
);
383 static int _gnutls_check_recv_type( ContentType recv_type
) {
385 case GNUTLS_CHANGE_CIPHER_SPEC
:
387 case GNUTLS_HANDSHAKE
:
388 case GNUTLS_APPLICATION_DATA
:
392 return GNUTLS_E_UNSUPPORTED_VERSION_PACKET
;
398 /* Checks if there are pending data into the record buffers. If there are
399 * then it copies the data.
401 static int _gnutls_check_buffers( GNUTLS_STATE state
, ContentType type
, opaque
* data
, int sizeofdata
) {
403 if ( (type
== GNUTLS_APPLICATION_DATA
|| type
== GNUTLS_HANDSHAKE
) && _gnutls_record_buffer_get_size(type
, state
) > 0) {
404 ret
= _gnutls_record_buffer_get(type
, state
, data
, sizeofdata
);
410 /* if the buffer just got empty */
411 if (_gnutls_record_buffer_get_size(type
, state
)==0) {
412 if ( (ret2
=_gnutls_io_clear_peeked_data( state
)) < 0) {
425 #define CHECK_RECORD_VERSION
427 /* Checks the record headers and returns the length, version and
430 static int _gnutls_check_record_headers( GNUTLS_STATE state
, uint8 headers
[RECORD_HEADER_SIZE
], ContentType type
,
431 HandshakeType htype
, /*output*/ ContentType
*recv_type
, GNUTLS_Version
*version
, uint16
*length
, uint16
* header_size
) {
433 /* Read the first two bytes to determine if this is a
437 if ( htype
== GNUTLS_CLIENT_HELLO
&& type
==GNUTLS_HANDSHAKE
&& headers
[0] > 127) {
439 /* if msb set and expecting handshake message
440 * it should be SSL 2 hello
442 *version
= GNUTLS_VERSION_UNKNOWN
; /* assume unknown version */
443 *length
= (((headers
[0] & 0x7f) << 8)) | headers
[1];
445 /* SSL 2.0 headers */
447 *recv_type
= GNUTLS_HANDSHAKE
; /* we accept only v2 client hello
450 /* in order to assist the handshake protocol.
451 * V2 compatibility is a mess.
453 state
->gnutls_internals
.v2_hello
= *length
;
455 _gnutls_record_log( "REC: V2 packet received. Length: %d\n", *length
);
460 *recv_type
= headers
[0];
461 #ifdef CHECK_RECORD_VERSION
462 *version
= _gnutls_version_get( headers
[1], headers
[2]);
465 *length
= READuint16( &headers
[3]);
471 /* Here we check if the advertized version is the one we
472 * negotiated in the handshake.
475 static int _gnutls_check_record_version( GNUTLS_STATE state
, HandshakeType htype
, GNUTLS_Version version
)
477 #ifdef CHECK_RECORD_VERSION
478 if ( (htype
!=GNUTLS_CLIENT_HELLO
&& htype
!=GNUTLS_SERVER_HELLO
) && gnutls_protocol_get_version(state
) != version
) {
481 _gnutls_record_log( "REC: INVALID VERSION PACKET: (%d) %d.%d\n", htype
, _gnutls_version_get_major(version
), _gnutls_version_get_minor(version
));
483 return GNUTLS_E_UNSUPPORTED_VERSION_PACKET
;
490 /* This function will check if the received record type is
491 * the one we actually expecting for.
493 static int _gnutls_record_check_type( GNUTLS_STATE state
, ContentType recv_type
,
494 ContentType type
, HandshakeType htype
, opaque
* data
, int data_size
) {
498 if ( (recv_type
== type
) && (type
== GNUTLS_APPLICATION_DATA
|| type
== GNUTLS_HANDSHAKE
)) {
499 _gnutls_record_buffer_put(type
, state
, (void *) data
, data_size
);
504 _gnutls_record_log( "REC: Alert[%d|%d] - %s - was received\n", data
[0], data
[1], gnutls_alert_get_name((int)data
[1]));
506 state
->gnutls_internals
.last_alert
= data
[1];
508 /* if close notify is received and
509 * the alert is not fatal
511 if (data
[1] == GNUTLS_A_CLOSE_NOTIFY
&& data
[0] != GNUTLS_AL_FATAL
) {
512 /* If we have been expecting for an alert do
515 return GNUTLS_E_INT_RET_0
; /* EOF */
518 /* if the alert is FATAL or WARNING
519 * return the apropriate message
523 ret
= GNUTLS_E_WARNING_ALERT_RECEIVED
;
524 if (data
[0] == GNUTLS_AL_FATAL
) {
525 _gnutls_session_unresumable( state
);
526 _gnutls_session_invalidate( state
);
528 ret
= GNUTLS_E_FATAL_ALERT_RECEIVED
;
535 case GNUTLS_CHANGE_CIPHER_SPEC
:
536 /* this packet is now handled above */
539 return GNUTLS_E_UNEXPECTED_PACKET
;
541 case GNUTLS_APPLICATION_DATA
:
542 /* even if data is unexpected put it into the buffer */
543 if ( (ret
=_gnutls_record_buffer_put(recv_type
, state
, (void *) data
, data_size
)) < 0) {
550 /* the got_application data is only returned
551 * if expecting client hello (for rehandshake
552 * reasons). Otherwise it is an unexpected packet
554 if (htype
== GNUTLS_CLIENT_HELLO
&& type
==GNUTLS_HANDSHAKE
)
555 return GNUTLS_E_GOT_APPLICATION_DATA
;
556 else return GNUTLS_E_UNEXPECTED_PACKET
;
559 case GNUTLS_HANDSHAKE
:
560 /* This is only legal if HELLO_REQUEST is received - and we are a client
562 if ( state
->security_parameters
.entity
==GNUTLS_SERVER
) {
564 return GNUTLS_E_UNEXPECTED_PACKET
;
568 return _gnutls_recv_hello_request( state
, data
, data_size
);
573 _gnutls_record_log( "REC: Received Unknown packet %d expecting %d\n", recv_type
, type
);
576 return GNUTLS_E_UNKNOWN_ERROR
;
584 #define MAX_EMPTY_PACKETS_SEQUENCE 4
586 /* This function behave exactly like read(). The only difference is
587 * that it accepts, the gnutls_state and the ContentType of data to
588 * send (if called by the user the Content is Userdata only)
589 * It is intended to receive data, under the current state.
591 ssize_t
gnutls_recv_int( GNUTLS_STATE state
, ContentType type
, HandshakeType htype
, char *data
, size_t sizeofdata
)
595 GNUTLS_Version version
;
597 ContentType recv_type
;
603 int empty_packet
= 0;
607 if (empty_packet
> MAX_EMPTY_PACKETS_SEQUENCE
) {
609 return GNUTLS_E_TOO_MANY_EMPTY_PACKETS
;
612 /* default headers for TLS 1.0
614 header_size
= RECORD_HEADER_SIZE
;
617 if (sizeofdata
== 0 || data
== NULL
) {
618 return GNUTLS_E_INVALID_PARAMETERS
;
621 if ( _gnutls_session_is_valid(state
)!=0 || state
->gnutls_internals
.may_read
!=0) {
623 return GNUTLS_E_INVALID_SESSION
;
626 /* If we have enough data in the cache do not bother receiving
627 * a new packet. (in order to flush the cache)
629 ret
= _gnutls_check_buffers( state
, type
, data
, sizeofdata
);
634 if ( (ret
= _gnutls_io_read_buffered( state
, &headers
, header_size
, -1)) != header_size
) {
635 if (ret
< 0 && gnutls_error_is_fatal(ret
)==0) return ret
;
637 _gnutls_session_invalidate( state
);
638 if (type
==GNUTLS_ALERT
) {
640 return 0; /* we were expecting close notify */
642 _gnutls_session_unresumable( state
);
644 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH
;
647 if ( (ret
=_gnutls_check_record_headers( state
, headers
, type
, htype
, &recv_type
, &version
, &length
, &header_size
)) < 0) {
652 /* Here we check if the Type of the received packet is
655 if ( (ret
= _gnutls_check_recv_type( recv_type
)) < 0) {
661 /* Here we check if the advertized version is the one we
662 * negotiated in the handshake.
664 if ( (ret
=_gnutls_check_record_version( state
, htype
, version
)) < 0) {
666 _gnutls_session_invalidate( state
);
670 _gnutls_record_log( "REC: Expected Packet[%d] %s(%d) with length: %d\n",
671 (int) uint64touint32(&state
->connection_state
.read_sequence_number
), _gnutls_packet2str(type
), type
, sizeofdata
);
672 _gnutls_record_log( "REC: Received Packet[%d] %s(%d) with length: %d\n",
673 (int) uint64touint32(&state
->connection_state
.read_sequence_number
), _gnutls_packet2str(recv_type
), recv_type
, length
);
675 if (length
> MAX_RECV_SIZE
) {
677 _gnutls_record_log( "REC: FATAL ERROR: Received packet with length: %d\n", length
);
679 _gnutls_session_unresumable( state
);
680 _gnutls_session_invalidate( state
);
682 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH
;
685 /* check if we have that data into buffer.
687 if ( (ret
= _gnutls_io_read_buffered( state
, &recv_data
, header_size
+length
, recv_type
)) != length
+header_size
) {
688 if (ret
<0 && gnutls_error_is_fatal(ret
)==0) return ret
;
690 _gnutls_session_unresumable( state
);
691 _gnutls_session_invalidate( state
);
693 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH
;
696 /* ok now we are sure that we can read all the data - so
699 _gnutls_io_clear_read_buffer( state
);
700 ciphertext
= &recv_data
[header_size
];
702 /* decrypt the data we got
704 tmplen
= _gnutls_decrypt( state
, ciphertext
, length
, &tmpdata
, recv_type
);
706 _gnutls_session_unresumable( state
);
707 _gnutls_session_invalidate( state
);
712 /* Check if this is a CHANGE_CIPHER_SPEC
714 if (type
== GNUTLS_CHANGE_CIPHER_SPEC
&& recv_type
== GNUTLS_CHANGE_CIPHER_SPEC
) {
716 _gnutls_record_log( "REC: ChangeCipherSpec Packet was received\n");
718 if (tmplen
!=sizeofdata
) { /* sizeofdata should be 1 */
720 gnutls_free(tmpdata
);
721 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH
;
723 memcpy( data
, tmpdata
, sizeofdata
);
724 gnutls_free(tmpdata
);
729 _gnutls_record_log( "REC: Decrypted Packet[%d] %s(%d) with length: %d\n",
730 (int) uint64touint32(&state
->connection_state
.read_sequence_number
), _gnutls_packet2str(recv_type
), recv_type
, tmplen
);
732 /* increase sequence number */
733 if (uint64pp( &state
->connection_state
.read_sequence_number
)!=0) {
734 _gnutls_session_invalidate( state
);
735 gnutls_free(tmpdata
);
737 return GNUTLS_E_RECORD_LIMIT_REACHED
;
740 if ( (ret
=_gnutls_record_check_type( state
, recv_type
, type
, htype
, tmpdata
, tmplen
)) < 0) {
741 gnutls_free( tmpdata
);
743 if (ret
==GNUTLS_E_INT_RET_0
) return 0;
748 gnutls_free( tmpdata
);
750 /* Get Application data from buffer */
751 if ((type
== GNUTLS_APPLICATION_DATA
|| type
== GNUTLS_HANDSHAKE
) && (recv_type
== type
)) {
753 ret
= _gnutls_record_buffer_get(type
, state
, data
, sizeofdata
);
759 /* if the buffer just got empty */
760 if (_gnutls_record_buffer_get_size(type
, state
)==0) {
761 if ( (ret2
= _gnutls_io_clear_peeked_data( state
)) < 0) {
769 ret
= GNUTLS_E_UNEXPECTED_PACKET
;
770 /* we didn't get what we wanted to
774 /* TLS 1.0 CBC protection. Read the next fragment.
785 /* Taken from libgcrypt */
788 parse_version_number( const char *s
, int *number
)
792 if( *s
== '0' && isdigit(s
[1]) )
793 return NULL
; /* leading zeros are not allowed */
794 for ( ; isdigit(*s
); s
++ ) {
799 return val
< 0? NULL
: s
;
804 parse_version_string( const char *s
, int *major
, int *minor
, int *micro
)
806 s
= parse_version_number( s
, major
);
807 if( !s
|| *s
!= '.' )
810 s
= parse_version_number( s
, minor
);
811 if( !s
|| *s
!= '.' )
814 s
= parse_version_number( s
, micro
);
817 return s
; /* patchlevel */
821 * Check that the the version of the library is at minimum the requested one
822 * and return the version string; return NULL if the condition is not
823 * satisfied. If a NULL is passed to this function, no check is done,
824 * but the version string is simply returned.
827 gnutls_check_version( const char *req_version
)
829 const char *ver
= GNUTLS_VERSION
;
830 int my_major
, my_minor
, my_micro
;
831 int rq_major
, rq_minor
, rq_micro
;
832 const char *my_plvl
, *rq_plvl
;
837 my_plvl
= parse_version_string( ver
, &my_major
, &my_minor
, &my_micro
);
839 return NULL
; /* very strange our own version is bogus */
840 rq_plvl
= parse_version_string( req_version
, &rq_major
, &rq_minor
,
843 return NULL
; /* req version string is invalid */
845 if ( my_major
> rq_major
846 || (my_major
== rq_major
&& my_minor
> rq_minor
)
847 || (my_major
== rq_major
&& my_minor
== rq_minor
848 && my_micro
> rq_micro
)
849 || (my_major
== rq_major
&& my_minor
== rq_minor
850 && my_micro
== rq_micro
851 && strcmp( my_plvl
, rq_plvl
) >= 0) ) {
859 * gnutls_record_send - sends to the peer the specified data
860 * @state: is a &GNUTLS_STATE structure.
861 * @data: contains the data to send
862 * @sizeofdata: is the length of the data
864 * This function has the similar semantics to write(). The only
865 * difference is that is accepts a GNUTLS state, and uses different
868 * If the EINTR is returned by the internal push function (write())
869 * then GNUTLS_E_INTERRUPTED, will be returned. If GNUTLS_E_INTERRUPTED or
870 * GNUTLS_E_AGAIN is returned you must call this function again, with the
871 * same parameters. Otherwise the write operation will be
872 * corrupted and the connection will be terminated.
874 * Returns the number of bytes sent, or a negative error code.
877 ssize_t
gnutls_record_send( GNUTLS_STATE state
, const void *data
, size_t sizeofdata
) {
878 return gnutls_send_int( state
, GNUTLS_APPLICATION_DATA
, -1, data
, sizeofdata
);
882 * gnutls_record_recv - reads data from the TLS record protocol
883 * @state: is a &GNUTLS_STATE structure.
884 * @data: contains the data to send
885 * @sizeofdata: is the length of the data
887 * This function has the similar semantics to read(). The only
888 * difference is that is accepts a GNUTLS state.
889 * Also returns the number of bytes received, zero on EOF, but
890 * a negative error code in case of an error.
892 * If this function returns GNUTLS_E_REHANDSHAKE, then you may
893 * ignore this message, send an alert containing NO_RENEGOTIATION,
894 * or perform a handshake again. (only a client may receive this message)
897 ssize_t
gnutls_record_recv( GNUTLS_STATE state
, void *data
, size_t sizeofdata
) {
898 return gnutls_recv_int( state
, GNUTLS_APPLICATION_DATA
, -1, data
, sizeofdata
);
902 * gnutls_record_get_max_size - returns the maximum record size
903 * @state: is a &GNUTLS_STATE structure.
905 * This function returns the maximum record size in this connection.
906 * The maximum record size is negotiated by the client after the
907 * first handshake message.
910 size_t gnutls_record_get_max_size( GNUTLS_STATE state
) {
911 return state
->security_parameters
.max_record_size
;
916 * gnutls_record_set_max_size - sets the maximum record size
917 * @state: is a &GNUTLS_STATE structure.
918 * @size: is the new size
920 * This function sets the maximum record size in this connection.
921 * This property can only be set to clients. The server may
922 * choose not to accept the requested size.
924 * Acceptable values are 2^9, 2^10, 2^11 and 2^12.
925 * Returns 0 on success. The requested record size does not
926 * get in effect immediately. It will be used after a successful
929 * This function uses a TLS extension called 'max record size'.
930 * Not all TLS implementations use or even understand this extension.
933 ssize_t
gnutls_record_set_max_size( GNUTLS_STATE state
, size_t size
) {
936 if (state
->security_parameters
.entity
==GNUTLS_SERVER
)
937 return GNUTLS_E_INVALID_REQUEST
;
939 new_size
= _gnutls_mre_record2num( size
);
946 state
->gnutls_internals
.proposed_record_size
= size
;