Next: Raw public-key credentials, Up: Associating the credentials [Contents][Index]
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.
In order to use certificate credentials one must first initialize a credentials
structure of type gnutls_certificate_credentials_t
. After use this structure must
be freed. This can be done with the following functions.
int gnutls_certificate_allocate_credentials (gnutls_certificate_credentials_t * res)
void 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 gnutls_certificate_set_x509_key_file2 (gnutls_certificate_credentials_t res, const char * certfile, const char * keyfile, gnutls_x509_crt_fmt_t type, const char * pass, unsigned int flags)
int gnutls_certificate_set_x509_key_mem2 (gnutls_certificate_credentials_t res, const gnutls_datum_t * cert, const gnutls_datum_t * key, gnutls_x509_crt_fmt_t type, const char * pass, unsigned int flags)
int 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)
It is recommended to use the higher level functions such as gnutls_certificate_set_x509_key_file2 which accept not only file names but URLs that specify objects stored in token, or system certificates and keys (see Application-specific keys). For these cases, another important function is gnutls_certificate_set_pin_function, that allows setting a callback function to retrieve a PIN if the input keys are protected by PIN.
cred: is a gnutls_certificate_credentials_t
type.
fn: A PIN callback
userdata: Data to be passed in the callback
This function will set a callback function to be used when required to access a protected object. This function overrides any other global PIN functions.
Note that this function must be called right after initialization to have effect.
Since: 3.1.0
If the imported keys and certificates need to be accessed before any TLS session is established, it is convenient to use gnutls_certificate_set_key in combination with gnutls_pcert_import_x509_raw and gnutls_privkey_import_x509_raw.
res: is a gnutls_certificate_credentials_t
type.
names: is an array of DNS names belonging to the public-key (NULL if none)
names_size: holds the size of the names list
pcert_list: contains a certificate list (chain) or raw public-key
pcert_list_size: holds the size of the certificate list
key: is a gnutls_privkey_t
key corresponding to the first public-key in pcert_list
This function sets a public/private key pair in the
gnutls_certificate_credentials_t type. The given public key may be encapsulated
in a certificate or can be given as a raw key. This function may be
called more than once, in case multiple key pairs exist for
the server. For clients that want to send more than their own end-
entity certificate (e.g., also an intermediate CA cert), the full
certificate chain must be provided in pcert_list
.
Note that the key
will become part of the credentials structure and must
not be deallocated. It will be automatically deallocated when the res
structure
is deinitialized.
If this function fails, the res
structure is at an undefined state and it must
not be reused to load other keys or certificates.
Note that, this function by default returns zero on success and a negative value on error.
Since 3.5.6, when the flag GNUTLS_CERTIFICATE_API_V2
is set using gnutls_certificate_set_flags()
it returns an index (greater or equal to zero). That index can be used for other functions to refer to the added key-pair.
Since GnuTLS 3.6.6 this function also handles raw public keys.
Returns: On success this functions returns zero, and otherwise a negative value on error (see above for modifying that behavior).
Since: 3.0
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 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 gnutls_sign_algorithm_get_requested. Both functions are shown below.
void gnutls_certificate_set_retrieve_function (gnutls_certificate_credentials_t cred, gnutls_certificate_retrieve_function * func)
void gnutls_certificate_set_retrieve_function2 (gnutls_certificate_credentials_t cred, gnutls_certificate_retrieve_function2 * func)
void gnutls_certificate_set_retrieve_function3 (gnutls_certificate_credentials_t cred, gnutls_certificate_retrieve_function3 * func)
int 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 gnutls_server_name_get, and serve the appropriate
certificate. Note that some of these functions require the gnutls_pcert_st
structure to be
filled in. Helper functions to fill in the structure are listed below.
typedef struct gnutls_pcert_st { gnutls_pubkey_t pubkey; gnutls_datum_t cert; gnutls_certificate_type_t type; } gnutls_pcert_st;
int gnutls_pcert_import_x509 (gnutls_pcert_st * pcert, gnutls_x509_crt_t crt, unsigned int flags)
int gnutls_pcert_import_x509_raw (gnutls_pcert_st * pcert, const gnutls_datum_t * cert, gnutls_x509_crt_fmt_t format, unsigned int flags)
void gnutls_pcert_deinit (gnutls_pcert_st * pcert)
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 Table 4.1 are
available in 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 by gnutls_certificate_server_set_request. The request contains a list of the by the server accepted 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 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.
session: is a gnutls_session_t
type.
req: is one of GNUTLS_CERT_REQUEST, GNUTLS_CERT_REQUIRE, GNUTLS_CERT_IGNORE
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 the GNUTLS_E_NO_CERTIFICATE_FOUND
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. Invoking
the function with req
GNUTLS_CERT_IGNORE has the same effect.
session: a gnutls_session_t
type.
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.
On the client side, it needs to set its certificates on the credentials structure, similarly to server side from a file, or via a callback. Once the certificates are available in the credentials structure, the client will send them if during the handshake the server requests a certificate signed by the issuer of its CA.
In the case a single certificate is available and the server does not
specify a signer’s list, then that certificate is always sent. It is,
however possible, to send a certificate even when the advertised CA
list by the server contains CAs other than its signer. That can be achieved
using the GNUTLS_FORCE_CLIENT_CERT
flag in gnutls_init.
int gnutls_certificate_set_x509_key_file (gnutls_certificate_credentials_t res, const char * certfile, const char * keyfile, gnutls_x509_crt_fmt_t type)
int gnutls_certificate_set_x509_simple_pkcs12_file (gnutls_certificate_credentials_t res, const char * pkcs12file, gnutls_x509_crt_fmt_t type, const char * password)
void gnutls_certificate_set_retrieve_function2 (gnutls_certificate_credentials_t cred, gnutls_certificate_retrieve_function2 * func)
Certificate verification is possible by loading the trusted authorities into the credentials structure by using the following functions, applicable to X.509 certificates. In modern systems it is recommended to utilize gnutls_certificate_set_x509_system_trust which will load the trusted authorities from the system store.
cred: is a gnutls_certificate_credentials_t
type.
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.20
int gnutls_certificate_set_x509_trust_file (gnutls_certificate_credentials_t cred, const char * cafile, gnutls_x509_crt_fmt_t type)
int gnutls_certificate_set_x509_trust_dir (gnutls_certificate_credentials_t cred, const char * ca_dir, gnutls_x509_crt_fmt_t type)
The peer’s certificate will be automatically verified if gnutls_session_set_verify_cert is called prior to handshake.
Alternatively, one must set a callback function during the handshake using gnutls_certificate_set_verify_function, which will verify the peer’s certificate once received. The verification should happen using gnutls_certificate_verify_peers3 within the callback. It will verify the certificate’s signature and the owner of the certificate. That will provide a brief verification output. If a detailed output is required one should call gnutls_certificate_get_peers to obtain the raw certificate of the peer and verify it using the functions discussed in X.509 certificates.
In both the automatic and the manual cases, the verification status returned can be printed using gnutls_certificate_verification_status_print.
session: is a gnutls session
hostname: is the expected name of the peer; may be NULL
flags: flags for certificate verification – gnutls_certificate_verify_flags
This function instructs GnuTLS to verify the peer’s certificate
using the provided hostname. If the verification fails the handshake
will also fail with GNUTLS_E_CERTIFICATE_VERIFICATION_ERROR
. In that
case the verification result can be obtained using gnutls_session_get_verify_cert_status()
.
The hostname
pointer provided must remain valid for the lifetime
of the session. More precisely it should be available during any subsequent
handshakes. If no hostname is provided, no hostname verification
will be performed. For a more advanced verification function check
gnutls_session_set_verify_cert2()
.
If flags
is provided which contain a profile, this function should be
called after any session priority setting functions.
The gnutls_session_set_verify_cert()
function is intended to be used by TLS
clients to verify the server’s certificate.
Since: 3.4.6
int gnutls_certificate_verify_peers3 (gnutls_session_t session, const char * hostname, unsigned int * status)
void gnutls_certificate_set_verify_function (gnutls_certificate_credentials_t cred, gnutls_certificate_verify_function * func)
Note that when using raw public-keys verification will not work because there is no corresponding certificate body belonging to the raw key that can be verified. In that case the gnutls_certificate_verify_peers family of functions will return a GNUTLS_E_INVALID_REQUEST error code. For authenticating raw public-keys one must use an out-of-band mechanism, e.g. by comparing hashes or using trust on first use (see Verifying a certificate using trust on first use authentication).
Next: Raw public-key credentials, Up: Associating the credentials [Contents][Index]