summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2001-10-21 11:36:45 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2001-10-21 11:36:45 +0000
commitc523488f0f38b9eeb6106a429d0902b1837a5ea1 (patch)
treeac2854643d1c85c97f9172d1ef150fd47c19f2cd
parent919fa2a0e6dece2d134eb12647e22cd186b70a85 (diff)
downloadgnutls-c523488f0f38b9eeb6106a429d0902b1837a5ea1.tar.gz
several cleanups
-rw-r--r--THANKS4
-rw-r--r--doc/tex/resumedb.tex2
-rw-r--r--lib/gnutls_buffers.c59
-rw-r--r--lib/gnutls_int.h4
-rw-r--r--lib/gnutls_kx.c5
-rw-r--r--lib/gnutls_record.c30
-rw-r--r--lib/gnutls_ui.c19
-rw-r--r--lib/gnutls_ui.h1
-rw-r--r--src/serv.c2
9 files changed, 103 insertions, 23 deletions
diff --git a/THANKS b/THANKS
index dd0ed46a98..f6c84602cb 100644
--- a/THANKS
+++ b/THANKS
@@ -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);