next_inactive up previous


GNUTLS

a Transport Layer Security Library
This document applies to GNUTLS 0.2.3


By Nikos Mavroyanopoulos and Fabio Fiorina


Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts and no Back-Cover Texts. A copy of the license is included in the chapter entitled "GNU Free Documentation License".


Contents

The Library

Introduction

GNUTLS is a portable library which implements the TLS 1.0 and SSL 3.0 protocols. TLS stands for 'Transport Layer Security' and is the sucessor of SSL1.1. TLS 1.01.2 is an Internet protocol, defined by IETF1.3that provides confidentiality, and authentication layers over a reliable transport layer1.4. GNUTLS implements the above protocols in reentrant way in order to be used in multiple threads of execution (without the need for Critical Sections).

Currently GNUTLS implements:

Confidentiality

Confidentiality is provided by using symmetric encryption algorithms like 3DES, AES1.5, or stream algorithms like ARCFOUR1.6. A symmetric encryption algorithm uses a single (secret) key to encrypt and decrypt data. Block algorithms in TLS also provide protection against statistical analysis of the data. GNUTLS makes use of this property thus, if you're operating in TLS 1.0 mode, a random number of blocks will be appended to the data. This will prevent eavesdroppers from guessing the actual data size.

Authentication

The following authentication schemas are supported in GNUTLS :

  1. X509 Public Key Infrastructure
  2. Anonymous authentication
  3. SRP authentication

Client Examples

This section contains examples of TLS and SSL clients, using GNUTLS .

Simple Client example with X509 Authentication

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 any other fancy features.
#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 = "443";
   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));
   if (err < 0) {
      fprintf(stderr, "Connect error\n");
      exit(1);
   }
   /* Initialize 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_REHANDSHAKE)
         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, GNUTLS_SHUT_RDWR);

 end:

   shutdown(sd, SHUT_RDWR);     /* no more receptions */
   close(sd);

   gnutls_deinit(state);

   gnutls_free_x509_client_sc(xcred);

   gnutls_global_deinit();

   return 0;
}

Getting peer's information

The above example was the simplest form of a client, it didn't even check the result of the peer's certificate verification function (ie. if we have an authenticated connection). The following function does check the peer's X509 Certificate, and prints some information about the current state.

This function should be called after a successful gnutls_handshake()

#define PRINTX(x,y) if (y[0]!=0) printf(" -   %s %s\n", x, y)
#define PRINT_DN(X) PRINTX( "CN:", X->common_name); \
	PRINTX( "OU:", X->organizational_unit_name); \
	PRINTX( "O:", X->organization); \
	PRINTX( "L:", X->locality_name); \
	PRINTX( "S:", X->state_or_province_name); \
	PRINTX( "C:", X->country); \
	PRINTX( "E:", X->email); \
	PRINTX( "SAN:", gnutls_x509pki_client_get_subject_dns_name(x509_info))

int print_info(GNUTLS_STATE state)
{
   const char *tmp;
   X509PKI_CLIENT_AUTH_INFO x509_info;
   const gnutls_DN* dn;

   /* print the key exchange's algorithm name
    */
   tmp = gnutls_kx_get_name(gnutls_get_current_kx(state));
   printf("- Key Exchange: %s\n", tmp);

   /* in case of X509 PKI
    */
   if (gnutls_get_auth_info_type(state) == GNUTLS_X509PKI) {
      x509_info = gnutls_get_auth_info(state);
      if (x509_info != NULL) {
         switch ( gnutls_x509pki_client_get_peer_certificate_status(x509_info)) {
         case GNUTLS_CERT_NOT_TRUSTED:
            printf("- Peer's X509 Certificate was NOT verified\n");
            break;
         case GNUTLS_CERT_EXPIRED:
            printf("- Peer's X509 Certificate was verified but is expired\n");
            break;
         case GNUTLS_CERT_TRUSTED:
            printf("- Peer's X509 Certificate was verified\n");
            break;
         case GNUTLS_CERT_NONE:
            printf("- Peer did not send any X509 Certificate.\n");
            break;
         case GNUTLS_CERT_INVALID:
         default:
            printf("- Peer's X509 Certificate was invalid\n");
            break;

         }
         printf(" - Certificate info:\n");
         printf(" - Certificate version: #%d\n", gnutls_x509pki_client_get_peer_certificate_version(x509_info));

         dn = gnutls_x509pki_client_get_peer_dn( x509_info);
         PRINT_DN(dn);

         printf(" - Certificate Issuer's info:\n");
         dn = gnutls_x509pki_client_get_issuer_dn( x509_info);
         PRINT_DN(dn);
      }
   }

   tmp = gnutls_version_get_name(gnutls_get_current_version(state));
   printf("- Version: %s\n", tmp);

   tmp = gnutls_compression_get_name(gnutls_get_current_compression_method(state));
   printf("- Compression: %s\n", tmp);

   tmp = gnutls_cipher_get_name(gnutls_get_current_cipher(state));
   printf("- Cipher: %s\n", tmp);

   tmp = gnutls_mac_get_name(gnutls_get_current_mac_algorithm(state));
   printf("- MAC: %s\n", tmp);

   return 0;
}

Resuming Sessions

The gnutls_handshake() function, is expensive since a lot of calculations are performed. In order to support many fast connections to the same server a client may use session resuming. Session resuming is a feature of the TLS protocol which allows a client to connect to a server, after a successful handshake, without the expensive calculations (ie. use the previously established keys). GNUTLS supports this feature, and this example illustrates a typical use of it (This is a modification of the simple client example).

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.

