GNUTLS

a Transport Layer Security Library
This is a Draft document
Applies to GnuTLS 0.4.0


Copyright © 2001,2002 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 SSL, the Secure Sockets Layer protocol designed by Netscape.

TLS 1.01.1 is an Internet protocol, defined by IETF1.2, that provides confidentiality, and authentication layers over any reliable transport layer.

GNUTLS implements the above protocols in a reentrant way. This allows multiple threads of execution, without the need for critical sections and locks. See http://www.gnutls.org/ and http://www.gnu.org/software/gnutls/ for updated versions of the GNUTLS software and this document.

Currently GNUTLS implements:

TLS layers

TLS 1.0 is a layered protocol, and consists of the Record Protocol, the Handshake Protocol and the Alert Protocol. The Record Protocol is to serve all other protocols and is above the transport layer. The Record protocol offers symmetric encryption, data authenticity, and optionally compression. In GNUTLS the record protocol is accessed using the gnutls_record_recv() and gnutls_record_send() functions.

The Alert protocol offers some signaling to the other protocols. It can help informing the peer for the cause of failures and other error conditions. See gnutls_alert_send(), gnutls_alert_send_appropriate() and gnutls_alert_get(). The alert protocol is above the record protocol.

The Handshake protocol is responsible for the security parameters' negotiation, the initial key exchange and authentication. See figure for the protocol layering in TLS. See the gnutls_handshake() function.

\includegraphics{layers}

The transport layer

GNUTLS can be used above any reliable transport layer. You may need to use the functions:

These functions accept a functions as a parameter. The given functions will be used by gnutls to send and receive data. These functions should return -1 on error and should set errno appropriately. GNUTLS supports EINTR and EAGAIN errno values. These values are usually used in non blocking IO and interrupted system calls. The corresponding values (GNUTLS_E_INTERRUPTED, GNUTLS_E_AGAIN) will be returned to the caller of the gnutls function. GNUTLS functions can be resumed (called again), if any of these values is returned.

By default, if none of the above functions are called, gnutls will use the berkeley sockets functions recv() and send(). In this case gnutls will use some hacks in order for select() to work, thus making easy to add TLS support to existing servers.

The TLS record protocol

The Record protocol is the secure communications provider. It's job is to encrypt and authenticate packets. The following functions are available:

Symmetric encryption algorithms

Confidentiality is provided by using block encryption algorithms like 3DES, AES1.4, or stream algorithms like ARCFOUR1.5 See fig:ciphers for a complete list. Ciphers are encryption algorithms that use 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.

Figure 1.1: Supported cipher algorithms
\begin{figure}\begin{tabular}{\vert l\vert p{9cm}\vert}
\par
\hline
3DES\_CBC & ...
...f TLS. It is a {\emph{GNUTLS}}{} extension.
\\
\hline
\end{tabular}\end{figure}

Figure 1.2: Supported MAC algorithms
\begin{figure}\begin{tabular}{\vert l\vert p{9cm}\vert}
\par\hline
MAC\_MD5 & MD...
...algorithm by NSA. Outputs 160 bits of data.
\\
\hline
\end{tabular}\end{figure}

The TLS alert protocol

The Alert protocol is there to allow signals to be sent between peers. These signals are mostly used to inform the peer about the cause of a protocol failure. Some of these signals are used internally by the protocol and the application protocol does not have to cope with them (see GNUTLS_A_CLOSE_NOTIFY), and others refer to the application protocol solely (see GNUTLS_A_USER_CANCELLED). An alert signal includes a level indication which may be either fatal or warning. Fatal alerts always terminate the current connection, and prevent future renegotiations using the current session ID.

The alert messages are protected by the record protocol, thus the information that it's included does not leak. You must take extreme care for the alert information not to leak, to a possible attacker (via public logfiles etc).

The TLS handshake protocol

The Handshake protocol is fully controlled by application layer (your program). Within this protocol the parameters for cipher suites, supported authentication methods etc. are negotiated. Thus the application layer has to set up the required parameters for the connection. See the following functions:

TLS cipher suites

The Handshake Protocol of TLS 1.0 negotiates cipher suites of the form
TLS_DHE_RSA_WITH_3DES_CBC_SHA. The usual cipher suites contain these parameters:

The ciphersuite negotiated in the handshake protocol, will affect the Record Protocol, by enabling encryption and data authentication. Note that TLS 1.0 does not always negotiate the strongest available cipher suite. There are cases where a man in the middle attacker could make the two entities negotiate the least secure method they support. For that reason do not enable ciphers and algorithms that you consider weak.

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 (by using the previously established keys). GNUTLS supports this feature, and the example resume client illustrates a typical use of it (This is a modification of the simple client example). Servers only need to use the gnutls_db_set_name() function if they want to use the gdbm backend to store sessions.

Keep in mind that sessions are expired after some time (for security reasons), thus it may be normal for a server not to resume a session even if you requested that. Also note that you must enable (using the priority functions), at least the algorithms used in the last session.

Resuming internals

The resuming capability (mostly in the server side) is one of the problems of a thread-safe TLS implementations. The problem is that all threads must share information in order to be able to resume sessions. The gnutls approach is, in case of a client, to leave all the burden of resuming to the client (ie. copy and keep the nesessary parameters). See gnutls_session_get_data(), gnutls_session_get_id() and gnutls_session_set_data().

The server side is different. Here the server only specifies a DB file, using gnutls_db_set_name(). This DB file is used to store the sessions' required parameters for resuming. This means that this file contains very sensitive information, such as encryption keys. In a multi-threaded application every thread can read from the DB file and access all previously established sessions, but only one thread can write at a time. The current behaviour of gnutls is not to block to wait for the DB to be ready for writing, but continue the process normally (and do not save the parameters).

GNUTLS also provides callback functions such as: gnutls_db_set_remove_function(), gnutls_db_set_store_function(),
gnutls_db_set_retrieve_function() and gnutls_db_set_ptr(). These callback functions are required in order to use a session storage method, other than the default gdbm backend.

If an alternative backend is in use, it might be usefull to be able to check for expired sessions in order to remove them, and save space. This is what gnutls_db_clean() does for the gdbm backend. GNUTLS provides the function gnutls_db_check_entry(), which takes as input session data, and returns a negative value if the data are to be removed.

Authentication methods

The following authentication schemas are supported in GNUTLS:

  1. Certificate authentication
  2. Anonymous authentication
  3. SRP authentication

Authentication using X.509 certificates

This authentication method is part of the certificate authentication method in GNUTLS. The X.509 protocols rely on a hierarchical trust model. In this trust model Certification Authorities (CAs) are used to certify entities. Usually more than one certification authorities exist, and certification authorities may certify other authorities to issue certificates as well, following a hierachical model. One needs to trust one or more CAs for his secure communications. In that case only the certificates issued by the trusted authorities are acceptable.

X.509 certificates contain the public parameters, of a public key algorithm, and the authority's signature, which proves the authenticity of the parameters.

The key exchange methods shown in figure are available in X.509 authentication.

Note that GNUTLS is not a generic purpose X.509 toolkit1.8. GNUTLS only includes the required, in order to use the TLS ciphersuites which require X.509 certificates.

Figure 1.3: Key exchange algorithms for OpenPGP and X.509 certificates.
\begin{figure}\begin{tabular}{\vert l\vert p{9cm}\vert}
\hline
RSA & The RSA alg...
...ters which are send to the peer.
\\
\hline
\end{tabular}\par
\par
\end{figure}

Authentication using OpenPGP keys

This authentication method is part of the certificate authentication method in GNUTLS. OpenPGP authentication relies on a distributed trust model, called the "web of trust". The "web of trust" uses a decentralized system of trusted introducers, which are the same as a CA. OpenPGP allows anyone to sign anyone's else public key. When Alice signs Bob's key, she is introducing Bob's key to anyone who trusts Alice. If someone trusts Alice to introduce keys, then Alice is a trusted introducer in the mind of that observer.

The key exchange methods shown in figure are available in OpenPGP authentication.

Anonymous authentication

The anonymous key exchange perform encryption but there is no indication of the identity of the peer. This kind of authentication is vulnerable to man in the middle attack, but this protocol can be used even if there is no prior communication or common trusted parties with the peer. Unless really required, do not use anonymous authentication. Available key exchange methods are shown in figure.

Figure 1.4: Supported anonymous key exchange algorithms
\begin{figure}\begin{tabular}{\vert l\vert p{9cm}\vert}
\par\hline
ANON\_DH & Th...
...changes Diffie Hellman parameters.
\\
\hline
\end{tabular}\par\par\end{figure}

Authentication using SRP

Authentication using the SRP1.10is actually password authentication, since the two peers are identified by the knowledge of a password. This protocol also offers protection against off-line attacks (password file stealing etc). This is achieved since SRP does not use the plain password to perform authentication, but something called a verifier. The verifier is gxmod (n) and x is a value calculated from the username and the password.

SRP is normaly used with a SHA based hash function, to calculate the value of x. In GNUTLS in addition to original SHA hash function, a hash function based on blowfish crypt is also supported. The blowfish crypt function has the property of variable complexity, thus the verifier may resist future attacks based on computational power, by just increasing the complexity of the function (sometimes called 'the cost').

The advantage of SRP authentication, over other proposed secure password authentication schemas, is that SRP does not require the server to hold the user's password. This kind of protection is similar to the one used traditionaly in the UNIX 'passwd' file, where the contents of this file did not cause harm to the system security if they were revealed.

Available key exchange methods are shown in figure.

