This is gnutls.info, produced by makeinfo version 4.13.90 from
gnutls.texi.
This manual is last updated 2 September 2012 for version 3.0.30 of
GnuTLS.
Copyright (C) 2001-2012 Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this
document under the terms of the GNU Free Documentation License,
Version 1.3 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
section entitled "GNU Free Documentation License".
INFO-DIR-SECTION Software libraries
START-INFO-DIR-ENTRY
* GnuTLS: (gnutls). GNU Transport Layer Security Library.
END-INFO-DIR-ENTRY
INFO-DIR-SECTION System Administration
START-INFO-DIR-ENTRY
* certtool: (gnutls)Invoking certtool. Manipulate certificates and keys.
* gnutls-serv: (gnutls)Invoking gnutls-serv. GnuTLS test server.
* gnutls-cli: (gnutls)Invoking gnutls-cli. GnuTLS test client.
* gnutls-cli-debug: (gnutls)Invoking gnutls-cli-debug. GnuTLS debug client.
* psktool: (gnutls)Invoking psktool. Simple TLS-Pre-Shared-Keys manager.
* srptool: (gnutls)Invoking srptool. Simple SRP password tool.
END-INFO-DIR-ENTRY
File: gnutls.info, Node: Top, Next: Preface, Up: (dir)
GnuTLS
******
This manual is last updated 2 September 2012 for version 3.0.30 of
GnuTLS.
Copyright (C) 2001-2012 Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this
document under the terms of the GNU Free Documentation License,
Version 1.3 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
section entitled "GNU Free Documentation License".
* Menu:
* Preface::
* Introduction to GnuTLS::
* Introduction to TLS::
* Certificate authentication::
* Shared-key and anonymous authentication::
* More on certificate authentication::
* How to use GnuTLS in applications::
* GnuTLS application examples::
* Other included programs::
* Internal architecture of GnuTLS::
* Upgrading from previous versions::
* Support::
* Error codes::
* Supported ciphersuites::
* API reference::
* Copying Information::
* Bibliography::
* Function and Data Index::
* Concept Index::
File: gnutls.info, Node: Preface, Next: Introduction to GnuTLS, Prev: Top, Up: Top
1 Preface
*********
This document demonstrates and explains the GnuTLS library API. A brief
introduction to the protocols and the technology involved is also
included so that an application programmer can better understand the
GnuTLS purpose and actual offerings. Even if GnuTLS is a typical
library software, it operates over several security and cryptographic
protocols which require the programmer to make careful and correct usage
of them. Otherwise it is likely to only obtain a false sense of
security. The term of security is very broad even if restricted to
computer software, and cannot be confined to a single cryptographic
library. For that reason, do not consider any program secure just
because it uses GnuTLS; there are several ways to compromise a program
or a communication line and GnuTLS only helps with some of them.
Although this document tries to be self contained, basic network
programming and public key infrastructure (PKI) knowledge is assumed in
most of it. A good introduction to networking can be found in
[_STEVENS_], to public key infrastructure in [_GUTPKI_] and to security
engineering in [_ANDERSON_].
Updated versions of the GnuTLS software and this document will be
available from and
.
File: gnutls.info, Node: Introduction to GnuTLS, Next: Introduction to TLS, Prev: Preface, Up: Top
2 Introduction to GnuTLS
************************
In brief GnuTLS can be described as a library which offers an API to
access secure communication protocols. These protocols provide privacy
over insecure lines, and were designed to prevent eavesdropping,
tampering, or message forgery.
Technically GnuTLS is a portable ANSI C based library which implements
the protocols ranging from SSL 3.0 to TLS 1.2 (see *note Introduction to
TLS::, for a detailed description of the protocols), accompanied with
the required framework for authentication and public key infrastructure.
Important features of the GnuTLS library include:
* Support for TLS 1.2, TLS 1.1, TLS 1.0 and SSL 3.0 protocols.
* Support for Datagram TLS 1.0.
* Support for handling and verification of X.509 and OpenPGP
certificates.
* Support for password authentication using TLS-SRP.
* Support for keyed authentication using TLS-PSK.
* Support for PKCS #11 tokens and smart-cards.
The GnuTLS library consists of three independent parts, namely the "TLS
protocol part", the "Certificate part", and the "Cryptographic back-end"
part. The "TLS protocol part" is the actual protocol implementation,
and is entirely implemented within the GnuTLS library. The "Certificate
part" consists of the certificate parsing, and verification functions
and it uses functionality from the libtasn1(1) library. The
"Cryptographic back-end" is provided by the nettle(2) library.
* Menu:
* Downloading and installing::
* Document overview::
---------- Footnotes ----------
(1)
(2)
File: gnutls.info, Node: Downloading and installing, Next: Document overview, Up: Introduction to GnuTLS
2.1 Downloading and installing
==============================
GnuTLS is available for download at:
GnuTLS uses a development cycle where even minor version numbers
indicate a stable release and a odd minor version number indicate a
development release. For example, GnuTLS 1.6.3 denote a stable release
since 6 is even, and GnuTLS 1.7.11 denote a development release since 7
is odd.
GnuTLS depends on Libnettle, and you will need to install it before
installing GnuTLS. Libnettle is available from
. Don't forget to verify the
cryptographic signature after downloading source code packages.
The package is then extracted, configured and built like many other
packages that use Autoconf. For detailed information on configuring and
building it, refer to the 'INSTALL' file that is part of the
distribution archive. Typically you invoke './configure' and then 'make
check install'. There are a number of compile-time parameters, as
discussed below.
The compression library, libz, as well as p11-kit are a optional
dependencies. You can get libz from and p11-kit
from .
The X.509 part of GnuTLS needs ASN.1 functionality, from a library
called libtasn1. A copy of libtasn1 is included in GnuTLS. If you want
to install it separately (e.g., to make it possibly to use libtasn1 in
other programs), you can get it from
.
A few 'configure' options may be relevant, summarized below. They
disable or enable particular features, to create a smaller library with
only the required features. Note however, that although a smaller
library is generated, the included programs are not guarranteed to
compile if some of these options are given.
--disable-srp-authentication
--disable-psk-authentication
--disable-anon-authentication
--disable-extra-pki
--disable-openpgp-authentication
--disable-openssl-compatibility
--without-p11-kit
For the complete list, refer to the output from 'configure --help'.
File: gnutls.info, Node: Document overview, Prev: Downloading and installing, Up: Introduction to GnuTLS
2.2 Overview
============
In this document we present an overview of the supported security
protocols in *note Introduction to TLS::, and continue by providing more
information on the certificate authentication in *note Certificate
authentication::, and shared-key as well anonymous authentication in
*note Shared-key and anonymous authentication::. We elaborate on
certificate authentication by demonstrating advanced usage of the API in
*note More on certificate authentication::. The core of the TLS library
is presented in *note How to use GnuTLS in applications:: and example
applications are listed in *note GnuTLS application examples::. In
*note Other included programs:: the usage of few included programs that
may assist debugging is presented. The last chapter is *note Internal
architecture of GnuTLS:: that provides a short introduction to GnuTLS'
internal architecture.
File: gnutls.info, Node: Introduction to TLS, Next: Certificate authentication, Prev: Introduction to GnuTLS, Up: Top
3 Introduction to TLS and DTLS
******************************
TLS stands for "Transport Layer Security" and is the successor of SSL,
the Secure Sockets Layer protocol [_SSL3_] designed by Netscape. TLS is
an Internet protocol, defined by IETF(1), described in [_RFC5246_]. The
protocol provides confidentiality, and authentication layers over any
reliable transport layer. The description, above, refers to TLS 1.0 but
applies to all other TLS versions as the differences between the
protocols are not major.
The DTLS protocol, or "Datagram TLS" [_RFC4347_] is a protocol with
identical goals as TLS, but can operate under unreliable transport
layers such as UDP. The discussions below apply to this protocol as
well, except when noted otherwise.
* Menu:
* TLS layers::
* The transport layer::
* The TLS record protocol::
* The TLS Alert Protocol::
* The TLS Handshake Protocol::
* TLS Extensions::
* How to use TLS in application protocols::
* On SSL 2 and older protocols::
---------- Footnotes ----------
(1) 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.
File: gnutls.info, Node: TLS layers, Next: The transport layer, Up: Introduction to TLS
3.1 TLS layers
==============
TLS 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. 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. *Note The Alert Protocol::, for more
information. The alert protocol is above the record protocol.
The handshake protocol is responsible for the security parameters'
negotiation, the initial key exchange and authentication. *Note The
Handshake Protocol::, for more information about the handshake protocol.
The protocol layering in TLS is shown in *note Figure 3.1:
fig:tls-layers.
[image src="gnutls-layers.png" ]
Figure 3.1: The TLS protocol layers.
File: gnutls.info, Node: The transport layer, Next: The TLS record protocol, Prev: TLS layers, Up: Introduction to TLS
3.2 The transport layer
=======================
TLS is not limited to any transport layer and can be used above any
transport layer, as long as it is a reliable one. DTLS can be used over
reliable and unreliable transport layers. GnuTLS supports TCP and UDP
layers transparently using the Berkeley sockets API. However, any
transport layer can be used by providing callbacks for GnuTLS to access
the transport layer (for details see *note Setting up the transport
layer::).
File: gnutls.info, Node: The TLS record protocol, Next: The TLS Alert Protocol, Prev: The transport layer, Up: Introduction to TLS
3.3 The TLS record protocol
===========================
The record protocol is the secure communications provider. Its purpose
is to encrypt, authenticate and --optionally-- compress packets. The
record layer functions can be called at any time after the handshake
process is finished, when there is need to receive or send data. In
DTLS however, due to re-transmission timers used in the handshake
out-of-order handshake data might be received for some time (maximum 60
seconds) after the handshake process is finished.
The functions to access the record protocol are limited to send and
receive functions, which might, given the importance of this protocol in
TLS, seem awkward. This is because the record protocol's parameters are
all set by the handshake protocol. The record protocol initially starts
with NULL parameters, which means no encryption, and no MAC is used.
Encryption and authentication begin just after the handshake protocol
has finished.
* Menu:
* Encryption algorithms used in the record layer::
* Compression algorithms used in the record layer::
* Weaknesses and countermeasures::
* On Record Padding::
File: gnutls.info, Node: Encryption algorithms used in the record layer, Next: Compression algorithms used in the record layer, Up: The TLS record protocol
3.3.1 Encryption algorithms used in the record layer
----------------------------------------------------
Confidentiality in the record layer is achieved by using symmetric block
encryption algorithms like '3DES', 'AES' or stream algorithms like
'ARCFOUR_128'. Ciphers are encryption algorithms that use a single,
secret, key to encrypt and decrypt data. Block algorithms in CBC mode
also provide protection against statistical analysis of the data. Thus,
if you're using the TLS protocol, a random number of blocks will be
appended to data, to prevent eavesdroppers from guessing the actual data
size.
The supported in GnuTLS ciphers and MAC algorithms are shown in *note
Table 3.1: tab:ciphers. and *note Table 3.2: tab:macs.
Algorithm Description
------------------------------------------------------------------
3DES_CBC This is the DES block cipher algorithm used with
triple encryption (EDE). Has 64 bits block size
and is used in CBC mode.
ARCFOUR_128 ARCFOUR_128 is a compatible algorithm with RSA's
RC4 algorithm, which is considered to be a trade
secret. It is a fast cipher but considered weak
today.
ARCFOUR_40 This is the ARCFOUR cipher fed with a 40 bit
key, which is considered weak.
AES_CBC AES or RIJNDAEL is the block cipher algorithm
that replaces the old DES algorithm. Has 128
bits block size and is used in CBC mode.
AES_GCM This is the AES algorithm in the authenticated
encryption GCM mode. This mode combines message
authentication and encryption and can be
extremely fast on CPUs that support hardware
acceleration.
CAMELLIA_CBC This is an 128-bit block cipher developed by
Mitsubishi and NTT. It is one of the approved
ciphers of the European NESSIE and Japanese
CRYPTREC projects.
Table 3.1: Supported ciphers.
Algorithm Description
------------------------------------------------------------------
MAC_MD5 This is an HMAC based on MD5 a cryptographic
hash algorithm designed by Ron Rivest. Outputs
128 bits of data.
MAC_SHA1 An HMAC based on the SHA1 cryptographic hash
algorithm designed by NSA. Outputs 160 bits of
data.
MAC_SHA256 An HMAC based on SHA256. Outputs 256 bits of
data.
MAC_AEAD This indicates that an authenticated encryption
algorithm, such as GCM, is in use.
Table 3.2: Supported MAC algorithms.
File: gnutls.info, Node: Compression algorithms used in the record layer, Next: Weaknesses and countermeasures, Prev: Encryption algorithms used in the record layer, Up: The TLS record protocol
3.3.2 Compression algorithms used in the record layer
-----------------------------------------------------
The TLS record layer also supports compression. The algorithms
implemented in GnuTLS can be found in the table below. The included
algorithms perform really good when text, or other compressible data are
to be transferred, but offer nothing on already compressed data, such as
compressed images, zipped archives etc. These compression algorithms,
may be useful in high bandwidth TLS tunnels, and in cases where network
usage has to be minimized. It should be noted however that compression
increases latency.
The record layer compression in GnuTLS is implemented based on
[_RFC3749_]. The supported algorithms are shown below.
'GNUTLS_COMP_UNKNOWN'
Unknown compression method.
'GNUTLS_COMP_NULL'
The NULL compression method (no compression).
'GNUTLS_COMP_DEFLATE'
The DEFLATE compression method from zlib.
'GNUTLS_COMP_ZLIB'
Same as 'GNUTLS_COMP_DEFLATE' .
Figure 3.2: Supported compression algorithms
Note that compression enables attacks such as traffic analysis, or even
plaintext recovery under certain circumstances. To avoid some of these
attacks GnuTLS allows each record to be compressed independently (i.e.,
stateless compression), by using the "%STATELESS_COMPRESSION" priority
string.
File: gnutls.info, Node: Weaknesses and countermeasures, Next: On Record Padding, Prev: Compression algorithms used in the record layer, Up: The TLS record protocol
3.3.3 Weaknesses and countermeasures
------------------------------------
Some weaknesses that may affect the security of the record layer have
been found in TLS 1.0 protocol. These weaknesses can be exploited by
active attackers, and exploit the facts that
1. TLS has separate alerts for "decryption_failed" and
"bad_record_mac"
2. The decryption failure reason can be detected by timing the
response time.
3. The IV for CBC encrypted packets is the last block of the previous
encrypted packet.
Those weaknesses were solved in TLS 1.1 [_RFC4346_] which is implemented
in GnuTLS. For this reason we suggest to always negotiate the highest
supported TLS version with the peer(1). For a detailed discussion of
the issues see the archives of the TLS Working Group mailing list and
[_CBCATT_].
---------- Footnotes ----------
(1) If this is not possible then please consult *note
Interoperability::.
File: gnutls.info, Node: On Record Padding, Prev: Weaknesses and countermeasures, Up: The TLS record protocol
3.3.4 On record padding
-----------------------
The TLS protocol allows for random padding of records in CBC ciphers, to
prevent statistical analysis based on the length of exchanged messages
(see [_RFC5246_] section 6.2.3.2). GnuTLS appears to be one of few
implementation that take advantage of this text, and pad records by a
random length.
The TLS implementation in the Symbian operating system, frequently used
by Nokia and Sony-Ericsson mobile phones, cannot handle non-minimal
record padding. What happens when one of these clients handshake with a
GnuTLS server is that the client will fail to compute the correct MAC
for the record. The client sends a TLS alert ('bad_record_mac') and
disconnects. Typically this will result in error messages such as 'A
TLS fatal alert has been received', 'Bad record MAC', or both, on the
GnuTLS server side.
GnuTLS implements a work around for this problem. However, it has to be
enabled specifically. It can be enabled by using *note
gnutls_record_disable_padding::, or *note gnutls_priority_set:: with the
'%COMPAT' priority string (see *note Priority Strings::).
If you implement an application that have a configuration file, we
recommend that you make it possible for users or administrators to
specify a GnuTLS protocol priority string, which is used by your
application via *note gnutls_priority_set::. To allow the best
flexibility, make it possible to have a different priority string for
different incoming IP addresses.
File: gnutls.info, Node: The TLS Alert Protocol, Next: The TLS Handshake Protocol, Prev: The TLS record protocol, Up: Introduction to TLS
3.4 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
(e.g. 'GNUTLS_A_CLOSE_NOTIFY'), and others refer to the application
protocol solely (e.g. '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
re-negotiations using the current session ID. All alert messages are
summarized in the table below.
The alert messages are protected by the record protocol, thus the
information that is included does not leak. You must take extreme care
for the alert information not to leak to a possible attacker, via public
log files etc.
Alert ID Description
------------------------------------------------------------------------
GNUTLS_A_CLOSE_NOTIFY 0 Close notify
GNUTLS_A_UNEXPECTED_MESSAGE 10 Unexpected message
GNUTLS_A_BAD_RECORD_MAC 20 Bad record MAC
GNUTLS_A_DECRYPTION_FAILED 21 Decryption failed
GNUTLS_A_RECORD_OVERFLOW 22 Record overflow
GNUTLS_A_DECOMPRESSION_FAILURE 30 Decompression failed
GNUTLS_A_HANDSHAKE_FAILURE 40 Handshake failed
GNUTLS_A_SSL3_NO_CERTIFICATE 41 No certificate (SSL
3.0)
GNUTLS_A_BAD_CERTIFICATE 42 Certificate is bad
GNUTLS_A_UNSUPPORTED_CERTIFICATE 43 Certificate is not
supported
GNUTLS_A_CERTIFICATE_REVOKED 44 Certificate was
revoked
GNUTLS_A_CERTIFICATE_EXPIRED 45 Certificate is
expired
GNUTLS_A_CERTIFICATE_UNKNOWN 46 Unknown certificate
GNUTLS_A_ILLEGAL_PARAMETER 47 Illegal parameter
GNUTLS_A_UNKNOWN_CA 48 CA is unknown
GNUTLS_A_ACCESS_DENIED 49 Access was denied
GNUTLS_A_DECODE_ERROR 50 Decode error
GNUTLS_A_DECRYPT_ERROR 51 Decrypt error
GNUTLS_A_EXPORT_RESTRICTION 60 Export restriction
GNUTLS_A_PROTOCOL_VERSION 70 Error in protocol
version
GNUTLS_A_INSUFFICIENT_SECURITY 71 Insufficient
security
GNUTLS_A_INTERNAL_ERROR 80 Internal error
GNUTLS_A_USER_CANCELED 90 User canceled
GNUTLS_A_NO_RENEGOTIATION 100 No renegotiation is
allowed
GNUTLS_A_UNSUPPORTED_EXTENSION 110 An unsupported
extension was sent
GNUTLS_A_CERTIFICATE_UNOBTAINABLE 111 Could not retrieve
the specified
certificate
GNUTLS_A_UNRECOGNIZED_NAME 112 The server name sent
was not recognized
GNUTLS_A_UNKNOWN_PSK_IDENTITY 115 The SRP/PSK username
is missing or not
known
File: gnutls.info, Node: The TLS Handshake Protocol, Next: TLS Extensions, Prev: The TLS Alert Protocol, Up: Introduction to TLS
3.5 The TLS handshake protocol
==============================
The handshake protocol is responsible for the ciphersuite negotiation,
the initial key exchange, and the authentication of the two peers. This
is fully controlled by the application layer, thus your program has to
set up the required parameters. The main handshake function is *note
gnutls_handshake::. In the next paragraphs we elaborate on the
handshake protocol, i.e., the ciphersuite negotiation.
* Menu:
* TLS Cipher Suites:: TLS session parameters.
* Authentication:: TLS authentication.
* Client Authentication:: Requesting a certificate from the client.
* Resuming Sessions:: Reusing previously established keys.
File: gnutls.info, Node: TLS Cipher Suites, Next: Authentication, Up: The TLS Handshake Protocol
3.5.1 TLS ciphersuites
----------------------
The handshake protocol of TLS negotiates cipher suites of a special form
illustrated by the 'TLS_DHE_RSA_WITH_3DES_CBC_SHA' cipher suite name. A
typical cipher suite contains these parameters:
* The key exchange algorithm. 'DHE_RSA' in the example.
* The Symmetric encryption algorithm and mode '3DES_CBC' in this
example.
* The MAC(1) algorithm used for authentication. 'MAC_SHA' is used in
the above example.
The cipher suite negotiated in the handshake protocol will affect the
record protocol, by enabling encryption and data authentication. Note
that you should not over rely on TLS to negotiate the strongest
available cipher suite. Do not enable ciphers and algorithms that you
consider weak.
All the supported ciphersuites are listed in *note ciphersuites::.
---------- Footnotes ----------
(1) MAC stands for Message Authentication Code. It can be described
as a keyed hash algorithm. See RFC2104.
File: gnutls.info, Node: Authentication, Next: Client Authentication, Prev: TLS Cipher Suites, Up: The TLS Handshake Protocol
3.5.2 Authentication
--------------------
The key exchange algorithms of the TLS protocol offer authentication,
which is a prerequisite for a secure connection. The available
authentication methods in GnuTLS follow.
* Certificate authentication: Authenticated key exchange using public
key infrastructure and certificates (X.509 or OpenPGP).
* SRP authentication: Authenticated key exchange using a password.
* PSK authentication: Authenticated key exchange using a pre-shared
key.
* Anonymous authentication: Key exchange without peer authentication.
File: gnutls.info, Node: Client Authentication, Next: Resuming Sessions, Prev: Authentication, Up: The TLS Handshake Protocol
3.5.3 Client authentication
---------------------------
In the case of ciphersuites that use certificate authentication, the
authentication of the client is optional in TLS. A server may request a
certificate from the client using the *note
gnutls_certificate_server_set_request:: function. We elaborate in *note
Certificate credentials::.
File: gnutls.info, Node: Resuming Sessions, Prev: Client Authentication, Up: The TLS Handshake Protocol
3.5.4 Resuming sessions
-----------------------
The TLS handshake process performs expensive calculations and a busy
server might easily be put under load. To reduce the load, session
resumption may be used. This is a feature of the TLS protocol which
allows a client to connect to a server after a successful handshake,
without the expensive calculations. This is achieved by re-using the
previously established keys, meaning the server needs to store the state
of established connections (unless session tickets are used - *note
Session tickets::).
Session resumption is an integral part of GnuTLS, and *note Session
resumption:: and *note ex:resume-client:: illustrate typical uses of it.
File: gnutls.info, Node: TLS Extensions, Next: How to use TLS in application protocols, Prev: The TLS Handshake Protocol, Up: Introduction to TLS
3.6 TLS extensions
==================
A number of extensions to the TLS protocol have been proposed mainly in
[_TLSEXT_]. The extensions supported in GnuTLS are:
* Maximum fragment length negotiation
* Server name indication
* Session tickets
* Safe Renegotiation
and they will be discussed in the subsections that follow.
* Menu:
* Maximum fragment length negotiation::
* Server name indication::
* Session tickets::
* Safe renegotiation::
File: gnutls.info, Node: Maximum fragment length negotiation, Next: Server name indication, Up: TLS Extensions
3.6.1 Maximum fragment length negotiation
-----------------------------------------
This extension allows a TLS implementation to negotiate a smaller value
for record packet maximum length. This extension may be useful to
clients with constrained capabilities. The functions shown below can be
used to control this extension.
'SIZE_T *note gnutls_record_get_max_size:: (gnutls_session_t SESSION)'
'SSIZE_T *note gnutls_record_set_max_size:: (gnutls_session_t SESSION, size_t SIZE)'
File: gnutls.info, Node: Server name indication, Next: Session tickets, Prev: Maximum fragment length negotiation, Up: TLS Extensions
3.6.2 Server name indication
----------------------------
A common problem in HTTPS servers is the fact that the TLS protocol is
not aware of the hostname that a client connects to, when the handshake
procedure begins. For that reason the TLS server has no way to know
which certificate to send.
This extension solves that problem within the TLS protocol, and allows a
client to send the HTTP hostname before the handshake begins within the
first handshake packet. The functions *note gnutls_server_name_set::
and *note gnutls_server_name_get:: can be used to enable this extension,
or to retrieve the name sent by a client.
'INT *note gnutls_server_name_set:: (gnutls_session_t SESSION, gnutls_server_name_type_t TYPE, const void * NAME, size_t NAME_LENGTH)'
'INT *note gnutls_server_name_get:: (gnutls_session_t SESSION, void * DATA, size_t * DATA_LENGTH, unsigned int * TYPE, unsigned int INDX)'
File: gnutls.info, Node: Session tickets, Next: Safe renegotiation, Prev: Server name indication, Up: TLS Extensions
3.6.3 Session tickets
---------------------
To resume a TLS session the server normally store session parameters.
This complicates deployment, and could be avoiding by delegating the
storage to the client. Because session parameters are sensitive they
are encrypted and authenticated with a key only known to the server and
then sent to the client. The Session Tickets in RFC 5077 [_TLSTKT_],
describe this idea, which is implemented in GnuTLS.
File: gnutls.info, Node: Safe renegotiation, Prev: Session tickets, Up: TLS Extensions
3.6.4 Safe renegotiation
------------------------
TLS gives the option to two communicating parties to renegotiate and
update their security parameters. One useful example of this feature
was for a client to initially connect using anonymous negotiation to a
server, and the renegotiate using some authenticated ciphersuite. This
occurred to avoid having the client sending its credentials in the
clear.
However this renegotiation, as initially designed would not ensure that
the party one is renegotiating is the same as the one in the initial
negotiation. For example one server could forward all renegotiation
traffic to an other server who will see this traffic as an initial
negotiation attempt.
This might be seen as a valid design decision, but it seems it was not
widely known or understood, thus today some application protocols the
TLS renegotiation feature in a manner that enables a malicious server to
insert content of his choice in the beginning of a TLS session.
The most prominent vulnerability was with HTTPS. There servers request a
renegotiation to enforce an anonymous user to use a certificate in order
to access certain parts of a web site. The attack works by having the
attacker simulate a client and connect to a server, with server-only
authentication, and send some data intended to cause harm. The server
will then require renegotiation from him in order to perform the
request. When the proper client attempts to contact the server, the
attacker hijacks that connection and forwards traffic to the initial
server that requested renegotiation. The attacker will not be able to
read the data exchanged between the client and the server. However, the
server will (incorrectly) assume that the initial request sent by the
attacker was sent by the now authenticated client. The result is a
prefix plain-text injection attack.
The above is just one example. Other vulnerabilities exists that do not
rely on the TLS renegotiation to change the client's authenticated
status (either TLS or application layer).
While fixing these application protocols and implementations would be
one natural reaction, an extension to TLS has been designed that
cryptographically binds together any renegotiated handshakes with the
initial negotiation. When the extension is used, the attack is detected
and the session can be terminated. The extension is specified in
[_RFC5746_].
GnuTLS supports the safe renegotiation extension. The default behavior
is as follows. Clients will attempt to negotiate the safe renegotiation
extension when talking to servers. Servers will accept the extension
when presented by clients. Clients and servers will permit an initial
handshake to complete even when the other side does not support the safe
renegotiation extension. Clients and servers will refuse renegotiation
attempts when the extension has not been negotiated.
Note that permitting clients to connect to servers when the safe
renegotiation extension is not enabled, is open up for attacks.
Changing this default behavior would prevent interoperability against
the majority of deployed servers out there. We will reconsider this
default behavior in the future when more servers have been upgraded.
Note that it is easy to configure clients to always require the safe
renegotiation extension from servers.
To modify the default behavior, we have introduced some new priority
strings (see *note Priority Strings::). The '%UNSAFE_RENEGOTIATION'
priority string permits (re-)handshakes even when the safe renegotiation
extension was not negotiated. The default behavior is
'%PARTIAL_RENEGOTIATION' that will prevent renegotiation with clients
and servers not supporting the extension. This is secure for servers
but leaves clients vulnerable to some attacks, but this is a trade-off
between security and compatibility with old servers. The
'%SAFE_RENEGOTIATION' priority string makes clients and servers require
the extension for every handshake. The latter is the most secure option
for clients, at the cost of not being able to connect to legacy servers.
Servers will also deny clients that do not support the extension from
connecting.
It is possible to disable use of the extension completely, in both
clients and servers, by using the '%DISABLE_SAFE_RENEGOTIATION' priority
string however we strongly recommend you to only do this for debugging
and test purposes.
The default values if the flags above are not specified are:
'Server:'
%PARTIAL_RENEGOTIATION
'Client:'
%PARTIAL_RENEGOTIATION
For applications we have introduced a new API related to safe
renegotiation. The *note gnutls_safe_renegotiation_status:: function is
used to check if the extension has been negotiated on a session, and can
be used both by clients and servers.
File: gnutls.info, Node: How to use TLS in application protocols, Next: On SSL 2 and older protocols, Prev: TLS Extensions, Up: Introduction to TLS
3.7 How to use TLS in application protocols
===========================================
This chapter is intended to provide some hints on how to use the TLS
over simple custom made application protocols. The discussion below
mainly refers to the TCP/IP transport layer but may be extended to other
ones too.
* Menu:
* Separate ports::
* Upward negotiation::
File: gnutls.info, Node: Separate ports, Next: Upward negotiation, Up: How to use TLS in application protocols
3.7.1 Separate ports
--------------------
Traditionally SSL was used in application protocols by assigning a new
port number for the secure services. That way two separate ports were
assigned, one for the non secure sessions, and one for the secured ones.
This has the benefit that if a user requests a secure session then the
client will try to connect to the secure port and fail otherwise. The
only possible attack with this method is a denial of service one. The
most famous example of this method is the famous "HTTP over TLS" or
HTTPS protocol [_RFC2818_].
Despite its wide use, this method is not as good as it seems. This
approach starts the TLS Handshake procedure just after the client
connects on the --so called-- secure port. That way the TLS protocol
does not know anything about the client, and popular methods like the
host advertising in HTTP do not work(1). There is no way for the client
to say "I connected to YYY server" before the Handshake starts, so the
server cannot possibly know which certificate to use.
Other than that it requires two separate ports to run a single service,
which is unnecessary complication. Due to the fact that there is a
limitation on the available privileged ports, this approach was soon
obsoleted.
---------- Footnotes ----------
(1) See also the Server Name Indication extension on *note
serverind::.
File: gnutls.info, Node: Upward negotiation, Prev: Separate ports, Up: How to use TLS in application protocols
3.7.2 Upward negotiation
------------------------
Other application protocols(1) use a different approach to enable the
secure layer. They use something often called as the "TLS upgrade"
method. This method is quite tricky but it is more flexible. The idea
is to extend the application protocol to have a "STARTTLS" request,
whose purpose it to start the TLS protocols just after the client
requests it. This approach does not require any extra port to be
reserved. There is even an extension to HTTP protocol to support that
method [_RFC2817_].
The tricky part, in this method, is that the "STARTTLS" request is sent
in the clear, thus is vulnerable to modifications. A typical attack is
to modify the messages in a way that the client is fooled and thinks
that the server does not have the "STARTTLS" capability. See a typical
conversation of a hypothetical protocol:
(client connects to the server)
CLIENT: HELLO I'M MR. XXX
SERVER: NICE TO MEET YOU XXX
CLIENT: PLEASE START TLS
SERVER: OK
*** TLS STARTS
CLIENT: HERE ARE SOME CONFIDENTIAL DATA
And see an example of a conversation where someone is acting in between:
(client connects to the server)
CLIENT: HELLO I'M MR. XXX
SERVER: NICE TO MEET YOU XXX
CLIENT: PLEASE START TLS
(here someone inserts this message)
SERVER: SORRY I DON'T HAVE THIS CAPABILITY
CLIENT: HERE ARE SOME CONFIDENTIAL DATA
As you can see above the client was fooled, and was dummy enough to send
the confidential data in the clear.
How to avoid the above attack? As you may have already noticed this one
is easy to avoid. The client has to ask the user before it connects
whether the user requests TLS or not. If the user answered that he
certainly wants the secure layer the last conversation should be:
(client connects to the server)
CLIENT: HELLO I'M MR. XXX
SERVER: NICE TO MEET YOU XXX
CLIENT: PLEASE START TLS
(here someone inserts this message)
SERVER: SORRY I DON'T HAVE THIS CAPABILITY
CLIENT: BYE
(the client notifies the user that the secure connection was not
possible)
This method, if implemented properly, is far better than the traditional
method, and the security properties remain the same, since only denial
of service is possible. The benefit is that the server may request
additional data before the TLS Handshake protocol starts, in order to
send the correct certificate, use the correct password file, or anything
else!
---------- Footnotes ----------
(1) See LDAP, IMAP etc.
File: gnutls.info, Node: On SSL 2 and older protocols, Prev: How to use TLS in application protocols, Up: Introduction to TLS
3.8 On SSL 2 and older protocols
================================
One of the initial decisions in the GnuTLS development was to implement
the known security protocols for the transport layer. Initially TLS 1.0
was implemented since it was the latest at that time, and was considered
to be the most advanced in security properties. Later the SSL 3.0
protocol was implemented since it is still the only protocol supported
by several servers and there are no serious security vulnerabilities
known.
One question that may arise is why we didn't implement SSL 2.0 in the
library. There are several reasons, most important being that it has
serious security flaws, unacceptable for a modern security library.
Other than that, this protocol is barely used by anyone these days since
it has been deprecated since 1996. The security problems in SSL 2.0
include:
* Message integrity compromised. The SSLv2 message authentication
uses the MD5 function, and is insecure.
* Man-in-the-middle attack. There is no protection of the handshake
in SSLv2, which permits a man-in-the-middle attack.
* Truncation attack. SSLv2 relies on TCP FIN to close the session,
so the attacker can forge a TCP FIN, and the peer cannot tell if it
was a legitimate end of data or not.
* Weak message integrity for export ciphers. The cryptographic keys
in SSLv2 are used for both message authentication and encryption,
so if weak encryption schemes are negotiated (say 40-bit keys) the
message authentication code uses the same weak key, which isn't
necessary.
Other protocols such as Microsoft's PCT 1 and PCT 2 were not implemented
because they were also abandoned and deprecated by SSL 3.0 and later TLS
1.0.
File: gnutls.info, Node: Certificate authentication, Next: Shared-key and anonymous authentication, Prev: Introduction to TLS, Up: Top
4 Certificate authentication
****************************
The most known authentication method of TLS are certificates. The PKIX
[_PKIX_] public key infrastructure is daily used by anyone using a
browser today. GnuTLS supports both X.509 certificates [_PKIX_] and
OpenPGP certificates using a common API.
The key exchange algorithms supported by certificate authentication are
shown in *note Table 4.1: tab:key-exchange.
Key exchange Description
------------------------------------------------------------------
RSA The RSA algorithm is used to encrypt a key and
send it to the peer. The certificate must allow
the key to be used for encryption.
RSA_EXPORT The RSA algorithm is used to encrypt a key and
send it to the peer. In the EXPORT algorithm,
the server signs temporary RSA parameters of 512
bits -- which are considered weak -- and sends
them to the client.
DHE_RSA The RSA algorithm is used to sign ephemeral
Diffie-Hellman parameters which are sent to the
peer. The key in the certificate must allow the
key to be used for signing. Note that key
exchange algorithms which use ephemeral
Diffie-Hellman parameters, offer perfect forward
secrecy. That means that even if the private
key used for signing is compromised, it cannot
be used to reveal past session data.
ECDHE_RSA The RSA algorithm is used to sign ephemeral
elliptic curve Diffie-Hellman parameters which
are sent to the peer. The key in the
certificate must allow the key to be used for
signing. It also offers perfect forward
secrecy. That means that even if the private
key used for signing is compromised, it cannot
be used to reveal past session data.
DHE_DSS The DSA algorithm is used to sign ephemeral
Diffie-Hellman parameters which are sent to the
peer. The certificate must contain DSA
parameters to use this key exchange algorithm.
DSA is the algorithm of the Digital Signature
Standard (DSS).
ECDHE_ECDSA The Elliptic curve DSA algorithm is used to sign
ephemeral elliptic curve Diffie-Hellman
parameters which are sent to the peer. The
certificate must contain ECDSA parameters to use
this key exchange algorithm.
Table 4.1: Supported key exchange algorithms.
* Menu:
* X.509 certificates::
* OpenPGP certificates::
* Digital signatures::
File: gnutls.info, Node: X.509 certificates, Next: OpenPGP certificates, Up: Certificate authentication
4.1 X.509 certificates
======================
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 hierarchical model.
[image src="gnutls-x509.png" ]
Figure 4.1: An example of the X.509 hierarchical trust 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. The framework is illustrated on *note Figure 4.1: fig:x509.
* Menu:
* X.509 certificate structure::
* Importing an X.509 certificate::
* X.509 distinguished names::
* Verifying X.509 certificate paths::
* Verifying a certificate in the context of TLS session::
* Verifying a certificate using trust on first use authentication::
File: gnutls.info, Node: X.509 certificate structure, Next: Importing an X.509 certificate, Up: X.509 certificates
4.1.1 X.509 certificate structure
---------------------------------
An X.509 certificate usually contains information about the certificate
holder, the signer, a unique serial number, expiration dates and some
other fields [_PKIX_] as shown in *note Table 4.2: tab:x509.
Field Description
------------------------------------------------------------------
version The field that indicates the version of the
certificate.
serialNumber This field holds a unique serial number per
certificate.
signature The issuing authority's signature.
issuer Holds the issuer's distinguished name.
validity The activation and expiration dates.
subject The subject's distinguished name of the
certificate.
extensions The extensions are fields only present in
version 3 certificates.
Table 4.2: X.509 certificate fields.
The certificate's _subject or issuer name_ is not just a single string.
It is a Distinguished name and in the ASN.1 notation is a sequence of
several object identifiers with their corresponding values. Some of
available OIDs to be used in an X.509 distinguished name are defined in
'gnutls/x509.h'.
The _Version_ field in a certificate has values either 1 or 3 for
version 3 certificates. Version 1 certificates do not support the
extensions field so it is not possible to distinguish a CA from a
person, thus their usage should be avoided.
The _validity_ dates are there to indicate the date that the specific
certificate was activated and the date the certificate's key would be
considered invalid.
Certificate _extensions_ are there to include information about the
certificate's subject that did not fit in the typical certificate
fields. Those may be e-mail addresses, flags that indicate whether the
belongs to a CA etc. All the supported X.509 version 3 extensions are
shown in *note Table 4.3: tab:x509-ext.
Extension OID Description
--------------------------------------------------------------------
Subject key id 2.5.29.14 An identifier of the key of
the subject.
Authority key id 2.5.29.35 An identifier of the
authority's key used to
sign the certificate.
Subject alternative 2.5.29.17 Alternative names to
name subject's distinguished
name.
Key usage 2.5.29.15 Constraints the key's usage
of the certificate.
Extended key usage 2.5.29.37 Constraints the purpose of
the certificate.
Basic constraints 2.5.29.19 Indicates whether this is a
CA certificate or not, and
specify the maximum path
lengths of certificate
chains.
CRL distribution 2.5.29.31 This extension is set by
points the CA, in order to inform
about the issued CRLs.
Proxy Certification 1.3.6.1.5.5.7.1.14Proxy Certificates includes
Information this extension that
contains the OID of the
proxy policy language used,
and can specify limits on
the maximum lengths of
proxy chains. Proxy
Certificates are specified
in [_RFC3820_].
Table 4.3: X.509 certificate extensions.
In GnuTLS the X.509 certificate structures are handled using the
'gnutls_x509_crt_t' type and the corresponding private keys with the
'gnutls_x509_privkey_t' type. All the available functions for X.509
certificate handling have their prototypes in 'gnutls/x509.h'. An
example program to demonstrate the X.509 parsing capabilities can be
found at *note ex:x509-info::.
File: gnutls.info, Node: Importing an X.509 certificate, Next: X.509 distinguished names, Prev: X.509 certificate structure, Up: X.509 certificates
4.1.2 Importing an X.509 certificate
------------------------------------
The certificate structure should be initialized using *note
gnutls_x509_crt_init::, and a certificate structure can be imported
using *note gnutls_x509_crt_import::.
'INT *note gnutls_x509_crt_init:: (gnutls_x509_crt_t * CERT)'
'INT *note gnutls_x509_crt_import:: (gnutls_x509_crt_t CERT, const gnutls_datum_t * DATA, gnutls_x509_crt_fmt_t FORMAT)'
'VOID *note gnutls_x509_crt_deinit:: (gnutls_x509_crt_t CERT)'
In several functions an array of certificates is required. To assist in
initialization and import the following two functions are provided.
'INT *note gnutls_x509_crt_list_import:: (gnutls_x509_crt_t * CERTS, unsigned int * CERT_MAX, const gnutls_datum_t * DATA, gnutls_x509_crt_fmt_t FORMAT, unsigned int FLAGS)'
'INT *note gnutls_x509_crt_list_import2:: (gnutls_x509_crt_t ** CERTS, unsigned int * SIZE, const gnutls_datum_t * DATA, gnutls_x509_crt_fmt_t FORMAT, unsigned int FLAGS)'
In all cases after use a certificate must be deinitialized using *note
gnutls_x509_crt_deinit::. Note that although the functions above apply
to 'gnutls_x509_crt_t' structure, similar functions exist for the CRL
structure 'gnutls_x509_crl_t'.
File: gnutls.info, Node: X.509 distinguished names, Next: Verifying X.509 certificate paths, Prev: Importing an X.509 certificate, Up: X.509 certificates
4.1.3 X.509 distinguished names
-------------------------------
The "subject" of an X.509 certificate is not described by a single name,
but rather with a distinguished name. This in X.509 terminology is a
list of strings each associated an object identifier. To make things
simple GnuTLS provides *note gnutls_x509_crt_get_dn:: which follows the
rules in [_RFC4514_] and returns a single string. Access to each string
by individual object identifiers can be accessed using *note
gnutls_x509_crt_get_dn_by_oid::.
-- Function: int gnutls_x509_crt_get_dn (gnutls_x509_crt_t CERT, char *
BUF, size_t * BUF_SIZE)
CERT: should contain a 'gnutls_x509_crt_t' structure
BUF: a pointer to a structure to hold the name (may be null)
BUF_SIZE: initially holds the size of 'buf'
This function will copy the name of the Certificate in the provided
buffer. The name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as
described in RFC4514. The output string will be ASCII or UTF-8
encoded, depending on the certificate data.
If 'buf' is null then only the size will be filled.
*Returns:* 'GNUTLS_E_SHORT_MEMORY_BUFFER' if the provided buffer is
not long enough, and in that case the 'buf_size' will be updated
with the required size. On success 0 is returned.
-- Function: int gnutls_x509_crt_get_dn_by_oid (gnutls_x509_crt_t CERT,
const char * OID, int INDX, unsigned int RAW_FLAG, void * BUF,
size_t * BUF_SIZE)
CERT: should contain a 'gnutls_x509_crt_t' structure
OID: holds an Object Identified in null terminated string
INDX: In case multiple same OIDs exist in the RDN, this specifies
which to send. Use (0) to get the first one.
RAW_FLAG: If non (0) returns the raw DER data of the DN part.
BUF: a pointer where the DN part will be copied (may be null).
BUF_SIZE: initially holds the size of 'buf'
This function will extract the part of the name of the Certificate
subject specified by the given OID. The output, if the raw flag is
not used, will be encoded as described in RFC4514. Thus a string
that is ASCII or UTF-8 encoded, depending on the certificate data.
Some helper macros with popular OIDs can be found in gnutls/x509.h
If raw flag is (0), this function will only return known OIDs as
text. Other OIDs will be DER encoded, as described in RFC4514 - in
hex format with a '#' prefix. You can check about known OIDs using
'gnutls_x509_dn_oid_known()' .
If 'buf' is null then only the size will be filled. If the
'raw_flag' is not specified the output is always null terminated,
although the 'buf_size' will not include the null character.
*Returns:* 'GNUTLS_E_SHORT_MEMORY_BUFFER' if the provided buffer is
not long enough, and in that case the *buf_size will be updated
with the required size. On success 0 is returned.
-- Function: int gnutls_x509_crt_get_dn_oid (gnutls_x509_crt_t CERT,
int INDX, void * OID, size_t * OID_SIZE)
CERT: should contain a 'gnutls_x509_crt_t' structure
INDX: This specifies which OID to return. Use (0) to get the first
one.
OID: a pointer to a buffer to hold the OID (may be null)
OID_SIZE: initially holds the size of 'oid'
This function will extract the OIDs of the name of the Certificate
subject specified by the given index.
If 'oid' is null then only the size will be filled. The 'oid'
returned will be null terminated, although 'oid_size' will not
account for the trailing null.
*Returns:* 'GNUTLS_E_SHORT_MEMORY_BUFFER' if the provided buffer is
not long enough, and in that case the 'oid_size' will be updated
with the required size. On success 0 is returned.
The more powerful *note gnutls_x509_crt_get_subject:: and *note
gnutls_x509_dn_get_rdn_ava:: provide efficient access to the contents of
the distinguished name structure.
-- Function: int gnutls_x509_crt_get_subject (gnutls_x509_crt_t CERT,
gnutls_x509_dn_t * DN)
CERT: should contain a 'gnutls_x509_crt_t' structure
DN: output variable with pointer to uint8_t DN.
Return the Certificate's Subject DN as an uint8_t data type. You
may use 'gnutls_x509_dn_get_rdn_ava()' to decode the DN.
Note that 'dn' should be treated as constant. Because points into
the 'cert' object, you may not deallocate 'cert' and continue to
access 'dn' .
*Returns:* Returns 0 on success, or an error code.
-- Function: int gnutls_x509_dn_get_rdn_ava (gnutls_x509_dn_t DN, int
IRDN, int IAVA, gnutls_x509_ava_st * AVA)
DN: input variable with uint8_t DN pointer
IRDN: index of RDN
IAVA: index of AVA.
AVA: Pointer to structure which will hold output information.
Get pointers to data within the DN.
Note that 'ava' will contain pointers into the 'dn' structure, so
you should not modify any data or deallocate it. Note also that
the DN in turn points into the original certificate structure, and
thus you may not deallocate the certificate and continue to access
'dn' .
*Returns:* Returns 0 on success, or an error code.
Similar functions exist to access the distinguished name of the issuer
of the certificate.
'INT *note gnutls_x509_crt_get_issuer_dn:: (gnutls_x509_crt_t CERT, char * BUF, size_t * BUF_SIZE)'
'INT *note gnutls_x509_crt_get_issuer_dn_by_oid:: (gnutls_x509_crt_t CERT, const char * OID, int INDX, unsigned int RAW_FLAG, void * BUF, size_t * BUF_SIZE)'
'INT *note gnutls_x509_crt_get_issuer_dn_oid:: (gnutls_x509_crt_t CERT, int INDX, void * OID, size_t * OID_SIZE)'
'INT *note gnutls_x509_crt_get_issuer:: (gnutls_x509_crt_t CERT, gnutls_x509_dn_t * DN)'
File: gnutls.info, Node: Verifying X.509 certificate paths, Next: Verifying a certificate in the context of TLS session, Prev: X.509 distinguished names, Up: X.509 certificates
4.1.4 Verifying X.509 certificate paths
---------------------------------------
Verifying certificate paths is important in X.509 authentication. For
this purpose the following functions are provided.
-- Function: int gnutls_x509_trust_list_add_cas
(gnutls_x509_trust_list_t LIST, const gnutls_x509_crt_t *
CLIST, int CLIST_SIZE, unsigned int FLAGS)
LIST: The structure of the list
CLIST: A list of CAs
CLIST_SIZE: The length of the CA list
FLAGS: should be 0.
This function will add the given certificate authorities to the
trusted list. The list of CAs must not be deinitialized during
this structure's lifetime.
*Returns:* The number of added elements is returned.
*Since:* 3.0
-- Function: int gnutls_x509_trust_list_add_named_crt
(gnutls_x509_trust_list_t LIST, gnutls_x509_crt_t CERT, const
void * NAME, size_t NAME_SIZE, unsigned int FLAGS)
LIST: The structure of the list
CERT: A certificate
NAME: An identifier for the certificate
NAME_SIZE: The size of the identifier
FLAGS: should be 0.
This function will add the given certificate to the trusted list
and associate it with a name. The certificate will not be be used
for verification with 'gnutls_x509_trust_list_verify_crt()' but
only with 'gnutls_x509_trust_list_verify_named_crt()' .
In principle this function can be used to set individual "server"
certificates that are trusted by the user for that specific server
but for no other purposes.
The certificate must not be deinitialized during the lifetime of
the trusted list.
*Returns:* On success, 'GNUTLS_E_SUCCESS' (0) is returned,
otherwise a negative error value.
*Since:* 3.0
-- Function: int gnutls_x509_trust_list_add_crls
(gnutls_x509_trust_list_t LIST, const gnutls_x509_crl_t *
CRL_LIST, int CRL_SIZE, unsigned int FLAGS, unsigned int
VERIFICATION_FLAGS)
LIST: The structure of the list
CRL_LIST: A list of CRLs
CRL_SIZE: The length of the CRL list
FLAGS: if GNUTLS_TL_VERIFY_CRL is given the CRLs will be verified
before being added.
VERIFICATION_FLAGS: gnutls_certificate_verify_flags if flags
specifies GNUTLS_TL_VERIFY_CRL
This function will add the given certificate revocation lists to
the trusted list. The list of CRLs must not be deinitialized
during this structure's lifetime.
This function must be called after
'gnutls_x509_trust_list_add_cas()' to allow verifying the CRLs for
validity.
*Returns:* The number of added elements is returned.
*Since:* 3.0
-- Function: int gnutls_x509_trust_list_verify_crt
(gnutls_x509_trust_list_t LIST, gnutls_x509_crt_t * CERT_LIST,
unsigned int CERT_LIST_SIZE, unsigned int FLAGS, unsigned int
* VERIFY, gnutls_verify_output_function FUNC)
LIST: The structure of the list
CERT_LIST: is the certificate list to be verified
CERT_LIST_SIZE: is the certificate list size
FLAGS: Flags that may be used to change the verification algorithm.
Use OR of the gnutls_certificate_verify_flags enumerations.
VERIFY: will hold the certificate verification output.
FUNC: If non-null will be called on each chain element verification
with the output.
This function will try to verify the given certificate and return
its status.
*Returns:* On success, 'GNUTLS_E_SUCCESS' (0) is returned,
otherwise a negative error value.
*Since:* 3.0
-- Function: int gnutls_x509_trust_list_verify_named_crt
(gnutls_x509_trust_list_t LIST, gnutls_x509_crt_t CERT, const
void * NAME, size_t NAME_SIZE, unsigned int FLAGS, unsigned
int * VERIFY, gnutls_verify_output_function FUNC)
LIST: The structure of the list
CERT: is the certificate to be verified
NAME: is the certificate's name
NAME_SIZE: is the certificate's name size
FLAGS: Flags that may be used to change the verification algorithm.
Use OR of the gnutls_certificate_verify_flags enumerations.
VERIFY: will hold the certificate verification output.
FUNC: If non-null will be called on each chain element verification
with the output.
This function will try to find a matching named certificate. If a
match is found the certificate is considered valid. In addition to
that this function will also check CRLs.
*Returns:* On success, 'GNUTLS_E_SUCCESS' (0) is returned,
otherwise a negative error value.
*Since:* 3.0
The verification function will verify a given certificate chain against
a list of certificate authorities and certificate revocation lists, and
output a bit-wise OR of elements of the 'gnutls_certificate_status_t'
enumeration shown in *note Figure 4.2: gnutls_certificate_status_t. The
'GNUTLS_CERT_INVALID' flag is always set on a verification error and
more detailed flags will also be set when appropriate.
'GNUTLS_CERT_INVALID'
The certificate is not signed by one of the known authorities or
the signature is invalid.
'GNUTLS_CERT_REVOKED'
Certificate is revoked by its authority. In X.509 this will be set
only if CRLs are checked.
'GNUTLS_CERT_SIGNER_NOT_FOUND'
The certificate's issuer is not known. This is the case if the
issuer is not included in the trusted certificate list.
'GNUTLS_CERT_SIGNER_NOT_CA'
The certificate's signer was not a CA. This may happen if this was
a version 1 certificate, which is common with some CAs, or a
version 3 certificate without the basic constrains extension.
'GNUTLS_CERT_INSECURE_ALGORITHM'
The certificate was signed using an insecure algorithm such as MD2
or MD5. These algorithms have been broken and should not be
trusted.
'GNUTLS_CERT_NOT_ACTIVATED'
The certificate is not yet activated.
'GNUTLS_CERT_EXPIRED'
The certificate has expired.
'GNUTLS_CERT_SIGNATURE_FAILURE'
- undescribed -
'GNUTLS_CERT_REVOCATION_DATA_SUPERSEDED'
The revocation data are old and have been superseded.
'GNUTLS_CERT_REVOCATION_DATA_ISSUED_IN_FUTURE'
The revocation data have a future issue date.
Figure 4.2: The 'gnutls_certificate_status_t' enumeration.
An example of certificate verification is shown in *note ex:verify2::.
It is also possible to have a set of certificates that are trusted for a
particular server but not to authorize other certificates. This purpose
is served by the functions *note gnutls_x509_trust_list_add_named_crt::
and *note gnutls_x509_trust_list_verify_named_crt::.
File: gnutls.info, Node: Verifying a certificate in the context of TLS session, Next: Verifying a certificate using trust on first use authentication, Prev: Verifying X.509 certificate paths, Up: X.509 certificates
4.1.5 Verifying a certificate in the context of TLS session
-----------------------------------------------------------
When operating in the context of a TLS session, the trusted certificate
authority list may also be set using:
'INT *note gnutls_certificate_set_x509_trust_file:: (gnutls_certificate_credentials_t CRED, const char * CAFILE, gnutls_x509_crt_fmt_t TYPE)'
'INT *note gnutls_certificate_set_x509_crl_file:: (gnutls_certificate_credentials_t RES, const char * CRLFILE, gnutls_x509_crt_fmt_t TYPE)'
'INT *note gnutls_certificate_set_x509_system_trust:: (gnutls_certificate_credentials_t CRED)'
Then it is not required to setup a trusted list as above. The function
*note gnutls_certificate_verify_peers2:: may then be used to verify the
peer's certificate chain. The flags are set similarly to the
verification functions in the previous section.
There is also the possibility to pass some input to the verification
functions in the form of flags. For *note
gnutls_x509_trust_list_verify_crt:: the flags are passed
straightforward, but *note gnutls_certificate_verify_peers2:: depends on
the flags set by calling *note gnutls_certificate_set_verify_flags::.
All the available flags are part of the enumeration
'gnutls_certificate_verify_flags' shown in *note Figure 4.3:
gnutls_certificate_verify_flags.
'GNUTLS_VERIFY_DISABLE_CA_SIGN'
If set a signer does not have to be a certificate authority. This
flag should normaly be disabled, unless you know what this means.
'GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT'
Allow trusted CA certificates with version 1. This is safer than
'GNUTLS_VERIFY_ALLOW_ANY_X509_V1_CA_CRT' , and should be used
instead. That way only signers in your trusted list will be
allowed to have certificates of version 1. This is the default.
'GNUTLS_VERIFY_DO_NOT_ALLOW_SAME'
If a certificate is not signed by anyone trusted but exists in the
trusted CA list do not treat it as trusted.
'GNUTLS_VERIFY_ALLOW_ANY_X509_V1_CA_CRT'
Allow CA certificates that have version 1 (both root and
intermediate). This might be dangerous since those haven't the
basicConstraints extension. Must be used in combination with
'GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT' .
'GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD2'
Allow certificates to be signed using the broken MD2 algorithm.
'GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5'
Allow certificates to be signed using the broken MD5 algorithm.
'GNUTLS_VERIFY_DISABLE_TIME_CHECKS'
Disable checking of activation and expiration validity periods of
certificate chains. Don't set this unless you understand the
security implications.
'GNUTLS_VERIFY_DISABLE_TRUSTED_TIME_CHECKS'
If set a signer in the trusted list is never checked for expiration
or activation.
'GNUTLS_VERIFY_DO_NOT_ALLOW_X509_V1_CA_CRT'
Do not allow trusted CA certificates that have version 1. This
option is to be used to deprecate all certificates of version 1.
'GNUTLS_VERIFY_DISABLE_CRL_CHECKS'
Disable checking for validity using certificate revocation lists.
'GNUTLS_VERIFY_ALLOW_UNSORTED_CHAIN'
A certificate chain is tolerated if unsorted (the case with many
TLS servers out there).
Figure 4.3: The 'gnutls_certificate_verify_flags' enumeration.
Although the verification of a certificate path indicates that the
certificate is signed by trusted authority, does not reveal anything
about the peer's identity. It is required to verify if the
certificate's owner is the one you expect. For more information consult
[_RFC2818_] and section *note ex:verify:: for an example.
File: gnutls.info, Node: Verifying a certificate using trust on first use authentication, Prev: Verifying a certificate in the context of TLS session, Up: X.509 certificates
4.1.6 Verifying a certificate using trust on first use authentication
---------------------------------------------------------------------
It is possible to use a trust on first use (similar to SSH)
authentication method in GnuTLS. That is the concept used by the SSH
programs, where the public key of the peer is not verified, or verified
in an out-of-bound way, but subsequent connections to the same peer
require the public key to remain the same. Such a system in combination
with the typical CA verification of a certificate, and OCSP revocation
checks, can help to provide multiple factor verification, where a single
point of failure is not enough to compromise the system. For example a
server compromise may be detected using OCSP, and a CA compromise can be
detected using the trust on first use method. Such a hybrid system with
X.509 and trust on first use authentication is shown in *note Simple
client example with SSH-style certificate verification::.
-- Function: int gnutls_verify_stored_pubkey (const char* DB_NAME,
gnutls_tdb_t TDB, const char* HOST, const char* SERVICE,
gnutls_certificate_type_t CERT_TYPE, const gnutls_datum_t *
CERT, unsigned int FLAGS)
DB_NAME: A file specifying the stored keys (use NULL for the
default)
TDB: A storage structure or NULL to use the default
HOST: The peer's name
SERVICE: non-NULL if this key is specific to a service (e.g. http)
CERT_TYPE: The type of the certificate
CERT: The raw (der) data of the certificate
FLAGS: should be 0.
This function will try to verify the provided certificate using a
list of stored public keys. The 'service' field if non-NULL should
be a port number.
The 'retrieve' variable if non-null specifies a custom backend for
the retrieval of entries. If it is NULL then the default file
backend will be used. In POSIX-like systems the file backend uses
the $HOME/.gnutls/known_hosts file.
Note that if the custom storage backend is provided the retrieval
function should return 'GNUTLS_E_CERTIFICATE_KEY_MISMATCH' if the
host/service pair is found but key doesn't match,
'GNUTLS_E_NO_CERTIFICATE_FOUND' if no such host/service with the
given key is found, and 0 if it was found. The storage function
should return 0 on success.
*Returns:* If no associated public key is found then
'GNUTLS_E_NO_CERTIFICATE_FOUND' will be returned. If a key is
found but does not match 'GNUTLS_E_CERTIFICATE_KEY_MISMATCH' is
returned. On success, 'GNUTLS_E_SUCCESS' (0) is returned, or a
negative error value on other errors.
*Since:* 3.0
-- Function: int gnutls_store_pubkey (const char* DB_NAME, gnutls_tdb_t
TDB, const char* HOST, const char* SERVICE,
gnutls_certificate_type_t CERT_TYPE, const gnutls_datum_t *
CERT, time_t EXPIRATION, unsigned int FLAGS)
DB_NAME: A file specifying the stored keys (use NULL for the
default)
TDB: A storage structure or NULL to use the default
HOST: The peer's name
SERVICE: non-NULL if this key is specific to a service (e.g. http)
CERT_TYPE: The type of the certificate
CERT: The data of the certificate
EXPIRATION: The expiration time (use 0 to disable expiration)
FLAGS: should be 0.
This function will store the provided certificate to the list of
stored public keys. The key will be considered valid until the
provided expiration time.
The 'store' variable if non-null specifies a custom backend for the
storage of entries. If it is NULL then the default file backend
will be used.
*Returns:* On success, 'GNUTLS_E_SUCCESS' (0) is returned,
otherwise a negative error value.
*Since:* 3.0
In addition to the above the *note gnutls_store_commitment:: can be used
to implement a key-pinning architecture as in [_KEYPIN_]. This provides
a way for web server to commit on a public key that is not yet active.
-- Function: int gnutls_store_commitment (const char* DB_NAME,
gnutls_tdb_t TDB, const char* HOST, const char* SERVICE,
gnutls_digest_algorithm_t HASH_ALGO, const gnutls_datum_t*
HASH, time_t EXPIRATION, unsigned int FLAGS)
DB_NAME: A file specifying the stored keys (use NULL for the
default)
TDB: A storage structure or NULL to use the default
HOST: The peer's name
SERVICE: non-NULL if this key is specific to a service (e.g. http)
HASH_ALGO: The hash algorithm type
HASH: The raw hash
EXPIRATION: The expiration time (use 0 to disable expiration)
FLAGS: should be 0.
This function will store the provided hash commitment to the list
of stored public keys. The key with the given hash will be
considered valid until the provided expiration time.
The 'store' variable if non-null specifies a custom backend for the
storage of entries. If it is NULL then the default file backend
will be used.
Note that this function is not thread safe with the default
backend.
*Returns:* On success, 'GNUTLS_E_SUCCESS' (0) is returned,
otherwise a negative error value.
*Since:* 3.0
The storage and verification functions may be used with the default text
file based back-end, or another back-end may be specified. That should
contain storage and retrieval functions and specified as below.
'INT *note gnutls_tdb_init:: (gnutls_tdb_t* TDB)'
'VOID *note gnutls_tdb_deinit:: (gnutls_tdb_t TDB)'
'VOID *note gnutls_tdb_set_verify_func:: (gnutls_tdb_t TDB, gnutls_tdb_verify_func VERIFY)'
'VOID *note gnutls_tdb_set_store_func:: (gnutls_tdb_t TDB, gnutls_tdb_store_func STORE)'
'VOID *note gnutls_tdb_set_store_commitment_func:: (gnutls_tdb_t TDB, gnutls_tdb_store_commitment_func CSTORE)'
File: gnutls.info, Node: OpenPGP certificates, Next: Digital signatures, Prev: X.509 certificates, Up: Certificate authentication
4.2 OpenPGP certificates
========================
The OpenPGP key 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 else's 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. For example in *note Figure
4.4: fig:openpgp, David trusts Alice to be an introducer and Alice
signed Bob's key thus Dave trusts Bob's key to be the real one.
[image src="gnutls-pgp.png" ]
Figure 4.4: An example of the OpenPGP trust model.
There are some key points that are important in that model. In the
example Alice has to sign Bob's key, only if she is sure that the key
belongs to Bob. Otherwise she may also make Dave falsely believe that
this is Bob's key. Dave has also the responsibility to know who to
trust. This model is similar to real life relations.
Just see how Charlie behaves in the previous example. Although he has
signed Bob's key - because he knows, somehow, that it belongs to Bob -
he does not trust Bob to be an introducer. Charlie decided to trust
only Kevin, for some reason. A reason could be that Bob is lazy enough,
and signs other people's keys without being sure that they belong to the
actual owner.
4.2.1 OpenPGP certificate structure
-----------------------------------
In GnuTLS the OpenPGP key structures [_RFC2440_] are handled using the
'gnutls_openpgp_crt_t' type and the corresponding private keys with the
'gnutls_openpgp_privkey_t' type. All the prototypes for the key
handling functions can be found at 'gnutls/openpgp.h'.
4.2.2 Verifying an OpenPGP certificate
--------------------------------------
The verification functions of OpenPGP keys, included in GnuTLS, are
simple ones, and do not use the features of the "web of trust". For
that reason, if the verification needs are complex, the assistance of
external tools like GnuPG and GPGME(1) is recommended.
In GnuTLS there is a verification function for OpenPGP certificates, the
*note gnutls_openpgp_crt_verify_ring::. This checks an OpenPGP key
against a given set of public keys (keyring) and returns the key status.
The key verification status is the same as in X.509 certificates,
although the meaning and interpretation are different. For example an
OpenPGP key may be valid, if the self signature is ok, even if no
signers were found. The meaning of verification status flags is the
same as in the X.509 certificates (see *note Figure 4.3:
gnutls_certificate_verify_flags.).
-- Function: int gnutls_openpgp_crt_verify_ring (gnutls_openpgp_crt_t
KEY, gnutls_openpgp_keyring_t KEYRING, unsigned int FLAGS,
unsigned int * VERIFY)
KEY: the structure that holds the key.
KEYRING: holds the keyring to check against
FLAGS: unused (should be 0)
VERIFY: will hold the certificate verification output.
Verify all signatures in the key, using the given set of keys
(keyring).
The key verification output will be put in 'verify' and will be one
or more of the 'gnutls_certificate_status_t' enumerated elements
bitwise or'd.
*Returns:* 'GNUTLS_E_SUCCESS' on success, or an error code.
-- Function: int gnutls_openpgp_crt_verify_self (gnutls_openpgp_crt_t
KEY, unsigned int FLAGS, unsigned int * VERIFY)
KEY: the structure that holds the key.
FLAGS: unused (should be 0)
VERIFY: will hold the key verification output.
Verifies the self signature in the key. The key verification
output will be put in 'verify' and will be one or more of the
gnutls_certificate_status_t enumerated elements bitwise or'd.
*Returns:* 'GNUTLS_E_SUCCESS' on success, or an error code.
4.2.3 Verifying a certificate in the context of a TLS session
-------------------------------------------------------------
Similarly with X.509 certificates, one needs to specify the OpenPGP
keyring file in the credentials structure. The certificates in this
file will be used by *note gnutls_certificate_verify_peers2:: to verify
the signatures in the certificate sent by the peer.
-- Function: int gnutls_certificate_set_openpgp_keyring_file
(gnutls_certificate_credentials_t C, const char * FILE,
gnutls_openpgp_crt_fmt_t FORMAT)
C: A certificate credentials structure
FILE: filename of the keyring.
FORMAT: format of keyring.
The function is used to set keyrings that will be used internally
by various OpenPGP functions. For example to find a key when it is
needed for an operations. The keyring will also be used at the
verification functions.
*Returns:* On success, 'GNUTLS_E_SUCCESS' (0) is returned,
otherwise a negative error value.
---------- Footnotes ----------
(1)
File: gnutls.info, Node: Digital signatures, Prev: OpenPGP certificates, Up: Certificate authentication
4.3 Digital signatures
======================
In this section we will provide some information about digital
signatures, how they work, and give the rationale for disabling some of
the algorithms used.
Digital signatures work by using somebody's secret key to sign some
arbitrary data. Then anybody else could use the public key of that
person to verify the signature. Since the data may be arbitrary it is
not suitable input to a cryptographic digital signature algorithm. For
this reason and also for performance cryptographic hash algorithms are
used to preprocess the input to the signature algorithm. This works as
long as it is difficult enough to generate two different messages with
the same hash algorithm output. In that case the same signature could
be used as a proof for both messages. Nobody wants to sign an innocent
message of donating 1 euro to Greenpeace and find out that he donated
1.000.000 euros to Bad Inc.
For a hash algorithm to be called cryptographic the following three
requirements must hold:
1. Preimage resistance. That means the algorithm must be one way and
given the output of the hash function H(x), it is impossible to
calculate x.
2. 2nd preimage resistance. That means that given a pair x,y with
y=H(x) it is impossible to calculate an x' such that y=H(x').
3. Collision resistance. That means that it is impossible to
calculate random x and x' such H(x')=H(x).
The last two requirements in the list are the most important in digital
signatures. These protect against somebody who would like to generate
two messages with the same hash output. When an algorithm is considered
broken usually it means that the Collision resistance of the algorithm
is less than brute force. Using the birthday paradox the brute force
attack takes 2^{((hash size) / 2)} operations. Today colliding
certificates using the MD5 hash algorithm have been generated as shown
in [_WEGER_].
There has been cryptographic results for the SHA-1 hash algorithms as
well, although they are not yet critical. Before 2004, MD5 had a
presumed collision strength of 2^{64}, but it has been showed to have a
collision strength well under 2^{50}. As of November 2005, it is
believed that SHA-1's collision strength is around 2^{63}. We consider
this sufficiently hard so that we still support SHA-1. We anticipate
that SHA-256/386/512 will be used in publicly-distributed certificates
in the future. When 2^{63} can be considered too weak compared to the
computer power available sometime in the future, SHA-1 will be disabled
as well. The collision attacks on SHA-1 may also get better, given the
new interest in tools for creating them.
4.3.1 Trading security for interoperability
-------------------------------------------
If you connect to a server and use GnuTLS' functions to verify the
certificate chain, and get a 'GNUTLS_CERT_INSECURE_ALGORITHM' validation
error (see *note Verifying X.509 certificate paths::), it means that
somewhere in the certificate chain there is a certificate signed using
'RSA-MD2' or 'RSA-MD5'. These two digital signature algorithms are
considered broken, so GnuTLS fails verifying the certificate. In some
situations, it may be useful to be able to verify the certificate chain
anyway, assuming an attacker did not utilize the fact that these
signatures algorithms are broken. This section will give help on how to
achieve that.
It is important to know that you do not have to enable any of the flags
discussed here to be able to use trusted root CA certificates
self-signed using 'RSA-MD2' or 'RSA-MD5'. The certificates in the
trusted list are considered trusted irrespective of the signature.
If you are using *note gnutls_certificate_verify_peers2:: to verify the
certificate chain, you can call *note
gnutls_certificate_set_verify_flags:: with the flags:
* 'GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD2'
* 'GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5'
as in the following example:
gnutls_certificate_set_verify_flags (x509cred,
GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5);
This will tell the verifier algorithm to enable 'RSA-MD5' when verifying
the certificates.
If you are using *note gnutls_x509_crt_verify:: or *note
gnutls_x509_crt_list_verify::, you can pass the
'GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5' parameter directly in the 'flags'
parameter.
If you are using these flags, it may also be a good idea to warn the
user when verification failure occur for this reason. The simplest is
to not use the flags by default, and only fall back to using them after
warning the user. If you wish to inspect the certificate chain
yourself, you can use *note gnutls_certificate_get_peers:: to extract
the raw server's certificate chain, *note gnutls_x509_crt_list_import::
to parse each of the certificates, and then *note
gnutls_x509_crt_get_signature_algorithm:: to find out the signing
algorithm used for each certificate. If any of the intermediary
certificates are using 'GNUTLS_SIGN_RSA_MD2' or 'GNUTLS_SIGN_RSA_MD5',
you could present a warning.
File: gnutls.info, Node: Shared-key and anonymous authentication, Next: More on certificate authentication, Prev: Certificate authentication, Up: Top
5 Shared-key and anonymous authentication
*****************************************
In addition to certificate authentication, the TLS protocol may be used
with password, shared-key and anonymous authentication methods. The
rest of this chapter discusses details of these methods.
* Menu:
* SRP authentication::
* PSK authentication::
* Anonymous authentication::
File: gnutls.info, Node: SRP authentication, Next: PSK authentication, Up: Shared-key and anonymous authentication
5.1 SRP authentication
======================
* Menu:
* Authentication using SRP::
* srptool Invocation:: Invoking srptool
File: gnutls.info, Node: Authentication using SRP, Next: srptool Invocation, Up: SRP authentication
5.1.1 Authentication using SRP
------------------------------
GnuTLS supports authentication via the Secure Remote Password or SRP
protocol (see [_RFC2945,TOMSRP_] for a description). The SRP key
exchange is an extension to the TLS protocol, and it provides an
authenticated with a password key exchange. The peers can be identified
using a single password, or there can be combinations where the client
is authenticated using SRP and the server using a certificate.
The advantage of SRP authentication, over other proposed secure password
authentication schemes, is that SRP is not susceptible to off-line
dictionary attacks. Moreover, SRP does not require the server to hold
the user's password. This kind of protection is similar to the one used
traditionally in the UNIX '/etc/passwd' file, where the contents of this
file did not cause harm to the system security if they were revealed.
The SRP needs instead of the plain password something called a verifier,
which is calculated using the user's password, and if stolen cannot be
used to impersonate the user.
Typical conventions in SRP are a password file, called 'tpasswd' that
holds the SRP verifiers (encoded passwords) and another file,
'tpasswd.conf', which holds the allowed SRP parameters. The included in
GnuTLS helper follow those conventions. The srptool program, discussed
in the next section is a tool to manipulate the SRP parameters.
The implementation in GnuTLS is based on [_TLSSRP_]. The supported key
exchange methods are shown below.
'SRP:'
Authentication using the SRP protocol.
'SRP_DSS:'
Client authentication using the SRP protocol. Server is
authenticated using a certificate with DSA parameters.
'SRP_RSA:'
Client authentication using the SRP protocol. Server is
authenticated using a certificate with RSA parameters.
-- Function: int gnutls_srp_verifier (const char * USERNAME, const char
* PASSWORD, const gnutls_datum_t * SALT, const gnutls_datum_t
* GENERATOR, const gnutls_datum_t * PRIME, gnutls_datum_t *
RES)
USERNAME: is the user's name
PASSWORD: is the user's password
SALT: should be some randomly generated bytes
GENERATOR: is the generator of the group
PRIME: is the group's prime
RES: where the verifier will be stored.
This function will create an SRP verifier, as specified in RFC2945.
The 'prime' and 'generator' should be one of the static parameters
defined in gnutls/gnutls.h or may be generated.
The verifier will be allocated with 'gnutls_malloc' () and will be
stored in 'res' using binary format.
*Returns:* On success, 'GNUTLS_E_SUCCESS' (0) is returned, or an
error code.
'INT *note gnutls_srp_base64_encode:: (const gnutls_datum_t * DATA, char * RESULT, size_t * RESULT_SIZE)'
'INT *note gnutls_srp_base64_decode:: (const gnutls_datum_t * B64_DATA, char * RESULT, size_t * RESULT_SIZE)'
File: gnutls.info, Node: srptool Invocation, Prev: Authentication using SRP, Up: SRP authentication
5.1.2 Invoking srptool
----------------------
Simple program that emulates the programs in the Stanford SRP (Secure
Remote Password) libraries using GnuTLS. It is intended for use in
places where you don't expect SRP authentication to be the used for
system users.
In brief, to use SRP you need to create two files. These are the
password file that holds the users and the verifiers associated with
them and the configuration file to hold the group parameters (called
tpasswd.conf).
This section was generated by *AutoGen*, using the 'agtexi-cmd' template
and the option descriptions for the 'srptool' program. This software is
released under the GNU General Public License, version 3 or later.
srptool help/usage ('--help')
.............................
This is the automatically generated usage text for srptool.
The text printed is the same whether selected with the 'help' option
('--help') or the 'more-help' option ('--more-help'). 'more-help' will
print the usage text by passing it through a pager program. 'more-help'
is disabled on platforms without a working 'fork(2)' function. The
'PAGER' environment variable is used to select the program, defaulting
to 'more'. Both will exit with a status code of 0.
srptool - GnuTLS SRP tool - Ver. @VERSION@
USAGE: lt-srptool [ - [] | --[{=| }] ]...
-d, --debug=num Enable debugging.
- It must be in the range:
0 to 9999
-i, --index specify the index of the group parameters in tpasswd.conf to use.
-u, --username=str specify a username
-p, --passwd=str specify a password file.
-s, --salt=num specify salt size.
--verify just verify the password.
-v, --passwd-conf=str specify a password conf file.
--create-conf=str Generate a password configuration file.
-v, --version[=arg] Output version information and exit
-h, --help Display extended usage information and exit
-!, --more-help Extended usage information passed thru pager
Options are specified by doubled hyphens and their name or by a single
hyphen and the flag character.
Simple program that emulates the programs in the Stanford SRP (Secure
Remote Password) libraries using GnuTLS. It is intended for use in places
where you don't expect SRP authentication to be the used for system users.
In brief, to use SRP you need to create two files. These are the password
file that holds the users and the verifiers associated with them and the
configuration file to hold the group parameters (called tpasswd.conf).
please send bug reports to: bug-gnutls@gnu.org
debug option (-d)
.................
This is the "enable debugging." option. This option takes an argument
number. Specifies the debug level.
verify option
.............
This is the "just verify the password." option. Verifies the password
provided against the password file.
passwd-conf option (-v)
.......................
This is the "specify a password conf file." option. This option takes
an argument string. Specify a filename or a PKCS #11 URL to read the
CAs from.
create-conf option
..................
This is the "generate a password configuration file." option. This
option takes an argument string. This generates a password
configuration file (tpasswd.conf) containing the required for TLS
parameters.
srptool exit status
...................
One of the following exit values will be returned:
'0 (EXIT_SUCCESS)'
Successful program execution.
'1 (EXIT_FAILURE)'
The operation failed or the command syntax was not valid.
srptool See Also
................
gnutls-cli-debug (1), gnutls-serv (1), srptool (1), psktool (1),
certtool (1)
srptool Examples
................
To create 'tpasswd.conf' which holds the g and n values for SRP protocol
(generator and a large prime), run:
$ srptool --create-conf /etc/tpasswd.conf
This command will create '/etc/tpasswd' and will add user 'test' (you
will also be prompted for a password). Verifiers are stored by default
in the way libsrp expects.
$ srptool --passwd /etc/tpasswd --passwd-conf /etc/tpasswd.conf -u test
This command will check against a password. If the password matches the
one in '/etc/tpasswd' you will get an ok.
$ srptool --passwd /etc/tpasswd --passwd\-conf /etc/tpasswd.conf --verify -u test
File: gnutls.info, Node: PSK authentication, Next: Anonymous authentication, Prev: SRP authentication, Up: Shared-key and anonymous authentication
5.2 PSK authentication
======================
* Menu:
* Authentication using PSK::
* psktool Invocation:: Invoking psktool
File: gnutls.info, Node: Authentication using PSK, Next: psktool Invocation, Up: PSK authentication
5.2.1 Authentication using PSK
------------------------------
Authentication using Pre-shared keys is a method to authenticate using
usernames and binary keys. This protocol avoids making use of public
key infrastructure and expensive calculations, thus it is suitable for
constraint clients.
The implementation in GnuTLS is based on [_TLSPSK_]. The supported PSK
key exchange methods are:
'PSK:'
Authentication using the PSK protocol.
'DHE-PSK:'
Authentication using the PSK protocol and Diffie-Hellman key
exchange. This method offers perfect forward secrecy.
'ECDHE-PSK:'
Authentication using the PSK protocol and Elliptic curve
Diffie-Hellman key exchange. This method offers perfect forward
secrecy.
Helper functions to generate and maintain PSK keys are also included in
GnuTLS.
'INT *note gnutls_key_generate:: (gnutls_datum_t * KEY, unsigned int KEY_SIZE)'
'INT *note gnutls_hex_encode:: (const gnutls_datum_t * DATA, char * RESULT, size_t * RESULT_SIZE)'
'INT *note gnutls_hex_decode:: (const gnutls_datum_t * HEX_DATA, void * RESULT, size_t * RESULT_SIZE)'
File: gnutls.info, Node: psktool Invocation, Prev: Authentication using PSK, Up: PSK authentication
5.2.2 Invoking psktool
----------------------
Program that generates random keys for use with TLS-PSK. The keys are
stored in hexadecimal format in a key file.
This section was generated by *AutoGen*, using the 'agtexi-cmd' template
and the option descriptions for the 'psktool' program. This software is
released under the GNU General Public License, version 3 or later.
psktool help/usage ('--help')
.............................
This is the automatically generated usage text for psktool.
The text printed is the same whether selected with the 'help' option
('--help') or the 'more-help' option ('--more-help'). 'more-help' will
print the usage text by passing it through a pager program. 'more-help'
is disabled on platforms without a working 'fork(2)' function. The
'PAGER' environment variable is used to select the program, defaulting
to 'more'. Both will exit with a status code of 0.
psktool - GnuTLS PSK tool - Ver. @VERSION@
USAGE: lt-psktool [ - [] | --[{=| }] ]...
-d, --debug=num Enable debugging.
- It must be in the range:
0 to 9999
-s, --keysize=num specify the key size in bytes
- It must be in the range:
0 to 512
-u, --username=str specify a username
-p, --passwd=str specify a password file.
-v, --version[=arg] Output version information and exit
-h, --help Display extended usage information and exit
-!, --more-help Extended usage information passed thru pager
Options are specified by doubled hyphens and their name or by a single
hyphen and the flag character.
Program that generates random keys for use with TLS-PSK. The keys are
stored in hexadecimal format in a key file.
please send bug reports to: bug-gnutls@gnu.org
debug option (-d)
.................
This is the "enable debugging." option. This option takes an argument
number. Specifies the debug level.
psktool exit status
...................
One of the following exit values will be returned:
'0 (EXIT_SUCCESS)'
Successful program execution.
'1 (EXIT_FAILURE)'
The operation failed or the command syntax was not valid.
psktool See Also
................
gnutls-cli-debug (1), gnutls-serv (1), srptool (1), certtool (1)
psktool Examples
................
To add a user 'psk_identity' in 'passwd.psk' for use with GnuTLS run:
$ ./psktool -u psk_identity -p passwd.psk
Generating a random key for user 'psk_identity'
Key stored to passwd.psk
$ cat psks.txt
psk_identity:88f3824b3e5659f52d00e959bacab954b6540344
$
This command will create 'passwd.psk' if it does not exist and will add
user 'psk_identity' (you will also be prompted for a password).
File: gnutls.info, Node: Anonymous authentication, Prev: PSK authentication, Up: Shared-key and anonymous authentication
5.3 Anonymous authentication
============================
The anonymous key exchange offers encryption without any indication of
the peer's identity. This kind of authentication is vulnerable to a man
in the middle attack, but can be used even if there is no prior
communication or shared trusted parties with the peer. Moreover it is
useful when complete anonymity is required. Unless in one of the above
cases, do not use anonymous authentication.
The available key exchange algorithms for anonymous authentication are
shown below, but note that few public servers support them. They
typically have to be explicitly enabled.
'ANON_DH:'
This algorithm exchanges Diffie-Hellman parameters.
'ANON_ECDH:'
This algorithm exchanges elliptic curve Diffie-Hellman parameters.
It is more efficient than ANON_DH on equivalent security levels.
File: gnutls.info, Node: More on certificate authentication, Next: How to use GnuTLS in applications, Prev: Shared-key and anonymous authentication, Up: Top
6 More on certificate authentication
************************************
Certificates are not the only structures involved in a public key
infrastructure. Several other structures that are used for certificate
requests, encrypted private keys, revocation lists, GnuTLS abstract key
structures, etc., are discussed in this chapter.
* Menu:
* PKCS 10 certificate requests::
* PKIX certificate revocation lists::
* OCSP certificate status checking::
* Managing encrypted keys::
* certtool Invocation:: Invoking certtool
* ocsptool Invocation:: Invoking ocsptool
* Smart cards and HSMs::
* Abstract key types::
File: gnutls.info, Node: PKCS 10 certificate requests, Next: PKIX certificate revocation lists, Up: More on certificate authentication
6.1 PKCS #10 certificate requests
=================================
A certificate request is a structure, which contain information about an
applicant of a certificate service. It usually contains a private key,
a distinguished name and secondary data such as a challenge password.
GnuTLS supports the requests defined in PKCS #10 [_RFC2986_]. Other
formats of certificate requests are not currently supported.
A certificate request can be generated by associating it with a private
key, setting the subject's information and finally self signing it. The
last step ensures that the requester is in possession of the private
key.
'INT *note gnutls_x509_crq_set_version:: (gnutls_x509_crq_t CRQ, unsigned int VERSION)'
'INT *note gnutls_x509_crq_set_dn_by_oid:: (gnutls_x509_crq_t CRQ, const char * OID, unsigned int RAW_FLAG, const void * DATA, unsigned int SIZEOF_DATA)'
'INT *note gnutls_x509_crq_set_key_usage:: (gnutls_x509_crq_t CRQ, unsigned int USAGE)'
'INT *note gnutls_x509_crq_set_key_purpose_oid:: (gnutls_x509_crq_t CRQ, const void * OID, unsigned int CRITICAL)'
'INT *note gnutls_x509_crq_set_basic_constraints:: (gnutls_x509_crq_t CRQ, unsigned int CA, int PATHLENCONSTRAINT)'
The *note gnutls_x509_crq_set_key:: and *note gnutls_x509_crq_sign2::
functions associate the request with a private key and sign it. If a
request is to be signed with a key residing in a PKCS #11 token it is
recommended to use the signing functions shown in *note Abstract key
types::.
-- Function: int gnutls_x509_crq_set_key (gnutls_x509_crq_t CRQ,
gnutls_x509_privkey_t KEY)
CRQ: should contain a 'gnutls_x509_crq_t' structure
KEY: holds a private key
This function will set the public parameters from the given private
key to the request.
*Returns:* On success, 'GNUTLS_E_SUCCESS' (0) is returned,
otherwise a negative error value.
-- Function: int gnutls_x509_crq_sign2 (gnutls_x509_crq_t CRQ,
gnutls_x509_privkey_t KEY, gnutls_digest_algorithm_t DIG,
unsigned int FLAGS)
CRQ: should contain a 'gnutls_x509_crq_t' structure
KEY: holds a private key
DIG: The message digest to use, i.e., 'GNUTLS_DIG_SHA1'
FLAGS: must be 0
This function will sign the certificate request with a private key.
This must be the same key as the one used in
'gnutls_x509_crt_set_key()' since a certificate request is self
signed.
This must be the last step in a certificate request generation
since all the previously set parameters are now signed.
*Returns:* 'GNUTLS_E_SUCCESS' on success, otherwise a negative
error code. 'GNUTLS_E_ASN1_VALUE_NOT_FOUND' is returned if you
didn't set all information in the certificate request (e.g., the
version using 'gnutls_x509_crq_set_version()' ).
The following example is about generating a certificate request, and a
private key. A certificate request can be later be processed by a CA
which should return a signed certificate.
/* This example code is placed in the public domain. */
#ifdef HAVE_CONFIG_H
#include
#endif
#include
#include
#include
#include
#include
#include
#include
/* This example will generate a private key and a certificate
* request.
*/
int
main (void)
{
gnutls_x509_crq_t crq;
gnutls_x509_privkey_t key;
unsigned char buffer[10 * 1024];
size_t buffer_size = sizeof (buffer);
unsigned int bits;
gnutls_global_init ();
/* Initialize an empty certificate request, and
* an empty private key.
*/
gnutls_x509_crq_init (&crq);
gnutls_x509_privkey_init (&key);
/* Generate an RSA key of moderate security.
*/
bits = gnutls_sec_param_to_pk_bits (GNUTLS_PK_RSA, GNUTLS_SEC_PARAM_NORMAL);
gnutls_x509_privkey_generate (key, GNUTLS_PK_RSA, bits, 0);
/* Add stuff to the distinguished name
*/
gnutls_x509_crq_set_dn_by_oid (crq, GNUTLS_OID_X520_COUNTRY_NAME,
0, "GR", 2);
gnutls_x509_crq_set_dn_by_oid (crq, GNUTLS_OID_X520_COMMON_NAME,
0, "Nikos", strlen ("Nikos"));
/* Set the request version.
*/
gnutls_x509_crq_set_version (crq, 1);
/* Set a challenge password.
*/
gnutls_x509_crq_set_challenge_password (crq, "something to remember here");
/* Associate the request with the private key
*/
gnutls_x509_crq_set_key (crq, key);
/* Self sign the certificate request.
*/
gnutls_x509_crq_sign2 (crq, key, GNUTLS_DIG_SHA1, 0);
/* Export the PEM encoded certificate request, and
* display it.
*/
gnutls_x509_crq_export (crq, GNUTLS_X509_FMT_PEM, buffer, &buffer_size);
printf ("Certificate Request: \n%s", buffer);
/* Export the PEM encoded private key, and
* display it.
*/
buffer_size = sizeof (buffer);
gnutls_x509_privkey_export (key, GNUTLS_X509_FMT_PEM, buffer, &buffer_size);
printf ("\n\nPrivate key: \n%s", buffer);
gnutls_x509_crq_deinit (crq);
gnutls_x509_privkey_deinit (key);
return 0;
}
File: gnutls.info, Node: PKIX certificate revocation lists, Next: OCSP certificate status checking, Prev: PKCS 10 certificate requests, Up: More on certificate authentication
6.2 PKIX certificate revocation lists
=====================================
A certificate revocation list (CRL) is a structure issued by an
authority periodically containing a list of revoked certificates serial
numbers. The CRL structure is signed with the issuing authorities'
keys. A typical CRL contains the fields as shown in *note Table 6.1:
tab:crl. Certificate revocation lists are used to complement the
expiration date of a certificate, in order to account for other reasons
of revocation, such as compromised keys, etc.
A certificate request can be generated by associating it with a private
key, setting the subject's information and finally self signing it. The
last step ensures that the requester is in possession of the private
key. Each CRL is valid for limited amount of time and is required to
provide, except for the current issuing time, also the issuing time of
the next update.
Field Description
------------------------------------------------------------------
version The field that indicates the version of the CRL
structure.
signature A signature by the issuing authority.
issuer Holds the issuer's distinguished name.
thisUpdate The issuing time of the revocation list.
nextUpdate The issuing time of the revocation list that
will update that one.
revokedCertificatesList of revoked certificates serial numbers.
extensions Optional CRL structure extensions.
Table 6.1: Certificate revocation list fields.
'INT *note gnutls_x509_crl_set_version:: (gnutls_x509_crl_t CRL, unsigned int VERSION)'
'INT *note gnutls_x509_crl_set_crt_serial:: (gnutls_x509_crl_t CRL, const void * SERIAL, size_t SERIAL_SIZE, time_t REVOCATION_TIME)'
'INT *note gnutls_x509_crl_set_crt:: (gnutls_x509_crl_t CRL, gnutls_x509_crt_t CRT, time_t REVOCATION_TIME)'
'INT *note gnutls_x509_crl_set_next_update:: (gnutls_x509_crl_t CRL, time_t EXP_TIME)'
'INT *note gnutls_x509_crl_set_this_update:: (gnutls_x509_crl_t CRL, time_t ACT_TIME)'
The *note gnutls_x509_crl_sign2:: and *note
gnutls_x509_crl_privkey_sign:: functions sign the revocation list with a
private key. The latter function can be used to sign with a key
residing in a PKCS #11 token.
-- Function: int gnutls_x509_crl_sign2 (gnutls_x509_crl_t CRL,
gnutls_x509_crt_t ISSUER, gnutls_x509_privkey_t ISSUER_KEY,
gnutls_digest_algorithm_t DIG, unsigned int FLAGS)
CRL: should contain a gnutls_x509_crl_t structure
ISSUER: is the certificate of the certificate issuer
ISSUER_KEY: holds the issuer's private key
DIG: The message digest to use. GNUTLS_DIG_SHA1 is the safe choice
unless you know what you're doing.
FLAGS: must be 0
This function will sign the CRL with the issuer's private key, and
will copy the issuer's information into the CRL.
This must be the last step in a certificate CRL since all the
previously set parameters are now signed.
*Returns:* On success, 'GNUTLS_E_SUCCESS' (0) is returned,
otherwise a negative error value.
-- Function: int gnutls_x509_crl_privkey_sign (gnutls_x509_crl_t CRL,
gnutls_x509_crt_t ISSUER, gnutls_privkey_t ISSUER_KEY,
gnutls_digest_algorithm_t DIG, unsigned int FLAGS)
CRL: should contain a gnutls_x509_crl_t structure
ISSUER: is the certificate of the certificate issuer
ISSUER_KEY: holds the issuer's private key
DIG: The message digest to use. GNUTLS_DIG_SHA1 is the safe choice
unless you know what you're doing.
FLAGS: must be 0
This function will sign the CRL with the issuer's private key, and
will copy the issuer's information into the CRL.
This must be the last step in a certificate CRL since all the
previously set parameters are now signed.
*Returns:* On success, 'GNUTLS_E_SUCCESS' (0) is returned,
otherwise a negative error value.
Since 2.12.0
Few extensions on the CRL structure are supported, including the CRL
number extension and the authority key identifier.
'INT *note gnutls_x509_crl_set_number:: (gnutls_x509_crl_t CRL, const void * NR, size_t NR_SIZE)'
'INT *note gnutls_x509_crl_set_authority_key_id:: (gnutls_x509_crl_t CRL, const void * ID, size_t ID_SIZE)'
File: gnutls.info, Node: OCSP certificate status checking, Next: Managing encrypted keys, Prev: PKIX certificate revocation lists, Up: More on certificate authentication
6.3 OCSP certificate status checking
====================================
Certificates may be revoked before their expiration time has been
reached. There are several reasons for revoking certificates, but a
typical situation is when the private key associated with a certificate
has been compromised. Traditionally, Certificate Revocation Lists
(CRLs) have been used by application to implement revocation checking,
however, several problems with CRLs have been identified [_RIVESTCRL_].
The Online Certificate Status Protocol, or OCSP [_RFC2560_], is a widely
implemented protocol to perform certificate revocation status checking.
An application that wish to verify the identity of a peer will verify
the certificate against a set of trusted certificates and then check
whether the certificate is listed in a CRL and/or perform an OCSP check
for the certificate.
Before performing the OCSP query, the application will need to figure
out the address of the OCSP server. The OCSP server address can be
provided by the local user in manual configuration or may be stored in
the certificate that is being checked. The latter is due to an
extension field called the Authority Information Access (AIA) which may
hold the location of the OCSP responder in the access method called
'id-ad-ocsp'. The following function extracts this information from a
certificate.
'INT *note gnutls_x509_crt_get_authority_info_access:: (gnutls_x509_crt_t CRT, unsigned int SEQ, int WHAT, gnutls_datum_t * DATA, unsigned int * CRITICAL)'
There are several functions in GnuTLS for creating and manipulating OCSP
requests and responses. The general idea is that a client application
create an OCSP request object, store some information about the
certificate to check in the request, and then export the request in DER
format. The request will then need to be sent to the OCSP responder,
which needs to be done by the application (GnuTLS does not send and
receive OCSP packets). Normally an OCSP response is received that the
application will need to import into an OCSP response object. The
digital signature in the OCSP response needs to be verified against a
set of trust anchors before the information in the response can be
trusted.
The ASN.1 structure of OCSP requests are briefly as follows. It is
useful to review the structures to get an understanding of which fields
are modified by GnuTLS functions.
OCSPRequest ::= SEQUENCE {
tbsRequest TBSRequest,
optionalSignature [0] EXPLICIT Signature OPTIONAL }
TBSRequest ::= SEQUENCE {
version [0] EXPLICIT Version DEFAULT v1,
requestorName [1] EXPLICIT GeneralName OPTIONAL,
requestList SEQUENCE OF Request,
requestExtensions [2] EXPLICIT Extensions OPTIONAL }
Request ::= SEQUENCE {
reqCert CertID,
singleRequestExtensions [0] EXPLICIT Extensions OPTIONAL }
CertID ::= SEQUENCE {
hashAlgorithm AlgorithmIdentifier,
issuerNameHash OCTET STRING, -- Hash of Issuer's DN
issuerKeyHash OCTET STRING, -- Hash of Issuers public key
serialNumber CertificateSerialNumber }
The basic functions to initialize, import, export and deallocate OCSP
requests are the following.
'INT *note gnutls_ocsp_req_init:: (gnutls_ocsp_req_t * REQ)'
'VOID *note gnutls_ocsp_req_deinit:: (gnutls_ocsp_req_t REQ)'
'INT *note gnutls_ocsp_req_import:: (gnutls_ocsp_req_t REQ, const gnutls_datum_t * DATA)'
'INT *note gnutls_ocsp_req_export:: (gnutls_ocsp_req_t REQ, gnutls_datum_t * DATA)'
'INT *note gnutls_ocsp_req_print:: (gnutls_ocsp_req_t REQ, gnutls_ocsp_print_formats_t FORMAT, gnutls_datum_t * OUT)'
There are two interfaces for setting the identity of a certificate in a
OCSP request, the first being a low-level function when you have the
issuer name hash, issuer key hash, and certificate serial number in
binary form. The second is usually more useful if you have the
certificate (and its issuer) in a 'gnutls_x509_crt_t' type. There is
also a function to extract this information from an OCSP request.
'INT *note gnutls_ocsp_req_add_cert_id:: (gnutls_ocsp_req_t REQ, gnutls_digest_algorithm_t DIGEST, const gnutls_datum_t * ISSUER_NAME_HASH, const gnutls_datum_t * ISSUER_KEY_HASH, const gnutls_datum_t * SERIAL_NUMBER)'
'INT *note gnutls_ocsp_req_add_cert:: (gnutls_ocsp_req_t REQ, gnutls_digest_algorithm_t DIGEST, gnutls_x509_crt_t ISSUER, gnutls_x509_crt_t CERT)'
'INT *note gnutls_ocsp_req_get_cert_id:: (gnutls_ocsp_req_t REQ, unsigned INDX, gnutls_digest_algorithm_t * DIGEST, gnutls_datum_t * ISSUER_NAME_HASH, gnutls_datum_t * ISSUER_KEY_HASH, gnutls_datum_t * SERIAL_NUMBER)'
Each OCSP request may contain a number of extensions. Extensions are
identified by an Object Identifier (OID) and an opaque data buffer whose
syntax and semantics is implied by the OID.
'INT *note gnutls_ocsp_req_get_extension:: (gnutls_ocsp_req_t REQ, unsigned INDX, gnutls_datum_t * OID, unsigned int * CRITICAL, gnutls_datum_t * DATA)'
'INT *note gnutls_ocsp_req_set_extension:: (gnutls_ocsp_req_t REQ, const char * OID, unsigned int CRITICAL, const gnutls_datum_t * DATA)'
A common OCSP Request extension is the nonce extension (OID
1.3.6.1.5.5.7.48.1.2), which is used to avoid replay attacks of earlier
recorded OCSP responses. The nonce extension carries a value that is
intended to be sufficiently random and unique so that an attacker will
not be able to give a stale response for the same nonce.
'INT *note gnutls_ocsp_req_get_nonce:: (gnutls_ocsp_req_t REQ, unsigned int * CRITICAL, gnutls_datum_t * NONCE)'
'INT *note gnutls_ocsp_req_set_nonce:: (gnutls_ocsp_req_t REQ, unsigned int CRITICAL, const gnutls_datum_t * NONCE)'
'INT *note gnutls_ocsp_req_randomize_nonce:: (gnutls_ocsp_req_t REQ)'
The OCSP response structures is a bit more complex than the request.
The important ASN.1 structure is as follows. In practice, all OCSP
responses contain a Basic OCSP response sub-structure.
OCSPResponse ::= SEQUENCE {
responseStatus OCSPResponseStatus,
responseBytes [0] EXPLICIT ResponseBytes OPTIONAL }
OCSPResponseStatus ::= ENUMERATED {
successful (0), --Response has valid confirmations
malformedRequest (1), --Illegal confirmation request
internalError (2), --Internal error in issuer
tryLater (3), --Try again later
--(4) is not used
sigRequired (5), --Must sign the request
unauthorized (6) --Request unauthorized }
ResponseBytes ::= SEQUENCE {
responseType OBJECT IDENTIFIER,
response OCTET STRING }
id-pkix-ocsp-basic OBJECT IDENTIFIER ::= { id-pkix-ocsp 1 }
BasicOCSPResponse ::= SEQUENCE {
tbsResponseData ResponseData,
signatureAlgorithm AlgorithmIdentifier,
signature BIT STRING,
certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
ResponseData ::= SEQUENCE {
version [0] EXPLICIT Version DEFAULT v1,
responderID ResponderID,
producedAt GeneralizedTime,
responses SEQUENCE OF SingleResponse,
responseExtensions [1] EXPLICIT Extensions OPTIONAL }
ResponderID ::= CHOICE {
byName [1] Name,
byKey [2] KeyHash }
KeyHash ::= OCTET STRING -- SHA-1 hash of responder's public key
(excluding the tag and length fields)
SingleResponse ::= SEQUENCE {
certID CertID,
certStatus CertStatus,
thisUpdate GeneralizedTime,
nextUpdate [0] EXPLICIT GeneralizedTime OPTIONAL,
singleExtensions [1] EXPLICIT Extensions OPTIONAL }
CertStatus ::= CHOICE {
good [0] IMPLICIT NULL,
revoked [1] IMPLICIT RevokedInfo,
unknown [2] IMPLICIT UnknownInfo }
RevokedInfo ::= SEQUENCE {
revocationTime GeneralizedTime,
revocationReason [0] EXPLICIT CRLReason OPTIONAL }
We provide basic functions for initialization, importing, exporting and
deallocating OCSP responses. The Basic OCSP Response structure is
automatically parsed when an OCSP Response is imported.
'INT *note gnutls_ocsp_resp_init:: (gnutls_ocsp_resp_t * RESP)'
'VOID *note gnutls_ocsp_resp_deinit:: (gnutls_ocsp_resp_t RESP)'
'INT *note gnutls_ocsp_resp_import:: (gnutls_ocsp_resp_t RESP, const gnutls_datum_t * DATA)'
'INT *note gnutls_ocsp_resp_export:: (gnutls_ocsp_resp_t RESP, gnutls_datum_t * DATA)'
'INT *note gnutls_ocsp_resp_print:: (gnutls_ocsp_resp_t RESP, gnutls_ocsp_print_formats_t FORMAT, gnutls_datum_t * OUT)'
The OCSP response needs to be verified against some set of trust anchors
before it can be relied upon.
'INT *note gnutls_ocsp_resp_verify:: (gnutls_ocsp_resp_t RESP, gnutls_x509_trust_list_t TRUSTLIST, unsigned int * VERIFY, unsigned int FLAGS)'
'INT *note gnutls_ocsp_resp_verify_direct:: (gnutls_ocsp_resp_t RESP, gnutls_x509_crt_t ISSUER, unsigned int * VERIFY, unsigned int FLAGS)'
File: gnutls.info, Node: Managing encrypted keys, Next: certtool Invocation, Prev: OCSP certificate status checking, Up: More on certificate authentication
6.4 Managing encrypted keys
===========================
Transferring or storing private keys in plain might not be a good idea.
Any access on the keys becomes a fatal compromise. Storing the keys in
hardware security modules (see *note Smart cards and HSMs::) could solve
the storage problem but it is not always practical or efficient enough.
This section describes alternative ways that involve encryption of the
private keys to store and transfer.
There are two alternatives to use for key encryption, PKCS #8 and #12
methods of private key encryption. The PKCS #8 method only allows
encryption of the private key, whilst the PKCS #12 method allows in
addition the bundling of other data into the structure. That could be
bundling together the certificate as well as the trusted CA certificate.
PKCS #8 structures
------------------
PKCS #8 keys can be imported and exported as normal private keys using
the functions below. An addition to the normal import functions, are a
password and a flags argument. The flags can be any element of the
'gnutls_pkcs_encrypt_flags_t' enumeration. Note however, that GnuTLS
only supports the PKCS #5 PBES2 encryption scheme. Keys encrypted with
the obsolete PBES1 scheme cannot be decrypted.
'INT *note gnutls_x509_privkey_import_pkcs8:: (gnutls_x509_privkey_t KEY, const gnutls_datum_t * DATA, gnutls_x509_crt_fmt_t FORMAT, const char * PASSWORD, unsigned int FLAGS)'
'INT *note gnutls_x509_privkey_export_pkcs8:: (gnutls_x509_privkey_t KEY, gnutls_x509_crt_fmt_t FORMAT, const char * PASSWORD, unsigned int FLAGS, void * OUTPUT_DATA, size_t * OUTPUT_DATA_SIZE)'
'GNUTLS_PKCS_PLAIN'
Unencrypted private key.
'GNUTLS_PKCS8_PLAIN'
Same as 'GNUTLS_PKCS_PLAIN' .
'GNUTLS_PKCS_USE_PKCS12_3DES'
PKCS-12 3DES.
'GNUTLS_PKCS8_USE_PKCS12_3DES'
Same as 'GNUTLS_PKCS_USE_PKCS12_3DES' .
'GNUTLS_PKCS_USE_PKCS12_ARCFOUR'
PKCS-12 ARCFOUR.
'GNUTLS_PKCS8_USE_PKCS12_ARCFOUR'
Same as 'GNUTLS_PKCS_USE_PKCS12_ARCFOUR' .
'GNUTLS_PKCS_USE_PKCS12_RC2_40'
PKCS-12 RC2-40.
'GNUTLS_PKCS8_USE_PKCS12_RC2_40'
Same as 'GNUTLS_PKCS_USE_PKCS12_RC2_40' .
'GNUTLS_PKCS_USE_PBES2_3DES'
PBES2 3DES.
'GNUTLS_PKCS_USE_PBES2_AES_128'
PBES2 AES-128.
'GNUTLS_PKCS_USE_PBES2_AES_192'
PBES2 AES-192.
'GNUTLS_PKCS_USE_PBES2_AES_256'
PBES2 AES-256.
Figure 6.1: Encryption flags
PKCS #12 structures
-------------------
A PKCS #12 structure [_PKCS12_] usually contains a user's private keys
and certificates. It is commonly used in browsers to export and import
the user's identities.
In GnuTLS the PKCS #12 structures are handled using the
'gnutls_pkcs12_t' type. This is an abstract type that may hold several
'gnutls_pkcs12_bag_t' types. The bag types are the holders of the
actual data, which may be certificates, private keys or encrypted data.
A bag of type encrypted should be decrypted in order for its data to be
accessed.
'INT *note gnutls_pkcs12_get_bag:: (gnutls_pkcs12_t PKCS12, int INDX, gnutls_pkcs12_bag_t BAG)'
'INT *note gnutls_pkcs12_verify_mac:: (gnutls_pkcs12_t PKCS12, const char * PASS)'
'INT *note gnutls_pkcs12_bag_decrypt:: (gnutls_pkcs12_bag_t BAG, const char * PASS)'
'INT *note gnutls_pkcs12_bag_get_count:: (gnutls_pkcs12_bag_t BAG)'
'INT *note gnutls_pkcs12_bag_get_data:: (gnutls_pkcs12_bag_t BAG, int INDX, gnutls_datum_t * DATA)'
'INT *note gnutls_pkcs12_bag_get_key_id:: (gnutls_pkcs12_bag_t BAG, int INDX, gnutls_datum_t * ID)'
'INT *note gnutls_pkcs12_bag_get_friendly_name:: (gnutls_pkcs12_bag_t BAG, int INDX, char ** NAME)'
The functions below are used to generate a PKCS #12 structure. An
example of their usage is also shown.
'INT *note gnutls_pkcs12_set_bag:: (gnutls_pkcs12_t PKCS12, gnutls_pkcs12_bag_t BAG)'
'INT *note gnutls_pkcs12_bag_encrypt:: (gnutls_pkcs12_bag_t BAG, const char * PASS, unsigned int FLAGS)'
'INT *note gnutls_pkcs12_generate_mac:: (gnutls_pkcs12_t PKCS12, const char * PASS)'
'INT *note gnutls_pkcs12_bag_set_data:: (gnutls_pkcs12_bag_t BAG, gnutls_pkcs12_bag_type_t TYPE, const gnutls_datum_t * DATA)'
'INT *note gnutls_pkcs12_bag_set_crl:: (gnutls_pkcs12_bag_t BAG, gnutls_x509_crl_t CRL)'
'INT *note gnutls_pkcs12_bag_set_crt:: (gnutls_pkcs12_bag_t BAG, gnutls_x509_crt_t CRT)'
'INT *note gnutls_pkcs12_bag_set_key_id:: (gnutls_pkcs12_bag_t BAG, int INDX, const gnutls_datum_t * ID)'
'INT *note gnutls_pkcs12_bag_set_friendly_name:: (gnutls_pkcs12_bag_t BAG, int INDX, const char * NAME)'
/* This example code is placed in the public domain. */
#ifdef HAVE_CONFIG_H
#include
#endif
#include
#include
#include
#include
#include "examples.h"
#define OUTFILE "out.p12"
/* This function will write a pkcs12 structure into a file.
* cert: is a DER encoded certificate
* pkcs8_key: is a PKCS #8 encrypted key (note that this must be
* encrypted using a PKCS #12 cipher, or some browsers will crash)
* password: is the password used to encrypt the PKCS #12 packet.
*/
int
write_pkcs12 (const gnutls_datum_t * cert,
const gnutls_datum_t * pkcs8_key, const char *password)
{
gnutls_pkcs12_t pkcs12;
int ret, bag_index;
gnutls_pkcs12_bag_t bag, key_bag;
char pkcs12_struct[10 * 1024];
size_t pkcs12_struct_size;
FILE *fd;
/* A good idea might be to use gnutls_x509_privkey_get_key_id()
* to obtain a unique ID.
*/
gnutls_datum_t key_id = { (void *) "\x00\x00\x07", 3 };
gnutls_global_init ();
/* Firstly we create two helper bags, which hold the certificate,
* and the (encrypted) key.
*/
gnutls_pkcs12_bag_init (&bag);
gnutls_pkcs12_bag_init (&key_bag);
ret = gnutls_pkcs12_bag_set_data (bag, GNUTLS_BAG_CERTIFICATE, cert);
if (ret < 0)
{
fprintf (stderr, "ret: %s\n", gnutls_strerror (ret));
return 1;
}
/* ret now holds the bag's index.
*/
bag_index = ret;
/* Associate a friendly name with the given certificate. Used
* by browsers.
*/
gnutls_pkcs12_bag_set_friendly_name (bag, bag_index, "My name");
/* Associate the certificate with the key using a unique key
* ID.
*/
gnutls_pkcs12_bag_set_key_id (bag, bag_index, &key_id);
/* use weak encryption for the certificate.
*/
gnutls_pkcs12_bag_encrypt (bag, password, GNUTLS_PKCS_USE_PKCS12_RC2_40);
/* Now the key.
*/
ret = gnutls_pkcs12_bag_set_data (key_bag,
GNUTLS_BAG_PKCS8_ENCRYPTED_KEY,
pkcs8_key);
if (ret < 0)
{
fprintf (stderr, "ret: %s\n", gnutls_strerror (ret));
return 1;
}
/* Note that since the PKCS #8 key is already encrypted we don't
* bother encrypting that bag.
*/
bag_index = ret;
gnutls_pkcs12_bag_set_friendly_name (key_bag, bag_index, "My name");
gnutls_pkcs12_bag_set_key_id (key_bag, bag_index, &key_id);
/* The bags were filled. Now create the PKCS #12 structure.
*/
gnutls_pkcs12_init (&pkcs12);
/* Insert the two bags in the PKCS #12 structure.
*/
gnutls_pkcs12_set_bag (pkcs12, bag);
gnutls_pkcs12_set_bag (pkcs12, key_bag);
/* Generate a message authentication code for the PKCS #12
* structure.
*/
gnutls_pkcs12_generate_mac (pkcs12, password);
pkcs12_struct_size = sizeof (pkcs12_struct);
ret =
gnutls_pkcs12_export (pkcs12, GNUTLS_X509_FMT_DER, pkcs12_struct,
&pkcs12_struct_size);
if (ret < 0)
{
fprintf (stderr, "ret: %s\n", gnutls_strerror (ret));
return 1;
}
fd = fopen (OUTFILE, "w");
if (fd == NULL)
{
fprintf (stderr, "cannot open file\n");
return 1;
}
fwrite (pkcs12_struct, 1, pkcs12_struct_size, fd);
fclose (fd);
gnutls_pkcs12_bag_deinit (bag);
gnutls_pkcs12_bag_deinit (key_bag);
gnutls_pkcs12_deinit (pkcs12);
return 0;
}
File: gnutls.info, Node: certtool Invocation, Next: ocsptool Invocation, Prev: Managing encrypted keys, Up: More on certificate authentication
6.5 Invoking certtool
=====================
Tool to parse and generate X.509 certificates, requests and private
keys. It can be used interactively or non interactively by specifying
the template command line option.
This section was generated by *AutoGen*, using the 'agtexi-cmd' template
and the option descriptions for the 'certtool' program. This software
is released under the GNU General Public License, version 3 or later.
certtool help/usage ('--help')
------------------------------
This is the automatically generated usage text for certtool.
The text printed is the same whether selected with the 'help' option
('--help') or the 'more-help' option ('--more-help'). 'more-help' will
print the usage text by passing it through a pager program. 'more-help'
is disabled on platforms without a working 'fork(2)' function. The
'PAGER' environment variable is used to select the program, defaulting
to 'more'. Both will exit with a status code of 0.
certtool - GnuTLS PKCS #11 tool - Ver. @VERSION@
USAGE: lt-certtool [ - [] | --[{=| }] ]...
-d, --debug=num Enable debugging.
- It must be in the range:
0 to 9999
--infile=file Input file
- file must pre-exist
--outfile=str Output file
-s, --generate-self-signed Generate a self-signed certificate
-c, --generate-certificate Generate a signed certificate
--generate-proxy Generates a proxy certificate
--generate-crl Generate a CRL
-u, --update-certificate Update a signed certificate
-p, --generate-privkey Generate a private key
-q, --generate-request Generate a PKCS #10 certificate request
-e, --verify-chain Verify a PEM encoded certificate chain.
--verify Verify a PEM encoded certificate chain using a trusted list.
- requires these options:
load-ca-certificate
--verify-crl Verify a CRL using a trusted list.
- requires these options:
load-ca-certificate
--generate-dh-params Generate PKCS #3 encoded Diffie-Hellman parameters.
--get-dh-params Get the included PKCS #3 encoded Diffie-Hellman parameters.
--dh-info Print information PKCS #3 encoded Diffie-Hellman parameters
--load-privkey=str Loads a private key file
--load-pubkey=str Loads a public key file
--load-request=file Loads a certificate request file
- file must pre-exist
--load-certificate=str Loads a certificate file
--load-ca-privkey=str Loads the certificate authority's private key file
--load-ca-certificate=str Loads the certificate authority's certificate file
--password=str Password to use
-i, --certificate-info Print information on the given certificate
--certificate-pubkey Print certificate's public key
--pgp-certificate-info Print information on the given OpenPGP certificate
--pgp-ring-info Print information on the given OpenPGP keyring structure
-l, --crl-info Print information on the given CRL structure
--crq-info Print information on the given certificate request
--no-crq-extensions Do not use extensions in certificate requests
--p12-info Print information on a PKCS #12 structure
--p7-info Print information on a PKCS #7 structure
--smime-to-p7 Convert S/MIME to PKCS #7 structure
-k, --key-info Print information on a private key
--pgp-key-info Print information on an OpenPGP private key
--pubkey-info Print information on a public key
--v1 Generate an X.509 version 1 certificate (with no extensions)
--to-p12 Generate a PKCS #12 structure
- requires these options:
load-certificate
--to-p8 Generate a PKCS #8 structure
-8, --pkcs8 Use PKCS #8 format for private keys
--rsa Generate RSA key
--dsa Generate DSA key
--ecc Generate ECC (ECDSA) key
--hash=str Hash algorithm to use for signing.
--inder Use DER format for input certificates and private keys.
- disabled as --no-inder
--inraw This is an alias for 'inder'
--outder Use DER format for output certificates and private keys
- disabled as --no-outder
--outraw This is an alias for 'outder'
--bits=num Specify the number of bits for key generate
--sec-param=str Specify the security level [low, legacy, normal, high, ultra].
--disable-quick-random No effect
--template=file Template file to use for non-interactive operation
- file must pre-exist
--pkcs-cipher=str Cipher to use for PKCS #8 and #12 operations
-v, --version[=arg] Output version information and exit
-h, --help Display extended usage information and exit
-!, --more-help Extended usage information passed thru pager
Options are specified by doubled hyphens and their name or by a single
hyphen and the flag character.
Tool to parse and generate X.509 certificates, requests and private keys.
It can be used interactively or non interactively by specifying the
template command line option.
please send bug reports to: bug-gnutls@gnu.org
debug option (-d)
-----------------
This is the "enable debugging." option. This option takes an argument
number. Specifies the debug level.
verify-chain option (-e)
------------------------
This is the "verify a pem encoded certificate chain." option. The last
certificate in the chain must be a self signed one.
verify option
-------------
This is the "verify a pem encoded certificate chain using a trusted
list." option.
This option has some usage constraints. It:
* must appear in combination with the following options:
load-ca-certificate.
The trusted certificate list must be loaded with -load-ca-certificate.
verify-crl option
-----------------
This is the "verify a crl using a trusted list." option.
This option has some usage constraints. It:
* must appear in combination with the following options:
load-ca-certificate.
The trusted certificate list must be loaded with -load-ca-certificate.
get-dh-params option
--------------------
This is the "get the included pkcs #3 encoded diffie-hellman
parameters." option. Returns stored DH parameters in GnuTLS. Those
parameters are used in the SRP protocol. The parameters returned by
fresh generation are more efficient since GnuTLS 3.0.9.
load-privkey option
-------------------
This is the "loads a private key file" option. This option takes an
argument string. This can be either a file or a PKCS #11 URL
load-pubkey option
------------------
This is the "loads a public key file" option. This option takes an
argument string. This can be either a file or a PKCS #11 URL
load-certificate option
-----------------------
This is the "loads a certificate file" option. This option takes an
argument string. This can be either a file or a PKCS #11 URL
load-ca-privkey option
----------------------
This is the "loads the certificate authority's private key file" option.
This option takes an argument string. This can be either a file or a
PKCS #11 URL
load-ca-certificate option
--------------------------
This is the "loads the certificate authority's certificate file" option.
This option takes an argument string. This can be either a file or a
PKCS #11 URL
to-p12 option
-------------
This is the "generate a pkcs #12 structure" option.
This option has some usage constraints. It:
* must appear in combination with the following options:
load-certificate.
It requires a certificate, a private key and possibly a CA certificate
to be specified.
hash option
-----------
This is the "hash algorithm to use for signing." option. This option
takes an argument string. Available hash functions are SHA1, RMD160,
SHA256, SHA384, SHA512.
inder option
------------
This is the "use der format for input certificates and private keys."
option. The input files will be assumed to be in DER or RAW format.
Unlike options that in PEM input would allow multiple input data (e.g.
multiple certificates), when reading in DER format a single data
structure is read.
inraw option
------------
This is an alias for the 'inder' option, *note the inder option
documentation: certtool inder.
outder option
-------------
This is the "use der format for output certificates and private keys"
option. The output will be in DER or RAW format.
outraw option
-------------
This is an alias for the 'outder' option, *note the outder option
documentation: certtool outder.
sec-param option
----------------
This is the "specify the security level [low, legacy, normal, high,
ultra]." option. This option takes an argument string 'Security
parameter'. This is alternative to the bits option.
pkcs-cipher option
------------------
This is the "cipher to use for pkcs #8 and #12 operations" option. This
option takes an argument string 'Cipher'. Cipher may be one of 3des,
3des-pkcs12, aes-128, aes-192, aes-256, rc2-40, arcfour.
certtool exit status
--------------------
One of the following exit values will be returned:
'0 (EXIT_SUCCESS)'
Successful program execution.
'1 (EXIT_FAILURE)'
The operation failed or the command syntax was not valid.
certtool See Also
-----------------
p11tool (1)
certtool Examples
-----------------
Generating private keys
-----------------------
To create an RSA private key, run:
$ certtool --generate-privkey --outfile key.pem --rsa
To create a DSA or elliptic curves (ECDSA) private key use the above
command combined with 'dsa' or 'ecc' options.
Generating certificate requests
-------------------------------
To create a certificate request (needed when the certificate is issued
by another party), run:
certtool --generate-request --load-privkey key.pem \
--outfile request.pem
If the private key is stored in a smart card you can generate a request
by specifying the private key object URL.
$ ./certtool --generate-request --load-privkey "pkcs11:..." \
--load-pubkey "pkcs11:..." --outfile request.pem
Generating a self-signed certificate
------------------------------------
To create a self signed certificate, use the command:
$ certtool --generate-privkey --outfile ca-key.pem
$ certtool --generate-self-signed --load-privkey ca-key.pem \
--outfile ca-cert.pem
Note that a self-signed certificate usually belongs to a certificate
authority, that signs other certificates.
Generating a certificate
------------------------
To generate a certificate using the previous request, use the command:
$ certtool --generate-certificate --load-request request.pem \
--outfile cert.pem --load-ca-certificate ca-cert.pem \
--load-ca-privkey ca-key.pem
To generate a certificate using the private key only, use the command:
$ certtool --generate-certificate --load-privkey key.pem \
--outfile cert.pem --load-ca-certificate ca-cert.pem \
--load-ca-privkey ca-key.pem
Certificate information
-----------------------
To view the certificate information, use:
$ certtool --certificate-info --infile cert.pem
PKCS #12 structure generation
-----------------------------
To generate a PKCS #12 structure using the previous key and certificate,
use the command:
$ certtool --load-certificate cert.pem --load-privkey key.pem \
--to-p12 --outder --outfile key.p12
Some tools (reportedly web browsers) have problems with that file
because it does not contain the CA certificate for the certificate. To
work around that problem in the tool, you can use the
-load-ca-certificate parameter as follows:
$ certtool --load-ca-certificate ca.pem \
--load-certificate cert.pem --load-privkey key.pem \
--to-p12 --outder --outfile key.p12
Diffie-Hellman parameter generation
-----------------------------------
To generate parameters for Diffie-Hellman key exchange, use the command:
$ certtool --generate-dh-params --outfile dh.pem --sec-param normal
Proxy certificate generation
----------------------------
Proxy certificate can be used to delegate your credential to a
temporary, typically short-lived, certificate. To create one from the
previously created certificate, first create a temporary key and then
generate a proxy certificate for it, using the commands:
$ certtool --generate-privkey > proxy-key.pem
$ certtool --generate-proxy --load-ca-privkey key.pem \
--load-privkey proxy-key.pem --load-certificate cert.pem \
--outfile proxy-cert.pem
Certificate revocation list generation
--------------------------------------
To create an empty Certificate Revocation List (CRL) do:
$ certtool --generate-crl --load-ca-privkey x509-ca-key.pem \
--load-ca-certificate x509-ca.pem
To create a CRL that contains some revoked certificates, place the
certificates in a file and use '--load-certificate' as follows:
$ certtool --generate-crl --load-ca-privkey x509-ca-key.pem \
--load-ca-certificate x509-ca.pem --load-certificate revoked-certs.pem
To verify a Certificate Revocation List (CRL) do:
$ certtool --verify-crl --load-ca-certificate x509-ca.pem < crl.pem
certtool Files
--------------
Certtool's template file format
-------------------------------
A template file can be used to avoid the interactive questions of
certtool. Initially create a file named 'cert.cfg' that contains the
information about the certificate. The template can be used as below:
$ certtool --generate-certificate cert.pem --load-privkey key.pem \
--template cert.cfg \
--load-ca-certificate ca-cert.pem --load-ca-privkey ca-key.pem
An example certtool template file that can be used to generate a
certificate request or a self signed certificate follows.
# X.509 Certificate options
#
# DN options
# The organization of the subject.
organization = "Koko inc."
# The organizational unit of the subject.
unit = "sleeping dept."
# The locality of the subject.
# locality =
# The state of the certificate owner.
state = "Attiki"
# The country of the subject. Two letter code.
country = GR
# The common name of the certificate owner.
cn = "Cindy Lauper"
# A user id of the certificate owner.
#uid = "clauper"
# Set domain components
#dc = "name"
#dc = "domain"
# If the supported DN OIDs are not adequate you can set
# any OID here.
# For example set the X.520 Title and the X.520 Pseudonym
# by using OID and string pairs.
#dn_oid = 2.5.4.12 Dr.
#dn_oid = 2.5.4.65 jackal
# This is deprecated and should not be used in new
# certificates.
# pkcs9_email = "none@none.org"
# The serial number of the certificate
serial = 007
# In how many days, counting from today, this certificate will expire.
expiration_days = 700
# X.509 v3 extensions
# A dnsname in case of a WWW server.
#dns_name = "www.none.org"
#dns_name = "www.morethanone.org"
# A subject alternative name URI
#uri = "http://www.example.com"
# An IP address in case of a server.
#ip_address = "192.168.1.1"
# An email in case of a person
email = "none@none.org"
# Challenge password used in certificate requests
challenge_passwd = 123456
# An URL that has CRLs (certificate revocation lists)
# available. Needed in CA certificates.
#crl_dist_points = "http://www.getcrl.crl/getcrl/"
# Whether this is a CA certificate or not
#ca
# for microsoft smart card logon
# key_purpose_oid = 1.3.6.1.4.1.311.20.2.2
### Other predefined key purpose OIDs
# Whether this certificate will be used for a TLS client
#tls_www_client
# Whether this certificate will be used for a TLS server
#tls_www_server
# Whether this certificate will be used to sign data (needed
# in TLS DHE ciphersuites).
signing_key
# Whether this certificate will be used to encrypt data (needed
# in TLS RSA ciphersuites). Note that it is preferred to use different
# keys for encryption and signing.
#encryption_key
# Whether this key will be used to sign other certificates.
#cert_signing_key
# Whether this key will be used to sign CRLs.
#crl_signing_key
# Whether this key will be used to sign code.
#code_signing_key
# Whether this key will be used to sign OCSP data.
#ocsp_signing_key
# Whether this key will be used for time stamping.
#time_stamping_key
# Whether this key will be used for IPsec IKE operations.
#ipsec_ike_key
### end of key purpose OIDs
# When generating a certificate from a certificate
# request, then honor the extensions stored in the request
# and store them in the real certificate.
#honor_crq_extensions
# Path length contraint. Sets the maximum number of
# certificates that can be used to certify this certificate.
# (i.e. the certificate chain length)
#path_len = -1
#path_len = 2
# OCSP URI
# ocsp_uri = http://my.ocsp.server/ocsp
# CA issuers URI
# ca_issuers_uri = http://my.ca.issuer
# Options for proxy certificates
# proxy_policy_language = 1.3.6.1.5.5.7.21.1
# Options for generating a CRL
# next CRL update will be in 43 days (wow)
#crl_next_update = 43
# this is the 5th CRL by this CA
#crl_number = 5
File: gnutls.info, Node: ocsptool Invocation, Next: Smart cards and HSMs, Prev: certtool Invocation, Up: More on certificate authentication
6.6 Invoking ocsptool
=====================
Ocsptool is a program that can parse and print information about OCSP
requests/responses, generate requests and verify responses.
This section was generated by *AutoGen*, using the 'agtexi-cmd' template
and the option descriptions for the 'ocsptool' program. This software
is released under the GNU General Public License, version 3 or later.
ocsptool help/usage ('--help')
------------------------------
This is the automatically generated usage text for ocsptool.
The text printed is the same whether selected with the 'help' option
('--help') or the 'more-help' option ('--more-help'). 'more-help' will
print the usage text by passing it through a pager program. 'more-help'
is disabled on platforms without a working 'fork(2)' function. The
'PAGER' environment variable is used to select the program, defaulting
to 'more'. Both will exit with a status code of 0.
ocsptool - GnuTLS OCSP tool - Ver. @VERSION@
USAGE: lt-ocsptool [ - [] | --[{=| }] ]...
-d, --debug=num Enable debugging.
- It must be in the range:
0 to 9999
-V, --verbose More verbose output
- may appear multiple times
--infile=file Input file
- file must pre-exist
--outfile=str Output file
--ask[=arg] Ask an OCSP/HTTP server on a certificate validity
- requires these options:
load-cert
load-issuer
-e, --verify-response Verify response
-i, --request-info Print information on a OCSP request
-j, --response-info Print information on a OCSP response
-q, --generate-request Generate an OCSP request
--nonce Don't add nonce to OCSP request
- disabled as --no-nonce
--load-issuer=file Read issuer certificate from file
- file must pre-exist
--load-cert=file Read certificate to check from file
- file must pre-exist
--load-trust=file Read OCSP trust anchors from file
- prohibits these options:
load-signer
- file must pre-exist
--load-signer=file Read OCSP response signer from file
- prohibits these options:
load-trust
- file must pre-exist
--inder Use DER format for input certificates and private keys
- disabled as --no-inder
-Q, --load-request=file Read DER encoded OCSP request from file
- file must pre-exist
-S, --load-response=file Read DER encoded OCSP response from file
- file must pre-exist
-v, --version[=arg] Output version information and exit
-h, --help Display extended usage information and exit
-!, --more-help Extended usage information passed thru pager
Options are specified by doubled hyphens and their name or by a single
hyphen and the flag character.
Ocsptool is a program that can parse and print information about OCSP
requests/responses, generate requests and verify responses.
please send bug reports to: bug-gnutls@gnu.org
debug option (-d)
-----------------
This is the "enable debugging." option. This option takes an argument
number. Specifies the debug level.
ask option
----------
This is the "ask an ocsp/http server on a certificate validity" option.
This option takes an optional argument string 'server name|url'.
This option has some usage constraints. It:
* must appear in combination with the following options: load-cert,
load-issuer.
Connects to the specified HTTP OCSP server and queries on the validity
of the loaded certificate.
ocsptool exit status
--------------------
One of the following exit values will be returned:
'0 (EXIT_SUCCESS)'
Successful program execution.
'1 (EXIT_FAILURE)'
The operation failed or the command syntax was not valid.
ocsptool See Also
-----------------
certtool (1)
ocsptool Examples
-----------------
Print information about an OCSP request
---------------------------------------
To parse an OCSP request and print information about the content, the
'-i' or '--request-info' parameter may be used as follows. The '-Q'
parameter specify the name of the file containing the OCSP request, and
it should contain the OCSP request in binary DER format.
$ ocsptool -i -Q ocsp-request.der
The input file may also be sent to standard input like this:
$ cat ocsp-request.der | ocsptool --request-info
Print information about an OCSP response
----------------------------------------
Similar to parsing OCSP requests, OCSP responses can be parsed using the
'-j' or '--response-info' as follows.
$ ocsptool -j -Q ocsp-response.der
$ cat ocsp-response.der | ocsptool --response-info
Generate an OCSP request
------------------------
The '-q' or '--generate-request' parameters are used to generate an OCSP
request. By default the OCSP request is written to standard output in
binary DER format, but can be stored in a file using '--outfile'. To
generate an OCSP request the issuer of the certificate to check needs to
be specified with '--load-issuer' and the certificate to check with
'--load-cert'. By default PEM format is used for these files, although
'--inder' can be used to specify that the input files are in DER format.
$ ocsptool -q --load-issuer issuer.pem --load-cert client.pem \
--outfile ocsp-request.der
When generating OCSP requests, the tool will add an OCSP extension
containing a nonce. This behaviour can be disabled by specifying
'--no-nonce'.
Verify signature in OCSP response
---------------------------------
To verify the signature in an OCSP response the '-e' or
'--verify-response' parameter is used. The tool will read an OCSP
response in DER format from standard input, or from the file specified
by '--load-response'. The OCSP response is verified against a set of
trust anchors, which are specified using '--load-trust'. The trust
anchors are concatenated certificates in PEM format. The certificate
that signed the OCSP response needs to be in the set of trust anchors,
or the issuer of the signer certificate needs to be in the set of trust
anchors and the OCSP Extended Key Usage bit has to be asserted in the
signer certificate.
$ ocsptool -e --load-trust issuer.pem \
--load-response ocsp-response.der
The tool will print status of verification.
Verify signature in OCSP response against given certificate
-----------------------------------------------------------
It is possible to override the normal trust logic if you know that a
certain certificate is supposed to have signed the OCSP response, and
you want to use it to check the signature. This is achieved using
'--load-signer' instead of '--load-trust'. This will load one
certificate and it will be used to verify the signature in the OCSP
response. It will not check the Extended Key Usage bit.
$ ocsptool -e --load-signer ocsp-signer.pem \
--load-response ocsp-response.der
This approach is normally only relevant in two situations. The first is
when the OCSP response does not contain a copy of the signer
certificate, so the '--load-trust' code would fail. The second is if
you want to avoid the indirect mode where the OCSP response signer
certificate is signed by a trust anchor.
Real-world example
------------------
Here is an example of how to generate an OCSP request for a certificate
and to verify the response. For illustration we'll use the
'blog.josefsson.org' host, which (as of writing) uses a certificate from
CACert. First we'll use 'gnutls-cli' to get a copy of the server
certificate chain. The server is not required to send this information,
but this particular one is configured to do so.
$ echo | gnutls-cli -p 443 blog.josefsson.org --print-cert > chain.pem
Use a text editor on 'chain.pem' to create three files for each separate
certificates, called 'cert.pem' for the first certificate for the domain
itself, secondly 'issuer.pem' for the intermediate certificate and
'root.pem' for the final root certificate.
The domain certificate normally contains a pointer to where the OCSP
responder is located, in the Authority Information Access Information
extension. For example, from 'certtool -i < cert.pem' there is this
information:
Authority Information Access Information (not critical):
Access Method: 1.3.6.1.5.5.7.48.1 (id-ad-ocsp)
Access Location URI: http://ocsp.CAcert.org/
This means the CA support OCSP queries over HTTP. We are now ready to
create a OCSP request for the certificate.
$ ocsptool --ask ocsp.CAcert.org --load-issuer issuer.pem \
--load-cert cert.pem --outfile ocsp-response.der
The request is sent via HTTP to the OCSP server address specified. If
the address is ommited ocsptool will use the address stored in the
certificate.
File: gnutls.info, Node: Smart cards and HSMs, Next: Abstract key types, Prev: ocsptool Invocation, Up: More on certificate authentication
6.7 Smart cards and HSMs
========================
In this section we present the smart-card and hardware security module
(HSM) support in GnuTLS using PKCS #11 [_PKCS11_]. Hardware security
modules and smart cards provide a way to store private keys and perform
operations on them without exposing them. This decouples cryptographic
keys from the applications that use them and provide an additional
security layer against cryptographic key extraction. Since this can
also be achieved in software components such as in Gnome keyring, we
will use the term security module to describe any cryptographic key
separation subsystem.
PKCS #11 is plugin API allowing applications to access cryptographic
operations on a security module, as well as to objects residing on it.
PKCS #11 modules exist for hardware tokens such as smart cards(1), the
trusted platform module (TPM)(2) as well as for software modules like
Gnome Keyring. The objects residing on a security module may be
certificates, public keys, private keys or secret keys. Of those
certificates and public/private key pairs can be used with GnuTLS. PKCS
#11's main advantage is that it allows operations on private key objects
such as decryption and signing without exposing the key.
Moreover PKCS #11 can be (ab)used to allow all applications in the same
operating system to access shared cryptographic keys and certificates in
a uniform way, as in *note Figure 6.2: fig:pkcs11-vision. That way
applications could load their trusted certificate list, as well as user
certificates from a common PKCS #11 module. Such a provider exists in
the Gnome system, being the Gnome Keyring.
[image src="pkcs11-vision.png" ]
Figure 6.2: PKCS #11 module usage.
* Menu:
* PKCS11 Initialization::
* Reading objects::
* Writing objects::
* Using a PKCS11 token with TLS::
* p11tool Invocation:: Invoking p11tool
---------- Footnotes ----------
(1)
(2)
File: gnutls.info, Node: PKCS11 Initialization, Next: Reading objects, Up: Smart cards and HSMs
6.7.1 Initialization
--------------------
To allow all the GnuTLS applications to access PKCS #11 tokens you can
use a configuration per module, stored in '/etc/pkcs11/modules/'. These
are the configuration files of p11-kit(1). For example a file that will
load the OpenSC module, could be named '/etc/pkcs11/modules/opensc' and
contain the following:
module: /usr/lib/opensc-pkcs11.so
If you use this file, then there is no need for other initialization in
GnuTLS, except for the PIN and token functions. Those allow retrieving
a PIN when accessing a protected object, such as a private key, as well
as probe the user to insert the token. All the initialization functions
are below.
-- Function: int gnutls_pkcs11_init (unsigned int FLAGS, const char *
DEPRECATED_CONFIG_FILE)
FLAGS: 'GNUTLS_PKCS11_FLAG_MANUAL' or 'GNUTLS_PKCS11_FLAG_AUTO'
DEPRECATED_CONFIG_FILE: either NULL or the location of a deprecated
configuration file
This function will initialize the PKCS 11 subsystem in gnutls. It
will read configuration files if 'GNUTLS_PKCS11_FLAG_AUTO' is used
or allow you to independently load PKCS 11 modules using
'gnutls_pkcs11_add_provider()' if 'GNUTLS_PKCS11_FLAG_MANUAL' is
specified.
Normally you don't need to call this function since it is being
called by 'gnutls_global_init()' using the
'GNUTLS_PKCS11_FLAG_AUTO' . If other option is required then it
must be called before it.
*Returns:* On success, 'GNUTLS_E_SUCCESS' (0) is returned,
otherwise a negative error value.
*Since:* 2.12.0
'VOID *note gnutls_pkcs11_set_token_function:: (gnutls_pkcs11_token_callback_t FN, void * USERDATA)'
'VOID *note gnutls_pkcs11_set_pin_function:: (gnutls_pkcs11_pin_callback_t FN, void * USERDATA)'
'INT *note gnutls_pkcs11_add_provider:: (const char * NAME, const char * PARAMS)'
Note that due to limitations of PKCS #11 there are issues when multiple
libraries are sharing a module. To avoid this problem GnuTLS uses
p11-kit that provides a middleware to control access to resources over
the multiple users.
Moreover PKCS #11 modules must be reinitialized on the child processes
after a 'fork'. GnuTLS provides *note gnutls_pkcs11_reinit:: to be
called for this purpose.
-- Function: int gnutls_pkcs11_reinit ( VOID)
This function will reinitialize the PKCS 11 subsystem in gnutls.
This is required by PKCS 11 when an application uses 'fork()' .
The reinitialization function must be called on the child.
*Returns:* On success, 'GNUTLS_E_SUCCESS' (0) is returned,
otherwise a negative error value.
*Since:* 3.0
---------- Footnotes ----------
(1)
File: gnutls.info, Node: Reading objects, Next: Writing objects, Prev: PKCS11 Initialization, Up: Smart cards and HSMs
6.7.2 Reading objects
---------------------
All PKCS #11 objects are referenced by GnuTLS functions by URLs as
described in [_PKCS11URI_]. This allows for a consistent naming of
objects across systems and applications in the same system. For example
a public key on a smart card may be referenced as:
pkcs11:token=Nikos;serial=307521161601031;model=PKCS%2315; \
manufacturer=EnterSafe;object=test1;objecttype=public;\
id=32f153f3e37990b08624141077ca5dec2d15faed
while the smart card itself can be referenced as:
pkcs11:token=Nikos;serial=307521161601031;model=PKCS%2315;manufacturer=EnterSafe
Objects stored in a PKCS #11 token can be extracted if they are not
marked as sensitive. Usually only private keys are marked as sensitive
and cannot be extracted, while certificates and other data can be
retrieved. The functions that can be used to access objects are shown
below.
'INT *note gnutls_pkcs11_obj_import_url:: (gnutls_pkcs11_obj_t CERT, const char * URL, unsigned int FLAGS)'
'INT *note gnutls_pkcs11_obj_export_url:: (gnutls_pkcs11_obj_t OBJ, gnutls_pkcs11_url_type_t DETAILED, char ** URL)'
-- Function: int gnutls_pkcs11_obj_get_info (gnutls_pkcs11_obj_t CRT,
gnutls_pkcs11_obj_info_t ITYPE, void * OUTPUT, size_t *
OUTPUT_SIZE)
CRT: should contain a 'gnutls_pkcs11_obj_t' structure
ITYPE: Denotes the type of information requested
OUTPUT: where output will be stored
OUTPUT_SIZE: contains the maximum size of the output and will be
overwritten with actual
This function will return information about the PKCS11 certificate
such as the label, id as well as token information where the key is
stored. When output is text it returns null terminated string
although 'output_size' contains the size of the actual data only.
*Returns:* 'GNUTLS_E_SUCCESS' (0) on success or a negative error
code on error.
*Since:* 2.12.0
'INT *note gnutls_x509_crt_import_pkcs11:: (gnutls_x509_crt_t CRT, gnutls_pkcs11_obj_t PKCS11_CRT)'
'INT *note gnutls_x509_crt_import_pkcs11_url:: (gnutls_x509_crt_t CRT, const char * URL, unsigned int FLAGS)'
'INT *note gnutls_x509_crt_list_import_pkcs11:: (gnutls_x509_crt_t * CERTS, unsigned int CERT_MAX, gnutls_pkcs11_obj_t * const OBJS, unsigned int FLAGS)'
Properties of the physical token can also be accessed and altered with
GnuTLS. For example data in a token can be erased (initialized), PIN
can be altered, etc.
'INT *note gnutls_pkcs11_token_init:: (const char * TOKEN_URL, const char * SO_PIN, const char * LABEL)'
'INT *note gnutls_pkcs11_token_get_url:: (unsigned int SEQ, gnutls_pkcs11_url_type_t DETAILED, char ** URL)'
'INT *note gnutls_pkcs11_token_get_info:: (const char * URL, gnutls_pkcs11_token_info_t TTYPE, void * OUTPUT, size_t * OUTPUT_SIZE)'
'INT *note gnutls_pkcs11_token_get_flags:: (const char * URL, unsigned int * FLAGS)'
'INT *note gnutls_pkcs11_token_set_pin:: (const char * TOKEN_URL, const char * OLDPIN, const char * NEWPIN, unsigned int FLAGS)'
The following examples demonstrate the usage of the API. The first
example will list all available PKCS #11 tokens in a system and the
latter will list all certificates in a token that have a corresponding
private key.
int i;
char* url;
gnutls_global_init();
for (i=0;;i++)
{
ret = gnutls_pkcs11_token_get_url(i, &url);
if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
break;
if (ret < 0)
exit(1);
fprintf(stdout, "Token[%d]: URL: %s\n", i, url);
gnutls_free(url);
}
gnutls_global_deinit();
/* This example code is placed in the public domain. */
#include
#include
#include
#include
#include
#define URL "pkcs11:URL"
int
main (int argc, char** argv)
{
gnutls_pkcs11_obj_t *obj_list;
gnutls_x509_crt_t xcrt;
unsigned int obj_list_size = 0;
gnutls_datum_t cinfo;
int ret;
unsigned int i;
obj_list_size = 0;
ret = gnutls_pkcs11_obj_list_import_url (NULL, &obj_list_size, URL,
GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY,
0);
if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
return -1;
/* no error checking from now on */
obj_list = malloc (sizeof (*obj_list) * obj_list_size);
gnutls_pkcs11_obj_list_import_url (obj_list, &obj_list_size, URL,
GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY,
0);
/* now all certificates are in obj_list */
for (i = 0; i < obj_list_size; i++)
{
gnutls_x509_crt_init (&xcrt);
gnutls_x509_crt_import_pkcs11 (xcrt, obj_list[i]);
gnutls_x509_crt_print (xcrt, GNUTLS_CRT_PRINT_FULL, &cinfo);
fprintf (stdout, "cert[%d]:\n %s\n\n", i, cinfo.data);
gnutls_free (cinfo.data);
gnutls_x509_crt_deinit (xcrt);
}
return 0;
}
File: gnutls.info, Node: Writing objects, Next: Using a PKCS11 token with TLS, Prev: Reading objects, Up: Smart cards and HSMs
6.7.3 Writing objects
---------------------
With GnuTLS you can copy existing private keys and certificates to a
token. Note that when copying private keys it is recommended to mark
them as sensitive using the 'GNUTLS_PKCS11_OBJ_FLAG_MARK_SENSITIVE' to
prevent its extraction. An object can be marked as private using the
flag 'GNUTLS_PKCS11_OBJ_FLAG_MARK_PRIVATE', to require PIN to be entered
before accessing the object (for operations or otherwise).
-- Function: int gnutls_pkcs11_copy_x509_privkey (const char *
TOKEN_URL, gnutls_x509_privkey_t KEY, const char * LABEL,
unsigned int KEY_USAGE, unsigned int FLAGS)
TOKEN_URL: A PKCS '11' URL specifying a token
KEY: A private key
LABEL: A name to be used for the stored data
KEY_USAGE: One of GNUTLS_KEY_*
FLAGS: One of GNUTLS_PKCS11_OBJ_* flags
This function will copy a private key into a PKCS '11' token
specified by a URL. It is highly recommended flags to contain
'GNUTLS_PKCS11_OBJ_FLAG_MARK_SENSITIVE' unless there is a strong
reason not to.
*Returns:* On success, 'GNUTLS_E_SUCCESS' (0) is returned,
otherwise a negative error value.
*Since:* 2.12.0
-- Function: int gnutls_pkcs11_copy_x509_crt (const char * TOKEN_URL,
gnutls_x509_crt_t CRT, const char * LABEL, unsigned int FLAGS)
TOKEN_URL: A PKCS '11' URL specifying a token
CRT: A certificate
LABEL: A name to be used for the stored data
FLAGS: One of GNUTLS_PKCS11_OBJ_FLAG_*
This function will copy a certificate into a PKCS '11' token
specified by a URL. The certificate can be marked as trusted or
not.
*Returns:* On success, 'GNUTLS_E_SUCCESS' (0) is returned,
otherwise a negative error value.
*Since:* 2.12.0
-- Function: int gnutls_pkcs11_delete_url (const char * OBJECT_URL,
unsigned int FLAGS)
OBJECT_URL: The URL of the object to delete.
FLAGS: One of GNUTLS_PKCS11_OBJ_* flags
This function will delete objects matching the given URL. Note that
not all tokens support the delete operation.
*Returns:* On success, the number of objects deleted is returned,
otherwise a negative error value.
*Since:* 2.12.0
File: gnutls.info, Node: Using a PKCS11 token with TLS, Next: p11tool Invocation, Prev: Writing objects, Up: Smart cards and HSMs
6.7.4 Using a PKCS #11 token with TLS
-------------------------------------
It is possible to use a PKCS #11 token to a TLS session, as shown in
*note ex:pkcs11-client::. In addition the following functions can be
used to load PKCS #11 key and certificates by specifying a PKCS #11 URL
instead of a filename.
'INT *note gnutls_certificate_set_x509_trust_file:: (gnutls_certificate_credentials_t CRED, const char * CAFILE, gnutls_x509_crt_fmt_t TYPE)'
'INT *note gnutls_certificate_set_x509_key_file:: (gnutls_certificate_credentials_t RES, const char * CERTFILE, const char * KEYFILE, gnutls_x509_crt_fmt_t TYPE)'
-- Function: int gnutls_certificate_set_x509_system_trust
(gnutls_certificate_credentials_t CRED)
CRED: is a 'gnutls_certificate_credentials_t' structure.
This function adds the system's default trusted CAs in order to
verify client or server certificates.
In the case the system is currently unsupported
'GNUTLS_E_UNIMPLEMENTED_FEATURE' is returned.
*Returns:* the number of certificates processed or a negative error
code on error.
*Since:* 3.0
File: gnutls.info, Node: p11tool Invocation, Prev: Using a PKCS11 token with TLS, Up: Smart cards and HSMs
6.7.5 Invoking p11tool
----------------------
Program that allows handling data from PKCS #11 smart cards and security
modules.
To use PKCS #11 tokens with gnutls the configuration file
/etc/gnutls/pkcs11.conf has to exist and contain a number of lines of
the form 'load=/usr/lib/opensc-pkcs11.so'.
This section was generated by *AutoGen*, using the 'agtexi-cmd' template
and the option descriptions for the 'p11tool' program. This software is
released under the GNU General Public License, version 3 or later.
p11tool help/usage ('--help')
.............................
This is the automatically generated usage text for p11tool.
The text printed is the same whether selected with the 'help' option
('--help') or the 'more-help' option ('--more-help'). 'more-help' will
print the usage text by passing it through a pager program. 'more-help'
is disabled on platforms without a working 'fork(2)' function. The
'PAGER' environment variable is used to select the program, defaulting
to 'more'. Both will exit with a status code of 0.
p11tool - GnuTLS PKCS #11 tool - Ver. @VERSION@
USAGE: lt-p11tool [ - [] | --[{=| }] ]... [url]
-d, --debug=num Enable debugging.
- It must be in the range:
0 to 9999
--outfile=str Output file
--list-tokens List all available tokens
--export Export the object specified by the URL
--list-mechanisms List all available mechanisms in a token
--list-all List all available objects in a token
--list-all-certs List all available certificates in a token
--list-certs List all certificates that have an associated private key
--list-all-privkeys List all available private keys in a token
--list-all-trusted List all available certificates marked as trusted
--initialize Initializes a PKCS #11 token
--write Writes the loaded objects to a PKCS #11 token
--delete Deletes the objects matching the PKCS #11 URL
--generate-rsa Generate an RSA private-public key pair
--generate-dsa Generate an RSA private-public key pair
--generate-ecc Generate an RSA private-public key pair
--label=str Sets a label for the write operation
--trusted Marks the object to be written as trusted
- disabled as --no-trusted
--private Marks the object to be written as private
- disabled as --no-private
- enabled by default
--login Force login to token
- disabled as --no-login
--detailed-url Print detailed URLs
- disabled as --no-detailed-url
--secret-key=str Provide a hex encoded secret key
--load-privkey=file Private key file to use
- file must pre-exist
--load-pubkey=file Public key file to use
- file must pre-exist
--load-certificate=file Certificate file to use
- file must pre-exist
-8, --pkcs8 Use PKCS #8 format for private keys
--bits=num Specify the number of bits for key generate
--sec-param=str Specify the security level
--inder Use DER/RAW format for input
- disabled as --no-inder
--inraw This is an alias for 'inder'
--provider=file Specify the PKCS #11 provider library
- file must pre-exist
-v, --version[=arg] Output version information and exit
-h, --help Display extended usage information and exit
-!, --more-help Extended usage information passed thru pager
Options are specified by doubled hyphens and their name or by a single
hyphen and the flag character.
Operands and options may be intermixed. They will be reordered.
Program that allows handling data from PKCS #11 smart cards and security
modules.
To use PKCS #11 tokens with gnutls the configuration file
/etc/gnutls/pkcs11.conf has to exist and contain a number of lines of the
form 'load=/usr/lib/opensc-pkcs11.so'.
please send bug reports to: bug-gnutls@gnu.org
debug option (-d)
.................
This is the "enable debugging." option. This option takes an argument
number. Specifies the debug level.
write option
............
This is the "writes the loaded objects to a pkcs #11 token" option. It
can be used to write private keys, certificates or secret keys to a
token.
generate-rsa option
...................
This is the "generate an rsa private-public key pair" option. Generates
an RSA private-public key pair on the specified token.
generate-dsa option
...................
This is the "generate an rsa private-public key pair" option. Generates
an RSA private-public key pair on the specified token.
generate-ecc option
...................
This is the "generate an rsa private-public key pair" option. Generates
an RSA private-public key pair on the specified token.
private option
..............
This is the "marks the object to be written as private" option.
This option has some usage constraints. It:
* is enabled by default.
The written object will require a PIN to be used.
sec-param option
................
This is the "specify the security level" option. This option takes an
argument string 'Security parameter'. This is alternative to the bits
option. Available options are [low, legacy, normal, high, ultra].
inder option
............
This is the "use der/raw format for input" option. Use DER/RAW format
for input certificates and private keys.
inraw option
............
This is an alias for the 'inder' option, *note the inder option
documentation: p11tool inder.
provider option
...............
This is the "specify the pkcs #11 provider library" option. This option
takes an argument file. This will override the default options in
/etc/gnutls/pkcs11.conf
p11tool exit status
...................
One of the following exit values will be returned:
'0 (EXIT_SUCCESS)'
Successful program execution.
'1 (EXIT_FAILURE)'
The operation failed or the command syntax was not valid.
p11tool See Also
................
certtool (1)
p11tool Examples
................
To view all tokens in your system use:
$ p11tool --list-tokens
To view all objects in a token use:
$ p11tool --login --list-all "pkcs11:TOKEN-URL"
To store a private key and a certificate in a token run:
$ p11tool --login --write "pkcs11:URL" --load-privkey key.pem \
--label "Mykey"
$ p11tool --login --write "pkcs11:URL" --load-certificate cert.pem \
--label "Mykey"
Note that some tokens require the same label to be used for the
certificate and its corresponding private key.
File: gnutls.info, Node: Abstract key types, Prev: Smart cards and HSMs, Up: More on certificate authentication
6.8 Abstract key types
======================
Since there are many forms of a public or private keys supported by
GnuTLS such as X.509, OpenPGP, or PKCS #11 it is desirable to allow
common operations on them. For these reasons the abstract
'gnutls_privkey_t' and 'gnutls_pubkey_t' were introduced in
'gnutls/abstract.h' header. Those types are initialized using a
specific type of key and then can be used to perform operations in an
abstract way. For example in order to sign an X.509 certificate with a
key that resides in a token the following steps must be used.
#inlude
#inlude
void sign_cert( gnutls_x509_crt_t to_be_signed)
{
gnutls_pkcs11_privkey_t ca_key;
gnutls_x509_crt_t ca_cert;
gnutls_privkey_t abs_key;
/* load the PKCS #11 key and certificates */
gnutls_pkcs11_privkey_init(&ca_key);
gnutls_pkcs11_privkey_import_url(ca_key, key_url);
gnutls_x509_crt_init(&ca_cert);
gnutls_x509_crt_import_pkcs11_url(&ca_cert, cert_url);
/* initialize the abstract key */
gnutls_privkey_init(&abs_key);
gnutls_privkey_import_pkcs11(abs_key, ca_key);
/* sign the certificate to be signed */
gnutls_x509_crt_privkey_sign(to_be_signed, ca_cert, ca_key,
GNUTLS_DIG_SHA256, 0);
}
* Menu:
* Abstract public keys::
* Abstract private keys::
* Operations::
File: gnutls.info, Node: Abstract public keys, Next: Abstract private keys, Up: Abstract key types
6.8.1 Public keys
-----------------
An abstract 'gnutls_pubkey_t' can be initialized using the functions
below. It can be imported through an existing structure like
'gnutls_x509_crt_t', or through an ASN.1 encoding of the X.509
'SubjectPublicKeyInfo' sequence.
-- Function: int gnutls_pubkey_import_x509 (gnutls_pubkey_t KEY,
gnutls_x509_crt_t CRT, unsigned int FLAGS)
KEY: The public key
CRT: The certificate to be imported
FLAGS: should be zero
This function will import the given public key to the abstract
'gnutls_pubkey_t' structure.
*Returns:* On success, 'GNUTLS_E_SUCCESS' (0) is returned,
otherwise a negative error value.
*Since:* 2.12.0
'INT *note gnutls_pubkey_import_openpgp:: (gnutls_pubkey_t KEY, gnutls_openpgp_crt_t CRT, unsigned int FLAGS)'
'INT *note gnutls_pubkey_import_pkcs11:: (gnutls_pubkey_t KEY, gnutls_pkcs11_obj_t OBJ, unsigned int FLAGS)'
'INT *note gnutls_pubkey_import_pkcs11_url:: (gnutls_pubkey_t KEY, const char * URL, unsigned int FLAGS)'
'INT *note gnutls_pubkey_import_privkey:: (gnutls_pubkey_t KEY, gnutls_privkey_t PKEY, unsigned int USAGE, unsigned int FLAGS)'
'INT *note gnutls_pubkey_import:: (gnutls_pubkey_t KEY, const gnutls_datum_t * DATA, gnutls_x509_crt_fmt_t FORMAT)'
-- Function: int gnutls_pubkey_export (gnutls_pubkey_t KEY,
gnutls_x509_crt_fmt_t FORMAT, void * OUTPUT_DATA, size_t *
OUTPUT_DATA_SIZE)
KEY: Holds the certificate
FORMAT: the format of output params. One of PEM or DER.
OUTPUT_DATA: will contain a certificate PEM or DER encoded
OUTPUT_DATA_SIZE: holds the size of output_data (and will be
replaced by the actual size of parameters)
This function will export the public key to DER or PEM format. The
contents of the exported data is the SubjectPublicKeyInfo X.509
structure.
If the buffer provided is not long enough to hold the output, then
*output_data_size is updated and 'GNUTLS_E_SHORT_MEMORY_BUFFER'
will be returned.
If the structure is PEM encoded, it will have a header of "BEGIN
CERTIFICATE".
*Returns:* In case of failure a negative error code will be
returned, and 0 on success.
*Since:* 2.12.0
Additional functions are available that will return information over a
public key.
'INT *note gnutls_pubkey_get_pk_algorithm:: (gnutls_pubkey_t KEY, unsigned int * BITS)'
'INT *note gnutls_pubkey_get_preferred_hash_algorithm:: (gnutls_pubkey_t KEY, gnutls_digest_algorithm_t * HASH, unsigned int * MAND)'
'INT *note gnutls_pubkey_get_key_id:: (gnutls_pubkey_t KEY, unsigned int FLAGS, unsigned char * OUTPUT_DATA, size_t * OUTPUT_DATA_SIZE)'
File: gnutls.info, Node: Abstract private keys, Next: Operations, Prev: Abstract public keys, Up: Abstract key types
6.8.2 Private keys
------------------
An abstract 'gnutls_privkey_t' can be initialized using the functions
below. It can be imported through an existing structure like
'gnutls_x509_privkey_t', but unlike public keys it cannot be exported.
That is to allow abstraction over PKCS #11 keys that are not
extractable.
'INT *note gnutls_privkey_import_x509:: (gnutls_privkey_t PKEY, gnutls_x509_privkey_t KEY, unsigned int FLAGS)'
'INT *note gnutls_privkey_import_openpgp:: (gnutls_privkey_t PKEY, gnutls_openpgp_privkey_t KEY, unsigned int FLAGS)'
'INT *note gnutls_privkey_import_pkcs11:: (gnutls_privkey_t PKEY, gnutls_pkcs11_privkey_t KEY, unsigned int FLAGS)'
'INT *note gnutls_privkey_get_pk_algorithm:: (gnutls_privkey_t KEY, unsigned int * BITS)'
'GNUTLS_PRIVKEY_TYPE_T *note gnutls_privkey_get_type:: (gnutls_privkey_t KEY)'
In order to support cryptographic operations using an external API, the
following function is provided. This allows for a simple extensibility
API without resorting to PKCS #11.
-- Function: int gnutls_privkey_import_ext (gnutls_privkey_t PKEY,
gnutls_pk_algorithm_t PK, void* USERDATA,
gnutls_privkey_sign_func SIGN_FUNC,
gnutls_privkey_decrypt_func DECRYPT_FUNC, unsigned int FLAGS)
PKEY: The private key
PK: The public key algorithm
USERDATA: private data to be provided to the callbacks
SIGN_FUNC: callback for signature operations
DECRYPT_FUNC: callback for decryption operations
FLAGS: Flags for the import
This function will associate the given callbacks with the
'gnutls_privkey_t' structure. At least one of the two callbacks
must be non-null.
*Returns:* On success, 'GNUTLS_E_SUCCESS' (0) is returned,
otherwise a negative error value.
*Since:* 3.0
File: gnutls.info, Node: Operations, Prev: Abstract private keys, Up: Abstract key types
6.8.3 Operations
----------------
The abstract key types can be used to access signing and signature
verification operations with the underlying keys.
-- Function: int gnutls_pubkey_verify_data2 (gnutls_pubkey_t PUBKEY,
gnutls_sign_algorithm_t ALGO, unsigned int FLAGS, const
gnutls_datum_t * DATA, const gnutls_datum_t * SIGNATURE)
PUBKEY: Holds the public key
ALGO: The signature algorithm used
FLAGS: should be 0 for now
DATA: holds the signed data
SIGNATURE: contains the signature
This function will verify the given signed data, using the
parameters from the certificate.
*Returns:* In case of a verification failure
'GNUTLS_E_PK_SIG_VERIFY_FAILED' is returned, and zero or positive
code on success.
*Since:* 3.0
-- Function: int gnutls_pubkey_verify_hash2 (gnutls_pubkey_t KEY,
gnutls_sign_algorithm_t ALGO, unsigned int FLAGS, const
gnutls_datum_t * HASH, const gnutls_datum_t * SIGNATURE)
KEY: Holds the public key
ALGO: The signature algorithm used
FLAGS: should be 0 for now
HASH: holds the hash digest to be verified
SIGNATURE: contains the signature
This function will verify the given signed digest, using the
parameters from the public key.
*Returns:* In case of a verification failure
'GNUTLS_E_PK_SIG_VERIFY_FAILED' is returned, and zero or positive
code on success.
*Since:* 3.0
-- Function: int gnutls_pubkey_encrypt_data (gnutls_pubkey_t KEY,
unsigned int FLAGS, const gnutls_datum_t * PLAINTEXT,
gnutls_datum_t * CIPHERTEXT)
KEY: Holds the public key
FLAGS: should be 0 for now
PLAINTEXT: The data to be encrypted
CIPHERTEXT: contains the encrypted data
This function will encrypt the given data, using the public key.
*Returns:* On success, 'GNUTLS_E_SUCCESS' (0) is returned,
otherwise a negative error value.
*Since:* 3.0
-- Function: int gnutls_privkey_sign_data (gnutls_privkey_t SIGNER,
gnutls_digest_algorithm_t HASH, unsigned int FLAGS, const
gnutls_datum_t * DATA, gnutls_datum_t * SIGNATURE)
SIGNER: Holds the key
HASH: should be a digest algorithm
FLAGS: should be 0 for now
DATA: holds the data to be signed
SIGNATURE: will contain the signature allocate with
'gnutls_malloc()'
This function will sign the given data using a signature algorithm
supported by the private key. Signature algorithms are always used
together with a hash functions. Different hash functions may be
used for the RSA algorithm, but only the SHA family for the DSA
keys.
Use 'gnutls_pubkey_get_preferred_hash_algorithm()' to determine the
hash algorithm.
*Returns:* On success, 'GNUTLS_E_SUCCESS' (0) is returned,
otherwise a negative error value.
*Since:* 2.12.0
-- Function: int gnutls_privkey_sign_hash (gnutls_privkey_t SIGNER,
gnutls_digest_algorithm_t HASH_ALGO, unsigned int FLAGS, const
gnutls_datum_t * HASH_DATA, gnutls_datum_t * SIGNATURE)
SIGNER: Holds the signer's key
HASH_ALGO: The hash algorithm used
FLAGS: zero for now
HASH_DATA: holds the data to be signed
SIGNATURE: will contain newly allocated signature
This function will sign the given hashed data using a signature
algorithm supported by the private key. Signature algorithms are
always used together with a hash functions. Different hash
functions may be used for the RSA algorithm, but only SHA-XXX for
the DSA keys.
Use 'gnutls_pubkey_get_preferred_hash_algorithm()' to determine the
hash algorithm.
*Returns:* On success, 'GNUTLS_E_SUCCESS' (0) is returned,
otherwise a negative error value.
*Since:* 2.12.0
-- Function: int gnutls_privkey_decrypt_data (gnutls_privkey_t KEY,
unsigned int FLAGS, const gnutls_datum_t * CIPHERTEXT,
gnutls_datum_t * PLAINTEXT)
KEY: Holds the key
FLAGS: zero for now
CIPHERTEXT: holds the data to be decrypted
PLAINTEXT: will contain the decrypted data, allocated with
'gnutls_malloc()'
This function will decrypt the given data using the algorithm
supported by the private key.
*Returns:* On success, 'GNUTLS_E_SUCCESS' (0) is returned,
otherwise a negative error value.
*Since:* 2.12.0
Signing existing structures, such as certificates, CRLs, or certificate
requests, as well as associating public keys with structures is also
possible using the key abstractions.
-- Function: int gnutls_x509_crq_set_pubkey (gnutls_x509_crq_t CRQ,
gnutls_pubkey_t KEY)
CRQ: should contain a 'gnutls_x509_crq_t' structure
KEY: holds a public key
This function will set the public parameters from the given public
key to the request.
*Returns:* On success, 'GNUTLS_E_SUCCESS' (0) is returned,
otherwise a negative error value.
*Since:* 2.12.0
-- Function: int gnutls_x509_crt_set_pubkey (gnutls_x509_crt_t CRT,
gnutls_pubkey_t KEY)
CRT: should contain a 'gnutls_x509_crt_t' structure
KEY: holds a public key
This function will set the public parameters from the given public
key to the request.
*Returns:* On success, 'GNUTLS_E_SUCCESS' (0) is returned,
otherwise a negative error value.
*Since:* 2.12.0
'INT *note gnutls_x509_crt_privkey_sign:: (gnutls_x509_crt_t CRT, gnutls_x509_crt_t ISSUER, gnutls_privkey_t ISSUER_KEY, gnutls_digest_algorithm_t DIG, unsigned int FLAGS)'
'INT *note gnutls_x509_crl_privkey_sign:: (gnutls_x509_crl_t CRL, gnutls_x509_crt_t ISSUER, gnutls_privkey_t ISSUER_KEY, gnutls_digest_algorithm_t DIG, unsigned int FLAGS)'
'INT *note gnutls_x509_crq_privkey_sign:: (gnutls_x509_crq_t CRQ, gnutls_privkey_t KEY, gnutls_digest_algorithm_t DIG, unsigned int FLAGS)'
File: gnutls.info, Node: How to use GnuTLS in applications, Next: GnuTLS application examples, Prev: More on certificate authentication, Up: Top
7 How to use GnuTLS in applications
***********************************
* Menu:
* Introduction to the library::
* Preparation::
* Session initialization::
* Associating the credentials::
* Setting up the transport layer::
* TLS handshake::
* Data transfer and termination::
* Handling alerts::
* Priority Strings::
* Advanced and other topics::
* Using the cryptographic library::
* Selecting cryptographic key sizes::
File: gnutls.info, Node: Introduction to the library, Next: Preparation, Up: How to use GnuTLS in applications
7.1 Introduction
================
* Menu:
* General idea::
* Error handling::
* Common types::
* Debugging and auditing::
* Thread safety::
* Callback functions::
File: gnutls.info, Node: General idea, Next: Error handling, Up: Introduction to the library
7.1.1 General idea
------------------
A brief description of how GnuTLS works internally is shown at *note
Figure 7.1: fig:gnutls-design. This section may become more clear after
having read the rest of this section. As shown in the figure, there is
a read-only global state that is initialized once by the global
initialization function. This global structure, among others, contains
the memory allocation functions used, and structures needed for the
ASN.1 parser. This structure is never modified by any GnuTLS function,
except for the deinitialization function which frees all allocated
memory and is called after the program has permanently finished using
GnuTLS.
[image src="gnutls-internals.png" ]
Figure 7.1: High level design of GnuTLS.
The credentials structures are used by the authentication methods, such
as certificate authentication. They store certificates, privates keys,
and other information that is needed to prove the identity to the peer,
and/or verify the indentity of the peer. The information stored in the
credentials structures is initialized once and then can be shared by
many TLS sessions.
A GnuTLS session contains all the required information to handle one
secure connection. The session communicates with the peers using the
provided functions of the transport layer. Every session has a unique
session ID shared with the peer.
Since TLS sessions can be resumed, servers need a database back-end to
hold the session's parameters. Every GnuTLS session after a successful
handshake calls the appropriate back-end function (see *note resume::)
to store the newly negotiated session. The session database is examined
by the server just after having received the client hello(1), and if the
session ID sent by the client, matches a stored session, the stored
session will be retrieved, and the new session will be a resumed one,
and will share the same session ID with the previous one.
---------- Footnotes ----------
(1) The first message in a TLS handshake
File: gnutls.info, Node: Error handling, Next: Common types, Prev: General idea, Up: Introduction to the library
7.1.2 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 and
receives will be disallowed. Such an example is
'GNUTLS_E_DECRYPTION_FAILED'. Non-fatal errors may warn about
something, i.e., 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 *note gnutls_record_recv::. This
error code indicates that the server requests a re-handshake. 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 *note
gnutls_error_is_fatal::. All errors can be converted to a descriptive
string using *note gnutls_strerror::.
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. For example the error codes
'GNUTLS_E_WARNING_ALERT_RECEIVED' and 'GNUTLS_E_FATAL_ALERT_RECEIVED'
that may returned when receiving data, should be handled by notifying
the user of the alert (as explained in *note Handling alerts::). See
*note Error codes::, for a description of the available error codes.
File: gnutls.info, Node: Common types, Next: Debugging and auditing, Prev: Error handling, Up: Introduction to the library
7.1.3 Common types
------------------
Several functions in GnuTLS use 'gnutls_datum_t' which is convenient way
to combine a pointer to data and data's size. Its definition is shown
below.
typedef struct
{
unsigned char *data;
unsigned int size;
} gnutls_datum_t;
Other functions that require data for scattered read use a structure
similar to 'struct iovec' typically used by 'readv'. It is shown below.
typedef struct
{
void *iov_base; /* Starting address */
size_t iov_len; /* Number of bytes to transfer */
} giovec_t;
File: gnutls.info, Node: Debugging and auditing, Next: Thread safety, Prev: Common types, Up: Introduction to the library
7.1.4 Debugging and auditing
----------------------------
In many cases things may not go as expected and further information, to
assist debugging, from GnuTLS is desired. Those are the cases where the
*note gnutls_global_set_log_level:: and *note
gnutls_global_set_log_function:: are to be used. Those will print
verbose information on the GnuTLS functions internal flow.
'VOID *note gnutls_global_set_log_level:: (int LEVEL)'
'VOID *note gnutls_global_set_log_function:: (gnutls_log_func LOG_FUNC)'
When debugging is not required, important issues, such as detected
attacks on the protocol still need to be logged. This is provided by
the logging function set by *note
gnutls_global_set_audit_log_function::. The provided function will
receive an message and the corresponding TLS session. The session
information might be used to derive IP addresses or other information
about the peer involved.
-- Function: void gnutls_global_set_audit_log_function
(gnutls_audit_log_func LOG_FUNC)
LOG_FUNC: it is the audit log function
This is the function where you set the logging function gnutls is
going to use. This is different from
'gnutls_global_set_log_function()' because it will report the
session of the event if any. Note that that session might be null
if there is no corresponding TLS session.
'gnutls_audit_log_func' is of the form, void
(*gnutls_audit_log_func)( gnutls_session_t, int level, const
char*);
*Since:* 3.0
File: gnutls.info, Node: Thread safety, Next: Callback functions, Prev: Debugging and auditing, Up: Introduction to the library
7.1.5 Thread safety
-------------------
The GnuTLS library is thread safe by design, meaning that objects of the
library such as TLS sessions, can be safely divided across threads as
long as a single thread accesses a single object. This is sufficient to
support a server which handles several sessions per thread. If,
however, an object needs to be shared across threads then access must be
protected with a mutex. Read-only access to objects, for example the
credentials holding structures, is also thread-safe.
The random generator of the cryptographic back-end, is not thread safe
and requires mutex locks which are setup by GnuTLS. Applications can
either call *note gnutls_global_init:: which will initialize the default
operating system provided locks (i.e. 'pthreads' on GNU/Linux and
'CriticalSection' on Windows), or manually specify the locking system
using the function *note gnutls_global_set_mutex:: before calling *note
gnutls_global_init::. Setting mutexes manually is recommended only for
applications that have full control of the underlying libraries. If
this is not the case, the use of the operating system defaults is
recommended. An example of non-native thread usage is shown below.
#include
int main()
{
/* When the system mutexes are not to be used
* gnutls_global_set_mutex() must be called explicitly
*/
gnutls_global_set_mutex (mutex_init, mutex_deinit,
mutex_lock, mutex_unlock);
gnutls_global_init();
}
-- Function: void gnutls_global_set_mutex (mutex_init_func INIT,
mutex_deinit_func DEINIT, mutex_lock_func LOCK,
mutex_unlock_func UNLOCK)
INIT: mutex initialization function
DEINIT: mutex deinitialization function
LOCK: mutex locking function
UNLOCK: mutex unlocking function
With this function you are allowed to override the default mutex
locks used in some parts of gnutls and dependent libraries. This
function should be used if you have complete control of your
program and libraries. Do not call this function from a library.
Instead only initialize gnutls and the default OS mutex locks will
be used.
This function must be called before 'gnutls_global_init()' .
*Since:* 2.12.0
File: gnutls.info, Node: Callback functions, Prev: Thread safety, Up: Introduction to the library
7.1.6 Callback functions
------------------------
There are several cases where GnuTLS may need out of band input from
your program. This is now implemented using some callback functions,
which your program is expected to register.
An example of this type of functions are the push and pull callbacks
which are used to specify the functions that will retrieve and send data
to the transport layer.
'VOID *note gnutls_transport_set_push_function:: (gnutls_session_t SESSION, gnutls_push_func PUSH_FUNC)'
'VOID *note gnutls_transport_set_pull_function:: (gnutls_session_t SESSION, gnutls_pull_func PULL_FUNC)'
Other callback functions may require more complicated input and data to
be allocated. Such an example is *note
gnutls_srp_set_server_credentials_function::. All callbacks should
allocate and free memory using 'gnutls_malloc' and 'gnutls_free'.
File: gnutls.info, Node: Preparation, Next: Session initialization, Prev: Introduction to the library, Up: How to use GnuTLS in applications
7.2 Preparation
===============
To use GnuTLS, you have to perform some changes to your sources and your
build system. The necessary changes are explained in the following
subsections.
* Menu:
* Headers::
* Initialization::
* Version check::
* Building the source::
File: gnutls.info, Node: Headers, Next: Initialization, Up: Preparation
7.2.1 Headers
-------------
All the data types and functions of the GnuTLS library are defined in
the header file 'gnutls/gnutls.h'. This must be included in all
programs that make use of the GnuTLS library.
File: gnutls.info, Node: Initialization, Next: Version check, Prev: Headers, Up: Preparation
7.2.2 Initialization
--------------------
GnuTLS must be initialized before it can be used. The library is
initialized by calling *note gnutls_global_init::. The resources
allocated by the initialization process can be released if the
application no longer has a need to call GnuTLS functions, this is done
by calling *note gnutls_global_deinit::.
In order to take advantage of the internationalization features in
GnuTLS, such as translated error messages, the application must set the
current locale using 'setlocale' before initializing GnuTLS.
File: gnutls.info, Node: Version check, Next: Building the source, Prev: Initialization, Up: Preparation
7.2.3 Version check
-------------------
It is often desirable to check that the version of 'gnutls' used is
indeed one which fits all requirements. Even with binary compatibility
new features may have been introduced but due to problem with the
dynamic linker an old version is actually used. So you may want to
check that the version is okay right after program start-up. See the
function *note gnutls_check_version::.
File: gnutls.info, Node: Building the source, Prev: Version check, Up: Preparation
7.2.4 Building the source
-------------------------
If you want to compile a source file including the 'gnutls/gnutls.h'
header file, you must make sure that the compiler can find it in the
directory hierarchy. This is accomplished by adding the path to the
directory in which the header file is located to the compilers include
file search path (via the '-I' option).
However, the path to the include file is determined at the time the
source is configured. To solve this problem, the library uses the
external package 'pkg-config' that knows the path to the include file
and other configuration options. The options that need to be added to
the compiler invocation at compile time are output by the '--cflags'
option to 'pkg-config gnutls'. The following example shows how it can
be used at the command line:
gcc -c foo.c `pkg-config gnutls --cflags`
Adding the output of 'pkg-config gnutls --cflags' to the compilers
command line will ensure that the compiler can find the
'gnutls/gnutls.h' header file.
A similar problem occurs when linking the program with the library.
Again, the compiler has to find the library files. For this to work,
the path to the library files has to be added to the library search path
(via the '-L' option). For this, the option '--libs' to 'pkg-config
gnutls' can be used. For convenience, this option also outputs all
other options that are required to link the program with the library
(for instance, the '-ltasn1' option). The example shows how to link
'foo.o' with the library to a program 'foo'.
gcc -o foo foo.o `pkg-config gnutls --libs`
Of course you can also combine both examples to a single command by
specifying both options to 'pkg-config':
gcc -o foo foo.c `pkg-config gnutls --cflags --libs`
When a program uses the GNU autoconf system, then the following line or
similar can be used to detect the presence of GnuTLS.
PKG_CHECK_MODULES([LIBGNUTLS], [gnutls >= 3.0.0])
AC_SUBST([LIBGNUTLS_CFLAGS])
AC_SUBST([LIBGNUTLS_LIBS])
File: gnutls.info, Node: Session initialization, Next: Associating the credentials, Prev: Preparation, Up: How to use GnuTLS in applications
7.3 Session initialization
==========================
In the previous sections we have discussed the global initialization
required for GnuTLS as well as the initialization required for each
authentication method's credentials (see *note Authentication::). In
this section we elaborate on the TLS or DTLS session initiation. Each
session is initialized using *note gnutls_init:: which among others is
used to specify the type of the connection (server or client), and the
underlying protocol type, i.e., datagram (UDP) or reliable (TCP).
-- Function: int gnutls_init (gnutls_session_t * SESSION, unsigned int
FLAGS)
SESSION: is a pointer to a 'gnutls_session_t' structure.
FLAGS: indicate if this session is to be used for server or client.
This function initializes the current session to null. Every
session 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 'GNUTLS_E_SUCCESS'
(0) on success.
'flags' can be one of 'GNUTLS_CLIENT' and 'GNUTLS_SERVER' . For a
DTLS entity, the flags 'GNUTLS_DATAGRAM' and 'GNUTLS_NONBLOCK' are
also available. The latter flag will enable a non-blocking
operation of the DTLS timers.
*Returns:* 'GNUTLS_E_SUCCESS' on success, or an error code.
After the session initialization details on the allowed ciphersuites and
protocol versions should be set using the priority functions such as
*note gnutls_priority_set_direct::. We elaborate on them in *note
Priority Strings::. The credentials used for the key exchange method,
such as certificates or usernames and passwords should also be
associated with the session current session using *note
gnutls_credentials_set::.
-- Function: int gnutls_credentials_set (gnutls_session_t SESSION,
gnutls_credentials_type_t TYPE, void * CRED)
SESSION: is a 'gnutls_session_t' structure.
TYPE: is the type of the credentials
CRED: is a pointer to a structure.
Sets the needed credentials for the specified type. Eg username,
password - or public and private keys etc. The 'cred' parameter is
a structure that depends on the specified type and on the current
session (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
'gnutls_anon_client_credentials_t' in case of a client. In case of
a server it should be 'gnutls_anon_server_credentials_t' .
For 'GNUTLS_CRD_SRP' , 'cred' should be
'gnutls_srp_client_credentials_t' in case of a client, and
'gnutls_srp_server_credentials_t' , in case of a server.
For 'GNUTLS_CRD_CERTIFICATE' , 'cred' should be
'gnutls_certificate_credentials_t' .
*Returns:* On success, 'GNUTLS_E_SUCCESS' (0) is returned,
otherwise a negative error code is returned.
File: gnutls.info, Node: Associating the credentials, Next: Setting up the transport layer, Prev: Session initialization, Up: How to use GnuTLS in applications
7.4 Associating the credentials
===============================
* Menu:
* Certificate credentials::
* SRP credentials::
* PSK credentials::
* Anonymous credentials::
Each authentication method is associated with a key exchange method, and
a credentials type. The contents of the credentials is
method-dependent, e.g. certificates for certificate authentication and
should be initialized and associated with a session (see *note
gnutls_credentials_set::). A mapping of the key exchange methods with
the credential types is shown in *note Table 7.1: tab:key-exchange-cred.
Authentication Key exchange Client Server
method credentials credentials
--------------------------------------------------------------------
Certificate 'KX_RSA', 'CRD_CERTIFICATE''CRD_CERTIFICATE'
'KX_DHE_RSA',
'KX_DHE_DSS',
'KX_ECDHE_RSA',
'KX_ECDHE_ECDSA',
'KX_RSA_EXPORT'
Password and 'KX_SRP_RSA', 'CRD_SRP' 'CRD_CERTIFICATE',
certificate 'KX_SRP_DSS' 'CRD_SRP'
Password 'KX_SRP' 'CRD_SRP' 'CRD_SRP'
Anonymous 'KX_ANON_DH', 'CRD_ANON' 'CRD_ANON'
'KX_ANON_ECDH'
Pre-shared key 'KX_PSK', 'CRD_PSK' 'CRD_PSK'
'KX_DHE_PSK',
'KX_ECDHE_PSK'
Table 7.1: Key exchange algorithms and the corresponding credential
types.
File: gnutls.info, Node: Certificate credentials, Next: SRP credentials, Up: Associating the credentials
7.4.1 Certificates
------------------
Server certificate authentication
.................................
When using certificates the server is required to have at least one
certificate and private key pair. Clients may not hold such a pair, but
a server could require it. In this section we discuss general issues
applying to both client and server certificates. The next section will
elaborate on issues arising from client authentication only.
'INT *note gnutls_certificate_allocate_credentials:: (gnutls_certificate_credentials_t * RES)'
'VOID *note gnutls_certificate_free_credentials:: (gnutls_certificate_credentials_t SC)'
After the credentials structures are initialized, the certificate and
key pair must be loaded. This occurs before any TLS session is
initialized, and the same structures are reused for multiple sessions.
Depending on the certificate type different loading functions are
available, as shown below. For X.509 certificates, the functions will
accept and use a certificate chain that leads to a trusted authority.
The certificate chain must be ordered in such way that every certificate
certifies the one before it. The trusted authority's certificate need
not to be included since the peer should possess it already.
'INT *note gnutls_certificate_set_x509_key_mem:: (gnutls_certificate_credentials_t RES, const gnutls_datum_t * CERT, const gnutls_datum_t * KEY, gnutls_x509_crt_fmt_t TYPE)'
'INT *note gnutls_certificate_set_x509_key:: (gnutls_certificate_credentials_t RES, gnutls_x509_crt_t * CERT_LIST, int CERT_LIST_SIZE, gnutls_x509_privkey_t KEY)'
'INT *note gnutls_certificate_set_x509_key_file:: (gnutls_certificate_credentials_t RES, const char * CERTFILE, const char * KEYFILE, gnutls_x509_crt_fmt_t TYPE)'
'INT *note gnutls_certificate_set_openpgp_key_mem:: (gnutls_certificate_credentials_t RES, const gnutls_datum_t * CERT, const gnutls_datum_t * KEY, gnutls_openpgp_crt_fmt_t FORMAT)'
'INT *note gnutls_certificate_set_openpgp_key:: (gnutls_certificate_credentials_t RES, gnutls_openpgp_crt_t CRT, gnutls_openpgp_privkey_t PKEY)'
'INT *note gnutls_certificate_set_openpgp_key_file:: (gnutls_certificate_credentials_t RES, const char * CERTFILE, const char * KEYFILE, gnutls_openpgp_crt_fmt_t FORMAT)'
'INT *note gnutls_certificate_set_key:: (gnutls_certificate_credentials_t RES, const char** NAMES, int NAMES_SIZE, gnutls_pcert_st * PCERT_LIST, int PCERT_LIST_SIZE, gnutls_privkey_t KEY)'
If multiple certificates are used with the functions above each client's
request will be served with the certificate that matches the requested
name (see *note Server name indication::).
As an alternative to loading from files or buffers, a callback may be
used for the server or the client to specify the certificate and the key
at the handshake time. In that case a certificate should be selected
according the peer's signature algorithm preferences. To get those
preferences use *note gnutls_sign_algorithm_get_requested::. Both
functions are shown below.
'VOID *note gnutls_certificate_set_retrieve_function:: (gnutls_certificate_credentials_t CRED, gnutls_certificate_retrieve_function * FUNC)'
'VOID *note gnutls_certificate_set_retrieve_function2:: (gnutls_certificate_credentials_t CRED, gnutls_certificate_retrieve_function2 * FUNC)'
'INT *note gnutls_sign_algorithm_get_requested:: (gnutls_session_t SESSION, size_t INDX, gnutls_sign_algorithm_t * ALGO)'
The functions above do not handle the requested server name
automatically. A server would need to check the name requested by the
client using *note gnutls_server_name_get::, and serve the appropriate
certificate.
In a handshake, the negotiated cipher suite depends on the certificate's
parameters, so some key exchange methods might not be available with all
certificates. GnuTLS will disable ciphersuites that are not compatible
with the key, or the enabled authentication methods. For example keys
marked as sign-only, will not be able to access the plain RSA
ciphersuites, that require decryption. It is not recommended to use RSA
keys for both signing and encryption. If possible use a different key
for the 'DHE-RSA' which uses signing and 'RSA' that requires decryption.
All the key exchange methods shown in *note Table 4.1: tab:key-exchange.
are available in certificate authentication.
Client certificate authentication
.................................
If a certificate is to be requested from the client during the
handshake, the server will send a certificate request message. This
behavior is controlled *note gnutls_certificate_server_set_request::.
The request contains a list of the acceptable by the server certificate
signers. This list is constructed using the trusted certificate
authorities of the server. In cases where the server supports a large
number of certificate authorities it makes sense not to advertise all of
the names to save bandwidth. That can be controlled using the function
*note gnutls_certificate_send_x509_rdn_sequence::. This however will
have the side-effect of not restricting the client to certificates
signed by server's acceptable signers.
-- Function: void gnutls_certificate_server_set_request
(gnutls_session_t SESSION, gnutls_certificate_request_t REQ)
SESSION: is a 'gnutls_session_t' structure.
REQ: is one of GNUTLS_CERT_REQUEST, GNUTLS_CERT_REQUIRE
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.
-- Function: void gnutls_certificate_send_x509_rdn_sequence
(gnutls_session_t SESSION, int STATUS)
SESSION: is a pointer to a 'gnutls_session_t' structure.
STATUS: is 0 or 1
If status is non zero, this function will order gnutls not to send
the rdnSequence in the certificate request message. That is the
server will not advertise its trusted CAs to the peer. If status
is zero then the default behaviour will take effect, which is to
advertise the server's trusted CAs.
This function has no effect in clients, and in authentication
methods other than certificate with X.509 certificates.
Client or server certificate verification
.........................................
Certificate verification is possible by loading the trusted authorities
into the credentials structure by using the following functions,
applicable to X.509 and OpenPGP certificates.
'INT *note gnutls_certificate_set_x509_trust_file:: (gnutls_certificate_credentials_t CRED, const char * CAFILE, gnutls_x509_crt_fmt_t TYPE)'
'INT *note gnutls_certificate_set_openpgp_keyring_file:: (gnutls_certificate_credentials_t C, const char * FILE, gnutls_openpgp_crt_fmt_t FORMAT)'
The peer's certificate is not automatically verified and one should call
*note gnutls_certificate_verify_peers2:: after a successful handshake to
verify the certificate's signature. Alternative the verification can
occur during the handshake by using *note
gnutls_certificate_set_verify_function::.
In order to report a detailed verification output, an alternative way
has to be used. For that, one should call *note
gnutls_certificate_get_peers:: to obtain the raw certificate of the peer
and verify it using the functions discussed in *note X.509
certificates::.
-- Function: int gnutls_certificate_verify_peers2 (gnutls_session_t
SESSION, unsigned int * STATUS)
SESSION: is a gnutls session
STATUS: is the output of the verification
This function will try to verify the peer's certificate and return
its status (trusted, invalid etc.). The value of 'status' should
be one or more of the gnutls_certificate_status_t enumerated
elements bitwise or'd. To avoid denial of service attacks some
default upper limits regarding the certificate key size and chain
size are set. To override them use
'gnutls_certificate_set_verify_limits()' .
Note that you must also check the peer's name in order to check if
the verified certificate belongs to the actual peer.
This function uses 'gnutls_x509_crt_list_verify()' with the CAs in
the credentials as trusted CAs.
*Returns:* a negative error code on error and 'GNUTLS_E_SUCCESS'
(0) on success.
-- Function: void gnutls_certificate_set_verify_function
(gnutls_certificate_credentials_t CRED,
gnutls_certificate_verify_function * FUNC)
CRED: is a 'gnutls_certificate_credentials_t' structure.
FUNC: is the callback function
This function sets a callback to be called when peer's certificate
has been received in order to verify it on receipt rather than
doing after the handshake is completed.
The callback's function prototype is: int
(*callback)(gnutls_session_t);
If the callback function is provided then gnutls will call it, in
the handshake, just after the certificate message has been
received. To verify or obtain the certificate the
'gnutls_certificate_verify_peers2()' ,
'gnutls_certificate_type_get()' , 'gnutls_certificate_get_peers()'
functions can be used.
The callback function should return 0 for the handshake to continue
or non-zero to terminate.
*Since:* 2.10.0
File: gnutls.info, Node: SRP credentials, Next: PSK credentials, Prev: Certificate credentials, Up: Associating the credentials
7.4.2 SRP
---------
The initialization functions in SRP credentials differ between client
and server. Clients supporting SRP should set the username and password
prior to connection, to the credentials structure. Alternatively *note
gnutls_srp_set_client_credentials_function:: may be used instead, to
specify a callback function that should return the SRP username and
password. The callback is called once during the TLS handshake.
'INT *note gnutls_srp_allocate_server_credentials:: (gnutls_srp_server_credentials_t * SC)'
'INT *note gnutls_srp_allocate_client_credentials:: (gnutls_srp_client_credentials_t * SC)'
'VOID *note gnutls_srp_free_server_credentials:: (gnutls_srp_server_credentials_t SC)'
'VOID *note gnutls_srp_free_client_credentials:: (gnutls_srp_client_credentials_t SC)'
'INT *note gnutls_srp_set_client_credentials:: (gnutls_srp_client_credentials_t RES, const char * USERNAME, const char * PASSWORD)'
-- Function: void gnutls_srp_set_client_credentials_function
(gnutls_srp_client_credentials_t CRED,
gnutls_srp_client_credentials_function * FUNC)
CRED: is a 'gnutls_srp_server_credentials_t' structure.
FUNC: is the callback function
This function can be used to set a callback to retrieve the
username and password for client SRP authentication. The
callback's function form is:
int (*callback)(gnutls_session_t, char** username, char**password);
The 'username' and 'password' must be allocated using
'gnutls_malloc()' . 'username' and 'password' should be ASCII
strings or UTF-8 strings prepared using the "SASLprep" profile of
"stringprep".
The callback function will be called once per handshake before the
initial hello message is sent.
The callback should not return a negative error code the second
time called, since the handshake procedure will be aborted.
The callback function should return 0 on success. -1 indicates an
error.
In server side the default behavior of GnuTLS is to read the usernames
and SRP verifiers from password files. These password file format is
compatible the with the _Stanford srp libraries_ format. If a different
password file format is to be used, then *note
gnutls_srp_set_server_credentials_function:: should be called, to set an
appropriate callback.
-- Function: int gnutls_srp_set_server_credentials_file
(gnutls_srp_server_credentials_t RES, const char *
PASSWORD_FILE, const char * PASSWORD_CONF_FILE)
RES: is a 'gnutls_srp_server_credentials_t' structure.
PASSWORD_FILE: is the SRP password file (tpasswd)
PASSWORD_CONF_FILE: is the SRP password conf file (tpasswd.conf)
This function sets the password files, in a
'gnutls_srp_server_credentials_t' structure. Those password files
hold usernames and verifiers and will be used for SRP
authentication.
*Returns:* On success, 'GNUTLS_E_SUCCESS' (0) is returned, or an
error code.
-- Function: void gnutls_srp_set_server_credentials_function
(gnutls_srp_server_credentials_t CRED,
gnutls_srp_server_credentials_function * FUNC)
CRED: is a 'gnutls_srp_server_credentials_t' structure.
FUNC: is the callback function
This function can be used to set a callback to retrieve the user's
SRP credentials. The callback's function form is:
int (*callback)(gnutls_session_t, const char* username,
gnutls_datum_t* salt, gnutls_datum_t *verifier, gnutls_datum_t* g,
gnutls_datum_t* n);
'username' contains the actual username. The 'salt' , 'verifier' ,
'generator' and 'prime' must be filled in using the
'gnutls_malloc()' . For convenience 'prime' and 'generator' may
also be one of the static parameters defined in gnutls.h.
In case the callback returned a negative number then gnutls will
assume that the username does not exist.
In order to prevent attackers from guessing valid usernames, if a
user does not exist, g and n values should be filled in using a
random user's parameters. In that case the callback must return
the special value (1).
The callback function will only be called once per handshake. The
callback function should return 0 on success, while -1 indicates an
error.
File: gnutls.info, Node: PSK credentials, Next: Anonymous credentials, Prev: SRP credentials, Up: Associating the credentials
7.4.3 PSK
---------
The initialization functions in PSK credentials differ between client
and server.
'INT *note gnutls_psk_allocate_server_credentials:: (gnutls_psk_server_credentials_t * SC)'
'INT *note gnutls_psk_allocate_client_credentials:: (gnutls_psk_client_credentials_t * SC)'
'VOID *note gnutls_psk_free_server_credentials:: (gnutls_psk_server_credentials_t SC)'
'VOID *note gnutls_psk_free_client_credentials:: (gnutls_psk_client_credentials_t SC)'
Clients supporting PSK should supply the username and key before a TLS
session is established. Alternatively *note
gnutls_psk_set_client_credentials_function:: can be used to specify a
callback function. This has the advantage that the callback will be
called only if PSK has been negotiated.
'INT *note gnutls_psk_set_client_credentials:: (gnutls_psk_client_credentials_t RES, const char * USERNAME, const gnutls_datum_t * KEY, gnutls_psk_key_flags FLAGS)'
-- Function: void gnutls_psk_set_client_credentials_function
(gnutls_psk_client_credentials_t CRED,
gnutls_psk_client_credentials_function * FUNC)
CRED: is a 'gnutls_psk_server_credentials_t' structure.
FUNC: is the callback function
This function can be used to set a callback to retrieve the
username and password for client PSK authentication. The
callback's function form is: int (*callback)(gnutls_session_t,
char** username, gnutls_datum_t* key);
The 'username' and 'key' ->data must be allocated using
'gnutls_malloc()' . 'username' should be ASCII strings or UTF-8
strings prepared using the "SASLprep" profile of "stringprep".
The callback function will be called once per handshake.
The callback function should return 0 on success. -1 indicates an
error.
In server side the default behavior of GnuTLS is to read the usernames
and PSK keys from a password file. The password file should contain
usernames and keys in hexadecimal format. The name of the password file
can be stored to the credentials structure by calling *note
gnutls_psk_set_server_credentials_file::. If a different password file
format is to be used, then a callback should be set instead by *note
gnutls_psk_set_server_credentials_function::.
The server can help the client chose a suitable username and password,
by sending a hint. Note that there is no common profile for the PSK
hint and applications are discouraged to use it. A server, may specify
the hint by calling *note gnutls_psk_set_server_credentials_hint::. The
client can retrieve the hint, for example in the callback function,
using *note gnutls_psk_client_get_hint::.
-- Function: int gnutls_psk_set_server_credentials_file
(gnutls_psk_server_credentials_t RES, const char *
PASSWORD_FILE)
RES: is a 'gnutls_psk_server_credentials_t' structure.
PASSWORD_FILE: is the PSK password file (passwd.psk)
This function sets the password file, in a
'gnutls_psk_server_credentials_t' structure. This password file
holds usernames and keys and will be used for PSK authentication.
*Returns:* On success, 'GNUTLS_E_SUCCESS' (0) is returned,
otherwise an error code is returned.
'VOID *note gnutls_psk_set_server_credentials_function:: (gnutls_psk_server_credentials_t CRED, gnutls_psk_server_credentials_function * FUNC)'
'INT *note gnutls_psk_set_server_credentials_hint:: (gnutls_psk_server_credentials_t RES, const char * HINT)'
'CONST CHAR * *note gnutls_psk_client_get_hint:: (gnutls_session_t SESSION)'
File: gnutls.info, Node: Anonymous credentials, Prev: PSK credentials, Up: Associating the credentials
7.4.4 Anonymous
---------------
The key exchange methods for anonymous authentication might require
Diffie-Hellman parameters to be generated by the server and associated
with an anonymous credentials structure. Check *note Parameter
generation:: for more information. The initialization functions for the
credentials are shown below.
'INT *note gnutls_anon_allocate_server_credentials:: (gnutls_anon_server_credentials_t * SC)'
'INT *note gnutls_anon_allocate_client_credentials:: (gnutls_anon_client_credentials_t * SC)'
'VOID *note gnutls_anon_free_server_credentials:: (gnutls_anon_server_credentials_t SC)'
'VOID *note gnutls_anon_free_client_credentials:: (gnutls_anon_client_credentials_t SC)'
File: gnutls.info, Node: Setting up the transport layer, Next: TLS handshake, Prev: Associating the credentials, Up: How to use GnuTLS in applications
7.5 Setting up the transport layer
==================================
The next step is to setup the underlying transport layer details. The
Berkeley sockets are implicitly used by GnuTLS, thus a call to *note
gnutls_transport_set_ptr2:: would be sufficient to specify the socket
descriptor.
-- Function: void gnutls_transport_set_ptr2 (gnutls_session_t SESSION,
gnutls_transport_ptr_t RECV_PTR, gnutls_transport_ptr_t
SEND_PTR)
SESSION: is a 'gnutls_session_t' structure.
RECV_PTR: is the value for the pull function
SEND_PTR: is the value for the push function
Used to set the first argument of the transport function (for push
and pull callbacks). In berkeley style sockets this function will
set the connection descriptor. With this function you can use two
different pointers for receiving and sending.
'VOID *note gnutls_transport_set_ptr:: (gnutls_session_t SESSION, gnutls_transport_ptr_t PTR)'
If however another transport layer than TCP is selected, then the
following functions have to be specified.
-- Function: void gnutls_transport_set_push_function (gnutls_session_t
SESSION, gnutls_push_func PUSH_FUNC)
SESSION: is a 'gnutls_session_t' structure.
PUSH_FUNC: a callback function similar to 'write()'
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 do not need to 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. The callback should
return a positive number indicating the bytes sent, and -1 on
error.
'push_func' is of the form, ssize_t
(*gnutls_push_func)(gnutls_transport_ptr_t, const void*, size_t);
-- Function: void gnutls_transport_set_vec_push_function
(gnutls_session_t SESSION, gnutls_vec_push_func VEC_FUNC)
SESSION: is a 'gnutls_session_t' structure.
VEC_FUNC: a callback function similar to 'writev()'
Using this function you can override the default writev(2) function
for gnutls to send data. Setting this callback instead of
'gnutls_transport_set_push_function()' is recommended since it
introduces less overhead in the TLS handshake process.
'vec_func' is of the form, ssize_t (*gnutls_vec_push_func)
(gnutls_transport_ptr_t, const giovec_t * iov, int iovcnt);
*Since:* 2.12.0
-- Function: void gnutls_transport_set_pull_function (gnutls_session_t
SESSION, gnutls_pull_func PULL_FUNC)
SESSION: is a 'gnutls_session_t' structure.
PULL_FUNC: a callback function similar to 'read()'
This is the function where you set a function for gnutls to receive
data. Normally, if you use berkeley style sockets, do not need to
use this function since the default recv(2) will probably be ok.
The callback should return 0 on connection termination, a positive
number indicating the number of bytes received, and -1 on error.
'gnutls_pull_func' is of the form, ssize_t
(*gnutls_pull_func)(gnutls_transport_ptr_t, void*, size_t);
The functions above accept a callback function which should return the
number of bytes written, or -1 on error and should set 'errno'
appropriately. In some environments, setting 'errno' is unreliable.
For example Windows have several errno variables in different CRTs, or
in other systems it may be a non thread-local variable. If this is a
concern to you, call *note gnutls_transport_set_errno:: with the
intended errno value instead of setting 'errno' directly.
-- Function: void gnutls_transport_set_errno (gnutls_session_t SESSION,
int ERR)
SESSION: is a 'gnutls_session_t' structure.
ERR: error value to store in session-specific errno variable.
Store 'err' in the session-specific errno variable. Useful values
for 'err' is EAGAIN and EINTR, other values are treated will be
treated as real errors in the push/pull function.
This function is useful in replacement push and pull functions set
by 'gnutls_transport_set_push_function()' and
'gnutls_transport_set_pull_function()' under Windows, where the
replacements may not have access to the same 'errno' variable that
is used by GnuTLS (e.g., the application is linked to msvcr71.dll
and gnutls is linked to msvcrt.dll).
GnuTLS currently only interprets the EINTR, EAGAIN and EMSGSIZE errno
values and returns the corresponding GnuTLS error codes:
* 'GNUTLS_E_INTERRUPTED'
* 'GNUTLS_E_AGAIN'
* 'GNUTLS_E_LARGE_PACKET'
The EINTR and EAGAIN values are returned by interrupted system calls, or
when non blocking IO is used. All GnuTLS functions can be resumed
(called again), if any of the above error codes is returned. The
EMSGSIZE value is returned when attempting to send a large datagram.
In the case of DTLS it is also desirable to override the generic
transport functions with functions that emulate the operation of
'recvfrom' and 'sendto'. In addition DTLS requires timers during the
receive of a handshake message, set using the *note
gnutls_transport_set_pull_timeout_function:: function. To check the
retransmission timers the function *note gnutls_dtls_get_timeout:: is
provided, which returns the time remaining until the next
retransmission, or better the time until *note gnutls_handshake:: should
be called again.
-- Function: void gnutls_transport_set_pull_timeout_function
(gnutls_session_t SESSION, gnutls_pull_timeout_func FUNC)
SESSION: is a 'gnutls_session_t' structure.
FUNC: a callback function
This is the function where you set a function for gnutls to know
whether data are ready to be received. It should wait for data a
given time frame in milliseconds. The callback should return 0 on
timeout, a positive number if data can be received, and -1 on
error. You'll need to override this function if 'select()' is not
suitable for the provided transport calls. The callback function
is used in DTLS only.
'gnutls_pull_timeout_func' is of the form, ssize_t
(*gnutls_pull_timeout_func)(gnutls_transport_ptr_t, unsigned int
ms);
*Since:* 3.0
-- Function: unsigned int gnutls_dtls_get_timeout (gnutls_session_t
SESSION)
SESSION: is a 'gnutls_session_t' structure.
This function will return the milliseconds remaining for a
retransmission of the previously sent handshake message. This
function is useful when DTLS is used in non-blocking mode, to
estimate when to call 'gnutls_handshake()' if no packets have been
received.
*Returns:* the remaining time in milliseconds.
*Since:* 3.0
* Menu:
* Asynchronous operation::
* DTLS sessions::
File: gnutls.info, Node: Asynchronous operation, Next: DTLS sessions, Up: Setting up the transport layer
7.5.1 Asynchronous operation
----------------------------
GnuTLS can be used with asynchronous socket or event-driven programming.
The approach is similar to using Berkeley sockets under such an
environment. The blocking, due to network interaction, calls such as
*note gnutls_handshake::, *note gnutls_record_recv::, can be set to
non-blocking by setting the underlying sockets to non-blocking. If
other push and pull functions are setup, then they should behave the
same way as 'recv' and 'send' when used in a non-blocking way, i.e., set
errno to 'EAGAIN'. Since, during a TLS protocol session GnuTLS does not
block except for network interaction, the non blocking 'EAGAIN' errno
will be propagated and GnuTLS functions will return the 'GNUTLS_E_AGAIN'
error code. Such calls can be resumed the same way as a system call
would. The only exception is *note gnutls_record_send::, which if
interrupted subsequent calls need not to include the data to be sent
(can be called with NULL argument).
The 'select' system call can also be used in combination with the GnuTLS
functions. 'select' allows monitoring of sockets and notifies on them
being ready for reading or writing data. Note however that this system
call cannot notify on data present in GnuTLS read buffers, it is only
applicable to the kernel sockets API. Thus if you are using it for
reading from a GnuTLS session, make sure that any cached data are read
completely. That can be achieved by checking there are no data waiting
to be read (using *note gnutls_record_check_pending::), either before
the 'select' system call, or after a call to *note gnutls_record_recv::.
GnuTLS does not keep a write buffer, thus when writing no additional
actions are required.
Although in the TLS protocol implementation each call to receive or send
function implies to restoring the same function that was interrupted, in
the DTLS protocol this requirement isn't true. There are cases where a
retransmission is required, which are indicated by a received message
and thus *note gnutls_record_get_direction:: must be called to decide
which direction to check prior to restoring a function call.
-- Function: int gnutls_record_get_direction (gnutls_session_t SESSION)
SESSION: is a 'gnutls_session_t' structure.
This function provides information about the internals of the
record protocol and is only useful if a prior gnutls function call
(e.g. 'gnutls_handshake()' ) was interrupted for some reason, that
is, if a function returned 'GNUTLS_E_INTERRUPTED' or
'GNUTLS_E_AGAIN' . In such a case, you might want to call
'select()' or 'poll()' before calling the interrupted gnutls
function again. To tell you whether a file descriptor should be
selected for either reading or writing,
'gnutls_record_get_direction()' returns 0 if the interrupted
function was trying to read data, and 1 if it was trying to write
data.
*Returns:* 0 if trying to read data, 1 if trying to write data.
Moreover, to prevent blocking from DTLS' retransmission timers to block
a handshake, the *note gnutls_init:: function should be called with the
'GNUTLS_NONBLOCK' flag set (see *note Session initialization::).
File: gnutls.info, Node: DTLS sessions, Prev: Asynchronous operation, Up: Setting up the transport layer
7.5.2 DTLS sessions
-------------------
Because datagram TLS can operate over connections where the peer of a
server cannot be reliably verified, functionality is available to
prevent denial of service attacks. GnuTLS requires a server to generate
a secret key that is used to sign a cookie(1). That cookie is sent to
the client using *note gnutls_dtls_cookie_send::, and the client must
reply using the correct cookie. The server side should verify the
initial message sent by client using *note gnutls_dtls_cookie_verify::.
If successful the session should be initialized and associated with the
cookie using *note gnutls_dtls_prestate_set::, before proceeding to the
handshake.
'INT *note gnutls_key_generate:: (gnutls_datum_t * KEY, unsigned int KEY_SIZE)'
'INT *note gnutls_dtls_cookie_send:: (gnutls_datum_t* KEY, void* CLIENT_DATA, size_t CLIENT_DATA_SIZE, gnutls_dtls_prestate_st* PRESTATE, gnutls_transport_ptr_t PTR, gnutls_push_func PUSH_FUNC)'
'INT *note gnutls_dtls_cookie_verify:: (gnutls_datum_t* KEY, void* CLIENT_DATA, size_t CLIENT_DATA_SIZE, void* _MSG, size_t MSG_SIZE, gnutls_dtls_prestate_st* PRESTATE)'
'VOID *note gnutls_dtls_prestate_set:: (gnutls_session_t SESSION, gnutls_dtls_prestate_st* PRESTATE)'
Note that the above apply to server side only and they are not mandatory
to be used. Not using them, however, allows denial of service attacks.
The client side cookie handling is part of *note gnutls_handshake::.
Datagrams are typically restricted by a maximum transfer unit (MTU). For
that both client and server side should set the correct maximum transfer
unit for the layer underneath GnuTLS. This will allow proper
fragmentation of DTLS messages and prevent messages from being silently
discarded by the transport layer. The "correct" maximum transfer unit
can be obtained through a path MTU discovery mechanism [_RFC4821_].
'VOID *note gnutls_dtls_set_mtu:: (gnutls_session_t SESSION, unsigned int MTU)'
'UNSIGNED INT *note gnutls_dtls_get_mtu:: (gnutls_session_t SESSION)'
'UNSIGNED INT *note gnutls_dtls_get_data_mtu:: (gnutls_session_t SESSION)'
---------- Footnotes ----------
(1) A key of 128 bits or 16 bytes should be sufficient for this
purpose.
File: gnutls.info, Node: TLS handshake, Next: Data transfer and termination, Prev: Setting up the transport layer, Up: How to use GnuTLS in applications
7.6 TLS handshake
=================
Once a session has been initialized and a network connection has been
set up, TLS and DTLS protocols perform a handshake. The handshake is
the actual key exchange.
-- Function: int gnutls_handshake (gnutls_session_t SESSION)
SESSION: is a 'gnutls_session_t' structure.
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 the client
has asked to resume a session, but the server couldn't, then a full
handshake will be performed.
The non-fatal errors such as 'GNUTLS_E_AGAIN' and
'GNUTLS_E_INTERRUPTED' interrupt the handshake procedure, which
should be resumed later. Call this function again, until it
returns 0; cf. 'gnutls_record_get_direction()' and
'gnutls_error_is_fatal()' .
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 specific case of a rehandshake.
Their meaning is that the client rejected the rehandshake request
or in the case of 'GNUTLS_E_GOT_APPLICATION_DATA' it might also
mean that some data were pending.
*Returns:* 'GNUTLS_E_SUCCESS' on success, otherwise a negative
error code.
The handshake process doesn't ensure the verification of the peer's
identity. When certificates are in use, this can be done, either after
the handshake is complete, or during the handshake if *note
gnutls_certificate_set_verify_function:: has been used. In both cases
the *note gnutls_certificate_verify_peers2:: function can be used to
verify the peer's certificate (see *note Certificate authentication::
for more information).
'INT *note gnutls_certificate_verify_peers2:: (gnutls_session_t SESSION, unsigned int * STATUS)'
File: gnutls.info, Node: Data transfer and termination, Next: Handling alerts, Prev: TLS handshake, Up: How to use GnuTLS in applications
7.7 Data transfer and termination
=================================
Once the handshake is complete and peer's identity has been verified
data can be exchanged. The available functions resemble the POSIX
'recv' and 'send' functions. It is suggested to use *note
gnutls_error_is_fatal:: to check whether the error codes returned by
these functions are fatal for the protocol or can be ignored.
-- Function: ssize_t gnutls_record_send (gnutls_session_t SESSION,
const void * DATA, size_t DATA_SIZE)
SESSION: is a 'gnutls_session_t' structure.
DATA: contains the data to send
DATA_SIZE: is the length of the data
This function has the similar semantics with 'send()' . The only
difference is that it accepts a GnuTLS session, and uses different
error codes. Note that if the send buffer is full, 'send()' will
block this function. See the 'send()' documentation for full
information. You can replace the default push function by using
'gnutls_transport_set_ptr2()' with a call to 'send()' with a
MSG_DONTWAIT flag if blocking is a problem. If the EINTR is
returned by the internal push function (the default is 'send()' )
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; alternatively
you could provide a 'NULL' pointer for data, and 0 for size. cf.
'gnutls_record_get_direction()' . The errno value EMSGSIZE maps to
'GNUTLS_E_LARGE_PACKET' .
*Returns:* The number of bytes sent, or a negative error code. The
number of bytes sent might be less than 'data_size' . The maximum
number of bytes this function can send in a single call depends on
the negotiated maximum record size.
-- Function: ssize_t gnutls_record_recv (gnutls_session_t SESSION, void
* DATA, size_t DATA_SIZE)
SESSION: is a 'gnutls_session_t' structure.
DATA: the buffer that the data will be read into
DATA_SIZE: the number of requested bytes
This function has the similar semantics with 'recv()' . The only
difference is that it accepts a GnuTLS session, and uses different
error codes. In the special case that a server requests a
renegotiation, the client may receive an error code of
'GNUTLS_E_REHANDSHAKE' . This message may be simply ignored,
replied with an alert 'GNUTLS_A_NO_RENEGOTIATION' , or replied with
a new handshake, depending on the client's will. If 'EINTR' is
returned by the internal push function (the default is 'recv()' )
then 'GNUTLS_E_INTERRUPTED' will be returned. If
'GNUTLS_E_INTERRUPTED' or 'GNUTLS_E_AGAIN' is returned, you must
call this function again to get the data. See also
'gnutls_record_get_direction()' . A server may also receive
'GNUTLS_E_REHANDSHAKE' when a client has initiated a handshake. In
that case the server can only initiate a handshake or terminate the
connection.
*Returns:* The number of bytes received and zero on EOF (for stream
connections). A negative error code is returned in case of an
error. The number of bytes received might be less than the
requested 'data_size' .
-- Function: int gnutls_error_is_fatal (int ERROR)
ERROR: is a GnuTLS error code, a negative error code
If a GnuTLS function returns a negative error code you may feed
that value to this function to see if the error condition is fatal.
Note that you may also want to check the error code manually, since
some non-fatal errors to the protocol (such as a warning alert or a
rehandshake request) may be fatal for your program.
This function is only useful if you are dealing with errors from
the record layer or the handshake layer.
*Returns:* 1 if the error code is fatal, for positive 'error'
values, 0 is returned. For unknown 'error' values, -1 is returned.
Although, in the TLS protocol the receive function can be called at any
time, when DTLS is used the GnuTLS receive functions must be called once
a message is available for reading, even if no data are expected. This
is because in DTLS various (internal) actions may be required due to
retransmission timers. Moreover, an extended receive function is shown
below, which allows the extraction of the message's sequence number.
Due to the unreliable nature of the protocol, this field allows
distinguishing out-of-order messages.
-- Function: ssize_t gnutls_record_recv_seq (gnutls_session_t SESSION,
void * DATA, size_t DATA_SIZE, unsigned char * SEQ)
SESSION: is a 'gnutls_session_t' structure.
DATA: the buffer that the data will be read into
DATA_SIZE: the number of requested bytes
SEQ: is the packet's 64-bit sequence number. Should have space for
8 bytes.
This function is the same as 'gnutls_record_recv()' , except that
it returns in addition to data, the sequence number of the data.
This is useful in DTLS where record packets might be received
out-of-order. The returned 8-byte sequence number is an integer in
big-endian format and should be treated as a unique message
identification.
*Returns:* The number of bytes received and zero on EOF. A negative
error code is returned in case of an error. The number of bytes
received might be less than 'data_size' .
*Since:* 3.0
The *note gnutls_record_check_pending:: helper function is available to
allow checking whether data are available to be read in a GnuTLS session
buffers. Note that this function complements but does not replace
'select', i.e., *note gnutls_record_check_pending:: reports no data to
be read, 'select' should be called to check for data in the network
buffers.
-- Function: size_t gnutls_record_check_pending (gnutls_session_t
SESSION)
SESSION: is a 'gnutls_session_t' structure.
This function checks if there are unread data in the gnutls
buffers. If the return value is non-zero the next call to
'gnutls_record_recv()' is guarranteed not to block.
*Returns:* Returns the size of the data or zero.
'INT *note gnutls_record_get_direction:: (gnutls_session_t SESSION)'
Once a TLS or DTLS session is no longer needed, it is recommended to use
*note gnutls_bye:: to terminate the session. That way the peer is
notified securely about the intention of termination, which allows
distinguishing it from a malicious connection termination. A session
can be deinitialized with the *note gnutls_deinit:: function.
-- Function: int gnutls_bye (gnutls_session_t SESSION,
gnutls_close_request_t HOW)
SESSION: is a 'gnutls_session_t' structure.
HOW: is an integer
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' the TLS session gets terminated and
further receives and sends will be disallowed. If the return value
is zero you may continue using the underlying transport layer.
'GNUTLS_SHUT_RDWR' sends an alert containing a close request and
waits for the peer to reply with the same message.
In case of 'GNUTLS_SHUT_WR' the TLS session 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.
Note that not all implementations will properly terminate a TLS
connection. Some of them, usually for performance reasons, will
terminate only the underlying transport layer, and thus not
distinguishing between a malicious party prematurely terminating
the connection and normal termination.
This function may also return 'GNUTLS_E_AGAIN' or
'GNUTLS_E_INTERRUPTED' ; cf. 'gnutls_record_get_direction()' .
*Returns:* 'GNUTLS_E_SUCCESS' on success, or an error code, see
function documentation for entire semantics.
-- Function: void gnutls_deinit (gnutls_session_t SESSION)
SESSION: is a 'gnutls_session_t' structure.
This function clears all buffers associated with the 'session' .
This function will also remove session data from the session
database if the session was terminated abnormally.
File: gnutls.info, Node: Handling alerts, Next: Priority Strings, Prev: Data transfer and termination, Up: How to use GnuTLS in applications
7.8 Handling alerts
===================
During a TLS connection alert messages may be exchanged by the two
peers. Those messages may be fatal, meaning the connection must be
terminated afterwards, or warning when something needs to be reported to
the peer, but without interrupting the session. The error codes
'GNUTLS_E_WARNING_ALERT_RECEIVED' or 'GNUTLS_E_FATAL_ALERT_RECEIVED'
signal those alerts when received, and may be returned by all GnuTLS
functions that receive data from the peer, being *note
gnutls_handshake:: and *note gnutls_record_recv::.
If those error codes are received the alert and its level should be
logged or reported to the peer using the functions below.
-- Function: gnutls_alert_description_t gnutls_alert_get
(gnutls_session_t SESSION)
SESSION: is a 'gnutls_session_t' structure.
This function will return the last alert number received. This
function should be called when 'GNUTLS_E_WARNING_ALERT_RECEIVED' or
'GNUTLS_E_FATAL_ALERT_RECEIVED' errors are returned by a gnutls
function. The peer may send alerts if he encounters an error. If
no alert has been received the returned value is undefined.
*Returns:* the last alert received, a 'gnutls_alert_description_t'
value.
-- Function: const char * gnutls_alert_get_name
(gnutls_alert_description_t ALERT)
ALERT: is an alert number.
This function will return a string that describes the given alert
number, or 'NULL' . See 'gnutls_alert_get()' .
*Returns:* string corresponding to 'gnutls_alert_description_t'
value.
The peer may also be warned or notified of a fatal issue by using one of
the functions below. All the available alerts are listed in *note The
Alert Protocol::.
-- Function: int gnutls_alert_send (gnutls_session_t SESSION,
gnutls_alert_level_t LEVEL, gnutls_alert_description_t DESC)
SESSION: is a 'gnutls_session_t' structure.
LEVEL: is the level of the alert
DESC: is the alert 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.
The error code of the underlying record send function will be
returned, so you may also receive 'GNUTLS_E_INTERRUPTED' or
'GNUTLS_E_AGAIN' as well.
*Returns:* On success, 'GNUTLS_E_SUCCESS' (0) is returned,
otherwise an error code is returned.
-- Function: int gnutls_error_to_alert (int ERR, int * LEVEL)
ERR: is a negative integer
LEVEL: the alert level will be stored there
Get an alert depending on the error code returned by a gnutls
function. All alerts sent by this function should be considered
fatal. The only exception is when 'err' is 'GNUTLS_E_REHANDSHAKE'
, where a warning alert should be sent to the peer indicating that
no renegotiation will be performed.
If there is no mapping to a valid alert the alert to indicate
internal error is returned.
*Returns:* the alert code to use for a particular error code.
File: gnutls.info, Node: Priority Strings, Next: Advanced and other topics, Prev: Handling alerts, Up: How to use GnuTLS in applications
7.9 Priority strings
====================
In order to specify cipher suite preferences on a TLS session there are
priority functions that accept a string specifying the enabled for the
handshake algorithms. That string may contain a single initial keyword
such as in *note Table 7.2: tab:prio-keywords. and may be followed by
additional algorithm or special keywords.
'INT *note gnutls_priority_set_direct:: (gnutls_session_t SESSION, const char * PRIORITIES, const char ** ERR_POS)'
'INT *note gnutls_priority_set:: (gnutls_session_t SESSION, gnutls_priority_t PRIORITY)'
Keyword Description
------------------------------------------------------------------
PERFORMANCE All the known to be secure ciphersuites are
enabled, limited to 128 bit ciphers and sorted
by terms of speed performance. The message
authenticity security level is of 64 bits or
more.
NORMAL Means all the known to be secure ciphersuites.
The ciphers are sorted by security margin,
although the 256-bit ciphers are included as a
fallback only. The message authenticity
security level is of 64 bits or more.
SECURE128 Means all known to be secure ciphersuites that
offer a security level 128-bit or more and a
message authenticity security level of 80 bits
or more.
SECURE192 Means all the known to be secure ciphersuites
that offer a security level 192-bit or more and
a message authenticity security level of 128
bits or more.
SECURE256 Currently alias for SECURE192.
SUITEB128 Means all the NSA Suite B cryptography (RFC5430)
ciphersuites with an 128 bit security level.
SUITEB192 Means all the NSA Suite B cryptography (RFC5430)
ciphersuites with an 192 bit security level.
EXPORT Means all ciphersuites are enabled, including
the low-security 40 bit ciphers.
NONE Means nothing is enabled. This disables even
protocols and compression methods. It should be
followed by the algorithms to be enabled.
Table 7.2: Supported initial keywords.
Unless the initial keyword is "NONE" the defaults (in preference order)
are for TLS protocols TLS 1.2, TLS1.1, TLS1.0, SSL3.0; for compression
NULL; for certificate types X.509. In key exchange algorithms when in
NORMAL or SECURE levels the perfect forward secrecy algorithms take
precedence of the other protocols. In all cases all the supported key
exchange algorithms are enabled(1).
Note that the SECURE levels distinguish between overall security level
and message authenticity security level. That is because the message
authenticity security level requires the adversary to break the
algorithms at real-time during the protocol run, whilst the overall
security level refers to off-line adversaries (e.g. adversaries
breaking the ciphertext years after it was captured).
The NONE keyword, if used, must followed by keywords specifying the
algorithms and protocols to be enabled. The other initial keywords may
be followed by such keywords. The order with which every algorithm or
protocol is specified is significant. Algorithms specified before
others will take precedence. The supported algorithms and protocols are
shown in *note Table 7.3: tab:prio-algorithms. To avoid collisions in
order to specify a compression algorithm in the priority string you have
to prefix it with "COMP-", protocol versions with "VERS-", signature
algorithms with "SIGN-" and certificate types with "CTYPE-". All other
algorithms don't need a prefix. Each specified keyword can be prefixed
with any of the following characters.
'!' or '-'
appended with an algorithm will remove this algorithm.
"+"
appended with an algorithm will add this algorithm.
Type Keywords
------------------------------------------------------------------
Ciphers AES-128-CBC, AES-256-CBC, AES-128-GCM,
CAMELLIA-128-CBC, CAMELLIA-256-CBC, ARCFOUR-128,
3DES-CBC ARCFOUR-40. Catch all name is
CIPHER-ALL which will add all the algorithms
from NORMAL priority.
Key exchange RSA, DHE-RSA, DHE-DSS, SRP, SRP-RSA, SRP-DSS,
PSK, DHE-PSK, ECDHE-RSA, ANON-ECDH, ANON-DH,
RSA-EXPORT. The Catch all name is KX-ALL which
will add all the algorithms from NORMAL
priority.
MAC MD5, SHA1, SHA256, AEAD (used with GCM ciphers
only). All algorithms from NORMAL priority can
be accessed with MAC-ALL.
Compression COMP-NULL, COMP-DEFLATE. Catch all is COMP-ALL.
algorithms
TLS versions VERS-SSL3.0, VERS-TLS1.0, VERS-TLS1.1,
VERS-TLS1.2, VERS-DTLS1.0. Catch all is
VERS-TLS-ALL.
Signature SIGN-RSA-SHA1, SIGN-RSA-SHA224, SIGN-RSA-SHA256,
algorithms SIGN-RSA-SHA384, SIGN-RSA-SHA512, SIGN-DSA-SHA1,
SIGN-DSA-SHA224, SIGN-DSA-SHA256, SIGN-RSA-MD5.
Catch all is SIGN-ALL. This is only valid for
TLS 1.2 and later.
Elliptic CURVE-SECP192R1, CURVE-SECP224R1,
curves CURVE-SECP256R1, CURVE-SECP384R1,
CURVE-SECP521R1. Catch all is CURVE-ALL.
Table 7.3: The supported algorithm keywords in priority strings.
Note that the DHE key exchange methods are generally slower(2) than
their elliptic curves counterpart (ECDHE). Moreover the plain
Diffie-Hellman key exchange requires parameters to be generated and
associated with a credentials structure by the server (see *note
Parameter generation::).
The available special keywords are shown in *note Table 7.4:
tab:prio-special.
Keyword Description
------------------------------------------------------------------
%COMPAT will enable compatibility
mode. It might mean that
violations of the protocols
are allowed as long as maximum
compatibility with problematic
clients and servers is
achieved. More specifically
this string would disable TLS
record random padding and
tolerate packets over the
maximum allowed TLS record.
%NO_EXTENSIONS will prevent the sending of
any TLS extensions in client
side. Note that TLS 1.2
requires extensions to be
used, as well as safe
renegotiation thus this option
must be used with care.
%STATELESS_COMPRESSION will disable keeping state
across records when
compressing. This may help to
mitigate attacks when
compression is used but an
attacker is in control of
input data.
%SERVER_PRECEDENCE The ciphersuite will be
selected according to server
priorities and not the
client's.
%DISABLE_SAFE_RENEGOTIATION will disable safe
renegotiation completely. Do
not use unless you know what
you are doing. Testing
purposes only.
%UNSAFE_RENEGOTIATION will allow handshakes and
re-handshakes without the safe
renegotiation extension. Note
that for clients this mode is
insecure (you may be under
attack), and for servers it
will allow insecure clients to
connect (which could be fooled
by an attacker). Do not use
unless you know what you are
doing and want maximum
compatibility.
%PARTIAL_RENEGOTIATION will allow initial handshakes
to proceed, but not
re-handshakes. This leaves
the client vulnerable to
attack, and servers will be
compatible with non-upgraded
clients for initial
handshakes. This is currently
the default for clients and
servers, for compatibility
reasons.
%SAFE_RENEGOTIATION will enforce safe
renegotiation. Clients and
servers will refuse to talk to
an insecure peer. Currently
this causes interoperability
problems, but is required for
full protection.
%SSL3_RECORD_VERSION will use SSL3.0 record version
in client hello. This is the
default.
%LATEST_RECORD_VERSION will use the latest TLS
version record version in
client hello.
%VERIFY_ALLOW_SIGN_RSA_MD5 will allow RSA-MD5 signatures
in certificate chains.
%VERIFY_ALLOW_X509_V1_CA_CRT will allow V1 CAs in chains.
Table 7.4: Special priority string keywords.
Finally the ciphersuites enabled by any priority string can be listed
using the 'gnutls-cli' application (see *note gnutls-cli Invocation::),
or by using the priority functions as in *note Listing the ciphersuites
in a priority string::.
Example priority strings are:
The default priority without the HMAC-MD5:
"NORMAL:-MD5"
Specifying RSA with AES-128-CBC:
"NONE:+VERS-TLS-ALL:+MAC-ALL:+RSA:+AES-128-CBC:+SIGN-ALL:+COMP-NULL"
Specifying the defaults except ARCFOUR-128:
"NORMAL:-ARCFOUR-128"
Enabling the 128-bit secure ciphers, while disabling SSL 3.0 and
enabling compression:
"SECURE128:-VERS-SSL3.0:+COMP-DEFLATE"
---------- Footnotes ----------
(1) Except for the RSA-EXPORT which is only enabled in EXPORT level.
(2) It depends on the group used. Primes with lesser bits are always
faster, but also easier to break. See *note Selecting cryptographic key
sizes:: for the acceptable security levels.
File: gnutls.info, Node: Advanced and other topics, Next: Using the cryptographic library, Prev: Priority Strings, Up: How to use GnuTLS in applications
7.10 Advanced and other topics
==============================
* Menu:
* Session resumption::
* Parameter generation::
* Keying Material Exporters::
* Channel Bindings::
* Interoperability::
* Compatibility with the OpenSSL library::
File: gnutls.info, Node: Session resumption, Next: Parameter generation, Up: Advanced and other topics
7.10.1 Session resumption
-------------------------
Client side
...........
To reduce time and roundtrips spent in a handshake the client can
request session resumption from a server that previously shared a
session with. For that the client has to retrieve and store the session
parameters. Before establishing a new session to the same server the
parameters must be re-associated with the GnuTLS session using *note
gnutls_session_set_data::.
'INT *note gnutls_session_get_data:: (gnutls_session_t SESSION, void * SESSION_DATA, size_t * SESSION_DATA_SIZE)'
'INT *note gnutls_session_get_id:: (gnutls_session_t SESSION, void * SESSION_ID, size_t * SESSION_ID_SIZE)'
'INT *note gnutls_session_set_data:: (gnutls_session_t SESSION, const void * SESSION_DATA, size_t SESSION_DATA_SIZE)'
Keep in mind that sessions will be expired after some time, depending on
the server, and a server may choose not to resume a session even when
requested to. The expiration is to prevent temporal session keys from
becoming long-term keys. Also note that as a client you must enable,
using the priority functions, at least the algorithms used in the last
session.
It is highly recommended for clients to enable the session ticket
extension using *note gnutls_session_ticket_enable_client:: in order to
allow resumption with servers that do not store any state.
'INT *note gnutls_session_ticket_enable_client:: (gnutls_session_t SESSION)'
-- Function: int gnutls_session_is_resumed (gnutls_session_t SESSION)
SESSION: is a 'gnutls_session_t' structure.
Check whether session is resumed or not.
*Returns:* non zero if this session is resumed, or a zero if this
is a new session.
Server side
...........
In order to support resumption a server can store the session security
parameters in a local database or by using session tickets (see *note
Session tickets::) to delegate storage to the client. Because session
tickets might not be supported by all clients, servers could combine the
two methods.
A storing server needs to specify callback functions to store, retrieve
and delete session data. These can be registered with the functions
below. The stored sessions in the database can be checked using *note
gnutls_db_check_entry:: for expiration.
'VOID *note gnutls_db_set_retrieve_function:: (gnutls_session_t SESSION, gnutls_db_retr_func RETR_FUNC)'
'VOID *note gnutls_db_set_store_function:: (gnutls_session_t SESSION, gnutls_db_store_func STORE_FUNC)'
'VOID *note gnutls_db_set_ptr:: (gnutls_session_t SESSION, void * PTR)'
'VOID *note gnutls_db_set_remove_function:: (gnutls_session_t SESSION, gnutls_db_remove_func REM_FUNC)'
'INT *note gnutls_db_check_entry:: (gnutls_session_t SESSION, gnutls_datum_t SESSION_ENTRY)'
A server utilizing tickets should generate ticket encryption and
authentication keys using *note gnutls_session_ticket_key_generate::.
Those keys should be associated with the GnuTLS session using *note
gnutls_session_ticket_enable_server::.
-- Function: int gnutls_session_ticket_enable_server (gnutls_session_t
SESSION, const gnutls_datum_t * KEY)
SESSION: is a 'gnutls_session_t' structure.
KEY: key to encrypt session parameters.
Request that the server should attempt session resumption using
SessionTicket. 'key' must be initialized with
'gnutls_session_ticket_key_generate()' .
*Returns:* On success, 'GNUTLS_E_SUCCESS' (0) is returned, or an
error code.
*Since:* 2.10.0
-- Function: int gnutls_session_ticket_key_generate (gnutls_datum_t *
KEY)
KEY: is a pointer to a 'gnutls_datum_t' which will contain a newly
created key.
Generate a random key to encrypt security parameters within
SessionTicket.
*Returns:* On success, 'GNUTLS_E_SUCCESS' (0) is returned, or an
error code.
*Since:* 2.10.0
-- Function: int gnutls_session_resumption_requested (gnutls_session_t
SESSION)
SESSION: is a 'gnutls_session_t' structure.
Check whether the client has asked for session resumption. This
function is valid only on server side.
*Returns:* non zero if session resumption was asked, or a zero if
not.
A server enabling both session tickets and a storage for session data
would use session tickets when clients support it and the storage
otherwise.
File: gnutls.info, Node: Parameter generation, Next: Keying Material Exporters, Prev: Session resumption, Up: Advanced and other topics
7.10.2 Parameter generation
---------------------------
Several TLS ciphersuites require additional parameters that need to be
generated or provided by the application. The Diffie-Hellman based
ciphersuites (ANON-DH or DHE), require the group parameters to be
provided. Those can either be be generated on the fly using *note
gnutls_dh_params_generate2:: or imported from pregenerated data using
*note gnutls_dh_params_import_pkcs3::. The parameters can be used in a
TLS session by calling *note gnutls_certificate_set_dh_params:: or *note
gnutls_anon_set_server_dh_params:: for anonymous sessions.
'INT *note gnutls_dh_params_generate2:: (gnutls_dh_params_t PARAMS, unsigned int BITS)'
'INT *note gnutls_dh_params_import_pkcs3:: (gnutls_dh_params_t PARAMS, const gnutls_datum_t * PKCS3_PARAMS, gnutls_x509_crt_fmt_t FORMAT)'
'VOID *note gnutls_certificate_set_dh_params:: (gnutls_certificate_credentials_t RES, gnutls_dh_params_t DH_PARAMS)'
'VOID *note gnutls_anon_set_server_dh_params:: (gnutls_anon_server_credentials_t RES, gnutls_dh_params_t DH_PARAMS)'
Due to the time-consuming calculations required for the generation of
Diffie-Hellman parameters we suggest against performing generation of
them within an application. The 'certtool' tool can be used to generate
or export known safe values that can be stored in code or in a
configuration file to provide the ability to replace. We also recommend
the usage of *note gnutls_sec_param_to_pk_bits:: (see *note Selecting
cryptographic key sizes::) to determine the bit size of the generated
parameters.
Note that the information stored in the generated PKCS #3 structure
changed with GnuTLS 3.0.9. Since that version the 'privateValueLength'
member of the structure is set, allowing the server utilizing the
parameters to use keys of the size of the security parameter. This
provides better performance in key exchange.
The ciphersuites that involve the RSA-EXPORT key exchange require
additional parameters. Those ciphersuites are rarely used today because
they are by design insecure, thus if you have no requirement for them,
the rest of this section can be skipped. The RSA-EXPORT key exchange
requires 512-bit RSA keys to be generated. It is recommended those
parameters to be refreshed (regenerated) in short intervals. The
following functions can be used for these parameters.
'INT *note gnutls_rsa_params_generate2:: (gnutls_rsa_params_t PARAMS, unsigned int BITS)'
'VOID *note gnutls_certificate_set_rsa_export_params:: (gnutls_certificate_credentials_t RES, gnutls_rsa_params_t RSA_PARAMS)'
'INT *note gnutls_rsa_params_import_pkcs1:: (gnutls_rsa_params_t PARAMS, const gnutls_datum_t * PKCS1_PARAMS, gnutls_x509_crt_fmt_t FORMAT)'
'INT *note gnutls_rsa_params_export_pkcs1:: (gnutls_rsa_params_t PARAMS, gnutls_x509_crt_fmt_t FORMAT, unsigned char * PARAMS_DATA, size_t * PARAMS_DATA_SIZE)'
To allow renewal of the parameters within an application without
accessing the credentials, which are a shared structure, an alternative
interface is available using a callback function.
-- Function: void gnutls_certificate_set_params_function
(gnutls_certificate_credentials_t RES, gnutls_params_function
* FUNC)
RES: is a gnutls_certificate_credentials_t structure
FUNC: is the function to be called
This function will set a callback in order for the server to get
the Diffie-Hellman or RSA parameters for certificate
authentication. The callback should return 'GNUTLS_E_SUCCESS' (0)
on success.
File: gnutls.info, Node: Keying Material Exporters, Next: Channel Bindings, Prev: Parameter generation, Up: Advanced and other topics
7.10.3 Keying material exporters
--------------------------------
The TLS PRF can be used by other protocols to derive keys based on the
TLS master secret. The API to use is *note gnutls_prf::. The function
needs to be provided with the label in the parameter 'label', and the
extra data to mix in the 'extra' parameter. Depending on whether you
want to mix in the client or server random data first, you can set the
'server_random_first' parameter.
For example, after establishing a TLS session using *note
gnutls_handshake::, you can invoke the TLS PRF with this call:
#define MYLABEL "EXPORTER-FOO"
#define MYCONTEXT "some context data"
char out[32];
rc = gnutls_prf (session, strlen (MYLABEL), MYLABEL, 0,
strlen (MYCONTEXT), MYCONTEXT, 32, out);
If you don't want to mix in the client/server random, there is a
low-level TLS PRF interface called *note gnutls_prf_raw::.
File: gnutls.info, Node: Channel Bindings, Next: Interoperability, Prev: Keying Material Exporters, Up: Advanced and other topics
7.10.4 Channel bindings
-----------------------
In user authentication protocols (e.g., EAP or SASL mechanisms) it is
useful to have a unique string that identifies the secure channel that
is used, to bind together the user authentication with the secure
channel. This can protect against man-in-the-middle attacks in some
situations. That unique string is called a "channel binding". For
background and discussion see [_RFC5056_].
In GnuTLS you can extract a channel binding using the *note
gnutls_session_channel_binding:: function. Currently only the type
'GNUTLS_CB_TLS_UNIQUE' is supported, which corresponds to the
'tls-unique' channel binding for TLS defined in [_RFC5929_].
The following example describes how to print the channel binding data.
Note that it must be run after a successful TLS handshake.
{
gnutls_datum_t cb;
int rc;
rc = gnutls_session_channel_binding (session,
GNUTLS_CB_TLS_UNIQUE,
&cb);
if (rc)
fprintf (stderr, "Channel binding error: %s\n",
gnutls_strerror (rc));
else
{
size_t i;
printf ("- Channel binding 'tls-unique': ");
for (i = 0; i < cb.size; i++)
printf ("%02x", cb.data[i]);
printf ("\n");
}
}
File: gnutls.info, Node: Interoperability, Next: Compatibility with the OpenSSL library, Prev: Channel Bindings, Up: Advanced and other topics
7.10.5 Interoperability
-----------------------
The TLS protocols support many ciphersuites, extensions and version
numbers. As a result, few implementations are not able to properly
interoperate once faced with extensions or version protocols they do not
support and understand. The TLS protocol allows for a graceful
downgrade to the commonly supported options, but practice shows it is
not always implemented correctly.
Because there is no way to achieve maximum interoperability with broken
peers without sacrificing security, GnuTLS ignores such peers by
default. This might not be acceptable in cases where maximum
compatibility is required. Thus we allow enabling compatibility with
broken peers using priority strings (see *note Priority Strings::). A
conservative priority string that would disable certain TLS protocol
options that are known to cause compatibility problems, is shown below.
NORMAL:%COMPAT
For broken peers that do not tolerate TLS version numbers over TLS 1.0
another priority string is:
NORMAL:-VERS-TLS-ALL:+VERS-TLS1.0:+VERS-SSL3.0:%COMPAT
This priority string will in addition to above, only enable SSL 3.0 and
TLS 1.0 as protocols. Note however that there are known attacks against
those protocol versions, especially over the CBC-mode ciphersuites. To
mitigate them another priority string that only allows the stream cipher
ARCFOUR is below.
NORMAL:-VERS-TLS-ALL:+VERS-TLS1.0:+VERS-SSL3.0:-CIPHER-ALL:+ARCFOUR-128:%COMPAT
File: gnutls.info, Node: Compatibility with the OpenSSL library, Prev: Interoperability, Up: Advanced and other topics
7.10.6 Compatibility with the OpenSSL library
---------------------------------------------
To ease GnuTLS' integration with existing applications, a compatibility
layer with the OpenSSL library is included in the 'gnutls-openssl'
library. This compatibility layer is not complete and it is not
intended to completely re-implement the OpenSSL API with GnuTLS. It
only provides limited source-level compatibility.
The prototypes for the compatibility functions are in the
'gnutls/openssl.h' header file. The limitations imposed by the
compatibility layer include:
* Error handling is not thread safe.
File: gnutls.info, Node: Using the cryptographic library, Next: Selecting cryptographic key sizes, Prev: Advanced and other topics, Up: How to use GnuTLS in applications
7.11 Using the cryptographic library
====================================
GnuTLS is not a low-level cryptographic library, i.e., it does not
provide access to basic cryptographic primitives. However it abstracts
the internal cryptographic back-end (see *note Cryptographic Backend::),
providing symmetric crypto, hash and HMAC algorithms, as well access to
the random number generation.
* Menu:
* Symmetric cryptography::
* Hash and HMAC functions::
* Random number generation::
File: gnutls.info, Node: Symmetric cryptography, Next: Hash and HMAC functions, Up: Using the cryptographic library
7.11.1 Symmetric cryptography
-----------------------------
The available functions to access symmetric crypto algorithms operations
are shown below. The supported algorithms are the algorithms required
by the TLS protocol. They are listed in *note Table 3.1: tab:ciphers.
'INT *note gnutls_cipher_init:: (gnutls_cipher_hd_t * HANDLE, gnutls_cipher_algorithm_t CIPHER, const gnutls_datum_t * KEY, const gnutls_datum_t * IV)'
'INT *note gnutls_cipher_encrypt2:: (gnutls_cipher_hd_t HANDLE, const void * TEXT, size_t TEXTLEN, void * CIPHERTEXT, size_t CIPHERTEXTLEN)'
'INT *note gnutls_cipher_decrypt2:: (gnutls_cipher_hd_t HANDLE, const void * CIPHERTEXT, size_t CIPHERTEXTLEN, void * TEXT, size_t TEXTLEN)'
'VOID *note gnutls_cipher_set_iv:: (gnutls_cipher_hd_t HANDLE, void * IV, size_t IVLEN)'
'VOID *note gnutls_cipher_deinit:: (gnutls_cipher_hd_t HANDLE)'
In order to support authenticated encryption with associated data (AEAD)
algorithms the following functions are provided to set the associated
data and retrieve the authentication tag.
'INT *note gnutls_cipher_add_auth:: (gnutls_cipher_hd_t HANDLE, const void * TEXT, size_t TEXT_SIZE)'
'INT *note gnutls_cipher_tag:: (gnutls_cipher_hd_t HANDLE, void * TAG, size_t TAG_SIZE)'
File: gnutls.info, Node: Hash and HMAC functions, Next: Random number generation, Prev: Symmetric cryptography, Up: Using the cryptographic library
7.11.2 Hash and HMAC functions
------------------------------
The available operations to access hash functions and hash-MAC (HMAC)
algorithms are shown below. HMAC algorithms provided keyed hash
functionality. They supported HMAC algorithms are listed in *note Table
3.2: tab:macs.
'INT *note gnutls_hmac_init:: (gnutls_hmac_hd_t * DIG, gnutls_mac_algorithm_t ALGORITHM, const void * KEY, size_t KEYLEN)'
'INT *note gnutls_hmac:: (gnutls_hmac_hd_t HANDLE, const void * TEXT, size_t TEXTLEN)'
'VOID *note gnutls_hmac_output:: (gnutls_hmac_hd_t HANDLE, void * DIGEST)'
'VOID *note gnutls_hmac_deinit:: (gnutls_hmac_hd_t HANDLE, void * DIGEST)'
'INT *note gnutls_hmac_get_len:: (gnutls_mac_algorithm_t ALGORITHM)'
'INT *note gnutls_hmac_fast:: (gnutls_mac_algorithm_t ALGORITHM, const void * KEY, size_t KEYLEN, const void * TEXT, size_t TEXTLEN, void * DIGEST)'
The available functions to access hash functions are shown below. The
supported hash functions are the same as the HMAC algorithms.
'INT *note gnutls_hash_init:: (gnutls_hash_hd_t * DIG, gnutls_digest_algorithm_t ALGORITHM)'
'INT *note gnutls_hash:: (gnutls_hash_hd_t HANDLE, const void * TEXT, size_t TEXTLEN)'
'VOID *note gnutls_hash_output:: (gnutls_hash_hd_t HANDLE, void * DIGEST)'
'VOID *note gnutls_hash_deinit:: (gnutls_hash_hd_t HANDLE, void * DIGEST)'
'INT *note gnutls_hash_get_len:: (gnutls_digest_algorithm_t ALGORITHM)'
'INT *note gnutls_hash_fast:: (gnutls_digest_algorithm_t ALGORITHM, const void * TEXT, size_t TEXTLEN, void * DIGEST)'
File: gnutls.info, Node: Random number generation, Prev: Hash and HMAC functions, Up: Using the cryptographic library
7.11.3 Random number generation
-------------------------------
Access to the random number generator is provided using the *note
gnutls_rnd:: function. It allows obtaining random data of various
levels.
'GNUTLS_RND_NONCE'
Non-predictable random number. Fatal in parts of session if
broken, i.e., vulnerable to statistical analysis.
'GNUTLS_RND_RANDOM'
Pseudo-random cryptographic random number. Fatal in session if
broken.
'GNUTLS_RND_KEY'
Fatal in many sessions if broken.
Figure 7.2: The random number levels.
-- Function: int gnutls_rnd (gnutls_rnd_level_t LEVEL, void * DATA,
size_t LEN)
LEVEL: a security level
DATA: place to store random bytes
LEN: The requested size
This function will generate random data and store it to output
buffer.
*Returns:* Zero or a negative error code on error.
*Since:* 2.12.0
File: gnutls.info, Node: Selecting cryptographic key sizes, Prev: Using the cryptographic library, Up: How to use GnuTLS in applications
7.12 Selecting cryptographic key sizes
======================================
Because many algorithms are involved in TLS, it is not easy to set a
consistent security level. For this reason in *note Table 7.5:
tab:key-sizes. we present some correspondence between key sizes of
symmetric algorithms and public key algorithms based on [_ECRYPT_].
Those can be used to generate certificates with appropriate key sizes as
well as select parameters for Diffie-Hellman and SRP authentication.
SecurityRSA, DH ECC Security Description
bits and SRP key parameter
parameter size
size
-----------------------------------------------------------------
80 1248 160 'LOW' Very short term
protection against
agencies
96 1776 192 'LEGACY' Legacy standard level
112 2432 224 'NORMAL' Medium-term
protection
128 3248 256 'HIGH' Long term protection
256 15424 512 'ULTRA' Foreseeable future
Table 7.5: Key sizes and security parameters.
The first column provides a security parameter in a number of bits.
This gives an indication of the number of combinations to be tried by an
adversary to brute force a key. For example to test all possible keys
in a 112 bit security parameter 2^{112} combinations have to be tried.
For today's technology this is infeasible. The next two columns
correlate the security parameter with actual bit sizes of parameters for
DH, RSA, SRP and ECC algorithms. A mapping to 'gnutls_sec_param_t'
value is given for each security parameter, on the next column, and
finally a brief description of the level.
Note, however, that the values suggested here are nothing more than an
educated guess that is valid today. There are no guarantees that an
algorithm will remain unbreakable or that these values will remain
constant in time. There could be scientific breakthroughs that cannot
be predicted or total failure of the current public key systems by
quantum computers. On the other hand though the cryptosystems used in
TLS are selected in a conservative way and such catastrophic
breakthroughs or failures are believed to be unlikely. The NIST
publication SP 800-57 [_NISTSP80057_] contains a similar table.
When using GnuTLS and a decision on bit sizes for a public key algorithm
is required, use of the following functions is recommended:
-- Function: unsigned int gnutls_sec_param_to_pk_bits
(gnutls_pk_algorithm_t ALGO, gnutls_sec_param_t PARAM)
ALGO: is a public key algorithm
PARAM: is a security parameter
When generating private and public key pairs a difficult question
is which size of "bits" the modulus will be in RSA and the group
size in DSA. The easy answer is 1024, which is also wrong. This
function will convert a human understandable security parameter to
an appropriate size for the specific algorithm.
*Returns:* The number of bits, or (0).
*Since:* 2.12.0
-- Function: gnutls_sec_param_t gnutls_pk_bits_to_sec_param
(gnutls_pk_algorithm_t ALGO, unsigned int BITS)
ALGO: is a public key algorithm
BITS: is the number of bits
This is the inverse of 'gnutls_sec_param_to_pk_bits()' . Given an
algorithm and the number of bits, it will return the security
parameter. This is a rough indication.
*Returns:* The security parameter.
*Since:* 2.12.0
Those functions will convert a human understandable security parameter
of 'gnutls_sec_param_t' type, to a number of bits suitable for a public
key algorithm.
The following functions will set the minimum acceptable group size for
Diffie-Hellman and SRP authentication.
'VOID *note gnutls_dh_set_prime_bits:: (gnutls_session_t SESSION, unsigned int BITS)'
'VOID *note gnutls_srp_set_prime_bits:: (gnutls_session_t SESSION, unsigned int BITS)'
File: gnutls.info, Node: GnuTLS application examples, Next: Other included programs, Prev: How to use GnuTLS in applications, Up: Top
8 GnuTLS application examples
*****************************
In this chapter several examples of real-world use cases are listed.
The examples are simplified to promote readability and contain little or
no error checking.
* Menu:
* Client examples::
* Server examples::
* OCSP example::
* Miscellaneous examples::
File: gnutls.info, Node: Client examples, Next: Server examples, Up: GnuTLS application examples
8.1 Client examples
===================
This section contains examples of TLS and SSL clients, using GnuTLS.
Note that some of the examples require functions implemented by another
example.
* Menu:
* Simple client example with X.509 certificate support::
* Simple client example with SSH-style certificate verification::
* Simple client example with anonymous authentication::
* Simple Datagram TLS client example::
* Obtaining session information::
* Using a callback to select the certificate to use::
* Verifying a certificate::
* Client using a smart card with TLS::
* Client with Resume capability example::
* Simple client example with SRP authentication::
* Simple client example in C++::
* Helper functions for TCP connections::
* Helper functions for UDP connections::
File: gnutls.info, Node: Simple client example with X.509 certificate support, Next: Simple client example with SSH-style certificate verification, Up: Client examples
8.1.1 Simple client example with X.509 certificate support
----------------------------------------------------------
Let's assume now that we want to create a TCP client which communicates
with servers that use X.509 or OpenPGP certificate authentication. The
following client is a very simple TLS client, which uses the high level
verification functions for certificates, but does not support session
resumption.
/* This example code is placed in the public domain. */
#ifdef HAVE_CONFIG_H
#include
#endif
#include
#include
#include
#include
#include
#include "examples.h"
/* A very basic TLS client, with X.509 authentication and server certificate
* verification. Note that error checking for missing files etc. is missing
* for simplicity.
*/
#define MAX_BUF 1024
#define CAFILE "/etc/ssl/certs/ca-certificates.crt"
#define MSG "GET / HTTP/1.0\r\n\r\n"
extern int tcp_connect (void);
extern void tcp_close (int sd);
static int _verify_certificate_callback (gnutls_session_t session);
int main (void)
{
int ret, sd, ii;
gnutls_session_t session;
char buffer[MAX_BUF + 1];
const char *err;
gnutls_certificate_credentials_t xcred;
gnutls_global_init ();
/* X509 stuff */
gnutls_certificate_allocate_credentials (&xcred);
/* sets the trusted cas file
*/
/* gnutls_certificate_set_x509_system_trust(xcred); */
gnutls_certificate_set_x509_trust_file (xcred, CAFILE, GNUTLS_X509_FMT_PEM);
gnutls_certificate_set_verify_function (xcred, _verify_certificate_callback);
/* If client holds a certificate it can be set using the following:
*
gnutls_certificate_set_x509_key_file (xcred,
"cert.pem", "key.pem",
GNUTLS_X509_FMT_PEM);
*/
/* Initialize TLS session
*/
gnutls_init (&session, GNUTLS_CLIENT);
gnutls_session_set_ptr (session, (void *) "my_host_name");
gnutls_server_name_set (session, GNUTLS_NAME_DNS, "my_host_name",
strlen("my_host_name"));
/* Use default priorities */
ret = gnutls_priority_set_direct (session, "NORMAL", &err);
if (ret < 0)
{
if (ret == GNUTLS_E_INVALID_REQUEST)
{
fprintf (stderr, "Syntax error at: %s\n", err);
}
exit (1);
}
/* put the x509 credentials to the current session
*/
gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
/* connect to the peer
*/
sd = tcp_connect ();
gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) sd);
/* Perform the TLS handshake
*/
do
{
ret = gnutls_handshake (session);
}
while (ret < 0 && gnutls_error_is_fatal (ret) == 0);
if (ret < 0)
{
fprintf (stderr, "*** Handshake failed\n");
gnutls_perror (ret);
goto end;
}
else
{
printf ("- Handshake was completed\n");
}
gnutls_record_send (session, MSG, strlen (MSG));
ret = gnutls_record_recv (session, buffer, MAX_BUF);
if (ret == 0)
{
printf ("- Peer has closed the TLS connection\n");
goto end;
}
else if (ret < 0)
{
fprintf (stderr, "*** Error: %s\n", gnutls_strerror (ret));
goto end;
}
printf ("- Received %d bytes: ", ret);
for (ii = 0; ii < ret; ii++)
{
fputc (buffer[ii], stdout);
}
fputs ("\n", stdout);
gnutls_bye (session, GNUTLS_SHUT_RDWR);
end:
tcp_close (sd);
gnutls_deinit (session);
gnutls_certificate_free_credentials (xcred);
gnutls_global_deinit ();
return 0;
}
/* This function will verify the peer's certificate, and check
* if the hostname matches, as well as the activation, expiration dates.
*/
static int
_verify_certificate_callback (gnutls_session_t session)
{
unsigned int status;
const gnutls_datum_t *cert_list;
unsigned int cert_list_size;
int ret;
gnutls_x509_crt_t cert;
const char *hostname;
/* read hostname */
hostname = gnutls_session_get_ptr (session);
/* This verification function uses the trusted CAs in the credentials
* structure. So you must have installed one or more CA certificates.
*/
ret = gnutls_certificate_verify_peers2 (session, &status);
if (ret < 0)
{
printf ("Error\n");
return GNUTLS_E_CERTIFICATE_ERROR;
}
if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
printf ("The certificate hasn't got a known issuer.\n");
if (status & GNUTLS_CERT_REVOKED)
printf ("The certificate has been revoked.\n");
if (status & GNUTLS_CERT_EXPIRED)
printf ("The certificate has expired\n");
if (status & GNUTLS_CERT_NOT_ACTIVATED)
printf ("The certificate is not yet activated\n");
if (status & GNUTLS_CERT_INVALID)
{
printf ("The certificate is not trusted.\n");
return GNUTLS_E_CERTIFICATE_ERROR;
}
/* Up to here the process is the same for X.509 certificates and
* OpenPGP keys. From now on X.509 certificates are assumed. This can
* be easily extended to work with openpgp keys as well.
*/
if (gnutls_certificate_type_get (session) != GNUTLS_CRT_X509)
return GNUTLS_E_CERTIFICATE_ERROR;
if (gnutls_x509_crt_init (&cert) < 0)
{
printf ("error in initialization\n");
return GNUTLS_E_CERTIFICATE_ERROR;
}
cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
if (cert_list == NULL)
{
printf ("No certificate was found!\n");
return GNUTLS_E_CERTIFICATE_ERROR;
}
if (gnutls_x509_crt_import (cert, &cert_list[0], GNUTLS_X509_FMT_DER) < 0)
{
printf ("error parsing certificate\n");
return GNUTLS_E_CERTIFICATE_ERROR;
}
if (!gnutls_x509_crt_check_hostname (cert, hostname))
{
printf ("The certificate's owner does not match hostname '%s'\n",
hostname);
return GNUTLS_E_CERTIFICATE_ERROR;
}
gnutls_x509_crt_deinit (cert);
/* notify gnutls to continue handshake normally */
return 0;
}
File: gnutls.info, Node: Simple client example with SSH-style certificate verification, Next: Simple client example with anonymous authentication, Prev: Simple client example with X.509 certificate support, Up: Client examples
8.1.2 Simple client example with SSH-style certificate verification
-------------------------------------------------------------------
This is an alternative verification function that will use the X.509
certificate authorities for verification, but also assume an trust on
first use (SSH-like) authentication system. That is the user is
prompted on unknown public keys and known public keys are considered
trusted.
/* This example code is placed in the public domain. */
#ifdef HAVE_CONFIG_H
#include
#endif
#include
#include
#include
#include
#include
#include "examples.h"
/* This function will verify the peer's certificate, check
* if the hostname matches. In addition it will perform an
* SSH-style authentication, where ultimately trusted keys
* are only the keys that have been seen before.
*/
int
_ssh_verify_certificate_callback (gnutls_session_t session)
{
unsigned int status;
const gnutls_datum_t *cert_list;
unsigned int cert_list_size;
int ret;
gnutls_x509_crt_t cert;
const char *hostname;
/* read hostname */
hostname = gnutls_session_get_ptr (session);
/* This verification function uses the trusted CAs in the credentials
* structure. So you must have installed one or more CA certificates.
*/
ret = gnutls_certificate_verify_peers2 (session, &status);
if (ret < 0)
{
printf ("Error\n");
return GNUTLS_E_CERTIFICATE_ERROR;
}
if (status & GNUTLS_CERT_INVALID)
printf ("The certificate is not trusted.\n");
if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
printf ("The certificate hasn't got a known issuer.\n");
if (status & GNUTLS_CERT_REVOKED)
printf ("The certificate has been revoked.\n");
if (status & GNUTLS_CERT_EXPIRED)
printf ("The certificate has expired\n");
if (status & GNUTLS_CERT_NOT_ACTIVATED)
printf ("The certificate is not yet activated\n");
/* Up to here the process is the same for X.509 certificates and
* OpenPGP keys. From now on X.509 certificates are assumed. This can
* be easily extended to work with openpgp keys as well.
*/
if (gnutls_certificate_type_get (session) != GNUTLS_CRT_X509)
return GNUTLS_E_CERTIFICATE_ERROR;
if (gnutls_x509_crt_init (&cert) < 0)
{
printf ("error in initialization\n");
return GNUTLS_E_CERTIFICATE_ERROR;
}
cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
if (cert_list == NULL)
{
printf ("No certificate was found!\n");
return GNUTLS_E_CERTIFICATE_ERROR;
}
/* This is not a real world example, since we only check the first
* certificate in the given chain.
*/
if (gnutls_x509_crt_import (cert, &cert_list[0], GNUTLS_X509_FMT_DER) < 0)
{
printf ("error parsing certificate\n");
return GNUTLS_E_CERTIFICATE_ERROR;
}
if (!gnutls_x509_crt_check_hostname (cert, hostname))
{
printf ("The certificate's owner does not match hostname '%s'\n",
hostname);
status |= GNUTLS_CERT_INVALID;
}
gnutls_x509_crt_deinit (cert);
/* service may be obtained alternatively using getservbyport() */
ret = gnutls_verify_stored_pubkey(NULL, NULL, hostname, "https",
GNUTLS_CRT_X509, &cert_list[0], 0);
if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND)
{
printf("Host %s is not known.", hostname);
if (status == 0)
printf("Its certificate is valid for %s.\n", hostname);
/* the certificate must be printed and user must be asked on
* whether it is trustworthy. --see gnutls_x509_crt_print() */
/* if not trusted */
return GNUTLS_E_CERTIFICATE_ERROR;
}
else if (ret == GNUTLS_E_CERTIFICATE_KEY_MISMATCH)
{
printf("Warning: host %s is known but has another key associated.", hostname);
printf("It might be that the server has multiple keys, or you are under attack\n");
if (status == 0)
printf("Its certificate is valid for %s.\n", hostname);
/* the certificate must be printed and user must be asked on
* whether it is trustworthy. --see gnutls_x509_crt_print() */
/* if not trusted */
return GNUTLS_E_CERTIFICATE_ERROR;
}
else if (ret < 0)
{
printf("gnutls_verify_stored_pubkey: %s\n", gnutls_strerror(ret));
return ret;
}
/* user trusts the key -> store it */
if (ret != 0)
{
ret = gnutls_store_pubkey(NULL, NULL, hostname, "https",
GNUTLS_CRT_X509, &cert_list[0],
0, 0);
if (ret < 0)
printf("gnutls_store_pubkey: %s\n", gnutls_strerror(ret));
}
/* notify gnutls to continue handshake normally */
return 0;
}