#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 = "443";
   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;
   /* variables used in session resuming */
   int t;
   char *session;
   char *session_id;
   int session_size;
   int session_id_size;
   char *tmp_session_id;
   int tmp_session_id_size;

   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);
   }
   gnutls_set_x509_client_trust(xcred, CAFILE, CRLFILE);

   for (t = 0; t < 2; t++) {    /* connect 2 times to the 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));
      if (err < 0) {
         fprintf(stderr, "Connect error");
         exit(1);
      }
      gnutls_init(&state, GNUTLS_CLIENT);
      gnutls_set_protocol_priority(state, GNUTLS_TLS1, GNUTLS_SSL3, 0);
      gnutls_set_cipher_priority(state, GNUTLS_3DES_CBC, GNUTLS_ARCFOUR, 0);
      gnutls_set_compression_priority(state, GNUTLS_NULL_COMPRESSION, 0);
      gnutls_set_kx_priority(state, GNUTLS_KX_RSA, 0);
      gnutls_set_mac_priority(state, GNUTLS_MAC_SHA, GNUTLS_MAC_MD5, 0);


      gnutls_set_cred(state, GNUTLS_X509PKI, xcred);

      if (t > 0) { /* if this is not the first time we connect */
         gnutls_set_current_session(state, session, session_size);
         free(session);
      }
      /* 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");
      }

      if (t == 0) { /* the first time we connect */
         /* get the session data size */
         gnutls_get_current_session(state, NULL, &session_size);
         session = malloc(session_size);

         /* put session data to the session variable */
         gnutls_get_current_session(state, session, &session_size);

         /* keep the current session ID. This is only needed
          * in order to check if the server actually resumed this
          * connection.
          */
         gnutls_get_current_session_id(state, NULL, &session_id_size);
         session_id = malloc(session_id_size);
         gnutls_get_current_session_id(state, session_id, &session_id_size);

      } else { /* the second time we connect */

         /* check if we actually resumed the previous session */
         gnutls_get_current_session_id(state, NULL, &tmp_session_id_size);
         tmp_session_id = malloc(tmp_session_id_size);
         gnutls_get_current_session_id(state, tmp_session_id, &tmp_session_id_size);

         if (memcmp(tmp_session_id, session_id, session_id_size) == 0) {
            printf("- Previous session was resumed\n");
         } else {
            fprintf(stderr, "*** Previous session was NOT resumed\n");
         }
         free(tmp_session_id);
         free(session_id);
      }

      /* This function was defined in a previous example
       */
      print_info(state);

      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_REHANDSHAKE)
            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, GNUTLS_SHUT_RDWR);

    end:

      shutdown(sd, SHUT_RDWR);  /* no more receptions */
      close(sd);

      gnutls_deinit(state);

   }  /* for() */

   gnutls_free_x509_client_sc(xcred);

   gnutls_global_deinit();

   return 0;
}

Simple Client example with SRP Authentication

Although SRP is not part of the TLS standard, GNUTLS implements David Taylor's1.7 proposal for using SRP algorithm within the TLS handshake protocol. The following client is a very simple SRP-TLS client which connects to a server and authenticates using username and password.

#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 USERNAME "user"
#define PASSWORD "pass"
#define SA struct sockaddr
#define MSG "GET / HTTP/1.0\r\n\r\n"

int main()
{
   const char *PORT = "443";
   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];
   SRP_CLIENT_CREDENTIALS xcred;

   if (gnutls_global_init() < 0) {
      fprintf(stderr, "global state initialization error\n");
      exit(1);
   }
   if (gnutls_allocate_srp_client_sc(&xcred) < 0) {
      fprintf(stderr, "memory error\n");
      exit(1);
   }
   gnutls_set_srp_client_cred(xcred, USERNAME, PASSWORD);

   /* 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));
   if (err < 0) {
      fprintf(stderr, "Connect error\n");
      exit(1);
   }
   /* Initialize 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_SRP, 0);

   /* allow the usage of both SHA and MD5
    */
   gnutls_set_mac_priority(state, GNUTLS_MAC_SHA, GNUTLS_MAC_MD5, 0);


   /* put the SRP credentials to the current state
    */
   gnutls_set_cred(state, GNUTLS_SRP, 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_REHANDSHAKE)
         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_srp_client_sc(xcred);

   gnutls_global_deinit();

   return 0;
}

Server Examples

This section contains examples of TLS and SSL servers, using GNUTLS .

Echo Server with X509 and SRP authentication

The following example is a server which supports both SRP and X509 authentication. This server also supports session resuming.
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <gnutls.h>

#define KEYFILE "key.pem"
#define CERTFILE "cert.pem"
#define CAFILE "ca.pem"
#define CRLFILE NULL

#define SRP_PASSWD "tpasswd"
#define SRP_PASSWD_CONF "tpasswd.conf"


/* This is a sample TCP echo server.
 */


#define SA struct sockaddr
#define ERR(err,s) if(err==-1) {perror(s);return(1);}
#define MAX_BUF 1024
#define PORT 5556               /* listen to 5556 port */

/* These are global */
SRP_SERVER_CREDENTIALS srp_cred;
X509PKI_SERVER_CREDENTIALS x509_cred;

GNUTLS_STATE initialize_state()
{
   GNUTLS_STATE state;
   int ret;

   gnutls_init(&state, GNUTLS_SERVER);

   /* in order to support session resuming:
    */
   if ((ret = gnutls_set_db_name(state, "gnutls-rsm.db")) < 0)
      fprintf(stderr, "*** DB error (%d)\n\n", ret);

   gnutls_set_cipher_priority(state, GNUTLS_RIJNDAEL_CBC, GNUTLS_3DES_CBC, 0);
   gnutls_set_compression_priority(state, GNUTLS_ZLIB, GNUTLS_NULL_COMPRESSION, 0);
   gnutls_set_kx_priority(state, GNUTLS_KX_RSA, GNUTLS_KX_SRP, 0);
   gnutls_set_protocol_priority(state, GNUTLS_TLS1, GNUTLS_SSL3, 0);
   gnutls_set_mac_priority(state, GNUTLS_MAC_SHA, GNUTLS_MAC_MD5, 0);

   gnutls_set_cred(state, GNUTLS_SRP, srp_cred);
   gnutls_set_cred(state, GNUTLS_X509PKI, x509_cred);

   /* request client certificate if any.
    */
   gnutls_x509pki_set_cert_request( state, GNUTLS_CERT_REQUEST);
   
   return state;
}

void print_info(GNUTLS_STATE state)
{
   SRP_SERVER_AUTH_INFO srp_info;
   const char *tmp;
   unsigned char sesid[32];
   int sesid_size, i;

   /* print session_id specific data */
   gnutls_get_current_session_id(state, sesid, &sesid_size);
   printf("\n- Session ID: ");
   for (i = 0; i < sesid_size; i++)
      printf("%.2X", sesid[i]);
   printf("\n");

   /* print srp specific data */
   if (gnutls_get_auth_info_type(state) == GNUTLS_SRP) {
      srp_info = gnutls_get_auth_info(state);
      if (srp_info != NULL)
         printf("\n- User '%s' connected\n",
                gnutls_srp_server_get_username(srp_info));
   }
   /* print state information */
   tmp = gnutls_version_get_name(gnutls_get_current_version(state));
   printf("- Version: %s\n", tmp);

   tmp = gnutls_kx_get_name(gnutls_get_current_kx(state));
   printf("- Key Exchange: %s\n", tmp);

   tmp =
       gnutls_compression_get_name
       (gnutls_get_current_compression_method(state));
   printf("- Compression: %s\n", tmp);

   tmp = gnutls_cipher_get_name(gnutls_get_current_cipher(state));
   printf("- Cipher: %s\n", tmp);

   tmp = gnutls_mac_get_name(gnutls_get_current_mac_algorithm(state));
   printf("- MAC: %s\n", tmp);

}



