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".
GNUTLS is a portable library which implements the TLS 1.0 and
SSL 3.0 protocols.
TLS stands for 'Transport Layer Security' and is the sucessor of SSL1.1.
TLS 1.01.2 is an Internet protocol,
defined by IETF1.3that provides confidentiality, and authentication layers over a reliable
transport layer1.4. GNUTLS implements the
above protocols in reentrant way in order to be used in multiple threads of
execution (without the need for Critical Sections 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:
the TLS 1.0 and SSL 3.0 protocols, without any weak algorithms1.5
X.509 Public Key Infrastructure (with several limitations).
TLS 1.0 supports ciphersuites like TLS_X509PKI_DHE_RSA_WITH_3DES_CBC_SHA.
These ciphersuites contain three parameters:
The authentication method (X.509 PKI in the example)1.6
The key exchange algorithm (DHE_RSA in the example)
The Symmetric encryption algorithm and mode (3DES_CBC in this
example)
The MAC1.7 algorithm used for authentication.
MAC_SHA is used in the above example.
The ciphersuite that will be used in the connection is negotiated at
the handshake procedure. However you must 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.
Confidentiality is provided by using block encryption algorithms like 3DES,
AES1.8, or
stream algorithms like ARCFOUR1.9 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.
If using this kind of authentication then the key exchange methods
shown in figure are
available to use. Authentication in this method is performed using signed
certificates by a trusted Certificate Authority (CA). Note that GNUTLS is
not a generic purpose X.509 toolkit1.12.
It does only include the required,
in order to use the TLS ciphersuites which require X.509 certificates.
The anonymous key exchanges 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.
Authentication using the SRP1.14is 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.
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.
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).
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.
GNUTLS can be used above any reliable transport layer. To do this you will only
need to set up the
gnutls_transport_set_push_func() and
gnutls_transport_set_pull_func()
functions. These functions will then be used by gnutls in order to send and receive data.
The functions specified 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.
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_MAC_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_read().
This error code requires a full handshake to be performed again, or an alert to be sent.
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 reaction, are to be returned by a
function, these error codes will be documented
in the function's reference.
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_X509PKI_CLIENT_CREDENTIALS xcred;
const int protocol_priority[] = { GNUTLS_TLS1, GNUTLS_SSL3, 0 };
const int kx_priority[] = { GNUTLS_KX_X509PKI_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_x509pki_allocate_client_sc(&xcred, 0) < 0) { /* no client private key */
fprintf(stderr, "memory error\n");
exit(1);
}
/* set's the trusted cas file
*/
gnutls_x509pki_set_client_trust_file(xcred, CAFILE, CRLFILE);
/* connects to server
*/
sd = socket(AF_INET, SOCK_STREAM, 0);
memset(&sa, '\0', sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_port = htons(atoi(PORT));
inet_pton(AF_INET, SERVER, &sa.sin_addr);
err = connect(sd, (SA *) & sa, sizeof(sa));
if (err < 0) {
fprintf(stderr, "Connect error\n");
exit(1);
}
/* Initialize TLS state
*/
gnutls_init(&state, GNUTLS_CLIENT);
/* allow both SSL3 and TLS1
*/
gnutls_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_X509PKI_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_X509PKI, 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_write( state, MSG, strlen(MSG));
ret = gnutls_read( 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_last(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_x509pki_free_client_sc(xcred);
gnutls_global_deinit();
return 0;
}
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.
Although SRP is not part of the TLS standard, GNUTLS implements
David Taylor's1.15 proposal 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_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_write( state, MSG, strlen(MSG));
ret = gnutls_read( 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_last(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;
}
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_STATE *state:
is a pointer to a GNUTLS_STATE structure.
ConnectionEndcon_end:
is used to indicate if this state is to be used for server or
client. Can be one of GNUTLS_CLIENT and GNUTLS_SERVER.
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
voidgnutls_deinit
(
GNUTLS_STATEstate
)
Arguments
GNUTLS_STATEstate:
is a GNUTLS_STATE structure.
Description
This function clears all buffers associated with the state.
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.
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.
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 must
either send an alert containing NO_RENEGOTIATION, or perform a
handshake. (only a client may receive this message)
This function returns the maximum record size in this connection.
The maximum record size is negotiated by the client after the
first handshake message.
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_check_pending
intgnutls_check_pending
(
GNUTLS_STATEstate
)
Arguments
GNUTLS_STATEstate:
is a GNUTLS_STATE structure.
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
intgnutls_rehandshake
(
GNUTLS_STATEstate
)
Arguments
GNUTLS_STATEstate:
is a a GNUTLS_STATE structure.
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
intgnutls_handshake
(
GNUTLS_STATEstate
)
Arguments
GNUTLS_STATEstate:
is a a GNUTLS_STATE structure.
Description
This function does the handshake of the TLS/SSL protocol,
and initializes the TLS connection. Here the identity of the peer
is checked automatically.
This function will fail if any problem is encountered,
and 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)
This function will set the maximum size of the handshake message sequence.
Since the handshake messages are kept into memory until the handshake is successful
this function allows you to set the maximum number of bytes that will be kept.
The default value is 128kb which is large enough. Set this to 0 if you do not want
to set an upper limit.
gnutls_error_is_fatal
intgnutls_error_is_fatal
(
interror
)
Arguments
interror:
is an error returned by a gnutls function. Error should be a negative value.
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
voidgnutls_perror
(
interror
)
Arguments
interror:
is an error returned by a gnutls function. Error is always a negative value.
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
(
interror
)
Arguments
interror:
is an error returned by a gnutls function. Error is always a negative value.
Description
This function is similar to strerror(). The only difference is that it
accepts an error (number) returned by a gnutls function.
GNUTLS_LISTlist:
is a 0 terminated list of BulkCipherAlgorithm elements.
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_LISTlist:
is a 0 terminated list of KXAlgorithm elements.
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_LISTlist:
is a 0 terminated list of MACAlgorithm elements.
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_LISTlist:
is a 0 terminated list of CompressionMethod elements.
Description
Sets the priority on the compression algorithms supported by gnutls.
Priority is higher for algorithms specified before others.
After specifying the algorithms you want, you should add 0.
Note that the priority is set on the client. The server does
not use the algorithm's priority except for disabling
algorithms that were not specified.
GNUTLS_LISTlist:
is a 0 terminated list of GNUTLS_Version elements.
Description
Sets the priority on the protocol versions supported by gnutls.
Priority is higher for protocols specified before others.
After specifying the protocols you want, you should add 0.
Note that the priority is set on the client. The server does
not use the protocols's priority except for disabling
protocols that were not specified.
gnutls_session_get_data
intgnutls_session_get_data
(
GNUTLS_STATEstate
, opaque*session
, int *session_size
)
Arguments
GNUTLS_STATEstate:
is a GNUTLS_STATE structure.
opaque*session:
is a pointer to space to hold the session.
int *session_size:
is the session's size, or it will be set by the function.
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
intgnutls_session_get_id
(
GNUTLS_STATEstate
, void*session
, int *session_size
)
Arguments
GNUTLS_STATEstate:
is a GNUTLS_STATE structure.
void*session:
is a pointer to space to hold the session id.
int *session_size:
is the session id's size, or it will be set by the function.
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.
opaque*session:
is a pointer to space to hold the session.
intsession_size:
is the session's size
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.
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.
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.
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.
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_STATEstate
)
Arguments
GNUTLS_STATEstate:
is a GNUTLS_STATE structure.
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.
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_datumsession_entry:
is the session data (not key)
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
intgnutls_db_clean
(
GNUTLS_STATEstate
)
Arguments
GNUTLS_STATEstate:
is a GNUTLS_STATE structure.
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.
Sets the needed credentials for the specified type.
Eg username, password - or public and private keys etc.
The (void* cred) parameter is a structure that depends on the
specified type and on the current state (client or server).
[ In order to minimize memory usage, and share credentials between
several threads gnutls keeps a pointer to cred, and not the whole cred
structure. Thus you will have to keep the structure allocated until
you call gnutls_deinit(). ]
For GNUTLS_ANON cred should be ANON_CLIENT_CREDENTIALS in case of a client.
In case of a server it should be ANON_SERVER_CREDENTIALS.
For GNUTLS_SRP cred should be SRP_CLIENT_CREDENTIALS
in case of a client, and SRP_SERVER_CREDENTIALS, in case
of a server.
For GNUTLS_X509PKI cred should be X509PKI_CLIENT_CREDENTIALS
in case of a client, and X509PKI_SERVER_CREDENTIALS, in case
of a server.
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 X509PKI ciphersuites (key exchange algorithms: KX_RSA, KX_DHE_RSA),
the same function are to be used to access the authentication data.
GNUTLS_X509PKI_CREDENTIALSres:
is an GNUTLS_X509PKI_CREDENTIALS structure.
char *CERTFILE:
is a PEM encoded file containing the certificate list (path) for
the specified private key
char *KEYFILE:
is a PEM encoded file containing a private key
Description
This function sets a certificate/private key pair in the
GNUTLS_X509PKI_CREDENTIALS structure. This function may be called
more than once (in case multiple keys/certificates exist for the
server).
Currently only PKCS-1 PEM encoded RSA private keys are accepted by
this function.
CertificateRequestreq:
is one of GNUTLS_CERT_REQUEST, GNUTLS_CERT_REQUIRE
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.
x509pki_client_cert_callback_func *func:
is the callback function
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 DER encoded X.509 certificates of the client.
'req_ca_cert' 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_x509pki_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.
x509pki_server_cert_callback_func *func:
is the callback function
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 DER encoded X.509 certificates 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.
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
intgnutls_global_init
( void
)
Arguments
void:
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.
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 (*PULL_FUNC)(GNUTLS_SOCKET_PTR, const void*, size_t);
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 (*PUSH_FUNC)(GNUTLS_SOCKET_PTR, const void*, size_t);
const gnutls_datum *idn:
should contain a DER encoded RDN sequence
gnutls_DN *rdn:
a pointer to a structure to hold the name
Description
This function will return the name of the given RDN sequence.
The name will be returned as a gnutls_DN structure.
Returns a negative error code in case of an error.
const gnutls_datum *cert:
should contain an X.509 DER encoded certificate
gnutls_DN *ret:
a pointer to a structure to hold the peer's name
Description
This function will return the name of the certificate holder. The name is gnutls_DN structure and
is a obtained by the peer's certificate. If the certificate send by the
peer is invalid, or in any other failure this function returns error.
Returns a negative error code in case of an error.
const gnutls_datum *cert:
should contain an X.509 DER encoded certificate
gnutls_DN *ret:
a pointer to a structure to hold the issuer's name
Description
This function will return the name of the issuer stated in the certificate. The name is a gnutls_DN structure and
is a obtained by the peer's certificate. If the certificate send by the
peer is invalid, or in any other failure this function returns error.
Returns a negative error code in case of an error.
const gnutls_datum *cert:
should contain an X.509 DER encoded certificate
char *ret:
is the place where dns name will be copied to
int *ret_size:
holds the size of ret.
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 only return the dnsName of the Alternative name, or a negative
error code.
Returns GNUTLS_E_MEMORY_ERROR if ret_size is not enough to hold dns name,
or the size of dns name if everything was ok.
If the certificate does not have a DNS name then returns GNUTLS_E_DATA_NOT_AVAILABLE;
const gnutls_datum * cert:
should contain an X.509 DER encoded certificate
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.
const gnutls_datum * cert:
should contain an X.509 DER encoded certificate
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.
const gnutls_datum *cert:
is an X.509 DER encoded certificate
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.
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. Returns a negative error code in case of an error, or GNUTLS_CERT_NONE if no certificate was sent.
const gnutls_datum *cert:
is an X.509 DER encoded certificate
char*result:
The place where the serial number will be copied
int*result_size:
Holds the size of the result field.
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.
const gnutls_datum*cert_list:
is the certificate list to be verified
intcert_list_length:
holds the number of certificate in cert_list
const gnutls_datum *CA_list:
is the CA list which will be used in verification
intCA_list_length:
holds the number of CA certificate in CA_list
const gnutls_datum*CRL_list:
not used
intCRL_list_length:
not used
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 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. Returns a negative error code in case of an error.
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.
This function will return the bits used in the Diffie Hellman authentication
with the peer. This should only be called in case of a server.
Returns a negative value in case of an error.
This function will return the bits used in the Diffie Hellman authentication
with the peer. This should only be called in case of a client.
Returns a negative value in case of an error.
gnutls_x509pki_get_peer_certificate_list
const gnutls_datum *gnutls_x509pki_get_peer_certificate_list
(
GNUTLS_STATEstate
, int *list_size
)
Arguments
GNUTLS_STATEstate:
is a gnutls state
int *list_size:
is the length of the certificate list
Description
This function will return the peer's raw certificate list as sent by the peer.
These certificates are DER encoded. 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.
This function will return the number of bits used in a Diffie Hellman Handshake. This will only
occur in case of DHE_* ciphersuites. The return value may be zero if no applicable ciphersuite was
used.
Returns a negative value in case of an error.
char*result:
is the place where the result will be copied.
int*result_size:
should hold the size of the result. The actual size
of the returned result will also be copied there.
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.
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. This function should not be called while a key
exchange is in progress.
Note that the bits value should be one of 1024, 2048, 3072 or 4096.
gnutls_datum*generator:
will hold the new generator
intbits:
is the prime's number of bits
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 stored in the
appropriate gnutls_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 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.