diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2001-07-28 10:36:46 +0000 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2001-07-28 10:36:46 +0000 |
commit | 4945ad1a3eb49c1321cda580c7ed8eddc769e511 (patch) | |
tree | 110632ba180bf666262578ccf3d043f306488afc | |
parent | f5eee1a355387fe8885f7b1e13f0f8260ddb8162 (diff) | |
download | gnutls-4945ad1a3eb49c1321cda580c7ed8eddc769e511.tar.gz |
added some documentation. Bug fixes in CHANGECIPHER_SPEC packet.
-rw-r--r-- | doc/API-template.html | 193 | ||||
-rw-r--r-- | doc/Makefile.am | 12 | ||||
-rwxr-xr-x | doc/scripts/gdoc | 2 | ||||
-rw-r--r-- | lib/gnutls.h.in | 10 | ||||
-rw-r--r-- | lib/gnutls_errors.c | 2 | ||||
-rw-r--r-- | lib/gnutls_errors_int.h | 1 | ||||
-rw-r--r-- | lib/gnutls_global.c | 20 | ||||
-rw-r--r-- | lib/gnutls_handshake.c | 3 | ||||
-rw-r--r-- | lib/gnutls_int.h | 3 | ||||
-rw-r--r-- | lib/gnutls_record.c | 8 | ||||
-rw-r--r-- | lib/gnutls_sig_check.c | 10 |
11 files changed, 234 insertions, 30 deletions
diff --git a/doc/API-template.html b/doc/API-template.html new file mode 100644 index 0000000000..b5053273d2 --- /dev/null +++ b/doc/API-template.html @@ -0,0 +1,193 @@ +<html> +<body> + +<a name="introduction"> </a> +<h2>Introduction</h2> + +<p> +gnuTLS is a library which implements the <B>TLS 1.0</b> and <b>SSL 3.0</b> protocols. +TLS stands for 'Transport Layer Security' and is the sucessor of SSL (Secure Sockets Layer). +<b>TLS 1.0</b> is described is <i>RFC 2246</i> and is an Internet protocol (thus it's mostly used over TCP/IP), +that provides confidentiality, and authentication layers. +</p> + +<p> +Confidentiality is provided by using symmetric encryption algorithms like <b>3DES</b>, <b>AES</b>, or +stream algorithms like <b>ARCFOUR</b>. A symmetric encryption algorithm uses a single (secret) key +to encrypt and decrypt data. +</p> + +<p> +The following authentication schemas are supported in gnuTLS: +<ul> +<li>x509 Public Key Infrastructure</li> +<li>Anonymous authentication</li> +<li>SRP authentication</li> +</ul> + +</p> + +<a name="x509_client_example"> </a> +<h2>x509 Client example</h2> + +<p> +Let's assume now that we want to create a client which communicates +with servers using the x509 authentication schema. The following client +is a very simple TLS client, it does not support session resuming nor +anything other fancy features. + +<xmp> + +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <gnutls.h> + +#define MAX_BUF 1024 +#define CRLFILE "crl.pem" +#define CAFILE "ca.pem" +#define SA struct sockaddr +#define MSG "GET / HTTP/1.0\r\n\r\n" + +int main() +{ + const char* PORT = "5556"; + const char* SERVER = "127.0.0.1"; + int err, ret; + int sd, ii; + struct sockaddr_in sa; + GNUTLS_STATE state; + char buffer[MAX_BUF+1]; + X509PKI_CLIENT_CREDENTIALS xcred; + + if (gnutls_global_init() < 0) { + fprintf(stderr, "global state initialization error\n"); + exit(1); + } + + + /* X509 stuff */ + if (gnutls_allocate_x509_client_sc( &xcred, 0) < 0) { /* no client private key */ + fprintf(stderr, "memory error\n"); + exit(1); + } + + /* set's the trusted cas file + */ + gnutls_set_x509_client_trust( xcred, CAFILE, CRLFILE); + + /* connects to server + */ + sd = socket(AF_INET, SOCK_STREAM, 0); + + memset(&sa, '\0', sizeof(sa)); + sa.sin_family = AF_INET; + sa.sin_port = htons(atoi(PORT)); + inet_pton( AF_INET, SERVER, &sa.sin_addr); + + err = connect(sd, (SA *) & sa, sizeof(sa)); + + /* Initiate TLS state + */ + gnutls_init(&state, GNUTLS_CLIENT); + + /* allow both SSL3 and TLS1 + */ + gnutls_set_protocol_priority( state, GNUTLS_TLS1, GNUTLS_SSL3, 0); + + /* allow only ARCFOUR and 3DES ciphers + * (3DES has the highest priority) + */ + gnutls_set_cipher_priority( state, GNUTLS_3DES_CBC, GNUTLS_ARCFOUR, 0); + + /* only allow null compression + */ + gnutls_set_compression_priority( state, GNUTLS_NULL_COMPRESSION, 0); + + /* use GNUTLS_KX_RSA + */ + gnutls_set_kx_priority( state, GNUTLS_KX_RSA, 0); + + /* allow the usage of both SHA and MD5 + */ + gnutls_set_mac_priority( state, GNUTLS_MAC_SHA, GNUTLS_MAC_MD5, 0); + + + /* put the x509 credentials to the current state + */ + gnutls_set_cred( state, GNUTLS_X509PKI, xcred); + + + /* Perform the TLS handshake + */ + ret = gnutls_handshake(sd, state); + + if (ret < 0) { + fprintf(stderr, "*** Handshake failed\n"); + gnutls_perror(ret); + goto end; + } else { + printf("- Handshake was completed\n"); + } + + gnutls_write( sd, state, MSG, strlen(MSG)); + + ret = gnutls_read(sd, state, buffer, MAX_BUF); + if (gnutls_is_fatal_error(ret) == 1 || ret==0) { + if (ret == 0) { + printf("- Peer has closed the GNUTLS connection\n"); + goto end; + } else { + fprintf(stderr, "*** Received corrupted data(%d) - server has terminated the connection abnormally\n", + ret); + goto end; + } + } else { + if (ret==GNUTLS_E_WARNING_ALERT_RECEIVED || ret==GNUTLS_E_FATAL_ALERT_RECEIVED) + printf("* Received alert [%d]\n", gnutls_get_last_alert(state)); + if (ret==GNUTLS_E_GOT_HELLO_REQUEST) + printf("* Received HelloRequest message (server asked to rehandshake)\n"); + } + + if (ret > 0) { + printf("- Received %d bytes: ", ret); + for (ii=0;ii<ret;ii++) { + fputc(buffer[ii], stdout); + } + fputs("\n", stdout); + } + + + gnutls_bye(sd, state, 0); + + end: + + shutdown( sd, SHUT_RDWR); /* no more receptions */ + close(sd); + + gnutls_deinit( state); + + gnutls_free_x509_client_sc( xcred); + + gnutls_global_deinit(); + + return 0; +} + + +</xmp> + +</p> + + +<a name="functions"> </a> +<h2>Function reference</h2> + +<p> +All functions return >=0 if everything is ok, or a negative value in case +of a failure. Failure is not always fatal. +</p> + diff --git a/doc/Makefile.am b/doc/Makefile.am index fe89ab971d..239207ab70 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -1,7 +1,7 @@ -EXTRA_DIST = TODO gnutls-api.txt gnutls-api.html ASN1.readme.txt +EXTRA_DIST = TODO gnutls-api.html ASN1.readme.txt -gnutls-api: gnutls-api.html gnutls-api.txt -gnutls-api.html: - @scripts/gdoc -html ../lib/*.c > gnutls-api.html -gnutls-api.txt: - @scripts/gdoc -text ../lib/*.c > gnutls-api.txt +gnutls-api: gnutls-api.html +gnutls-api.html: API-template.html + @cat API-template.html > gnutls-api.html + @scripts/gdoc -html ../lib/*.c >> gnutls-api.html + @echo "</body></html>" >> gnutls-api.html diff --git a/doc/scripts/gdoc b/doc/scripts/gdoc index 95e59d53da..a83cfb7637 100755 --- a/doc/scripts/gdoc +++ b/doc/scripts/gdoc @@ -226,7 +226,7 @@ sub output_html { my %args = %{$_[0]}; my ($parameter, $section); my $count; - print "<h2>Function</h2>\n"; + print "\n\n<a name=\"". $args{'function'} . "\"> </a><h2>Function</h2>\n"; print "<i>".$args{'functiontype'}."</i>\n"; print "<b>".$args{'function'}."</b>\n"; diff --git a/lib/gnutls.h.in b/lib/gnutls.h.in index 471bfc9973..761cb8f34f 100644 --- a/lib/gnutls.h.in +++ b/lib/gnutls.h.in @@ -234,8 +234,14 @@ int gnutls_set_x509_trust( X509PKI_CREDENTIALS res, char* CAFILE, char* CRLFILE) int gnutls_global_init(); void gnutls_global_deinit(); -void gnutls_set_recv_func( ssize_t (*recv_func)(SOCKET, void*, size_t, int)); -void gnutls_set_send_func( ssize_t (*send_func)(SOCKET, const void*, size_t, int)); +typedef ssize_t (*RECV_FUNC)(SOCKET, void*, size_t,int); +typedef ssize_t (*SEND_FUNC)(SOCKET, const void*, size_t,int); + +RECV_FUNC _gnutls_recv_func; +SEND_FUNC _gnutls_send_func; + +void gnutls_global_set_send_func( SEND_FUNC send_func); +void gnutls_global_set_recv_func( RECV_FUNC recv_func); /* error codes appended here */ diff --git a/lib/gnutls_errors.c b/lib/gnutls_errors.c index b8fae8fd43..65b3ea8480 100644 --- a/lib/gnutls_errors.c +++ b/lib/gnutls_errors.c @@ -32,6 +32,7 @@ struct gnutls_error_entry { typedef struct gnutls_error_entry gnutls_error_entry; static gnutls_error_entry error_algorithms[] = { + GNUTLS_ERROR_ENTRY( GNUTLS_E_SUCCESS, 0), GNUTLS_ERROR_ENTRY( GNUTLS_E_MAC_FAILED, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_UNKNOWN_CIPHER, 1), GNUTLS_ERROR_ENTRY( GNUTLS_E_UNKNOWN_CIPHER_SUITE, 1), @@ -103,6 +104,7 @@ static gnutls_error_entry error_algorithms[] = { int gnutls_is_fatal_error(int error) { int ret = 0; + GNUTLS_ERROR_ALG_LOOP(ret = p->fatal); return ret; } diff --git a/lib/gnutls_errors_int.h b/lib/gnutls_errors_int.h index 01ddd5ce52..d186b2db61 100644 --- a/lib/gnutls_errors_int.h +++ b/lib/gnutls_errors_int.h @@ -1,3 +1,4 @@ +#define GNUTLS_E_SUCCESS 0 #define GNUTLS_E_MAC_FAILED -1 #define GNUTLS_E_UNKNOWN_CIPHER -2 #define GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM -3 diff --git a/lib/gnutls_global.c b/lib/gnutls_global.c index f21a199152..1f83b8f459 100644 --- a/lib/gnutls_global.c +++ b/lib/gnutls_global.c @@ -30,8 +30,12 @@ extern const static_asn pkcs1_asn1_tab[]; extern const static_asn pkix_asn1_tab[]; static void* old_sig_handler; -ssize_t (*_gnutls_recv_func)( SOCKET, void*, size_t, int); -ssize_t (*_gnutls_send_func)( SOCKET,const void*, size_t, int); + +typedef ssize_t (*RECV_FUNC)(SOCKET, void*, size_t,int); +typedef ssize_t (*SEND_FUNC)(SOCKET, const void*, size_t,int); + +RECV_FUNC _gnutls_recv_func; +SEND_FUNC _gnutls_send_func; static node_asn *PKIX1_ASN; static node_asn *PKCS1_ASN; @@ -45,8 +49,8 @@ node_asn* _gnutls_get_pkcs() { } /** - * gnutls_set_recv_func - This function sets the recv() function - * @(*recv_func): it's a recv(2) like function + * gnutls_global_set_recv_func - This function sets the recv() function + * @recv_func: it's a recv(2) like function * * This is the function were you set the recv() function gnutls * is going to use. Normaly you may not use this function since @@ -56,13 +60,13 @@ node_asn* _gnutls_get_pkcs() { * called once and after gnutls_global_init(). * **/ -void gnutls_set_recv_func( ssize_t (*recv_func)(SOCKET,void*,size_t,int)) { +void gnutls_global_set_recv_func( RECV_FUNC recv_func) { _gnutls_recv_func = recv_func; } /** - * gnutls_set_send_func - This function sets the send() function - * @(*send_func): it's a send(2) like function + * gnutls_global_set_send_func - This function sets the send() function + * @send_func: it's a send(2) like function * * This is the function were you set the send() function gnutls * is going to use. Normaly you may not use this function since @@ -71,7 +75,7 @@ void gnutls_set_recv_func( ssize_t (*recv_func)(SOCKET,void*,size_t,int)) { * a front end to this function. This function should be * called once and after gnutls_global_init(). **/ -void gnutls_set_send_func( ssize_t (*send_func)(SOCKET, const void*,size_t,int)) { +void gnutls_global_set_send_func( SEND_FUNC send_func) { _gnutls_send_func = send_func; } diff --git a/lib/gnutls_handshake.c b/lib/gnutls_handshake.c index e46b4958bc..433aa4248c 100644 --- a/lib/gnutls_handshake.c +++ b/lib/gnutls_handshake.c @@ -1421,10 +1421,11 @@ static int _gnutls_recv_handshake_final(SOCKET cd, GNUTLS_STATE state, int init) { int ret = 0; + char ch; ret = gnutls_recv_int(cd, state, GNUTLS_CHANGE_CIPHER_SPEC, -1, - NULL, 0, 0); + &ch, 1, 0); if (ret < 0) { ERR("recv ChangeCipherSpec", ret); gnutls_assert(); diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h index 0cbe811de3..19a8bf04e9 100644 --- a/lib/gnutls_int.h +++ b/lib/gnutls_int.h @@ -31,8 +31,9 @@ #define BUFFERS_DEBUG #define RECORD_DEBUG #define HANDSHAKE_DEBUG -#define DEBUG */ +#define DEBUG + #define SOCKET int #define LIST ... diff --git a/lib/gnutls_record.c b/lib/gnutls_record.c index 82491ba7c6..c9fa9f01e2 100644 --- a/lib/gnutls_record.c +++ b/lib/gnutls_record.c @@ -562,7 +562,6 @@ ssize_t gnutls_recv_int(SOCKET cd, GNUTLS_STATE state, ContentType type, Handsha if (state->gnutls_internals.valid_connection == VALID_FALSE || sizeofdata==0) { return 0; /* EOF */ -/* return GNUTLS_E_INVALID_SESSION; */ } /* in order for GNUTLS_E_AGAIN to be returned the socket @@ -729,11 +728,14 @@ ssize_t gnutls_recv_int(SOCKET cd, GNUTLS_STATE state, ContentType type, Handsha #endif gnutls_free(ciphertext); gnutls_free(tmpdata); - if (tmplen!=1) { + + if (tmplen!=sizeofdata) { /* sizeofdata should be 1 */ gnutls_assert(); return GNUTLS_E_UNEXPECTED_PACKET_LENGTH; } - return 0; + memcpy( data, tmpdata, sizeofdata); + + return tmplen; } #ifdef RECORD_DEBUG diff --git a/lib/gnutls_sig_check.c b/lib/gnutls_sig_check.c index de1b89e6c3..ec249bdfef 100644 --- a/lib/gnutls_sig_check.c +++ b/lib/gnutls_sig_check.c @@ -168,10 +168,6 @@ _gnutls_pkcs1_rsa_verify_sig( gnutls_datum* signature, gnutls_datum* text, MPI e return ret; } -#ifdef DEBUG -fprintf(stderr, "digest_size: %s\n", _gnutls_bin2hex(digest,digest_size)); -#endif - gnutls_free_datum( &decrypted); if (digest_size != gnutls_hash_get_algo_len(hash)) { @@ -182,9 +178,7 @@ fprintf(stderr, "digest_size: %s\n", _gnutls_bin2hex(digest,digest_size)); hd = gnutls_hash_init( hash); gnutls_hash( hd, text->data, text->size); gnutls_hash_deinit( hd, md); -#ifdef DEBUG - fprintf(stderr, "cmd: %s\n", _gnutls_bin2hex(md, 16)); -#endif + if (memcmp( md, digest, digest_size)!=0) { gnutls_assert(); return GNUTLS_E_PK_SIGNATURE_FAILED; @@ -216,7 +210,7 @@ gnutls_datum* tbs; return GNUTLS_CERT_TRUSTED; } #ifdef DEBUG -fprintf(stderr, "PK: %d\n", issuer->subject_pk_algorithm); + fprintf(stderr, "PK: %d\n", issuer->subject_pk_algorithm); #endif gnutls_assert(); |