summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2001-07-28 10:36:46 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2001-07-28 10:36:46 +0000
commit4945ad1a3eb49c1321cda580c7ed8eddc769e511 (patch)
tree110632ba180bf666262578ccf3d043f306488afc
parentf5eee1a355387fe8885f7b1e13f0f8260ddb8162 (diff)
downloadgnutls-4945ad1a3eb49c1321cda580c7ed8eddc769e511.tar.gz
added some documentation. Bug fixes in CHANGECIPHER_SPEC packet.
-rw-r--r--doc/API-template.html193
-rw-r--r--doc/Makefile.am12
-rwxr-xr-xdoc/scripts/gdoc2
-rw-r--r--lib/gnutls.h.in10
-rw-r--r--lib/gnutls_errors.c2
-rw-r--r--lib/gnutls_errors_int.h1
-rw-r--r--lib/gnutls_global.c20
-rw-r--r--lib/gnutls_handshake.c3
-rw-r--r--lib/gnutls_int.h3
-rw-r--r--lib/gnutls_record.c8
-rw-r--r--lib/gnutls_sig_check.c10
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">&nbsp</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">&nbsp</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">&nbsp</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'} . "\">&nbsp</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();