int main()
{
   int err, listen_sd, i;
   int sd, ret;
   struct sockaddr_in sa_serv;
   struct sockaddr_in sa_cli;
   int client_len;
   char topbuf[512];
   GNUTLS_STATE state;
   char buffer[MAX_BUF + 1];
   int optval = 1;
   int http = 0;
   char name[256];

   strcpy(name, "Echo Server");

   /* this must be called once in the program
    */
   if (gnutls_global_init() < 0) {
      fprintf(stderr, "global state initialization error\n");
      exit(1);
   }
   if (gnutls_allocate_x509_server_sc(&x509_cred, 1) < 0) {
      fprintf(stderr, "memory error\n");
      exit(1);
   }
   if (gnutls_set_x509_server_trust(x509_cred, CAFILE, CRLFILE) < 0) {
      fprintf(stderr, "X509 PARSE ERROR\nDid you have ca.pem?\n");
      exit(1);
   }
   if (gnutls_set_x509_server_key(x509_cred, CERTFILE, KEYFILE) < 0) {
      fprintf(stderr, "X509 PARSE ERROR\nDid you have key.pem and cert.pem?\n");
      exit(1);
   }
   /* SRP_PASSWD a password file (created with the included crypt utility) 
    * Read README.crypt prior to using SRP.
    */
   gnutls_allocate_srp_server_sc(&srp_cred);
   gnutls_set_srp_server_cred(srp_cred, SRP_PASSWD, SRP_PASSWD_CONF);


   /* Socket operations
    */
   listen_sd = socket(AF_INET, SOCK_STREAM, 0);
   ERR(listen_sd, "socket");

   memset(&sa_serv, '\0', sizeof(sa_serv));
   sa_serv.sin_family = AF_INET;
   sa_serv.sin_addr.s_addr = INADDR_ANY;
   sa_serv.sin_port = htons(PORT);  /* Server Port number */

   setsockopt(listen_sd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(int));

   err = bind(listen_sd, (SA *) & sa_serv, sizeof(sa_serv));
   ERR(err, "bind");
   err = listen(listen_sd, 1024);
   ERR(err, "listen");

   printf("%s ready. Listening to port '%d'.\n\n", name, PORT);

   client_len = sizeof(sa_cli);
   for (;;) {
      state = initialize_state();

      sd = accept(listen_sd, (SA *) & sa_cli, &client_len);

      printf("- connection from %s, port %d\n",
             inet_ntop(AF_INET, &sa_cli.sin_addr, topbuf,
                       sizeof(topbuf)), ntohs(sa_cli.sin_port));


      ret = gnutls_handshake(sd, state);
      if (ret < 0) {
         close(sd);
         gnutls_deinit(state);
         fprintf(stderr, "*** Handshake has failed (%s)\n\n",
                 gnutls_strerror(ret));
         continue;
      }
      printf("- Handshake was completed\n");

      print_info(state);

      i = 0;
      for (;;) {
         bzero(buffer, MAX_BUF + 1);
         ret = gnutls_read(sd, state, buffer, MAX_BUF);

         if (gnutls_is_fatal_error(ret) == 1 || ret == 0) {
            if (ret == 0) {
               printf
                   ("\n- Peer has closed the GNUTLS connection\n");
               break;
            } else {
               fprintf(stderr,
                       "\n*** Received corrupted data(%d). Closing the connection.\n\n",
                       ret);
               break;
            }

         }
         if (ret > 0) {
            /* echo data back to the client
             */
            gnutls_write(sd, state, buffer,
                         strlen(buffer));
         }
         if (ret == GNUTLS_E_WARNING_ALERT_RECEIVED || ret == GNUTLS_E_FATAL_ALERT_RECEIVED) {
            ret = gnutls_get_last_alert(state);
            printf("* Received alert '%d'.\n", ret);
         }
      }
      printf("\n");
      gnutls_bye(sd, state, 1); /* do not wait for
                                 * the peer to close the connection.
                                 */

      close(sd);
      gnutls_deinit(state);

   }
   close(listen_sd);

   gnutls_free_x509_server_sc(x509_cred);
   gnutls_free_srp_server_sc(srp_cred);

   gnutls_global_deinit();

   return 0;

}

Function Reference


gnutls_set_lowat

int gnutls_set_lowat ( GNUTLS_STATE state , int num )

Arguments

Description

Used to set the lowat value in order for select to check if there are pending data to socket buffer. Used only if you have changed the default low water value (default is 1). Normally you will not need that function. If you plan to use non standard recv() function you should set this to zero.


gnutls_init

int gnutls_init ( GNUTLS_STATE * state , ConnectionEnd con_end )

Arguments

Description

This function initializes the current state to null. Every state must be initialized before use, so internal structures can be allocated. This function allocates structures which can only be free'd by calling gnutls_deinit(). Returns zero on success.


gnutls_deinit

int gnutls_deinit ( GNUTLS_STATE state )

Arguments

Description

This function clears all buffers associated with the &state.


gnutls_send_alert

int gnutls_send_alert ( SOCKET cd , GNUTLS_STATE state , AlertLevel level , AlertDescription desc )

Arguments

Description

This function will send an alert to the peer in order to inform him of something important (eg. his Certificate could not be verified). If the alert level is Fatal then the peer is expected to close the connection, otherwise he may ignore the alert and continue. Returns 0 on success.


gnutls_bye

int gnutls_bye ( SOCKET cd , GNUTLS_STATE state , CloseRequest how )

Arguments

Description

Terminates the current TLS/SSL connection. The connection should have been initiated using gnutls_handshake(). 'how' should be one of GNUTLS_SHUT_RDWR, GNUTLS_SHUT_WR.

in case of GNUTLS_SHUT_RDWR then the connection gets terminated and further receives and sends will be disallowed. If the return value is zero you may continue using the TCP connection.