Figure 1.5: Supported SRP key exchange algorithms
\begin{figure}\begin{tabular}{\vert l\vert p{9cm}\vert}
\par\hline
SRP & Authentication using the SRP protocol.
\\
\hline
\end{tabular}\par\par\end{figure}

Error Handling

In GNUTLS most functions return an integer type as a result. In almost all cases a zero or a positive number means success, and a negative number indicates failure, or a situation that some action has to be taken. Thus negative error codes may be fatal or not.

Fatal errors terminate the connection immediately and further sends ard receives will be disallowed. An example of a fatal error code is GNUTLS_E_DECRYPTION_FAILED. Non-fatal errors may warn about something (ie a warning alert was received), or indicate the some action has to be taken. This is the case with the error code GNUTLS_E_REHANDSHAKE returned by gnutls_record_recv(). This error code indicates that the server requests a rehandshake. The client may ignore this request, or may reply with an alert. You can test if an error code is a fatal one by using the gnutls_error_is_fatal().

If any non fatal errors, that require an action, are to be returned by a function, these error codes will be documented in the function's reference.

GNUTLS examples

Client examples

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

Simple client example with X.509 certificate support

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];
   GNUTLS_CERTIFICATE_CLIENT_CREDENTIALS xcred;
   const int protocol_priority[] = { GNUTLS_TLS1, GNUTLS_SSL3, 0 };
   const int kx_priority[] = { GNUTLS_KX_RSA, 0 };
   const int cipher_priority[] = { GNUTLS_CIPHER_3DES_CBC, GNUTLS_CIPHER_ARCFOUR, 0};
   const int comp_priority[] = { GNUTLS_COMP_ZLIB, GNUTLS_COMP_NULL, 0 };
   const int mac_priority[] = { GNUTLS_MAC_SHA, GNUTLS_MAC_MD5, 0 };


   if (gnutls_global_init() < 0) {
      fprintf(stderr, "global state initialization error\n");
      exit(1);
   }
   /* X509 stuff */
   if (gnutls_certificate_allocate_client_sc(&xcred) < 0) {  
      fprintf(stderr, "memory error\n");
      exit(1);
   }
   /* set's the trusted cas file
    */
   gnutls_certificate_set_x509_trust_file(xcred, CAFILE, GNUTLS_X509_FMT_PEM);

   /* 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_protocol_set_priority(state, protocol_priority);

   /* allow only ARCFOUR and 3DES ciphers
    * (3DES has the highest priority)
    */
   gnutls_cipher_set_priority(state, cipher_priority);

   /* only allow null compression
    */
   gnutls_compression_set_priority(state, comp_priority);

   /* use GNUTLS_KX_RSA
    */
   gnutls_kx_set_priority(state, kx_priority);

   /* allow the usage of both SHA and MD5
    */
   gnutls_mac_set_priority(state, mac_priority);


   /* put the x509 credentials to the current state
    */
   gnutls_cred_set(state, GNUTLS_CRD_CERTIFICATE, xcred);


   gnutls_transport_set_ptr( state, sd);
   /* Perform the TLS handshake
    */
   ret = gnutls_handshake( state);

   if (ret < 0) {
      fprintf(stderr, "*** Handshake failed\n");
      gnutls_perror(ret);
      goto end;
   } else {
      printf("- Handshake was completed\n");
   }

   gnutls_record_send( state, MSG, strlen(MSG));

   ret = gnutls_record_recv( state, buffer, MAX_BUF);
   if (gnutls_error_is_fatal(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_alert_get(state));
      if (ret == GNUTLS_E_REHANDSHAKE)
         printf("* Received HelloRequest message (server asked to rehandshake)\n");
         gnutls_alert_send_appropriate( state, ret); /* we don't want rehandshake */
   }

   if (ret > 0) {
      printf("- Received %d bytes: ", ret);
      for (ii = 0; ii < ret; ii++) {
         fputc(buffer[ii], stdout);
      }
      fputs("\n", stdout);
   }
   gnutls_bye( state, GNUTLS_SHUT_RDWR);

 end:

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

   gnutls_deinit(state);

   gnutls_certificate_free_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)

/* This function will print some details of the
 * given state.
 */
int print_info(GNUTLS_STATE state)
{
   const char *tmp;
   GNUTLS_CredType cred;
   gnutls_x509_dn dn;
   const gnutls_datum *cert_list;
   int status;
   int cert_list_size = 0;
   GNUTLS_KXAlgorithm kx;


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

   cred = gnutls_auth_get_type(state);
   switch (cred) {
   case GNUTLS_CRD_ANON:
      printf("- Anonymous DH using prime of %d bits\n",
             gnutls_dh_get_bits(state));
      break;
   case GNUTLS_CRD_CERTIFICATE:
      /* in case of certificate authentication
       */
      cert_list = gnutls_certificate_get_peers(state, &cert_list_size);
      status = gnutls_certificate_verify_peers(state);
      
      if ( status < 0) {
         if ( status == GNUTLS_E_NO_CERTIFICATE_FOUND)
            printf("- Peer did not send any X509 Certificate.\n");
         else
            printf("- Could not verify certificate\n");
      } else {

         if ( status & GNUTLS_CERT_INVALID)
            printf("- Peer's certificate is invalid\n");
         if ( status & GNUTLS_CERT_EXPIRED)
            printf("- Peer's certificate is expired\n");
         if ( status & GNUTLS_CERT_CORRUPTED)
            printf("- Peer's certificate is corrupted.\n");
         if ( status & GNUTLS_CERT_REVOKED)
            printf("- Peer's certificate is revoked\n");

         if ( status & GNUTLS_CERT_NOT_TRUSTED)
            printf("- Peer's certificate is not trusted\n");
         else
            printf("- Peer's certificate is trusted\n");
      }

      /* Check if we have been using ephemeral Diffie Hellman.
       */
      if (kx == GNUTLS_KX_DHE_RSA || kx == GNUTLS_KX_DHE_DSS) {
         printf("\n- Ephemeral DH using prime of %d bits\n",
                gnutls_dh_get_bits(state));
      }

      /* if the certificate list is available, then
       * print some information about it.
       */
      if (cert_list_size > 0 && gnutls_cert_type_get(state) == GNUTLS_CRT_X509) {
         char digest[20];
         char serial[40];
         int digest_size = sizeof(digest), i;
         int serial_size = sizeof(serial);
         char printable[120];
         char *print;
         int algo, bits;

         printf(" - Certificate info:\n");

         /* Print the fingerprint of the certificate
          */
         if (gnutls_x509_fingerprint(GNUTLS_DIG_MD5, &cert_list[0], digest, &digest_size) >= 0) {
            print = printable;
            for (i = 0; i < digest_size; i++) {
               sprintf(print, "%.2x ", (unsigned char) digest[i]);
               print += 3;
            }
            printf(" - Certificate fingerprint: %s\n", printable);
         }

         /* Print the serial number of the certificate.
          */
         if (gnutls_x509_extract_certificate_serial(&cert_list[0], serial, &serial_size) >= 0) {
            print = printable;
            for (i = 0; i < serial_size; i++) {
               sprintf(print, "%.2x ", (unsigned char) serial[i]);
               print += 3;
            }
            printf(" - Certificate serial number: %s\n", printable);
         }

         /* Extract some of the public key algorithm's parameters
          */
         algo = gnutls_x509_extract_certificate_pk_algorithm( &cert_list[0], &bits);
         printf("Certificate public key: ");

         if (algo==GNUTLS_PK_RSA) {
            printf("RSA\n");
            printf(" Modulus: %d bits\n", bits);
         } else if (algo==GNUTLS_PK_DSA) {
            printf("DSA\n");
            printf(" Exponent: %d bits\n", bits);
         } else {
            printf("UNKNOWN\n");
         }

         /* Print the version of the X.509 
          * certificate.
          */
         printf(" - Certificate version: #%d\n", gnutls_x509_extract_certificate_version(&cert_list[0]));

         gnutls_x509_extract_certificate_dn(&cert_list[0], &dn);
         PRINT_DN(dn);

         gnutls_x509_extract_certificate_issuer_dn(&cert_list[0], &dn);
         printf(" - Certificate Issuer's info:\n");
         PRINT_DN(dn);

      }
   }

   tmp = gnutls_protocol_get_name(gnutls_protocol_get_version(state));
   printf("- Protocol: %s\n", tmp);

   tmp = gnutls_cert_type_get_name( gnutls_cert_type_get(state));
   printf("- Certificate Type: %s\n", tmp);

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

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

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

   return 0;
}


Client with Resume capability example

#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"

const int protocol_priority[] = { GNUTLS_TLS1, GNUTLS_SSL3, 0 };
const int kx_priority[] = { GNUTLS_KX_RSA, GNUTLS_KX_DHE_RSA, 0 };
const int cipher_priority[] = { GNUTLS_CIPHER_3DES_CBC, GNUTLS_CIPHER_ARCFOUR, 0};
const int comp_priority[] = { GNUTLS_COMP_ZLIB, GNUTLS_COMP_NULL, 0 };
const int mac_priority[] = { GNUTLS_MAC_SHA, GNUTLS_MAC_MD5, 0 };

