Next: TLS 1.2 re-authentication, Previous: Session resumption, Up: Advanced topics [Contents][Index]
In this section the functionality for additional certificate verification methods is listed. These methods are intended to be used in addition to normal PKI verification, in order to reduce the risk of a compromised CA being undetected.
The GnuTLS library includes functionality to use an SSH-like trust on first use authentication. The available functions to store and verify public keys are listed below.
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 a raw public-key or a public-key provided via
a raw (DER-encoded) certificate using a list of stored public keys.
The service
field if non-NULL should be a port number.
The db_name
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.
As of GnuTLS 3.6.6 this function also verifies raw public keys.
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.13
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 a raw public-key or a public-key provided via a raw (DER-encoded) certificate to the list of stored public keys. The key will be considered valid until the provided expiration time.
The tdb
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.
Unless an alternative tdb
is provided, the storage format is a textual format
consisting of a line for each host with fields separated by ’|’. The contents of
the fields are a format-identifier which is set to ’g0’, the hostname that the
rest of the data applies to, the numeric port or host name, the expiration
time in seconds since the epoch (0 for no expiration), and a base64
encoding of the raw (DER) public key information (SPKI) of the peer.
As of GnuTLS 3.6.6 this function also accepts raw public keys.
Returns: On success, GNUTLS_E_SUCCESS
(0) is returned, otherwise a
negative error value.
Since: 3.0.13
In addition to the above the 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.
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 or GNUTLS_SCOMMIT_FLAG_ALLOW_BROKEN
.
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 tdb
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 gnutls_tdb_init (gnutls_tdb_t * tdb)
void gnutls_tdb_deinit (gnutls_tdb_t tdb)
void gnutls_tdb_set_verify_func (gnutls_tdb_t tdb, gnutls_tdb_verify_func verify)
void gnutls_tdb_set_store_func (gnutls_tdb_t tdb, gnutls_tdb_store_func store)
void gnutls_tdb_set_store_commitment_func (gnutls_tdb_t tdb, gnutls_tdb_store_commitment_func cstore)
Since the DANE library is not included in GnuTLS it requires programs to be linked against it. This can be achieved with the following commands.
gcc -o foo foo.c `pkg-config gnutls-dane --cflags --libs`
When a program uses the GNU autoconf system, then the following line or similar can be used to detect the presence of the library.
PKG_CHECK_MODULES([LIBDANE], [gnutls-dane >= 3.0.0]) AC_SUBST([LIBDANE_CFLAGS]) AC_SUBST([LIBDANE_LIBS])
The high level functionality provided by the DANE library is shown below.
s: A DANE state structure (may be NULL)
chain: A certificate chain
chain_size: The size of the chain
chain_type: The type of the certificate chain
hostname: The hostname associated with the chain
proto: The protocol of the service connecting (e.g. tcp)
port: The port of the service connecting (e.g. 443)
sflags: Flags for the initialization of s
(if NULL)
vflags: Verification flags; an OR’ed list of dane_verify_flags_t
.
verify: An OR’ed list of dane_verify_status_t
.
This function will verify the given certificate chain against the
CA constrains and/or the certificate available via DANE.
If no information via DANE can be obtained the flag DANE_VERIFY_NO_DANE_INFO
is set. If a DNSSEC signature is not available for the DANE
record then the verify flag DANE_VERIFY_NO_DNSSEC_DATA
is set.
Due to the many possible options of DANE, there is no single threat model countered. When notifying the user about DANE verification results it may be better to mention: DANE verification did not reject the certificate, rather than mentioning a successful DANE verification.
Note that this function is designed to be run in addition to
PKIX - certificate chain - verification. To be run independently
the DANE_VFLAG_ONLY_CHECK_EE_USAGE
flag should be specified;
then the function will check whether the key of the peer matches the
key advertised in the DANE entry.
Returns: a negative error code on error and DANE_E_SUCCESS
(0)
when the DANE entries were successfully parsed, irrespective of
whether they were verified (see verify
for that information). If
no usable entries were encountered DANE_E_REQUESTED_DATA_NOT_AVAILABLE
will be returned.
int dane_verify_session_crt (dane_state_t s, gnutls_session_t session, const char * hostname, const char * proto, unsigned int port, unsigned int sflags, unsigned int vflags, unsigned int * verify)
const char * dane_strerror (int error)
Note that the dane_state_t
structure that is accepted by both
verification functions is optional. It is required when many queries
are performed to optimize against multiple re-initializations of the
resolving back-end and loading of DNSSEC keys.
The following flags are returned by the verify functions to indicate the status of the verification.
DANE_VERIFY_CA_CONSTRAINTS_VIOLATED
The CA constraints were violated.
DANE_VERIFY_CERT_DIFFERS
The certificate obtained via DNS differs.
DANE_VERIFY_UNKNOWN_DANE_INFO
No known DANE data was found in the DNS record.
In order to generate a DANE TLSA entry to use in a DNS server you may use danetool (see danetool Invocation).
Next: TLS 1.2 re-authentication, Previous: Session resumption, Up: Advanced topics [Contents][Index]