in case of GNUTLS_SHUT_WR then the connection gets terminated and further sends will be disallowed. In order to reuse the TCP connection you should wait for an EOF from the peer.


gnutls_get_current_cipher

BulkCipherAlgorithm gnutls_get_current_cipher ( GNUTLS_STATE state )

Arguments

Description

Returns the currently used cipher.


gnutls_get_current_kx

KXAlgorithm gnutls_get_current_kx ( GNUTLS_STATE state )

Arguments

Description

Returns the key exchange algorithm used in the last handshake.


gnutls_get_current_mac_algorithm

MACAlgorithm gnutls_get_current_mac_algorithm ( GNUTLS_STATE state )

Arguments

Description

Returns the currently used mac algorithm.


gnutls_get_current_compression_method

CompressionMethod gnutls_get_current_compression_method ( GNUTLS_STATE state )

Arguments

Description

Returns the currently used compression method.


gnutls_get_last_alert

AlertDescription gnutls_get_last_alert ( GNUTLS_STATE state )

Arguments

Description

Returns the last alert number received. This function should be called if GNUTLS_E_WARNING_ALERT_RECEIVED or GNUTLS_E_FATAL_ALERT_RECEIVED has been returned by a gnutls function. The peer may send alerts if he thinks some things were not right. Check gnutls.h for the available alert descriptions.


gnutls_send

ssize_t gnutls_send ( SOCKET cd , GNUTLS_STATE state , const void * data , size_t sizeofdata , int flags )

Arguments

Description

This function has the same semantics as send() has. The only difference is that is accepts a GNUTLS state. Currently flags cannot be anything except 0.


gnutls_recv

ssize_t gnutls_recv ( SOCKET cd , GNUTLS_STATE state , void * data , size_t sizeofdata , int flags )

Arguments

Description

This function has the same semantics as recv() has. The only difference is that is accepts a GNUTLS state. Flags are the flags passed to recv() and should be used with care in gnutls. The only acceptable flag is currently MSG_DONTWAIT. In that case, if the socket is set to non blocking IO it will return GNUTLS_E_AGAIN, if there are no data in the socket. Returns the number of bytes received, zero on EOF, or a negative error code.


gnutls_write

ssize_t gnutls_write ( SOCKET cd , GNUTLS_STATE state , const void * data , size_t sizeofdata )

Arguments

Description

This function has the same semantics as write() has. The only difference is that is accepts a GNUTLS state.


gnutls_read

ssize_t gnutls_read ( SOCKET cd , GNUTLS_STATE state , void * data , size_t sizeofdata )

Arguments

Description

This function has the same semantics as read() has. The only difference is that is accepts a GNUTLS state. Returns the number of bytes received, zero on EOF, or a negative error code.


gnutls_check_pending

int gnutls_check_pending ( GNUTLS_STATE state )

Arguments

Description

This function checks if there are any data to receive in the gnutls buffers. Returns the size of that data or 0. Notice that you may also use select() to check for data in the TCP connection, instead of this function. (gnutls leaves some data in the tcp buffer in order for select to work).


gnutls_rehandshake

int gnutls_rehandshake ( SOCKET cd , GNUTLS_STATE state )

Arguments

Description

This function will renegotiate security parameters with the client. This should only be called in case of a server. If the client does not wish to renegotiate parameters he will reply with an alert message, thus the return code will be GNUTLS_E_WARNING_ALERT_RECEIVED and the alert will be GNUTLS_NO_RENEGOTIATION.


gnutls_handshake

int gnutls_handshake ( SOCKET cd , GNUTLS_STATE state )

Arguments

Description

This function does the handshake of the TLS/SSL protocol, and initializes the TLS connection. Here the identity of the peer is checked automatically. This function will fail if any problem is encountered, and the connection should be terminated.


gnutls_is_fatal_error

int gnutls_is_fatal_error ( int error )

Arguments

Description

If a function returns a negative value you may feed that value to this function to see if it is fatal. Returns 1 for a fatal error 0 otherwise. However you may want to check the error code manualy, since some non-fatal errors to the protocol may be fatal for you (your program).


gnutls_perror

void gnutls_perror ( int error )

Arguments

Description

This function is like perror(). However it accepts an error returned by a gnutls function.


gnutls_strerror

const char* gnutls_strerror ( int error )

Arguments

Description

This function is similar to strerror(). The only difference is that it accepts an error (number) returned by a gnutls function.


gnutls_mac_get_name

const char * gnutls_mac_get_name ( MACAlgorithm algorithm )

Arguments

Description

Returns a string that contains the name of the specified MAC algorithm.


gnutls_compression_get_name

const char * gnutls_compression_get_name ( CompressionMethod algorithm )

Arguments

Description

Returns a pointer to a string that contains the name of the specified compression algorithm.


gnutls_cipher_get_name

const char * gnutls_cipher_get_name ( BulkCipherAlgorithm algorithm )

Arguments

Description

Returns a pointer to a string that contains the name of the specified cipher.


gnutls_kx_get_name

const char * gnutls_kx_get_name ( KXAlgorithm algorithm )

Arguments

Description

Returns a pointer to a string that contains the name of the specified key exchange algorithm.


gnutls_version_get_name

const char * gnutls_version_get_name ( GNUTLS_Version version )

Arguments

Description

Returns a string that contains the name of the specified TLS version.


gnutls_set_cipher_priority

int gnutls_set_cipher_priority ( GNUTLS_STATE state , LIST )

Arguments

Description

Sets the priority on the ciphers supported by gnutls. Priority is higher for ciphers specified before others. After specifying the ciphers you want, you should add 0. Note that the priority is set on the client. The server does not use the algorithm's priority except for disabling algorithms that were not specified.


gnutls_set_kx_priority

int gnutls_set_kx_priority ( GNUTLS_STATE state , LIST )

Arguments

Description

Sets the priority on the key exchange algorithms supported by gnutls. Priority is higher for algorithms specified before others. After specifying the algorithms you want, you should add 0. Note that the priority is set on the client. The server does not use the algorithm's priority except for disabling algorithms that were not specified.


gnutls_set_mac_priority

int gnutls_set_mac_priority ( GNUTLS_STATE state , LIST )

Arguments

Description

Sets the priority on the mac algorithms supported by gnutls. Priority is higher for algorithms specified before others. After specifying the algorithms you want, you should add 0. Note that the priority is set on the client. The server does not use the algorithm's priority except for disabling algorithms that were not specified.