int main()
{
   const char *PORT = "443";
   const char *SERVER = "127.0.0.1";
   int err, ret;
   int sd, ii, alert;
   struct sockaddr_in sa;
   GNUTLS_STATE state;
   char buffer[MAX_BUF + 1];
   GNUTLS_CERTIFICATE_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_certificate_allocate_client_sc(&xcred) < 0) {
      fprintf(stderr, "memory error\n");
      exit(1);
   }
   gnutls_certificate_set_x509_trust_file(xcred, CAFILE, GNUTLS_X509_FMT_PEM);

   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_protocol_set_priority(state, protocol_priority);
      gnutls_cipher_set_priority(state, cipher_priority);
      gnutls_compression_set_priority(state, comp_priority);
      gnutls_kx_set_priority(state, kx_priority);
      gnutls_mac_set_priority(state, mac_priority);

      gnutls_cred_set(state, GNUTLS_CRD_CERTIFICATE, xcred);

      if (t > 0) { /* if this is not the first time we connect */
         gnutls_session_set_data(state, session, session_size);
         free(session);
      }
      
      gnutls_transport_set_ptr( state, sd);

      /* Perform the TLS handshake
       */
      ret = gnutls_handshake( 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_session_get_data(state, NULL, &session_size);
         session = malloc(session_size);

         /* put session data to the session variable */
         gnutls_session_get_data(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_session_get_id(state, NULL, &session_id_size);
         session_id = malloc(session_id_size);
         gnutls_session_get_id(state, session_id, &session_id_size);

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

         /* check if we actually resumed the previous session */
         gnutls_session_get_id(state, NULL, &tmp_session_id_size);
         tmp_session_id = malloc(tmp_session_id_size);
         gnutls_session_get_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_record_send( state, MSG, strlen(MSG));

      ret = gnutls_record_recv( state, buffer, MAX_BUF);
      if (gnutls_error_is_fatal(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)
            alert = gnutls_alert_get(state);
            printf("* Received alert [%d]: %s\n", alert, gnutls_alert_get_name(alert));
         if (ret == GNUTLS_E_REHANDSHAKE) {
            printf("* Received HelloRequest message (server asked to rehandshake)\n");
            gnutls_alert_send_appropriate( state, ret); /* we don't want rehandshake */
         }
      }

      if (ret > 0) {
         printf("- Received %d bytes: ", ret);
         for (ii = 0; ii < ret; ii++) {
            fputc(buffer[ii], stdout);
         }
         fputs("\n", stdout);
      }
      gnutls_bye( state, GNUTLS_SHUT_RDWR);

    end:

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

      gnutls_deinit(state);

   }  /* for() */

   gnutls_certificate_free_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's proposal2.1 for using the 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"

const int protocol_priority[] = { GNUTLS_TLS1, GNUTLS_SSL3, 0 };
const int kx_priority[] = { GNUTLS_KX_SRP, 0 };
const int cipher_priority[] = { GNUTLS_CIPHER_3DES_CBC, GNUTLS_CIPHER_ARCFOUR, 0};
const int comp_priority[] = { GNUTLS_COMP_NULL, 0 };
const int mac_priority[] = { GNUTLS_MAC_SHA, GNUTLS_MAC_MD5, 0 };

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];
   GNUTLS_SRP_CLIENT_CREDENTIALS xcred;

   if (gnutls_global_init() < 0) {
      fprintf(stderr, "global state initialization error\n");
      exit(1);
   }
   if (gnutls_srp_allocate_client_sc(&xcred) < 0) {
      fprintf(stderr, "memory error\n");
      exit(1);
   }
   gnutls_srp_set_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_protocol_set_priority(state, protocol_priority);
 
   /* allow only ARCFOUR and 3DES ciphers
    * (3DES has the highest priority)
    */
    gnutls_cipher_set_priority(state, cipher_priority);

   /* only allow null compression
    */
   gnutls_compression_set_priority(state, comp_priority);
 
   /* use GNUTLS_KX_SRP
    */
   gnutls_kx_set_priority(state, kx_priority);
 
   /* allow the usage of both SHA and MD5
    */
   gnutls_mac_set_priority(state, mac_priority);


   /* put the SRP credentials to the current state
    */
   gnutls_cred_set(state, GNUTLS_CRD_SRP, xcred);

   gnutls_transport_set_ptr( state, sd);

   /* Perform the TLS handshake
    */
   ret = gnutls_handshake( state);

   if (ret < 0) {
      fprintf(stderr, "*** Handshake failed\n");
      gnutls_perror(ret);
      goto end;
   } else {
      printf("- Handshake was completed\n");
   }

   gnutls_record_send( state, MSG, strlen(MSG));

   ret = gnutls_record_recv( state, buffer, MAX_BUF);
   if (gnutls_error_is_fatal(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_alert_get(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( state, 0);

 end:

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

   gnutls_deinit(state);

   gnutls_srp_free_client_sc(xcred);

   gnutls_global_deinit();

   return 0;
}

Server examples

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

Echo Server with X.509 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 */
#define DH_BITS 1024

/* These are global */
GNUTLS_SRP_SERVER_CREDENTIALS srp_cred;
GNUTLS_CERTIFICATE_SERVER_CREDENTIALS x509_cred;

GNUTLS_STATE initialize_state()
{
   GNUTLS_STATE state;
   int ret;
   const int protocol_priority[] = { GNUTLS_TLS1, GNUTLS_SSL3, 0 };
   const int kx_priority[] = { GNUTLS_KX_RSA, GNUTLS_KX_DHE_RSA, GNUTLS_KX_SRP, 0 };
   const int cipher_priority[] = { GNUTLS_CIPHER_RIJNDAEL_CBC, GNUTLS_CIPHER_3DES_CBC, 0};
   const int comp_priority[] = { GNUTLS_COMP_ZLIB, GNUTLS_COMP_NULL, 0 };
   const int mac_priority[] = { GNUTLS_MAC_SHA, GNUTLS_MAC_MD5, 0 };

   gnutls_init(&state, GNUTLS_SERVER);

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

   gnutls_protocol_set_priority(state, protocol_priority);
   gnutls_cipher_set_priority(state, cipher_priority);
   gnutls_compression_set_priority(state, comp_priority);
   gnutls_kx_set_priority(state, kx_priority);
   gnutls_mac_set_priority(state, mac_priority);

   gnutls_cred_set(state, GNUTLS_CRD_SRP, srp_cred);
   gnutls_cred_set(state, GNUTLS_CRD_CERTIFICATE, x509_cred);

   /* request client certificate if any.
    */
   gnutls_certificate_server_set_request( state, GNUTLS_CERT_REQUEST);

   gnutls_dh_set_prime_bits( state, DH_BITS);
   
   return state;
}

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

   /* print session_id specific data */
   gnutls_session_get_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_auth_get_type(state) == GNUTLS_CRD_SRP) {
         printf("\n- User '%s' connected\n",
                gnutls_srp_server_get_username( state));
   }

   /* print state information */
   tmp = gnutls_protocol_get_name(gnutls_protocol_get_version(state));
   printf("- Version: %s\n", tmp);

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

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

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

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

}

GNUTLS_DH_PARAMS dh_params;

static int generate_dh_primes(void) {
gnutls_datum prime, generator;

   /* Generate Diffie Hellman parameters - for use with DHE
    * kx algorithms. These should be discarded and regenerated
    * once a day, once a week or once a month. Depends on the
    * security requirements.
    */
   gnutls_dh_params_init( &dh_params);
   gnutls_dh_params_generate( &prime, &generator, DH_BITS);
   gnutls_dh_params_set( dh_params, prime, generator);

   free( prime.data);
   free( generator.data);
}

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_certificate_allocate_server_sc(&x509_cred) < 0) {
      fprintf(stderr, "memory error\n");
      exit(1);
   }
   if (gnutls_certificate_set_x509_trust_file(x509_cred, CAFILE, 
      GNUTLS_X509_FMT_PEM) < 0) {
      fprintf(stderr, "X509 PARSE ERROR\nDid you have ca.pem?\n");
      exit(1);
   }
   if (gnutls_certificate_set_x509_key_file(x509_cred, CERTFILE, KEYFILE, 
      GNUTLS_X509_FMT_PEM) < 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_srp_allocate_server_sc(&srp_cred);
   gnutls_srp_set_server_cred_file(srp_cred, SRP_PASSWD, SRP_PASSWD_CONF);

   generate_dh_params();
   
   gnutls_certificate_set_dh_params( x509_cred, dh_params);

   /* 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));

      gnutls_transport_set_ptr( state, sd);
      ret = gnutls_handshake( 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_record_recv( state, buffer, MAX_BUF);

         if (gnutls_error_is_fatal(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_record_send( state, buffer,
                         strlen(buffer));
         }
         if (ret == GNUTLS_E_WARNING_ALERT_RECEIVED || ret == GNUTLS_E_FATAL_ALERT_RECEIVED) {
            ret = gnutls_alert_get(state);
            printf("* Received alert '%d' - '%s'.\n", ret, gnutls_alert_get_name( ret));
         }
      }
      printf("\n");
      gnutls_bye( state, 1); /* do not wait for
                                 * the peer to close the connection.
                                 */

      close(sd);
      gnutls_deinit(state);

   }
   close(listen_sd);

   gnutls_certificate_free_server_sc(x509_cred);
   gnutls_srp_free_server_sc(srp_cred);

   gnutls_global_deinit();

   return 0;

}

ASN.1 structures handling

Introduction

This file describes the forth version of ASN.1 parser I developed3.1. The main difference from the first version is the use of pointers and the possibility to save/get ASN1 definitions in/from a C vector. Other differences are:

ASN.1 syntax

The parser is case sensitive. The comments begin with "- " and end at the end of line. An example is in "Certificate.txt" file. The ASN.1 declarations must have this form:

      object_name {<object definition>}

      DEFINITIONS <EXPLICIT or IMPLICIT> TAGS ::=

      BEGIN 

      <type and constants definitions>

      END

