diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2001-10-21 11:36:45 +0000 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2001-10-21 11:36:45 +0000 |
commit | c523488f0f38b9eeb6106a429d0902b1837a5ea1 (patch) | |
tree | ac2854643d1c85c97f9172d1ef150fd47c19f2cd | |
parent | 919fa2a0e6dece2d134eb12647e22cd186b70a85 (diff) | |
download | gnutls-c523488f0f38b9eeb6106a429d0902b1837a5ea1.tar.gz |
several cleanups
-rw-r--r-- | THANKS | 4 | ||||
-rw-r--r-- | doc/tex/resumedb.tex | 2 | ||||
-rw-r--r-- | lib/gnutls_buffers.c | 59 | ||||
-rw-r--r-- | lib/gnutls_int.h | 4 | ||||
-rw-r--r-- | lib/gnutls_kx.c | 5 | ||||
-rw-r--r-- | lib/gnutls_record.c | 30 | ||||
-rw-r--r-- | lib/gnutls_ui.c | 19 | ||||
-rw-r--r-- | lib/gnutls_ui.h | 1 | ||||
-rw-r--r-- | src/serv.c | 2 |
9 files changed, 103 insertions, 23 deletions
@@ -1,4 +1,6 @@ -Tarun Upadhyay <tarun@poboxes.com> for his work on the initial ASN.1 DER parser. +Tarun Upadhyay <tarun@poboxes.com> Neil Spring <nspring@saavie.org> +Paul Sheer <psheer@icon.co.za> + diff --git a/doc/tex/resumedb.tex b/doc/tex/resumedb.tex index 3129df1b20..13a437c964 100644 --- a/doc/tex/resumedb.tex +++ b/doc/tex/resumedb.tex @@ -12,6 +12,8 @@ information)}{resume-example} illustrates a typical use of it (This is a modific \par Keep in mind that sessions are expired after some time (for security reasons), thus it may be normal for a server not to resume a session even if you requested that. +Also note that you must enable (using the priority functions), the +algorithms used in the last session. \subsection{Resuming internals} The resuming capability (mostly in the server side) is one of the problems of a thread-safe TLS diff --git a/lib/gnutls_buffers.c b/lib/gnutls_buffers.c index 28ef75e043..274225960f 100644 --- a/lib/gnutls_buffers.c +++ b/lib/gnutls_buffers.c @@ -164,7 +164,8 @@ static ssize_t _gnutls_Read(int fd, void *iptr, size_t sizeOfPtr, int flag) #ifdef READ_DEBUG _gnutls_log( "READ: returning %d bytes from %d\n", sizeOfPtr-left, fd); #endif - return sizeOfPtr-left; + goto finish; + //return sizeOfPtr-left; } if (errno==EAGAIN) return GNUTLS_E_AGAIN; else return GNUTLS_E_INTERRUPTED; @@ -183,6 +184,8 @@ static ssize_t _gnutls_Read(int fd, void *iptr, size_t sizeOfPtr, int flag) } + finish: + #ifdef READ_DEBUG _gnutls_log( "READ: read %d bytes from %d\n", (sizeOfPtr-left), fd); for (x=0;x<((sizeOfPtr-left)/16)+1;x++) { @@ -240,6 +243,9 @@ void _gnutls_read_clear_buffer( GNUTLS_STATE state) { * MAX_RECV_SIZE. * * sizeOfPtr should be unsigned. + * + * This is not a general purpose function. It returns EXACTLY the data requested. + * */ ssize_t _gnutls_read_buffered( int fd, GNUTLS_STATE state, opaque **iptr, size_t sizeOfPtr, int flag, ContentType recv_type) { @@ -247,6 +253,7 @@ ssize_t _gnutls_read_buffered( int fd, GNUTLS_STATE state, opaque **iptr, size_t int min; char *buf; int recvlowat = RCVLOWAT; + int recvdata; *iptr = NULL; @@ -267,22 +274,32 @@ ssize_t _gnutls_read_buffered( int fd, GNUTLS_STATE state, opaque **iptr, size_t *iptr = buf; - /* calculate the actual size + /* calculate the actual size, ie. get the minimum of the + * buffered data and the requested data. */ min = GMIN( state->gnutls_internals.recv_buffer_data_size, sizeOfPtr); if ( min > 0) { + /* if we have enough buffered data + * then just return them. + */ if ( min == sizeOfPtr) { return min; } } - /* min is over zero */ - sizeOfPtr -= min; - + /* min is over zero. recvdata is the data we must + * receive in order to return the requested data. + */ + recvdata = sizeOfPtr - min; + /* read fresh data - but leave RCVLOWAT bytes in the kernel buffer. */ - if ( sizeOfPtr - recvlowat > 0) { - ret = _gnutls_Read( fd, &buf[min], sizeOfPtr - recvlowat, flag); + if ( recvdata - recvlowat > 0) { + ret = _gnutls_Read( fd, &buf[min], recvdata - recvlowat, flag); + + /* return immediately if we got an interrupt or eagain + * error. + */ if (ret < 0 && gnutls_is_fatal_error(ret)==0) return ret; } @@ -305,7 +322,11 @@ ssize_t _gnutls_read_buffered( int fd, GNUTLS_STATE state, opaque **iptr, size_t ret += ret2; - if (ret < recvlowat) { +#ifdef READ_DEBUG + _gnutls_log("RB: Have %d bytes into buffer. Adding %d bytes.\nRB: Requested %d bytes\n", state->gnutls_internals.recv_buffer_data_size, ret, sizeOfPtr); +#endif + + if (ret > 0 && ret < recvlowat) { gnutls_assert(); return GNUTLS_E_AGAIN; } @@ -314,13 +335,20 @@ ssize_t _gnutls_read_buffered( int fd, GNUTLS_STATE state, opaque **iptr, size_t */ state->gnutls_internals.recv_buffer_data_size += ret; - ret+=min; - + if (ret==0) { /* EOF */ + gnutls_assert(); + return 0; + } + + ret = state->gnutls_internals.recv_buffer_data_size; + if ((ret > 0) && (ret < sizeOfPtr)) { /* Short Read */ + gnutls_assert(); return GNUTLS_E_AGAIN; - } else + } else { return ret; + } } @@ -354,10 +382,17 @@ ssize_t _gnutls_write(int fd, const void *iptr, size_t n, int flags) i = _gnutls_send_func(fd, &ptr[i], left, flags); if (i == -1) { if (errno == EAGAIN || errno == EINTR) { + if (n-left > 0) { + gnutls_assert(); + return n-left; + } + if (errno==EAGAIN) return GNUTLS_E_AGAIN; else return GNUTLS_E_INTERRUPTED; - } else + } else { + gnutls_assert(); return GNUTLS_E_UNKNOWN_ERROR; + } } left -= i; } diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index 36396d2753..02ebe6c162 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -26,11 +26,11 @@ /* #define WRITE_DEBUG -#define READ_DEBUG #define BUFFERS_DEBUG #define HARD_DEBUG #define HANDSHAKE_DEBUG -#define RECORD_DEBUG*/ +#define RECORD_DEBUG +#define READ_DEBUG*/ #define DEBUG diff --git a/lib/gnutls_kx.c b/lib/gnutls_kx.c index 732e232658..cc41272698 100644 --- a/lib/gnutls_kx.c +++ b/lib/gnutls_kx.c @@ -502,9 +502,10 @@ int _gnutls_recv_client_certificate(SOCKET cd, GNUTLS_STATE state) return 0; } /* certificate was required */ - if (optional==MANDATORY_PACKET) + if (optional==MANDATORY_PACKET) { gnutls_send_alert( cd, state, GNUTLS_FATAL, GNUTLS_BAD_CERTIFICATE); - gnutls_assert(); + gnutls_assert(); + } return ret; } diff --git a/lib/gnutls_record.c b/lib/gnutls_record.c index 488c6cb48c..1d22b3758a 100644 --- a/lib/gnutls_record.c +++ b/lib/gnutls_record.c @@ -532,6 +532,20 @@ ssize_t _gnutls_send_change_cipher_spec(SOCKET cd, GNUTLS_STATE state) } +static int _gnutls_check_recv_type( ContentType recv_type) { + switch( recv_type) { + case GNUTLS_CHANGE_CIPHER_SPEC: + case GNUTLS_ALERT: + case GNUTLS_HANDSHAKE: + case GNUTLS_APPLICATION_DATA: + return 0; + default: + gnutls_assert(); + return GNUTLS_E_UNSUPPORTED_VERSION_PACKET; + } + +} + #define CHECK_RECORD_VERSION /* This function behave exactly like read(). The only difference is @@ -600,7 +614,7 @@ ssize_t gnutls_recv_int(SOCKET cd, GNUTLS_STATE state, ContentType type, Handsha /* Read the first two bytes to determine if this is a * version 2 message */ - if ( headers[0] > 127 && type==GNUTLS_HANDSHAKE && htype == GNUTLS_CLIENT_HELLO) { + if ( htype == GNUTLS_CLIENT_HELLO && type==GNUTLS_HANDSHAKE && headers[0] > 127) { /* if msb set and expecting handshake message * it should be SSL 2 hello @@ -627,6 +641,17 @@ ssize_t gnutls_recv_int(SOCKET cd, GNUTLS_STATE state, ContentType type, Handsha length = READuint16( &headers[3]); } + /* Here we check if the Type of the received packet is + * ok. + */ + if ( (ret = _gnutls_check_recv_type( recv_type)) < 0) { + gnutls_assert(); + return ret; + } + + /* Here we check if the advertized version is the one we + * negotiated in the handshake. + */ #ifdef CHECK_RECORD_VERSION if ( (htype!=GNUTLS_CLIENT_HELLO && htype!=GNUTLS_SERVER_HELLO) && gnutls_get_current_version(state) != version) { gnutls_assert(); @@ -796,7 +821,8 @@ ssize_t gnutls_recv_int(SOCKET cd, GNUTLS_STATE state, ContentType type, Handsha break; case GNUTLS_HANDSHAKE: - /* This is only legal if HELLO_REQUEST is received - and we are a client */ + /* This is only legal if HELLO_REQUEST is received - and we are a client + */ if (htype!=GNUTLS_HELLO_REQUEST && state->security_parameters.entity==GNUTLS_SERVER) { gnutls_assert(); gnutls_free( tmpdata); diff --git a/lib/gnutls_ui.c b/lib/gnutls_ui.c index 3548ffccfa..19392ce863 100644 --- a/lib/gnutls_ui.c +++ b/lib/gnutls_ui.c @@ -37,6 +37,7 @@ * * This function will return the username of the peer. This should only be * called in case of SRP authentication and in case of a server. + * Returns NULL in case of an error. * **/ const char* gnutls_srp_server_get_username( GNUTLS_STATE state) { @@ -57,6 +58,7 @@ SRP_SERVER_AUTH_INFO info; * * This function will return the bits used in the Diffie Hellman authentication * with the peer. This should only be called in case of a server. + * Returns a negative value in case of an error. * **/ int gnutls_anon_server_get_dh_bits( GNUTLS_STATE state) { @@ -75,6 +77,7 @@ ANON_SERVER_AUTH_INFO info; * * This function will return the bits used in the Diffie Hellman authentication * with the peer. This should only be called in case of a client. + * Returns a negative value in case of an error. * **/ int gnutls_anon_client_get_dh_bits( GNUTLS_STATE state) { @@ -96,6 +99,7 @@ ANON_CLIENT_AUTH_INFO info; * This function will return the name of the peer. The name is gnutls_DN structure and * is a obtained by the peer's certificate. If the certificate send by the * peer is invalid, or in any other failure this function returns NULL. + * Returns NULL in case of an error. * **/ const gnutls_DN* gnutls_x509pki_get_peer_dn( GNUTLS_STATE state) { @@ -115,6 +119,7 @@ X509PKI_AUTH_INFO info; * This function will return the name of the peer's certificate issuer. The name is gnutls_DN structure and * is a obtained by the peer's certificate. If the certificate send by the * peer is invalid, or in any other failure this function returns NULL. + * Returns NULL in case of an error. * **/ const gnutls_DN* gnutls_x509pki_get_issuer_dn( GNUTLS_STATE state) { @@ -134,6 +139,7 @@ X509PKI_AUTH_INFO info; * This function will return the peer's certificate status (TRUSTED, EXPIRED etc.). This is the output * of the certificate verification function. However you must also check the peer's name in order * to check if the verified certificate belongs to the actual peer. + * Returns GNUTLS_CERT_NONE in case of an error, or if no certificate was sent. * **/ CertificateStatus gnutls_x509pki_get_peer_certificate_status( GNUTLS_STATE state) { @@ -142,7 +148,7 @@ X509PKI_AUTH_INFO info; CHECK_AUTH(GNUTLS_X509PKI, GNUTLS_E_INVALID_REQUEST); info = _gnutls_get_auth_info(state); - if (info==NULL) return GNUTLS_E_UNKNOWN_ERROR; + if (info==NULL) return GNUTLS_CERT_NONE; return info->peer_certificate_status; } @@ -152,6 +158,7 @@ X509PKI_AUTH_INFO info; * * This function will return the peer's certificate version (1, 2, 3). This is obtained by the X509 Certificate * Version field. If the certificate is invalid then version will be zero. + * Returns a negative value in case of an error. * **/ int gnutls_x509pki_get_peer_certificate_version( GNUTLS_STATE state) { @@ -171,6 +178,7 @@ X509PKI_AUTH_INFO info; * This function will return the number of bits used in a Diffie Hellman Handshake. This will only * occur in case of DHE_* ciphersuites. The return value may be zero if no applicable ciphersuite was * used. + * Returns a negative value in case of an error. * **/ int gnutls_x509pki_get_dh_bits( GNUTLS_STATE state) { @@ -189,6 +197,7 @@ X509PKI_AUTH_INFO info; * * This function will return the peer's certificate activation time in UNIX time (ie seconds since * 00:00:00 UTC January 1, 1970). + * Returns a (time_t) -1 in case of an error. * **/ time_t gnutls_x509pki_get_peer_certificate_activation_time( GNUTLS_STATE state) { @@ -207,6 +216,7 @@ X509PKI_AUTH_INFO info; * * This function will return the peer's certificate expiration time in UNIX time (ie seconds since * 00:00:00 UTC January 1, 1970). + * Returns a (time_t) -1 in case of an error. * **/ time_t gnutls_x509pki_get_peer_certificate_expiration_time( GNUTLS_STATE state) { @@ -226,6 +236,7 @@ X509PKI_AUTH_INFO info; * * This function will return the peer's certificate key usage. This is specified in X509v3 Certificate * Extensions and is an 8bit string. + * Returns zero in case of an error. * **/ unsigned char gnutls_x509pki_get_key_usage( GNUTLS_STATE state) { @@ -242,11 +253,12 @@ X509PKI_AUTH_INFO info; * gnutls_x509pki_get_certificate_request_status - This function returns the certificate request status * @state: is a gnutls state * - * This function will return 0 if the peer (server) did not requested client + * This function will return 0 if the peer (server) did not request client * authentication or 1 otherwise. + * Returns a negative value in case of an error. * **/ -unsigned char gnutls_x509pki_get_certificate_request_status( GNUTLS_STATE state) { +int gnutls_x509pki_get_certificate_request_status( GNUTLS_STATE state) { X509PKI_AUTH_INFO info; CHECK_AUTH(GNUTLS_X509PKI, 0); @@ -265,6 +277,7 @@ X509PKI_AUTH_INFO info; * This is specified in X509v3 Certificate Extensions. * GNUTLS will only return the dnsName of the Alternative name, or a null * string. + * Returns NULL in case of an error. * **/ const char* gnutls_x509pki_get_subject_dns_name( GNUTLS_STATE state) { diff --git a/lib/gnutls_ui.h b/lib/gnutls_ui.h index d7c7052c68..aea6d1caa7 100644 --- a/lib/gnutls_ui.h +++ b/lib/gnutls_ui.h @@ -59,6 +59,7 @@ int gnutls_anon_client_get_dh_bits( GNUTLS_STATE state); int gnutls_set_x509_cert_callback( X509PKI_CREDENTIALS, x509_cert_callback_func *); int gnutls_x509pki_set_cert_request( GNUTLS_STATE, CertificateRequest); +int gnutls_x509pki_get_certificate_request_status( GNUTLS_STATE); const gnutls_DN* gnutls_x509pki_get_peer_dn( GNUTLS_STATE); const gnutls_DN* gnutls_x509pki_get_issuer_dn( GNUTLS_STATE); CertificateStatus gnutls_x509pki_get_peer_certificate_status( GNUTLS_STATE); diff --git a/src/serv.c b/src/serv.c index 79da5428a6..0ccde3d8cf 100644 --- a/src/serv.c +++ b/src/serv.c @@ -372,7 +372,7 @@ int main(int argc, char **argv) exit(1); } - /* this is a password file (created with the included crypt utility) + /* this is a password file (created with the included srpcrypt utility) * Read README.crypt prior to using SRP. */ gnutls_allocate_srp_server_sc( &srp_cred); |