gnutls_set_compression_priority

int gnutls_set_compression_priority ( GNUTLS_STATE state , LIST )

Arguments

Description

Sets the priority on the compression algorithms supported by gnutls. Priority is higher for algorithms specified before others. After specifying the algorithms you want, you should add 0. Note that the priority is set on the client. The server does not use the algorithm's priority except for disabling algorithms that were not specified.


gnutls_set_protocol_priority

int gnutls_set_protocol_priority ( GNUTLS_STATE state , LIST )

Arguments

Description

Sets the priority on the protocol versions supported by gnutls. Priority is higher for protocols specified before others. After specifying the protocols you want, you should add 0. Note that the priority is set on the client. The server does not use the protocols's priority except for disabling protocols that were not specified.


gnutls_get_current_session

int gnutls_get_current_session ( GNUTLS_STATE state , opaque* session , int * session_size )

Arguments

Description

Returns all session parameters - in order to support resuming. The client should call this - and keep the returned session - if he wants to resume that current version later by calling gnutls_set_current_session() This function must be called after a successful handshake.

Resuming sessions is really useful and speedups connections after a succesful one.


gnutls_get_current_session_id

int gnutls_get_current_session_id ( GNUTLS_STATE state , void* session , int * session_size )

Arguments

Description

Returns the current session id. This can be used if you want to check if the next session you tried to resume was actually resumed. (resumed sessions have the same sessionID with the first session)

Session id is some data set by the server, that identify the current session. In TLS 1.0 session id should not be more than 32 bytes.


gnutls_set_current_session

int gnutls_set_current_session ( GNUTLS_STATE state , opaque* session , int session_size )

Arguments

Description

Sets all session parameters - in order to support resuming session must be the one returned by gnutls_get_current_session(); This function should be called before gnutls_handshake(). Keep in mind that session resuming is advisory. The server may choose not to resume the session, thus a full handshake will be performed.


gnutls_set_cache_expiration

int gnutls_set_cache_expiration ( GNUTLS_STATE state , int seconds )

Arguments

Description

Sets the expiration time for resumed sessions. The default is 3600 (one hour) at the time writing this.


gnutls_set_db_name

int gnutls_set_db_name ( GNUTLS_STATE state , char* filename )

Arguments

Description

Sets the name of the (gdbm) database to be used to keep the sessions to be resumed. This function also creates the database - if it does not exist - and opens it for reading.


gnutls_clean_db

int gnutls_clean_db ( GNUTLS_STATE state )

Arguments

Description

This function Deletes all expired records in the resumed sessions' database. This database may become huge if this function is not called. (this function is also quite expensive)


gnutls_ext_get_dnsname

const char* gnutls_ext_get_dnsname ( GNUTLS_STATE state )

Arguments

Description

This function is to be used by servers that support virtual hosting. The client may give the server the dnsname they connected to. if no name was given this function returns NULL.


gnutls_ext_set_dnsname

int gnutls_ext_set_dnsname ( GNUTLS_STATE state , const char* dnsname )

Arguments

Description

This function is to be used by clients that want to inform ( via a TLS extension mechanism) the server of the name they connected to. This should be used by clients that connect to servers that do virtual hosting.


gnutls_set_cred

int gnutls_set_cred ( GNUTLS_STATE state , CredType type , void* cred )

Arguments

Description

Sets the needed credentials for the specified type. Eg username, password - or public and private keys etc. The (void* cred) parameter is a structure that depends on the specified type and on the current state (client or server). [ In order to minimize memory usage, and share credentials between several threads gnutls keeps a pointer to cred, and not the whole cred structure. Thus you will have to keep the structure allocated until you call gnutls_deinit(). ]

For GNUTLS_ANON cred should be NULL in case of a client. In case of a server it should be ANON_SERVER_CREDENTIALS.

For GNUTLS_SRP cred should be SRP_CLIENT_CREDENTIALS in case of a client, and SRP_SERVER_CREDENTIALS, in case of a server.

For GNUTLS_X509PKI cred should be X509PKI_CLIENT_CREDENTIALS in case of a client, and X509PKI_SERVER_CREDENTIALS, in case of a server.


gnutls_get_auth_info_type

CredType gnutls_get_auth_info_type ( GNUTLS_STATE state )

Arguments

Description

Returns type of credentials for the current authentication schema. The returned information can be used to distinguish the appropriate structures for the gnutls_get_auth_info() function. Eg. if this function returns GNUTLS_X509PKI then the return type of gnutls_get_auth_info() will be X509PKI_(SERVER/CLIENT)_AUTH_INFO (depends on the side - client/server)


gnutls_get_auth_info

void* gnutls_get_auth_info ( GNUTLS_STATE state )

Arguments

Description

This function must be called after a succesful gnutls_handshake(). Returns a pointer to authentication information. That information is data obtained by the handshake protocol, the key exchange algorithm, and the TLS extensions messages.

In case of GNUTLS_ANON returns a pointer to &ANON_(SERVER/CLIENT)_AUTH_INFO; In case of GNUTLS_X509PKI returns a pointer to structure &X509PKI_(SERVER/CLIENT)_AUTH_INFO; In case of GNUTLS_SRP returns a pointer to structure &SRP_(SERVER/CLIENT)_AUTH_INFO;


gnutls_free_srp_client_sc

void gnutls_free_srp_client_sc ( SRP_CLIENT_CREDENTIALS sc )

Arguments

Description

This structure is complex enough to manipulate directly thus this helper function is provided in order to free (deallocate) the structure.


gnutls_allocate_srp_client_sc

int gnutls_allocate_srp_client_sc ( SRP_CLIENT_CREDENTIALS * sc )

Arguments

Description

This structure is complex enough to manipulate directly thus this helper function is provided in order to allocate the structure.


gnutls_set_srp_client_cred

int gnutls_set_srp_client_cred ( SRP_CLIENT_CREDENTIALS res , char * username , char * password )

Arguments


gnutls_free_srp_server_sc

void gnutls_free_srp_server_sc ( SRP_SERVER_CREDENTIALS sc )

Arguments

Description

This structure is complex enough to manipulate directly thus this helper function is provided in order to free (deallocate) the structure.


gnutls_allocate_srp_server_sc

int gnutls_allocate_srp_server_sc ( SRP_SERVER_CREDENTIALS * sc )

Arguments

Description

This structure is complex enough to manipulate directly thus this helper function is provided in order to allocate the structure.