The token "::=" must be separate from others elements, so this is a wrong declaration: Version ::=INTEGER the correct one is : Version ::= INTEGER Here is the list of types that the parser can manage:

This version doesn't manage REAL type. It also not allow the use of "EXPORT" and "IMPORT" sections.

The SIZE constraints are allowed but no check is done on them.

Naming

If you have this definitions:

      Example { 1 2 3 4 }

      DEFINITIONS EXPLICIT TAGS ::=

      BEGIN 

      Group ::= SEQUENCE {
         id   OBJECT IDENTIFIER,
         value  Value
      }

      Value ::= SEQUENCE {
         value1  INTEGER,
         value2  BOOLEAN 
      }

      END

to identify the type 'Group' you have to use the null terminated string "Example.Group". Others examples: Field 'id' in 'Group' type : "Example.Group.id" Field 'value1' in filed 'value' in type 'Group': "Example.Group.value.value1" These strings are used in functions that are described below. Elements of structured types that don't have a name, receve the name "?1","?2", and so on. The name "?LAST" indicates the last element of a SET_OF or SEQUENCE_OF.

Future developments

  1. type REAL
  2. improve the error signaling with strings that give you more details. Examples: in case of ASN1 syntax error you will have the line number where the error is, if creating a der encoding the result is ASN_VALUE_NOT_FOUND you will have the name of the element without the value.
  3. improve the 'visit_tree' function and change the output from stdout to a null terminated string.

Function reference

GNUTLS function reference


gnutls_protocol_get_version

GNUTLS_Version gnutls_protocol_get_version ( GNUTLS_STATE state )

Arguments

Description

Returns the version of the currently used protocol.


gnutls_transport_set_lowat

void gnutls_transport_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. This function is only usefull if using berkeley style sockets. Otherwise it must be called and set lowat to zero.


gnutls_transport_set_ptr

void gnutls_transport_set_ptr ( GNUTLS_STATE state , GNUTLS_TRANSPORT_PTR ptr )

Arguments

Description

Used to set the first argument of the transport function (like PUSH and PULL). In berkeley style sockets this function will set the connection handle.


gnutls_transport_get_ptr

GNUTLS_TRANSPORT_PTR gnutls_transport_get_ptr ( GNUTLS_STATE state )

Arguments

Description

Used to get the first argument of the transport function (like PUSH and PULL). This must have been set using gnutls_transport_set_ptr().


gnutls_bye

