\gnutls{} implements all the known counter-measures for these attacks. For the first
two cases, \gnutls{} does only have one error code for both of the decryption failures,
-and processes the message normaly even if a padding error occured. This avoids
+and processes the message normally even if a padding error occured. This avoids
both of these attacks.
For the latter, an empty record can be sent before every record packet, and this is
believed to avoid the known attacks in CBC encrypted packets. See the function
*
*/
-#include "gnutls_int.h"
-
#ifdef ENABLE_ANON
+#include "gnutls_int.h"
+
#include "gnutls_errors.h"
#include "auth_anon.h"
#include "gnutls_auth_int.h"
*
**/
void gnutls_credentials_clear( gnutls_session session) {
- AUTH_CRED * ccred, *ncred;
-
- if (session->key && session->key->cred) { /* begining of the list */
+ if (session->key && session->key->cred) { /* beginning of the list */
+ AUTH_CRED * ccred, *ncred;
ccred = session->key->cred;
while(ccred!=NULL) {
ncred = ccred->next;
- if (ccred!=NULL) gnutls_free(ccred);
+ gnutls_free(ccred);
ccred = ncred;
}
session->key->cred = NULL;
AUTH_CRED * ccred=NULL, *pcred=NULL;
int exists=0;
- if (session->key->cred==NULL) { /* begining of the list */
+ if (session->key->cred==NULL) { /* beginning of the list */
session->key->cred = gnutls_malloc(sizeof(AUTH_CRED));
if (session->key->cred == NULL) return GNUTLS_E_MEMORY_ERROR;
- /* copy credentials localy */
+ /* copy credentials locally */
session->key->cred->credentials = cred;
session->key->cred->next = NULL;
ccred = pcred->next;
- /* copy credentials localy */
+ /* copy credentials locally */
ccred->credentials = cred;
ccred->next = NULL;
}
/*
- * This returns an pointer to the linked list. Don't
+ * This returns a pointer to the linked list. Don't
* free that!!!
*/
const void *_gnutls_get_kx_cred( gnutls_session session, gnutls_kx_algorithm algo, int *err)
*
* HANDSHAKE LAYER:
* 1. Uses a buffer to hold data that was not sent or received
- * complete. (Ie. sent 10 bytes of a handshake packet that is 20 bytes
+ * complete. (E.g. sent 10 bytes of a handshake packet that is 20 bytes
* long).
* (see _gnutls_handshake_send_int(), _gnutls_handshake_recv_int())
*
default:
return GNUTLS_E_INVALID_REQUEST;
}
- return 0;
}
/**
* Clears the peeked data (read with MSG_PEEK).
*/
int _gnutls_io_clear_peeked_data( gnutls_session session) {
-char *peekdata = NULL;
+char *peekdata;
int ret, sum;
if (session->internals.have_peeked_data==0 || RCVLOWAT==0)
* This function reads data from the socket and keeps them in a buffer, of up to
* MAX_RECV_SIZE.
*
- * sizeOfPtr should be unsigned.
- *
* This is not a general purpose function. It returns EXACTLY the data requested,
* which are stored in a local (in the session) buffer. A pointer (iptr) to this buffer is returned.
*
if (session->internals.handshake_send_buffer.length == 0) {
ret = session->internals.handshake_send_buffer_prev_size; /* done */
session->internals.handshake_send_buffer_prev_size = 0;
-
- return ret;
}
return ret;
ssize_t _gnutls_handshake_io_send_int( gnutls_session session, ContentType type, HandshakeType htype, const void *iptr, size_t n)
{
size_t left;
- ssize_t i = 0, ret=0;
+ ssize_t ret=0;
const opaque *ptr;
ssize_t retval = 0;
} else if (session->internals.handshake_send_buffer.length > 0) {
gnutls_assert();
return GNUTLS_E_INTERNAL_ERROR;
- } else {
+ }
#ifdef WRITE_DEBUG
+ else {
size_t sum=0, x, j;
_gnutls_write_log( "HWRITE: will write %d bytes to %d.\n", n, gnutls_transport_get_ptr(session));
_gnutls_write_log( "\n");
}
_gnutls_write_log( "\n");
-#endif
-
-
}
+#endif
if (n==0) { /* if we have no data to send */
gnutls_assert();
gnutls_assert();
return ret;
}
- i = ret;
- left -= i;
+ left -= ret;
}
retval = n + session->internals.handshake_send_buffer_prev_size;
/**
- * gnutls_certificate_allocate_credentials - Used to allocate an gnutls_certificate_credentials structure
+ * gnutls_certificate_allocate_credentials - Used to allocate a gnutls_certificate_credentials structure
* @res: is a pointer to an &gnutls_certificate_credentials structure.
*
* This structure is complex enough to manipulate directly thus
*
* 'req_ca_cert', is only used in X.509 certificates.
* Contains a list with the CA names that the server considers trusted.
- * Normaly we should send a certificate that is signed
+ * Normally we should send a certificate that is signed
* by one of these CAs. These names are DER encoded. To get a more
* meaningful value use the function gnutls_x509_rdn_get().
*
* choosen by the user. The index is relative to the certificates in the
* callback's parameter. The value (-1) indicates that the user
* does not want to use client authentication.
- *
- * This function returns 0 on success.
**/
void gnutls_certificate_client_set_select_function(gnutls_session session,
certificate_client_select_func
if (verify < 0) {
gnutls_assert();
- return verify;
}
-
return verify;
}
}
-/* This function will convert a der certificate, to a format
+/* This function will convert a der certificate to a format
* (structure) that gnutls can understand and use. Actually the
* important thing on this function is that it extracts the
* certificate's (public key) parameters.
int _gnutls_x509_cert2gnutls_cert(gnutls_cert * gcert, const gnutls_datum *derCert,
int flags /* OR of ConvFlags */)
{
- int ret = 0;
+ int ret;
gnutls_x509_crt cert;
ret = gnutls_x509_crt_init( &cert);
ret = gnutls_x509_crt_export( cert, GNUTLS_X509_FMT_DER, der, &der_size);
if (ret < 0) {
gnutls_assert();
+ gnutls_free(der);
return ret;
}
LZO_FUNC _gnutls_lzo1x_decompress_safe = NULL;
LZO_FUNC _gnutls_lzo1x_1_compress = NULL;
-/* The flag d is the direction (compressed, decompress). Non zero is
+/* The flag d is the direction (compress, decompress). Non zero is
* decompress.
*/
GNUTLS_COMP_HANDLE _gnutls_comp_init( gnutls_compression_method method, int d)
}
if (err!=Z_OK) {
gnutls_assert();
- gnutls_free( ret);
gnutls_free( ret->handle);
+ gnutls_free( ret);
return NULL;
}
break;
}
case GNUTLS_COMP_LZO:
if (d) /* LZO does not use memory on decompressor */
- ret->handle = NULL;
+ { /* ret->handle = NULL; */ }
else {
ret->handle = gnutls_malloc( LZO1X_1_MEM_COMPRESS);
}
break;
-
- default:
- break;
}
#endif
return ret;
int err;
if (handle!=NULL) {
- switch( handle->algo) {
- case GNUTLS_COMP_LZO:
- break;
#ifdef HAVE_LIBZ
+ switch( handle->algo) {
+ /* case GNUTLS_COMP_LZO:
+ break; */
case GNUTLS_COMP_ZLIB:
if (d)
err = inflateEnd( handle->handle);
else
err = deflateEnd( handle->handle);
break;
-#endif
- default:
- break;
}
+#endif
gnutls_free( handle->handle);
gnutls_free( handle);
return GNUTLS_E_COMPRESSION_FAILED;
size = plain_size + plain_size / 64 + 16 + 3;
- *compressed=NULL;
-
*compressed = gnutls_malloc(size);
if (*compressed==NULL) {
gnutls_assert();
return GNUTLS_E_MEMORY_ERROR;
}
- err = _gnutls_lzo1x_1_compress( plain, plain_size, *compressed,
- &out_len, handle->handle);
+ err = _gnutls_lzo1x_1_compress( plain, plain_size, *compressed,
+ &out_len, handle->handle);
- if (err!=LZO_E_OK) {
- gnutls_assert();
- gnutls_free( *compressed);
- return GNUTLS_E_COMPRESSION_FAILED;
- }
+ if (err!=LZO_E_OK) {
+ gnutls_assert();
+ gnutls_free( *compressed);
+ return GNUTLS_E_COMPRESSION_FAILED;
+ }
compressed_size = out_len;
break;
z_stream *zhandle;
size = (plain_size+plain_size)+10;
- *compressed=NULL;
-
*compressed = gnutls_malloc(size);
if (*compressed==NULL) {
gnutls_assert();
zhandle->next_out = (Bytef*) *compressed;
zhandle->avail_out = size;
- err = deflate( zhandle, Z_SYNC_FLUSH);
+ err = deflate( zhandle, Z_SYNC_FLUSH);
- if (err!=Z_OK || zhandle->avail_in != 0) {
- gnutls_assert();
- gnutls_free( *compressed);
- return GNUTLS_E_COMPRESSION_FAILED;
- }
+ if (err!=Z_OK || zhandle->avail_in != 0) {
+ gnutls_assert();
+ gnutls_free( *compressed);
+ return GNUTLS_E_COMPRESSION_FAILED;
+ }
compressed_size = size - zhandle->avail_out;
break;
zhandle->next_out = (Bytef*) (*plain + cur_pos);
zhandle->avail_out = out_size - cur_pos;
- err = inflate( zhandle, Z_SYNC_FLUSH);
+ err = inflate( zhandle, Z_SYNC_FLUSH);
- cur_pos = out_size - zhandle->avail_out;
+ cur_pos = out_size - zhandle->avail_out;
} while( (err==Z_BUF_ERROR && zhandle->avail_out==0 && out_size < max_record_size)
|| ( err==Z_OK && zhandle->avail_in != 0));
* This function will remove the current session data from the session
* database. This will prevent future handshakes reusing these session
* data. This function should be called if a session was terminated
- * abnormaly, and before gnutls_deinit() is called.
+ * abnormally, and before gnutls_deinit() is called.
*
* Normally gnutls_deinit() will remove abnormally terminated sessions.
*
*
* This is the function where you set the logging function gnutls
* is going to use. This function only accepts a character array.
- * Normaly you may not use this function since it is only used
+ * Normally you may not use this function since it is only used
* for debugging purposes.
*
* gnutls_log_func is of the form,
* @session: gnutls session
*
* This is the function where you set a function for gnutls
- * to receive data. Normaly, if you use berkeley style sockets,
+ * to receive data. Normally, if you use berkeley style sockets,
* you may not use this function since the default (recv(2)) will
* probably be ok.
* This function should be called once and after gnutls_global_init().
}
-/* This function copies the appropriate ciphersuites, to a localy allocated buffer
+/* This function copies the appropriate ciphersuites to a locally allocated buffer
* Needed in client hello messages. Returns the new data length.
*/
static int _gnutls_copy_ciphersuites(gnutls_session session,
}
-/* This function copies the appropriate compression methods, to a localy allocated buffer
+/* This function copies the appropriate compression methods, to a locally allocated buffer
* Needed in hello messages. Returns the new data length.
*/
static int _gnutls_copy_comp_methods(gnutls_session session,
void *_gnutls_calloc(size_t nmemb, size_t size)
{
void *ret;
- ret = gnutls_malloc(size*nmemb);
- if (ret == NULL)
- return ret;
-
- memset(ret, 0, size);
-
+ size *= nmemb;
+ ret = gnutls_malloc(size);
+ if (ret != NULL) memset(ret, 0, size);
return ret;
}
svoid *gnutls_secure_calloc(size_t nmemb, size_t size)
{
svoid *ret;
- ret = gnutls_secure_malloc(size*nmemb);
- if (ret == NULL)
- return ret;
-
- memset(ret, 0, size);
-
+ size *= nmemb;
+ ret = gnutls_secure_malloc(size);
+ if (ret != NULL) memset(ret, 0, size);
return ret;
}
{
void *ret;
- if (size == 0) return ptr;
+ if (size == 0) return ptr;
ret = gnutls_realloc( ptr, size);
if ( ret == NULL) {
}
/* Copies the record version into the headers. The
- * version, must have 2 bytes at least.
+ * version must have 2 bytes at least.
*/
inline static void copy_record_version( gnutls_session session, HandshakeType htype,
opaque version[2])
return retval;
}
-/* This function behave exactly like write(). The only difference is
+/* This function behaves exactly like write(). The only difference is
* that it accepts, the gnutls_session and the ContentType of data to
* send (if called by the user the Content is specific)
* It is intended to transfer data, under the current session.
}
-/* Checks if there are pending data into the record buffers. If there are
+/* Checks if there are pending data in the record buffers. If there are
* then it copies the data.
*/
static int _gnutls_check_buffers( gnutls_session session, ContentType type, opaque* data, int sizeofdata) {
- int ret = 0, ret2=0;
if ( (type == GNUTLS_APPLICATION_DATA || type == GNUTLS_HANDSHAKE) && _gnutls_record_buffer_get_size(type, session) > 0) {
+ int ret = 0, ret2=0;
ret = _gnutls_record_buffer_get(type, session, data, sizeofdata);
if (ret < 0) {
gnutls_assert();
}
/* This function will check if the received record type is
- * the one we actually expecting for.
+ * the one we actually expect.
*/
static int _gnutls_record_check_type( gnutls_session session, ContentType recv_type,
ContentType type, HandshakeType htype, opaque* data, int data_size) {
#define MAX_EMPTY_PACKETS_SEQUENCE 4
-/* This function behave exactly like read(). The only difference is
- * that it accepts, the gnutls_session and the ContentType of data to
+/* This function behaves exactly like read(). The only difference is
+ * that it accepts the gnutls_session and the ContentType of data to
* send (if called by the user the Content is Userdata only)
* It is intended to receive data, under the current session.
*/
uint16 header_size;
int empty_packet = 0;
+ if (sizeofdata == 0 || data == NULL) {
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
begin:
if (empty_packet > MAX_EMPTY_PACKETS_SEQUENCE) {
header_size = RECORD_HEADER_SIZE;
ret = 0;
- if (sizeofdata == 0 || data == NULL) {
- return GNUTLS_E_INVALID_REQUEST;
- }
-
if ( _gnutls_session_is_valid(session)!=0 || session->internals.may_read!=0) {
gnutls_assert();
return GNUTLS_E_INVALID_SESSION;
* Actually this code is called if we just received
* an empty packet. An empty TLS packet is usually
* sent to protect some vulnerabilities in the CBC mode.
- * In that case we go to the begining and start reading
+ * In that case we go to the beginning and start reading
* the next packet.
*/
if (ret==0) {
* error codes.
*
* If the EINTR is returned by the internal push function (write())
- * then GNUTLS_E_INTERRUPTED, will be returned. If GNUTLS_E_INTERRUPTED or
+ * then GNUTLS_E_INTERRUPTED will be returned. If GNUTLS_E_INTERRUPTED or
* GNUTLS_E_AGAIN is returned you must call this function again, with the
* same parameters. Otherwise the write operation will be
* corrupted and the connection will be terminated.
/* Decodes the PKCS #7 signed data, and returns an ASN1_TYPE,
* which holds them. If raw is non null then the raw decoded
- * data are copied (they are localy allocated) there.
+ * data are copied (they are locally allocated) there.
*/
static
int _decode_pkcs7_signed_data( ASN1_TYPE pkcs7, ASN1_TYPE * sdata, gnutls_datum* raw)
return ret;
}
-/* encodes data and puts the result into result (localy alocated)
+/* encodes data and puts the result into result (locally allocated)
* The result_size is the return value
*/
int _gnutls_base64_encode(const uint8 * data, size_t data_size, uint8 ** result)
return ret;
}
-/* encodes data and puts the result into result (localy alocated)
+/* encodes data and puts the result into result (locally allocated)
* The result_size is the return value
*/
int _gnutls_fbase64_encode(const char *msg, const uint8 * data, int data_size,
opaque* ret;
int size;
+ if (result==NULL) return GNUTLS_E_INVALID_REQUEST;
+
size = _gnutls_fbase64_encode( msg, data->data, data->size, &ret);
if (size < 0)
return size;
- if (result==NULL) {
- gnutls_free(ret);
- return GNUTLS_E_INVALID_REQUEST;
- } else {
- result->data = ret;
- result->size = size;
- }
-
+ result->data = ret;
+ result->size = size;
return 0;
}
-/* decodes data and puts the result into result (localy alocated)
+/* decodes data and puts the result into result (locally allocated)
* The result_size is the return value
*/
int _gnutls_base64_decode(const uint8 * data, size_t data_size, uint8 ** result)
gnutls_datum n;
} SRP_PWD_ENTRY;
-/* this is localy alocated. It should be freed using the provided function */
+/* this is locally allocated. It should be freed using the provided function */
int _gnutls_srp_pwd_read_entry( gnutls_session state, char* username, SRP_PWD_ENTRY**);
void _gnutls_srp_entry_free( SRP_PWD_ENTRY * entry);
int _gnutls_sbase64_encode(uint8 * data, size_t data_size, uint8 ** result);
}
-/* encodes data and puts the result into result (localy alocated)
+/* encodes data and puts the result into result (locally allocated)
* The result_size is the return value
*/
int _gnutls_sbase64_encode(uint8 * data, size_t data_size, uint8 ** result)
return ret;
}
-/* decodes data and puts the result into result (localy alocated)
+/* decodes data and puts the result into result (locally allocated)
* The result_size is the return value.
* That function does not ignore newlines tabs etc. You should remove them
* before calling it.
}
/* returns data_size or a negative number on failure
- * data is allocated localy
+ * data is allocated locally
*/
int _gnutls_srp_send_params( gnutls_session state, opaque* data, size_t data_size) {
uint len;