gnutls_set_srp_server_cred

int gnutls_set_srp_server_cred ( SRP_SERVER_CREDENTIALS res , char * password_file , char * password_conf_file )

Arguments


gnutls_free_x509_sc

void gnutls_free_x509_sc ( X509PKI_CREDENTIALS sc )

Arguments

Description

This structure is complex enough to manipulate directly thus this helper function is provided in order to free (deallocate) the structure.


gnutls_allocate_x509_sc

int gnutls_allocate_x509_sc ( X509PKI_CREDENTIALS * res , int ncerts )

Arguments

Description

This structure is complex enough to manipulate directly thus this helper function is provided in order to allocate the structure.


gnutls_set_x509_key

int gnutls_set_x509_key ( X509PKI_CREDENTIALS res , char * CERTFILE , char * KEYFILE )

Arguments

Description

This function sets a certificate/private key pair in the X509PKI_CREDENTIALS structure. This function may be called more than once (in case multiple keys/certificates exist for the server).

Currently only PKCS-1 PEM encoded RSA private keys are accepted by this function.


gnutls_set_x509_trust

int gnutls_set_x509_trust ( X509PKI_CREDENTIALS res , char * CAFILE , char * CRLFILE )

Arguments

Description

This function sets the trusted CAs in order to verify client certificates.


gnutls_x509pki_set_cert_request

int gnutls_x509pki_set_cert_request ( GNUTLS_STATE state , CertificateRequest req )

Arguments

Description

This function specifies if we (in case of a server) are going to send a certificate request message to the client. If 'req' is GNUTLS_CERT_REQUIRE then the server will return an error if the peer does not provide a certificate. If you do not call this function then the client will not be asked to send a certificate.


gnutls_set_x509_cert_callback

int gnutls_set_x509_cert_callback ( X509PKI_CREDENTIALS cred , int (*x509_cert_callback )

Arguments

Description

The callback's function form is: int (*callback)(gnutls_DN *client_cert, gnutls_DN *issuer_cert, int ncerts, gnutls_DN* req_ca_cert, int nreqs);

'client_cert' contains 'ncerts' gnutls_DN structures which hold DN data from the client certificate. 'issuer_cert' holds DN data for the issuer of the certificate. Ie. issuer_cert[i] is the issuer of client_cert[i]. (i < ncerts)

'req_ca_cert' contains a list with the CA certificates that the server considers trusted. Normaly we should send a certificate that is signed by one of these CAs.

This function specifies what we (in case of a client) are going to do when we have to send a certificate. If this callback function is not provided then gnutls will automaticaly try to find an appropriate certificate to send.

If the callback function is provided then gnutls will call it once with NULL parameters. If the callback function returns a positive or zero number then gnutls will attempt to automaticaly choose the appropriate certificate. If gnutls fails to find an appropriate certificate, then it will call the callback function again with the appropriate parameters.

In case the callback returned a negative number then gnutls will not attempt to choose the appropriate certificate and will call again the callback function with the appropriate parameters, and rely only to the return value of the callback function.

The callback function should return the index of the certificate choosen by the user (or -1 to indicate that the user does not want to use client authentication).

This function returns 0 on success.


gnutls_global_set_recv_func

void gnutls_global_set_recv_func ( RECV_FUNC recv_func )

Arguments

Description

This is the function were you set the recv() function gnutls is going to use. Normaly you may not use this function since the default (recv(2)) will probably be ok, unless you use some external library (like gnu pthreads), which provide a front end to this function. This function should be called once and after gnutls_global_init(). RECV_FUNC is of the form, ssize_t (*RECV_FUNC)(SOCKET, void*, size_t,int);


gnutls_global_set_send_func

void gnutls_global_set_send_func ( SEND_FUNC send_func )

Arguments

Description

This is the function were you set the send() function gnutls is going to use. Normaly you may not use this function since the default (send(2)) will probably be ok, unless you use some external library (like gnu pthreads), which provide a front end to this function. This function should be called once and after gnutls_global_init(). SEND_FUNC is of the form, ssize_t (*SEND_FUNC)(SOCKET, const void*, size_t,int);


gnutls_global_set_log_func

void gnutls_global_set_log_func ( LOG_FUNC log_func )

Arguments

Description

This is the function were 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 for debugging reasons. LOG_FUNC is of the form, void (*LOG_FUNC)( const char*);


gnutls_global_init

int gnutls_global_init ( )

Arguments

Description

This function initializes the global state to defaults. Every gnutls application has a global state which holds common parameters shared by gnutls state structures. You must call gnutls_global_deinit() when gnutls usage is no longer needed Returns zero on success.

If signals are supported in your system, this function sets SIGPIPE, to SIG_IGN. The old signal handler will be restored when calling gnutls_global_deinit().


gnutls_global_deinit

void gnutls_global_deinit ( )

Arguments

Description

This function deinitializes the global state.


gnutls_free_anon_server_sc

void gnutls_free_anon_server_sc ( ANON_SERVER_CREDENTIALS sc )

Arguments

Description

This structure is complex enough to manipulate directly thus this helper function is provided in order to free (deallocate) the structure.


gnutls_allocate_anon_server_sc

int gnutls_allocate_anon_server_sc ( ANON_SERVER_CREDENTIALS * sc )

Arguments

Description

This structure is complex enough to manipulate directly thus this helper function is provided in order to allocate the structure.


gnutls_set_anon_server_cred

int gnutls_set_anon_server_cred ( ANON_SERVER_CREDENTIALS res , int dh_bits )

Arguments


gnutls_srp_server_get_username

const char* gnutls_srp_server_get_username ( SRP_SERVER_AUTH_INFO info )

Arguments

Description

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.


gnutls_anon_server_get_dh_bits

int gnutls_anon_server_get_dh_bits ( ANON_SERVER_AUTH_INFO info )

Arguments

Description

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.


gnutls_anon_client_get_dh_bits

int gnutls_anon_client_get_dh_bits ( ANON_CLIENT_AUTH_INFO info )

Arguments

Description

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.


gnutls_x509pki_get_peer_dn

const gnutls_DN* gnutls_x509pki_get_peer_dn ( X509PKI_CLIENT_AUTH_INFO info )

Arguments

Description

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.


gnutls_x509pki_get_issuer_dn

const gnutls_DN* gnutls_x509pki_get_issuer_dn ( X509PKI_CLIENT_AUTH_INFO info )

Arguments

Description

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.


gnutls_x509pki_get_peer_certificate_status

CertificateStatus gnutls_x509pki_get_peer_certificate_status ( X509PKI_CLIENT_AUTH_INFO info )

Arguments

Description

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.


gnutls_x509pki_get_peer_certificate_version

int gnutls_x509pki_get_peer_certificate_version ( X509PKI_CLIENT_AUTH_INFO info )

Arguments

Description

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.


gnutls_x509pki_get_peer_certificate_activation_time

time_t gnutls_x509pki_get_peer_certificate_activation_time ( X509PKI_CLIENT_AUTH_INFO info )

Arguments

Description

This function will return the peer's certificate activation time in UNIX time (ie seconds since

00

00:00 UTC January 1, 1970).