int gnutls_bye ( GNUTLS_STATE state , GNUTLS_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 TLS connection gets terminated and further receives and sends will be disallowed. If the return value is zero you may continue using the connection. GNUTLS_SHUT_RDWR actually sends an alert containing a close request and waits for the peer to reply with the same message.

In case of GNUTLS_SHUT_WR then the TLS connection gets terminated and further sends will be disallowed. In order to reuse the connection you should wait for an EOF from the peer. GNUTLS_SHUT_WR sends an alert containing a close request.

This function may also return GNUTLS_E_AGAIN, or GNUTLS_E_INTERRUPTED.


gnutls_record_send

ssize_t gnutls_record_send ( GNUTLS_STATE state , const void * data , size_t sizeofdata )

Arguments

Description

This function has the similar semantics to write(). The only difference is that is accepts a GNUTLS state, and uses different error codes.

If the EINTR is returned by the internal push function (write()) then GNUTLS_E_INTERRUPTED, will be returned. If GNUTLS_E_INTERRUPTED or GNUTLS_E_AGAIN is returned you must call this function again, with the same parameters. Otherwise the write operation will be corrupted and the connection will be terminated.

Returns the number of bytes sent, or a negative error code.


gnutls_record_recv

ssize_t gnutls_record_recv ( GNUTLS_STATE state , void * data , size_t sizeofdata )

Arguments

Description

This function has the similar semantics to read(). The only difference is that is accepts a GNUTLS state. Also returns the number of bytes received, zero on EOF, but a negative error code in case of an error.

If this function returns GNUTLS_E_REHANDSHAKE, then you may ignore this message, send an alert containing NO_RENEGOTIATION, or perform a handshake again. (only a client may receive this message)


gnutls_record_get_max_size

size_t gnutls_record_get_max_size ( GNUTLS_STATE state )

Arguments

Description

This function returns the maximum record size in this connection. The maximum record size is negotiated by the client after the first handshake message.


gnutls_record_set_max_size

ssize_t gnutls_record_set_max_size ( GNUTLS_STATE state , size_t size )

Arguments

Description

This function sets the maximum record size in this connection. This property can only be set to clients. The server may choose not to accept the requested size.

Acceptable values are 29, 210, 211 and 212. Returns 0 on success. The requested record size does not get in effect immediately. It will be used after a successful handshake.

This function uses a TLS extension called 'max record size'. Not all TLS implementations use or even understand this extension.


gnutls_record_check_pending

size_t gnutls_record_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 ( GNUTLS_STATE state )

Arguments

Description

This function will renegotiate security parameters with the client. This should only be called in case of a server.

This message informs the peer that we want to renegotiate parameters (perform a handshake).

If this function succeeds (returns 0), you must call the gnutls_handshake() function in order to negotiate the new parameters.

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_A_NO_RENEGOTIATION.


gnutls_handshake

int gnutls_handshake ( GNUTLS_STATE state )

Arguments

Description

This function does the handshake of the TLS/SSL protocol, and initializes the TLS connection.

This function will fail if any problem is encountered, and will return a negative error code. In case of a client, if it has been asked to resume a session, but the server didn't, then a full handshake will be performed.

This function may also return the non-fatal errors GNUTLS_E_AGAIN, or GNUTLS_E_INTERRUPTED. In that case you may resume the handshake (call this function again, until it returns ok)

If this function is called by a server after a rehandshake request then GNUTLS_E_GOT_APPLICATION_DATA or GNUTLS_E_WARNING_ALERT_RECEIVED may be returned. Note that these are non fatal errors, only in the case of a rehandshake. In that case they mean that the client rejected the rehandshake request.


gnutls_handshake_set_max_packet_length

void gnutls_handshake_set_max_packet_length ( GNUTLS_STATE state , int max )

Arguments

Description

This function will set the maximum size of a handshake message. Handshake messages over this size are rejected. The default value is 16kb which is large enough. Set this to 0 if you do not want to set an upper limit.


gnutls_error_is_fatal

int gnutls_error_is_fatal ( 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(). The only difference is that 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 ( GNUTLS_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 ( GNUTLS_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 ( GNUTLS_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 ( GNUTLS_KXAlgorithm algorithm )

Arguments

Description

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


gnutls_protocol_get_name

const char * gnutls_protocol_get_name ( GNUTLS_Version version )

Arguments

Description

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


gnutls_cert_type_get_name

const char * gnutls_cert_type_get_name ( GNUTLS_CertificateType type )

Arguments

Description

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


gnutls_cipher_set_priority

int gnutls_cipher_set_priority ( GNUTLS_STATE state , GNUTLS_LIST 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_kx_set_priority

int gnutls_kx_set_priority ( GNUTLS_STATE state , GNUTLS_LIST 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_mac_set_priority

int gnutls_mac_set_priority ( GNUTLS_STATE state , GNUTLS_LIST 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_compression_set_priority

int gnutls_compression_set_priority ( GNUTLS_STATE state , GNUTLS_LIST 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.

TLS 1.0 does not define any compression algorithms except NULL. Other compression algorithms are to be considered as gnutls extensions.


gnutls_protocol_set_priority

int gnutls_protocol_set_priority ( GNUTLS_STATE state , GNUTLS_LIST list )

Arguments

Description

Sets the priority on the protocol versions supported by gnutls. This function actually enables or disables protocols. Newer protocol versions always have highest priority.


gnutls_cert_type_set_priority

int gnutls_cert_type_set_priority ( GNUTLS_STATE state , GNUTLS_LIST list )

Arguments

Description

Sets the priority on the certificate types supported by gnutls. Priority is higher for types specified before others. After specifying the types you want, you should add 0. Note that the certificate type priority is set on the client. The server does not use the cert type priority except for disabling types that were not specified.


gnutls_session_get_data

int gnutls_session_get_data ( 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_session_set_data() This function must be called after a successful handshake.

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


gnutls_session_get_id

int gnutls_session_get_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. This is because resumed sessions have the same sessionID with the original 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_session_set_data

int gnutls_session_set_data ( 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_session_get_data(); 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_db_set_retrieve_function

void gnutls_db_set_retrieve_function ( GNUTLS_STATE state , GNUTLS_DB_RETR_FUNC retr_func )

Arguments

Description

Sets the function that will be used to retrieve data from the resumed sessions database. This function must return a gnutls_datum containing the data on success, or a gnutls_datum containing null and 0 on failure. This function should only be used if you do not plan to use the included gdbm backend.

The first argument to store_func() will be null unless gnutls_db_set_ptr() has been called.


gnutls_db_set_remove_function

void gnutls_db_set_remove_function ( GNUTLS_STATE state , GNUTLS_DB_REMOVE_FUNC rem_func )

Arguments

Description

Sets the function that will be used to remove data from the resumed sessions database. This function must return 0 on success. This function should only be used if you do not plan to use the included gdbm backend.

The first argument to rem_func() will be null unless gnutls_db_set_ptr() has been called.


gnutls_db_set_store_function

void gnutls_db_set_store_function ( GNUTLS_STATE state , GNUTLS_DB_STORE_FUNC store_func )

Arguments

Description

Sets the function that will be used to store data from the resumed sessions database. This function must remove 0 on success. This function should only be used if you do not plan to use the included gdbm backend.

The first argument to store_func() will be null unless gnutls_db_set_ptr() has been called.


gnutls_db_set_ptr

void gnutls_db_set_ptr ( GNUTLS_STATE state , void* ptr )

Arguments

Description

Sets the pointer that will be sent to db store, retrieve and delete functions, as the first argument. Should only be called if not using the gdbm backend.


gnutls_db_get_ptr

void* gnutls_db_get_ptr ( GNUTLS_STATE state )

Arguments

Description

Returns the pointer that will be sent to db store, retrieve and delete functions, as the first argument. Should only be used if not using the default (gdbm) backend.


gnutls_db_set_cache_expiration

void gnutls_db_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_db_set_name

int gnutls_db_set_name ( GNUTLS_STATE state , const 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. You should not call this function if using an other backend than gdbm (ie. called function gnutls_db_set_store_func() etc.)


gnutls_db_check_entry

int gnutls_db_check_entry ( GNUTLS_STATE state , gnutls_datum session_entry )

Arguments

Description

This function should only be used if not using the gdbm backend. This function returns GNUTLS_E_EXPIRED, if the database entry has expired or 0 otherwise. This function is to be used when you want to clear unnesessary session which occupy space in your backend.


gnutls_db_clean

int gnutls_db_clean ( 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. This function should only be called if using the gdbm backend.


gnutls_db_remove_session

void gnutls_db_remove_session ( GNUTLS_STATE state )

Arguments

Description

This function will remove the current session data from the session database. This will prevent future handshakes reusing these session data. This function should be called if a session was terminated abnormaly.


gnutls_b64_encode_fmt

int gnutls_b64_encode_fmt ( const char* msg , const gnutls_datum * data , char* result , int* result_size )

Arguments

Description

This function will convert the given data to printable data, using the base64 encoding. This is the encoding used in PEM messages. If the provided buffer is not long enough GNUTLS_E_INVALID_REQUEST is returned.


gnutls_b64_decode_fmt

int gnutls_b64_decode_fmt ( const gnutls_datum * b64_data , char* result , int* result_size )

Arguments

Description

This function will decode the given encoded data.


gnutls_cred_set

int gnutls_cred_set ( GNUTLS_STATE state , GNUTLS_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_CRD_ANON cred should be ANON_CLIENT_CREDENTIALS in case of a client. In case of a server it should be ANON_SERVER_CREDENTIALS.

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

For GNUTLS_CRD_CERTIFICATE cred should be CERTIFICATE_CLIENT_CREDENTIALS in case of a client, and CERTIFICATE_SERVER_CREDENTIALS, in case of a server.


gnutls_auth_get_type

GNUTLS_CredType gnutls_auth_get_type ( GNUTLS_STATE state )

Arguments

Description

Returns type of credentials for the current authentication schema. The returned information is to be used to distinguish the function used to access authentication data.

Eg. for CERTIFICATE ciphersuites (key exchange algorithms: KX_RSA, KX_DHE_RSA), the same function are to be used to access the authentication data.


gnutls_srp_free_client_sc

void gnutls_srp_free_client_sc ( GNUTLS_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_srp_allocate_client_sc

int gnutls_srp_allocate_client_sc ( GNUTLS_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_srp_set_client_cred

int gnutls_srp_set_client_cred ( GNUTLS_SRP_CLIENT_CREDENTIALS res , char * username , char * password )

Arguments


gnutls_srp_free_server_sc

void gnutls_srp_free_server_sc ( GNUTLS_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_srp_allocate_server_sc

int gnutls_srp_allocate_server_sc ( GNUTLS_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_srp_set_server_cred_file

int gnutls_srp_set_server_cred_file ( GNUTLS_SRP_SERVER_CREDENTIALS res , char * password_file , char * password_conf_file )

Arguments


gnutls_srp_server_set_select_func

void gnutls_srp_server_set_select_func ( GNUTLS_STATE state , srp_server_select_func * func )

Arguments

Description

The callback's function form is: int (*callback)(GNUTLS_STATE, const char** pfiles, const char** pconffiles, int npfiles);

'pfiles' contains 'npfiles' char* structures which hold the password file name. 'pconffiles' contain the corresponding conf files.

This function specifies what we, in case of a server, are going to do when we have to use a password file. If this callback function is not provided then gnutls will automaticaly select the first password file

In case the callback returned a negative number then gnutls will not attempt to choose the appropriate certificate and the caller function will fail.

The callback function will only be called once per handshake. The callback function should return the index of the certificate choosen by the server. -1 indicates an error.


gnutls_certificate_free_sc

void gnutls_certificate_free_sc ( GNUTLS_CERTIFICATE_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_certificate_allocate_sc

int gnutls_certificate_allocate_sc ( GNUTLS_CERTIFICATE_CREDENTIALS * res )

Arguments

Description

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


gnutls_certificate_server_set_request

void gnutls_certificate_server_set_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_certificate_client_set_select_func

void gnutls_certificate_client_set_select_func ( GNUTLS_STATE state , certificate_client_select_func * func )

Arguments

Description

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

'client_cert' contains 'ncerts' gnutls_datum structures which hold the raw certificates (DER for X.509 or binary for OpenPGP), of the client.

'req_ca_cert', is only used in X.509 certificates. Contains a list with the CA names that the server considers trusted. Normaly we should send a certificate that is signed by one of these CAs. These names are DER encoded. To get a more meaningful value use the function gnutls_x509_extract_dn().

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. -1 indicates that the user does not want to use client authentication.

This function returns 0 on success.


gnutls_certificate_server_set_select_func

void gnutls_certificate_server_set_select_func ( GNUTLS_STATE state , certificate_server_select_func * func )

Arguments

Description

The callback's function form is: int (*callback)(GNUTLS_STATE, gnutls_datum *server_cert, int ncerts);

'server_cert' contains 'ncerts' gnutls_datum structures which hold the raw certificate (DER encoded in X.509) of the server.

This function specifies what we, in case of a server, 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. (actually send the first in the list)

In case the callback returned a negative number then gnutls will not attempt to choose the appropriate certificate and the caller function will fail.

The callback function will only be called once per handshake. The callback function should return the index of the certificate choosen by the server. -1 indicates an error.


gnutls_certificate_verify_peers

int gnutls_certificate_verify_peers ( GNUTLS_STATE state )

Arguments

Description

This function will try to verify the peer's certificate and return it's status (TRUSTED, EXPIRED etc.). The return value (status) should be one of the CertificateStatus enumerated elements. However you must also check the peer's name in order to check if the verified certificate belongs to the actual peer.

The return value (status) should be one or more of the CertificateStatus enumerated elements bitwise or'd.

GNUTLS_CERT_NOT_TRUSTED: the peer's certificate is not trusted.

GNUTLS_CERT_INVALID: the certificate chain is broken.

GNUTLS_CERT_REVOKED: the certificate has been revoked (not implemented yet).

GNUTLS_CERT_EXPIRED: the certificate has expired.

GNUTLS_CERT_CORRUPTED: the certificate is corrupted.

A negative error code is returned in case of an error. GNUTLS_E_NO_CERTIFICATE_FOUND is returned to indicate that no certificate was sent by the peer.


gnutls_global_set_log_func

void gnutls_global_set_log_func ( GNUTLS_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 ( void )

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.


gnutls_global_deinit

void gnutls_global_deinit ( void )

Arguments

Description

This function deinitializes the global state.


gnutls_transport_set_pull_func

void gnutls_transport_set_pull_func ( GNUTLS_STATE state , GNUTLS_PULL_FUNC pull_func )

Arguments

Description

This is the function where you set a function for gnutls to receive data. Normaly, if you use berkeley style sockets, you may not use this function since the default (recv(2)) will probably be ok. This function should be called once and after gnutls_global_init(). PULL_FUNC is of the form, ssize_t (*GNUTLS_PULL_FUNC)(GNUTLS_TRANSPORT_PTR, const void*, size_t);


gnutls_transport_set_push_func

void gnutls_transport_set_push_func ( GNUTLS_STATE state , GNUTLS_PUSH_FUNC push_func )

Arguments

Description

This is the function where you set a push function for gnutls to use in order to send data. If you are going to use berkeley style sockets, you may not use this function since the default (send(2)) will probably be ok. Otherwise you should specify this function for gnutls to be able to send data.

This function should be called once and after gnutls_global_init(). PUSH_FUNC is of the form, ssize_t (*GNUTLS_PUSH_FUNC)(GNUTLS_TRANSPORT_PTR, const void*, size_t);


gnutls_anon_free_server_sc

void gnutls_anon_free_server_sc ( GNUTLS_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_anon_allocate_server_sc

int gnutls_anon_allocate_server_sc ( GNUTLS_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_anon_free_client_sc

void gnutls_anon_free_client_sc ( GNUTLS_ANON_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_anon_allocate_client_sc

int gnutls_anon_allocate_client_sc ( GNUTLS_ANON_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_srp_server_get_username

const char * gnutls_srp_server_get_username ( GNUTLS_STATE state )

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. Returns NULL in case of an error.


gnutls_dh_set_prime_bits

void gnutls_dh_set_prime_bits ( GNUTLS_STATE state , int bits )

Arguments

Description

This function sets the number of bits, for use in an Diffie Hellman key exchange. This is used both in DH ephemeral and DH anonymous cipher suites. This will set the minimum size of the prime that will be used for the handshake.


gnutls_dh_get_prime_bits

int gnutls_dh_get_prime_bits ( GNUTLS_STATE state )

Arguments

Description

This function will return the bits used in the last Diffie Hellman authentication with the peer. Should be used for both anonymous and ephemeral diffie Hellman. Returns a negative value in case of an error.


gnutls_dh_get_secret_bits

int gnutls_dh_get_secret_bits ( GNUTLS_STATE state )

Arguments

Description

This function will return the bits used in the last Diffie Hellman authentication with the peer. Should be used for both anonymous and ephemeral diffie Hellman. Returns a negative value in case of an error.


gnutls_dh_get_peers_public_bits

int gnutls_dh_get_peers_public_bits ( GNUTLS_STATE state )

Arguments

Description

This function will return the bits used in the last Diffie Hellman authentication with the peer. Should be used for both anonymous and ephemeral diffie Hellman. Returns a negative value in case of an error.


gnutls_certificate_get_ours

const gnutls_datum * gnutls_certificate_get_ours ( GNUTLS_STATE state )

Arguments

Description

This function will return the raw certificate list as sent to the peer, in the last handshake. These certificates are in raw format. In X.509 this is a certificate list. In OpenPGP this is a single certificate. Returns NULL in case of an error, or if no certificate was used.


gnutls_certificate_get_peers

const gnutls_datum * gnutls_certificate_get_peers ( GNUTLS_STATE state , int * list_size )

Arguments

Description

This function will return the peer's raw certificate (list) as sent by the peer. These certificates are in raw format (DER encoded for X509). In case of a X509 then a certificate list may be present. The first certificate in the list is the peer's certificate, following the issuer's certificate, then the issuer's issuer etc. Returns NULL in case of an error, or if no certificate was sent.


gnutls_certificate_client_get_request_status

int gnutls_certificate_client_get_request_status ( GNUTLS_STATE state )

Arguments

Description

This function will return 0 if the peer (server) did not request client authentication or 1 otherwise. Returns a negative value in case of an error.


gnutls_x509_fingerprint

int gnutls_x509_fingerprint ( GNUTLS_DigestAlgorithm algo , const gnutls_datum* data , char* result , size_t* result_size )

Arguments

Description

This function will calculate a fingerprint (actually a hash), of the given data. The result is not printable data. You should convert it to hex, or to something else printable. Returns a negative value in case of an error.


gnutls_anon_set_server_dh_params

void gnutls_anon_set_server_dh_params ( GNUTLS_ANON_SERVER_CREDENTIALS res , GNUTLS_DH_PARAMS dh_params )

Arguments

Description

This function will set the diffie hellman parameters for an anonymous server to use. These parameters will be used in Anonymous Diffie Hellman cipher suites.


gnutls_certificate_set_dh_params

int gnutls_certificate_set_dh_params ( GNUTLS_CERTIFICATE_CREDENTIALS res , GNUTLS_DH_PARAMS dh_params )

Arguments

Description

This function will set the diffie hellman parameters for a certificate server to use. These parameters will be used in Ephemeral Diffie Hellman cipher suites.


gnutls_dh_params_set

int gnutls_dh_params_set ( GNUTLS_DH_PARAMS dh_params , gnutls_datum prime , gnutls_datum generator , int bits )

Arguments

Description

This function will replace the pair of prime and generator for use in the Diffie-Hellman key exchange. The new parameters should be stored in the appropriate gnutls_datum.

Note that the bits value should be one of 768, 1024, 2048, 3072 or 4096.


gnutls_dh_params_init

int gnutls_dh_params_init ( GNUTLS_DH_PARAMS* dh_params )

Arguments

Description

This function will initialize the DH parameters structure.


gnutls_dh_params_deinit

void gnutls_dh_params_deinit ( GNUTLS_DH_PARAMS dh_params )

Arguments

Description

This function will initialize the DH parameters structure.


gnutls_dh_params_generate

int gnutls_dh_params_generate ( gnutls_datum* prime , gnutls_datum* generator , int bits )

Arguments

Description

This function will generate a new pair of prime and generator for use in the Diffie-Hellman key exchange. The new parameters will be allocated using malloc and will be stored in the appropriate datum. This function is normally very slow. An other function (gnutls_dh_replace_params()) should be called in order to replace the included DH primes in the gnutls library.

Note that the bits value should be one of 768, 1024, 2048, 3072 or 4096. Also note that the generation of new DH parameters is only usefull to servers. Clients use the parameters sent by the server, thus it's no use calling this in client side.


gnutls_alert_send

int gnutls_alert_send ( GNUTLS_STATE state , GNUTLS_AlertLevel level , GNUTLS_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_alert_send_appropriate

int gnutls_alert_send_appropriate ( GNUTLS_STATE state , int err )

Arguments

Description

Sends an alert to the peer depending on the error code returned by a gnutls function. All alerts sent by this function are fatal, so connection should be considered terminated after calling this function. The only exception is when err == GNUTLS_E_REHANDSHAKE, then a warning alert is sent to the peer indicating the no renegotiation will be performed.

This function may also return GNUTLS_E_AGAIN, or GNUTLS_E_INTERRUPTED.

If the return value is GNUTLS_E_UNIMPLEMENTED_FEATURE, then no alert has been sent to the peer.


gnutls_alert_get

GNUTLS_AlertDescription gnutls_alert_get ( 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_alert_get_name

const char* gnutls_alert_get_name ( int alert )

Arguments

Description

Returns a string that describes the given alert number. See. gnutls_alert_get().


gnutls_cipher_get

GNUTLS_BulkCipherAlgorithm gnutls_cipher_get ( GNUTLS_STATE state )

Arguments

Description

Returns the currently used cipher.


gnutls_cert_type_get

GNUTLS_CertificateType gnutls_cert_type_get ( GNUTLS_STATE state )

Arguments

Description

Returns the currently used certificate type. The certificate type is by default X.509, unless it is negotiated as a TLS extension.


gnutls_kx_get

GNUTLS_KXAlgorithm gnutls_kx_get ( GNUTLS_STATE state )

Arguments

Description

Returns the key exchange algorithm used in the last handshake.


gnutls_mac_get

GNUTLS_MACAlgorithm gnutls_mac_get ( GNUTLS_STATE state )

Arguments

Description

Returns the currently used mac algorithm.


gnutls_compression_get

GNUTLS_CompressionMethod gnutls_compression_get ( GNUTLS_STATE state )

Arguments

Description

Returns the currently used compression method.


gnutls_init

int gnutls_init ( GNUTLS_STATE * state , GNUTLS_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

void gnutls_deinit ( GNUTLS_STATE state )

Arguments

Description

This function clears all buffers associated with the state.


gnutls_openpgp_send_key

void gnutls_openpgp_send_key ( GNUTLS_STATE state , GNUTLS_OpenPGPKeyStatus status )

Arguments

Description

This function will order gnutls to send the key fingerprint instead of the key in the initial handshake procedure. This should be used with care and only when there is indication or knowledge that the server can obtain the client's key.


gnutls_record_set_cbc_protection

void gnutls_record_set_cbc_protection ( GNUTLS_STATE state , int prot )

Arguments

Description

A newly discovered attack against the record protocol requires some counter-measures to be taken. GnuTLS will not enable them by default thus, sends an empty record packet, before each actual record packet, in order to assure that the IV is not known to potential attackers.

This function will enable or disable the chosen plaintext protection in the TLS record protocol (used with ciphers in CBC mode). if prot == 0 then protection is disabled (default), otherwise it is enabled.

The protection used will slightly decrease performance, and add 20 or more bytes per record packet.


gnutls_x509_extract_dn

int gnutls_x509_extract_dn ( const gnutls_datum * idn , gnutls_x509_dn * rdn )

Arguments

Description

This function will return the name of the given RDN sequence. The name will be returned as a gnutls_x509_dn structure. Returns a negative error code in case of an error.


gnutls_x509_extract_certificate_dn

int gnutls_x509_extract_certificate_dn ( const gnutls_datum * cert , gnutls_x509_dn * ret )

Arguments

Description

This function will return the name of the certificate holder. The name is gnutls_x509_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 error. Returns a negative error code in case of an error.


gnutls_x509_extract_certificate_issuer_dn

int gnutls_x509_extract_certificate_issuer_dn ( const gnutls_datum * cert , gnutls_x509_dn * ret )

Arguments

Description

This function will return the name of the issuer stated in the certificate. The name is a gnutls_x509_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 error. Returns a negative error code in case of an error.


gnutls_x509_extract_subject_alt_name

int gnutls_x509_extract_subject_alt_name ( const gnutls_datum * cert , int seq , char * ret , int * ret_size )

Arguments

Description

This function will return the alternative name (the dns part of it), contained in the given certificate.

This is specified in X509v3 Certificate Extensions. GNUTLS will return the Alternative name, or a negative error code. Returns GNUTLS_E_INVALID_REQUEST if ret_size is not enough to hold the alternative name, or the type of alternative name if everything was ok. The type is one of the enumerated GNUTLS_X509_SUBJECT_ALT_NAME.

If the certificate does not have an Alternative name with the specified sequence number then returns GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;


gnutls_x509_extract_certificate_activation_time

time_t gnutls_x509_extract_certificate_activation_time ( const gnutls_datum * cert )

Arguments

Description

This function will return the certificate's activation time in UNIX time (ie seconds since 00:00:00 UTC January 1, 1970). Returns a (time_t) -1 in case of an error.


gnutls_x509_extract_certificate_expiration_time

time_t gnutls_x509_extract_certificate_expiration_time ( const gnutls_datum * cert )

Arguments

Description

This function will return the certificate's expiration time in UNIX time (ie seconds since 00:00:00 UTC January 1, 1970). Returns a (time_t) -1 in case of an error.


gnutls_x509_extract_certificate_version

int gnutls_x509_extract_certificate_version ( const gnutls_datum * cert )

Arguments

Description

This function will return the X.509 certificate's version (1, 2, 3). This is obtained by the X509 Certificate Version field. Returns a negative value in case of an error.


gnutls_x509_verify_certificate

int gnutls_x509_verify_certificate ( const gnutls_datum* cert_list , int cert_list_length , const gnutls_datum * CA_list , int CA_list_length , const gnutls_datum* CRL_list , int CRL_list_length )

Arguments

Description

This function will try to verify the given certificate list and return it's status (TRUSTED, EXPIRED etc.). The return value (status) should be one or more of the CertificateStatus enumerated elements bitwise or'd.

However you must also check the peer's name in order to check if the verified certificate belongs to the actual peer.

Returns a negative error code in case of an error.


gnutls_x509_extract_certificate_serial

int gnutls_x509_extract_certificate_serial ( const gnutls_datum * cert , char* result , int* result_size )

Arguments

Description

This function will return the X.509 certificate's serial number. This is obtained by the X509 Certificate serialNumber field. Serial is not always a 32 or 64bit number. Some CAs use large serial numbers, thus it may be wise to handle it as something opaque. Returns a negative value in case of an error.


gnutls_certificate_set_x509_key_file

int gnutls_certificate_set_x509_key_file ( GNUTLS_CERTIFICATE_CREDENTIALS res , char * CERTFILE , char * KEYFILE , GNUTLS_X509_CertificateFmt type )

Arguments

Description

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

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


gnutls_certificate_set_x509_trust_mem

int gnutls_certificate_set_x509_trust_mem ( GNUTLS_CERTIFICATE_CREDENTIALS res , const gnutls_datum * CA , GNUTLS_X509_CertificateFmt type )

Arguments

Description

This function adds the trusted CAs in order to verify client certificates. This function may be called multiple times.


gnutls_certificate_set_x509_trust_file

int gnutls_certificate_set_x509_trust_file ( GNUTLS_CERTIFICATE_CREDENTIALS res , char * CAFILE , GNUTLS_X509_CertificateFmt type )

Arguments

Description

This function sets the trusted CAs in order to verify client certificates. This function may be called multiple times. Returns the number of certificate processed.


gnutls_certificate_set_x509_key_mem

int gnutls_certificate_set_x509_key_mem ( GNUTLS_CERTIFICATE_CREDENTIALS res , const gnutls_datum* CERT , const gnutls_datum* KEY , GNUTLS_X509_CertificateFmt type )

Arguments

Description

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

Currently are supported

RSA PKCS-1 encoded private keys, DSA private keys.

DSA private keys are encoded the OpenSSL way, which is an ASN.1 DER sequence of 6 INTEGERs - version, p, q, g, pub, priv.


gnutls_x509_pkcs7_extract_certificate

int gnutls_x509_pkcs7_extract_certificate ( const gnutls_datum * pkcs7_struct , int indx , char* certificate , int* certificate_size )

Arguments

Description

This function will return a certificate of the PKCS7 or RFC2630 certificate set. Returns 0 on success. If the provided buffer is not long enough, then GNUTLS_E_INVALID_REQUEST is returned.


gnutls_x509_extract_certificate_pk_algorithm

int gnutls_x509_extract_certificate_pk_algorithm ( const gnutls_datum * cert , int* bits )

Arguments

Description

This function will return the public key algorithm of an X.509 certificate.

If bits is non null, it should have enough size to hold the parameters size in bits. For RSA the bits returned is the modulus. For DSA the bits returned are of the public exponent.

Returns a member of the GNUTLS_PKAlgorithm enumeration on success, or a negative value on error.


gnutls_x509_pkcs7_extract_certificate_count

int gnutls_x509_pkcs7_extract_certificate_count ( const gnutls_datum * pkcs7_struct )

Arguments

Description

This function will return the certificate number of the PKCS7 or RFC2630 certificate set. Returns a negative value on failure.


gnutls_openpgp_get_key

int gnutls_openpgp_get_key ( gnutls_datum * key , const gnutls_datum * keyring , key_attr_t by , opaque * pattern )

Arguments

Description

This function can be used to retrieve keys by different pattern from a binary or a file keyring.


gnutls_certificate_set_openpgp_key_file

int gnutls_certificate_set_openpgp_key_file ( GNUTLS_CERTIFICATE_CREDENTIALS res , char* CERTFILE , char* KEYFILE )

Arguments

Description

This funtion is used to load OpenPGP keys into the GnuTLS structure. It doesn't matter whether the keys are armored or but, but the files should only contain one key which should not be encrypted.


gnutls_openpgp_extract_key_name

int gnutls_openpgp_extract_key_name ( const gnutls_datum * cert , int idx , gnutls_openpgp_name * dn )

Arguments

Description

Extracts the userID from the raw OpenPGP key.


gnutls_openpgp_extract_key_pk_algorithm

int gnutls_openpgp_extract_key_pk_algorithm ( const gnutls_datum * cert , int * r_bits )

Arguments

Description

This function will return the public key algorithm of an OpenPGP certificate.

If bits is non null, it should have enough size to hold the parameters size in bits. For RSA the bits returned is the modulus. For DSA the bits returned are of the public exponent.

Returns a member of the GNUTLS_PKAlgorithm enumeration on success, or a negative value on error.


gnutls_openpgp_extract_key_version

int gnutls_openpgp_extract_key_version ( const gnutls_datum * cert )

Arguments

Description

Extract the version of the OpenPGP key.


gnutls_openpgp_extract_key_creation_time

time_t gnutls_openpgp_extract_key_creation_time ( const gnutls_datum * cert )

Arguments

Description

Returns the timestamp when the OpenPGP key was created.


gnutls_openpgp_extract_key_expiration_time

time_t gnutls_openpgp_extract_key_expiration_time ( const gnutls_datum * cert )

Arguments

Description

Returns the time when the OpenPGP key expires. A value of '0' means that the key doesn't expire at all.


gnutls_openpgp_verify_key

int gnutls_openpgp_verify_key ( const char * trustdb , const gnutls_datum* keyring , const gnutls_datum* cert_list , int cert_list_length )

Arguments

Description

Verify all signatures in the certificate list. When the key is not available, the signature is skipped. The return value is one of the CertificateStatus entries.


gnutls_openpgp_fingerprint

int gnutls_openpgp_fingerprint ( const gnutls_datum * cert , byte * fpr , size_t * fprlen )

Arguments

Description

Returns the fingerprint of the OpenPGP key. Depence on the algorithm, the fingerprint can be 16 or 20 bytes.


gnutls_openpgp_keyid

int gnutls_openpgp_keyid ( const gnutls_datum * cert , uint32 * keyid )

Arguments

Description

Returns the 64-bit keyID of the OpenPGP key.


gnutls_openpgp_add_keyring_file

int gnutls_openpgp_add_keyring_file ( gnutls_datum * keyring , const char * name )

Arguments

Description

The function is used to set keyrings that will be used internally by various OpenCDK functions. For example to find a key when it is needed for an operations.


gnutls_openpgp_add_keyring_mem

int gnutls_openpgp_add_keyring_mem ( gnutls_datum * keyring , const char * data , size_t len )

Arguments

Description

Same as gnutls_openpgp_add_keyring_mem but now we store the data instead of the filename.


gnutls_openpgp_recv_key

int gnutls_openpgp_recv_key ( const char * host , short port , uint32 keyid , gnutls_datum * key )

Arguments

Description

@host - the hostname of the keyserver. @port - the service port (if not set use 11371). @keyid - The 32-bit keyID (rightmost bits keyid[1]) @key - Context to store the raw (dearmored) key.

Try to connect to a public keyserver to get the specified key.


gnutls_certificate_set_openpgp_keyserver

void gnutls_certificate_set_openpgp_keyserver ( GNUTLS_CERTIFICATE_CREDENTIALS res , char* keyserver , int port )

Arguments

Description

This funtion will set a key server for use with openpgp keys. This key server will only be used if the peer sends a key fingerprint instead of a key in the handshake. Using a key server may delay the handshake process.

ASN.1 parser function reference


asn1_parser_asn1

int asn1_parser_asn1 ( char * file_name , node_asn ** pointer )

Arguments

Description

Creates the structures needed to manage the definitions included in *FILE_NAME file.

Returns

ASN_OK: the file has a correct syntax and every identifier is known.

ASN_FILE_NOT_FOUND: an error occured while opening FILE_NAME.

ASN_SYNTAX_ERROR: the syntax is not correct.

ASN_IDENTIFIER_NOT_FOUND: in the file there is an identifier that is not defined.


asn1_parser_asn1_file_c

int asn1_parser_asn1_file_c ( char * file_name )

Arguments

Description

Creates a file containing a C vector to use to manage the definitions included in *FILE_NAME file. If *FILE_NAME is "/aa/bb/xx.yy" the file created is "/aa/bb/xx_asn1_tab.c", and the vector is "xx_asn1_tab".

Returns

ASN_OK: the file has a correct syntax and every identifier is known.

ASN_FILE_NOT_FOUND: an error occured while opening FILE_NAME.

ASN_SYNTAX_ERROR: the syntax is not correct.

ASN_IDENTIFIER_NOT_FOUND: in the file there is an identifier that is not defined.


asn1_create_tree

int asn1_create_tree ( const static_asn * root , node_asn ** pointer )

Arguments

Description

Creates the structures needed to manage the ASN1 definitions. ROOT is a vector created by 'asn1_parser_asn1_file_c' function.

Returns

ASN_OK: structure created correctly.

ASN_GENERIC_ERROR: an error occured while structure creation


asn1_visit_tree

void asn1_visit_tree ( node_asn * pointer , char * name )

Arguments

Description

Prints on the standard output the structure's tree starting from the NAME element inside the structure *POINTER.


asn1_delete_structure

int asn1_delete_structure ( node_asn * root )

Arguments

Description

Deletes the structure *POINTER.

Returns

ASN_OK: everything OK

ASN_ELEMENT_NOT_FOUND: pointer==NULL.


asn1_create_structure

int asn1_create_structure ( node_asn * root , char * source_name , node_asn ** pointer , char * dest_name )

Arguments

Description

Creates a structure called DEST_NAME of type SOURCE_NAME.

Returns

ASN_OK: creation OK

ASN_ELEMENT_NOT_FOUND: SOURCE_NAME isn't known

Example

using "pkix.asn" result=asn1_create_structure(cert_def,"PKIX1.Certificate",cert,"certificate1");


asn1_write_value

int asn1_write_value ( node_asn * node_root , char * name , unsigned char * value , int len )

Arguments

Description

Set the value of one element inside a structure.

Returns

ASN_OK: set value OK

ASN_ELEMENT_NOT_FOUND: NAME is not a valid element.

ASN_VALUE_NOT_VALID: VALUE has a wrong format.

Examples

description for each type

INTEGER

VALUE must contain a two's complement form integer. value[0]=0xFF , len=1 $ \rightarrow$ integer=-1 value[0]=0xFF value[1]=0xFF , len=2 $ \rightarrow$ integer=-1 value[0]=0x01 , len=1 $ \rightarrow$ integer= 1 value[0]=0x00 value[1]=0x01 , len=2 $ \rightarrow$ integer= 1 value="123" , len=0 $ \rightarrow$ integer= 123

ENUMERATED

as INTEGER (but only with not negative numbers)

BOOLEAN

VALUE must be the null terminated string "TRUE" or "FALSE" and LEN != 0 value="TRUE" , len=1 $ \rightarrow$ boolean=TRUE value="FALSE" , len=1 $ \rightarrow$ boolean=FALSE

OBJECT IDENTIFIER

VALUE must be a null terminated string with each number separated by a blank (e.g. "1 2 3 543 1"). LEN != 0 value="1 2 840 10040 4 3" , len=1 $ \rightarrow$ OID=dsa-with-sha

UTCTime

VALUE must be a null terminated string in one of these formats: "YYMMDDhhmmssZ" "YYMMDDhhmmssZ" "YYMMDDhhmmss+hh'mm'" "YYMMDDhhmmss-hh'mm'" "YYMMDDhhmm+hh'mm'" "YYMMDDhhmm-hh'mm'". LEN != 0 value="9801011200Z" , len=1 $ \rightarrow$ time=Jannuary 1st, 1998 at 12h 00m Greenwich Mean Time

GeneralizedTime

VALUE must be in one of this format: "YYYYMMDDhhmmss.sZ" "YYYYMMDDhhmmss.sZ" "YYYYMMDDhhmmss.s+hh'mm'" "YYYYMMDDhhmmss.s-hh'mm'" "YYYYMMDDhhmm+hh'mm'" "YYYYMMDDhhmm-hh'mm'" where ss.s indicates the seconds with any precision like "10.1" or "01.02". LEN != 0 value="2001010112001.12-0700" , len=1 $ \rightarrow$ time=Jannuary 1st, 2001 at 12h 00m 01.12s Pacific Daylight Time

OCTET STRING

VALUE contains the octet string and LEN is the number of octet. value=" \x01 \x02 \x03" , len=3 $ \rightarrow$ three bytes octet string

BIT STRING

VALUE contains the bit string organized by bytes and LEN is the number of bits. value=" \xCF" , len=6 $ \rightarrow$ bit string="110011" (six bits)

CHOICE

if NAME indicates a choice type, VALUE must specify one of the alternatives with a null terminated string. LEN != 0 Using "pkix.asn": result=asn1_write_value(cert,"certificate1.tbsCertificate.subject","rdnSequence",1);

ANY

VALUE indicates the der encoding of a structure. LEN != 0

SEQUENCE OF

VALUE must be the null terminated string "NEW" and LEN != 0. With this instruction another element is appended in the sequence. The name of this element will be "?1" if it's the first one, "?2" for the second and so on. Using "pkix.asn": result=asn1_write_value(cert,"certificate1.tbsCertificate.subject.rdnSequence","NEW",1);

SET OF

the same as SEQUENCE OF. Using "pkix.asn": result=asn1_write_value(cert,"certificate1.tbsCertificate.subject.rdnSequence.?LAST","NEW",1);

If an element is OPTIONAL and you want to delete it, you must use the value=NULL and len=0. Using "pkix.asn": result=asn1_write_value(cert,"certificate1.tbsCertificate.issuerUniqueID",NULL,0);


asn1_read_value

int asn1_read_value ( node_asn * root , char * name , unsigned char * value , int * len )

Arguments

Description

Returns the value of one element inside a structure.

Returns

ASN_OK: set value OK

ASN_ELEMENT_NOT_FOUND: NAME is not a valid element.

ASN_VALUE_NOT_FOUND: there isn't any value for the element selected.

Examples

a description for each type

INTEGER

VALUE will contain a two's complement form integer. integer=-1 $ \rightarrow$ value[0]=0xFF , len=1 integer=1 $ \rightarrow$ value[0]=0x01 , len=1

ENUMERATED

as INTEGER (but only with not negative numbers)

BOOLEAN

VALUE will be the null terminated string "TRUE" or "FALSE" and LEN=5 or LEN=6

OBJECT IDENTIFIER

VALUE will be a null terminated string with each number separated by a blank (i.e. "1 2 3 543 1"). LEN = strlen(VALUE)+1

UTCTime

VALUE will be a null terminated string in one of these formats: "YYMMDDhhmmss+hh'mm'" or "YYMMDDhhmmss-hh'mm'" LEN=strlen(VALUE)+1

GeneralizedTime

VALUE will be a null terminated string in the same format used to set the value

OCTET STRING

VALUE will contain the octet string and LEN will be the number of octet.

BIT STRING

VALUE will contain the bit string organized by bytes and LEN will be the number of bits.

CHOICE

if NAME indicates a choice type, VALUE will specify the alternative selected

ANY

if NAME indicates an any type, VALUE will indicate the DER encoding of the structure actually used.

If an element is OPTIONAL and the function "read_value" returns ASN_ELEMENT_NOT_FOUND, it means that this element wasn't present in the der encoding that created the structure. The first element of a SEQUENCE_OF or SET_OF is named "?1". The second one "?2" and so on.


asn1_number_of_elements

int asn1_number_of_elements ( node_asn * root , char * name , int * num )

Arguments

Description

Counts the number of elements of a sub-structure called NAME with names equal to "?1","?2", ...

Returns

ASN_OK

creation OK

ASN_ELEMENT_NOT_FOUND

NAME isn't known

ASN_GENERIC_ERROR

parameter num equal to NULL


asn1_create_der

int asn1_create_der ( node_asn * root , char * name , unsigned char * der , int * len )

Arguments

Description

Creates the DER encoding for the NAME structure (inside *POINTER structure).

Returns

ASN_OK: DER encoding OK

ASN_ELEMENT_NOT_FOUND: NAME is not a valid element.

ASN_VALUE_NOT_FOUND: there is an element without a value.


asn1_get_der

int asn1_get_der ( node_asn * root , unsigned char * der , int len )

Arguments

Description

Fill the structure *POINTER with values of a DER encoding string. The sructure must just be created with function 'create_stucture'.

Returns

ASN_OK: DER encoding OK

ASN_ELEMENT_NOT_FOUND: NAME is not a valid element.

ASN_TAG_ERROR,ASN_DER_ERROR: the der encoding doesn't match the structure NAME.


asn1_get_start_end_der

int asn1_get_start_end_der ( node_asn * root , unsigned char * der , int len , char * name_element , int * start , int * end )

Arguments

Description

Find the start and end point of an element in a DER encoding string. I mean that if you have a der encoding and you have already used the function "get_der" to fill a structure, it may happen that you want to find the piece of string concerning an element of the structure.

Example

the sequence "tbsCertificate" inside an X509 certificate.

Returns

ASN_OK: DER encoding OK

ASN_ELEMENT_NOT_FOUND: NAME or NAME_ELEMENT is not a valid element.

ASN_TAG_ERROR,ASN_DER_ERROR: the der encoding doesn't match the structure NAME.

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

...1.1
described in RFC 2246
...IETF1.2
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.
... algorithms1.3
There are ciphersuites in TLS 1.0 that are considered weak. These ciphersuites are deliberately weak in order to be able to export encryption software from some countries.
...AES1.4
AES or Advanced Encryption Standard is actually the RIJNDAEL algorithm. This is the algorithm that will replace DES.
...ARCFOUR1.5
ARCFOUR is a compatible algorithm with RSA's RC4 algorithm.
...insecure1.6
due to small key length
... MAC1.7
MAC stands for Message Authentication Code. It can be described as a keyed hash algorithm. See RFC2104.
... toolkit1.8
Aegypten is such a toolkit. See http://www.gnupg.org/aegypten/
...DSS1.9
DSS stands for Digital Signature Standard
... SRP1.10
SRP stands for Secure Password Protocol and is described in RFC2945. The SRP key exchange is not a part of the TLS 1.0protocol
... proposal2.1
This is work in progress.
... developed3.1
ASN.1 Structure handling in GNUTLS is developed by Fabio Fiorina


Nikos Mavroyanopoulos 2002-04-01