gnutls_x509pki_get_peer_certificate_expiration_time

time_t gnutls_x509pki_get_peer_certificate_expiration_time ( X509PKI_CLIENT_AUTH_INFO info )

Arguments

Description

This function will return the peer's certificate expiration time in UNIX time (ie seconds since

00

00:00 UTC January 1, 1970).


gnutls_x509pki_get_key_usage

unsigned char gnutls_x509pki_get_key_usage ( X509PKI_CLIENT_AUTH_INFO info )

Arguments

Description

This function will return the peer's certificate key usage. This is specified in X509v3 Certificate Extensions and is an 8bit string.


gnutls_x509pki_get_certificate_request_status

unsigned char gnutls_x509pki_get_certificate_request_status ( X509PKI_CLIENT_AUTH_INFO info )

Arguments

Description

This function will return 0 if the peer (server) did not requested client authentication or 1 otherwise.


gnutls_x509pki_get_subject_dns_name

const char* gnutls_x509pki_get_subject_dns_name ( X509PKI_CLIENT_AUTH_INFO info )

Arguments

Description

This function will return the peer's alternative name (the dns part of it). This is specified in X509v3 Certificate Extensions. GNUTLS will only return the dnsName of the Alternative name, or a null string.

GNU Free Documentation License

Version 1.1, March 2000

Copyright © 2000 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.

Preamble

The purpose of this License is to make a manual, textbook, or other written document ``free'' in the sense of freedom: to assure everyone the effective freedom to copy and redistribute it, with or without modifying it, either commercially or noncommercially. Secondarily, this License preserves for the author and publisher a way to get credit for their work, while not being considered responsible for modifications made by others.

This License is a kind of ``copyleft'', which means that derivative works of the document must themselves be free in the same sense. It complements the GNU General Public License, which is a copyleft license designed for free software.

We have designed this License in order to use it for manuals for free software, because free software needs free documentation: a free program should come with manuals providing the same freedoms that the software does. But this License is not limited to software manuals; it can be used for any textual work, regardless of subject matter or whether it is published as a printed book. We recommend this License principally for works whose purpose is instruction or reference.

Applicability and Definitions

This License applies to any manual or other work that contains a notice placed by the copyright holder saying it can be distributed under the terms of this License. The ``Document'', below, refers to any such manual or work. Any member of the public is a licensee, and is addressed as ``you''.

A ``Modified Version'' of the Document means any work containing the Document or a portion of it, either copied verbatim, or with modifications and/or translated into another language.

A ``Secondary Section'' is a named appendix or a front-matter section of the Document that deals exclusively with the relationship of the publishers or authors of the Document to the Document's overall subject (or to related matters) and contains nothing that could fall directly within that overall subject. (For example, if the Document is in part a textbook of mathematics, a Secondary Section may not explain any mathematics.) The relationship could be a matter of historical connection with the subject or with related matters, or of legal, commercial, philosophical, ethical or political position regarding them.

The ``Invariant Sections'' are certain Secondary Sections whose titles are designated, as being those of Invariant Sections, in the notice that says that the Document is released under this License.

The ``Cover Texts'' are certain short passages of text that are listed, as Front-Cover Texts or Back-Cover Texts, in the notice that says that the Document is released under this License.

A ``Transparent'' copy of the Document means a machine-readable copy, represented in a format whose specification is available to the general public, whose contents can be viewed and edited directly and straightforwardly with generic text editors or (for images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor, and that is suitable for input to text formatters or for automatic translation to a variety of formats suitable for input to text formatters. A copy made in an otherwise Transparent file format whose markup has been designed to thwart or discourage subsequent modification by readers is not Transparent. A copy that is not ``Transparent'' is called ``Opaque''.

Examples of suitable formats for Transparent copies include plain ASCII without markup, Texinfo input format, LATEX input format, SGML or XML using a publicly available DTD, and standard-conforming simple HTML designed for human modification. Opaque formats include PostScript, PDF, proprietary formats that can be read and edited only by proprietary word processors, SGML or XML for which the DTD and/or processing tools are not generally available, and the machine-generated HTML produced by some word processors for output purposes only.

The ``Title Page'' means, for a printed book, the title page itself, plus such following pages as are needed to hold, legibly, the material this License requires to appear in the title page. For works in formats which do not have any title page as such, ``Title Page'' means the text near the most prominent appearance of the work's title, preceding the beginning of the body of the text.

Verbatim Copying

You may copy and distribute the Document in any medium, either commercially or noncommercially, provided that this License, the copyright notices, and the license notice saying this License applies to the Document are reproduced in all copies, and that you add no other conditions whatsoever to those of this License. You may not use technical measures to obstruct or control the reading or further copying of the copies you make or distribute. However, you may accept compensation in exchange for copies. If you distribute a large enough number of copies you must also follow the conditions in section 3.

You may also lend copies, under the same conditions stated above, and you may publicly display copies.

Copying in Quantity

If you publish printed copies of the Document numbering more than 100, and the Document's license notice requires Cover Texts, you must enclose the copies in covers that carry, clearly and legibly, all these Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover. Both covers must also clearly and legibly identify you as the publisher of these copies. The front cover must present the full title with all words of the title equally prominent and visible. You may add other material on the covers in addition. Copying with changes limited to the covers, as long as they preserve the title of the Document and satisfy these conditions, can be treated as verbatim copying in other respects.

If the required texts for either cover are too voluminous to fit legibly, you should put the first ones listed (as many as fit reasonably) on the actual cover, and continue the rest onto adjacent pages.

If you publish or distribute Opaque copies of the Document numbering more than 100, you must either include a machine-readable Transparent copy along with each Opaque copy, or state in or with each Opaque copy a publicly-accessible computer-network location containing a complete Transparent copy of the Document, free of added material, which the general network-using public has access to download anonymously at no charge using public-standard network protocols. If you use the latter option, you must take reasonably prudent steps, when you begin distribution of Opaque copies in quantity, to ensure that this Transparent copy will remain thus accessible at the stated location until at least one year after the last time you distribute an Opaque copy (directly or through your agents or retailers) of that edition to the public.

It is requested, but not required, that you contact the authors of the Document well before redistributing any large number of copies, to give them a chance to provide you with an updated version of the Document.

Modifications

You may copy and distribute a Modified Version of the Document under the conditions of sections 2 and 3 above, provided that you release the Modified Version under precisely this License, with the Modified Version filling the role of the Document, thus licensing distribution and modification of the Modified Version to whoever possesses a copy of it. In addition, you must do these things in the Modified Version:

If the Modified Version includes new front-matter sections or appendices that qualify as Secondary Sections and contain no material copied from the Document, you may at your option designate some or all of these sections as invariant. To do this, add their titles to the list of Invariant Sections in the Modified Version's license notice. These titles must be distinct from any other section titles.

You may add a section entitled ``Endorsements'', provided it contains nothing but endorsements of your Modified Version by various parties - for example, statements of peer review or that the text has been approved by an organization as the authoritative definition of a standard.

You may add a passage of up to five words as a Front-Cover Text, and a passage of up to 25 words as a Back-Cover Text, to the end of the list of Cover Texts in the Modified Version. Only one passage of Front-Cover Text and one of Back-Cover Text may be added by (or through arrangements made by) any one entity. If the Document already includes a cover text for the same cover, previously added by you or by arrangement made by the same entity you are acting on behalf of, you may not add another; but you may replace the old one, on explicit permission from the previous publisher that added the old one.

The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicity for or to assert or imply endorsement of any Modified Version.

Combining Documents

You may combine the Document with other documents released under this License, under the terms defined in section 4 above for modified versions, provided that you include in the combination all of the Invariant Sections of all of the original documents, unmodified, and list them all as Invariant Sections of your combined work in its license notice.

The combined work need only contain one copy of this License, and multiple identical Invariant Sections may be replaced with a single copy. If there are multiple Invariant Sections with the same name but different contents, make the title of each such section unique by adding at the end of it, in parentheses, the name of the original author or publisher of that section if known, or else a unique number. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work.

In the combination, you must combine any sections entitled ``History'' in the various original documents, forming one section entitled ``History''; likewise combine any sections entitled ``Acknowledgements'', and any sections entitled ``Dedications''. You must delete all sections entitled ``Endorsements.''

Collections of Documents

You may make a collection consisting of the Document and other documents released under this License, and replace the individual copies of this License in the various documents with a single copy that is included in the collection, provided that you follow the rules of this License for verbatim copying of each of the documents in all other respects.

You may extract a single document from such a collection, and distribute it individually under this License, provided you insert a copy of this License into the extracted document, and follow this License in all other respects regarding verbatim copying of that document.

Aggregation With Independent Works

A compilation of the Document or its derivatives with other separate and independent documents or works, in or on a volume of a storage or distribution medium, does not as a whole count as a Modified Version of the Document, provided no compilation copyright is claimed for the compilation. Such a compilation is called an ``aggregate'', and this License does not apply to the other self-contained works thus compiled with the Document, on account of their being thus compiled, if they are not themselves derivative works of the Document.

If the Cover Text requirement of section 3 is applicable to these copies of the Document, then if the Document is less than one quarter of the entire aggregate, the Document's Cover Texts may be placed on covers that surround only the Document within the aggregate. Otherwise they must appear on covers around the whole aggregate.

Translation

Translation is considered a kind of modification, so you may distribute translations of the Document under the terms of section 4. Replacing Invariant Sections with translations requires special permission from their copyright holders, but you may include translations of some or all Invariant Sections in addition to the original versions of these Invariant Sections. You may include a translation of this License provided that you also include the original English version of this License. In case of a disagreement between the translation and the original English version of this License, the original English version will prevail.

Termination

You may not copy, modify, sublicense, or distribute the Document except as expressly provided for under this License. Any other attempt to copy, modify, sublicense or distribute the Document is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.

Future Revisions of This License

The Free Software Foundation may publish new, revised versions of the GNU Free Documentation License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. See http://www.gnu.org/copyleft/.

Each version of the License is given a distinguishing version number. If the Document specifies that a particular numbered version of this License "or any later version" applies to it, you have the option of following the terms and conditions either of that specified version or of any later version that has been published (not as a draft) by the Free Software Foundation. If the Document does not specify a version number of this License, you may choose any version ever published (not as a draft) by the Free Software Foundation.

ADDENDUM: How to use this License for your documents

To use this License in a document you have written, include a copy of the License in the document and put the following copyright and license notices just after the title page:

Copyright © YEAR YOUR NAME. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with the Invariant Sections being LIST THEIR TITLES, with the Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. A copy of the license is included in the section entitled ``GNU Free Documentation License''.

If you have no Invariant Sections, write ``with no Invariant Sections'' instead of saying which ones are invariant. If you have no Front-Cover Texts, write ``no Front-Cover Texts'' instead of ``Front-Cover Texts being LIST''; likewise for Back-Cover Texts.

If your document contains nontrivial examples of program code, we recommend releasing these examples in parallel under your choice of free software license, such as the GNU General Public License, to permit their use in free software.



Footnotes

... SSL1.1
SSL or Secure Sockets Layer is a protocol designed by Netscape. TLS 1.0 is based on SSL 3.0 protocol. SSL 2.0 is a very old protocol which is vulnerable to several attacks. SSL 2.0 is not implemented in GNUTLS
... 1.01.2
described in RFC 2246
... IETF1.3
IETF or Internet Engineering Task Force is a large open international community of network designers, operators, vendors, and researchers concerned with the evolution of the Internet architecture and the smooth operation of the Internet. It is open to any interested individual.
... layer1.4
TLS is mostly used over TCP/IP although this is not restrictive, you may use it over any reliable transport layer.
...AES1.5
AES or Advanced Encryption Standard is actually the RIJNDAEL algorithm. This is the algorithm that will replace DES.
...ARCFOUR1.6
ARCFOUR is a compatible algorithm with RSA's RC4 algorithm.
... Taylor's1.7
Work in progress.

next_inactive up previous
Nikos Mavroyanopoulos 2001-09-19