Blob Blame History Raw
@node More on certificate authentication
@section More on certificate authentication
@cindex 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::
* OCSP stapling::
* Managing encrypted keys::
* certtool Invocation::            Invoking certtool
* ocsptool Invocation::            Invoking ocsptool
* danetool Invocation::            Invoking danetool
@end menu

@node PKCS 10 certificate requests
@subsection @acronym{PKCS} #10 certificate requests
@cindex certificate requests
@cindex PKCS #10

A certificate request is a structure, which contain information about
an applicant of a certificate service.  It typically contains a public
key, a distinguished name and secondary data such as a challenge
password. @acronym{GnuTLS} supports the requests defined in
@acronym{PKCS} #10 @xcite{RFC2986}. Other formats of certificate requests
are not currently supported by GnuTLS.

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.

@showfuncF{gnutls_x509_crq_set_version,gnutls_x509_crq_set_dn,gnutls_x509_crq_set_dn_by_oid,gnutls_x509_crq_set_key_usage,gnutls_x509_crq_set_key_purpose_oid,gnutls_x509_crq_set_basic_constraints}

The @funcref{gnutls_x509_crq_set_key} and @funcref{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 @ref{Abstract key types}.

@showfuncdesc{gnutls_x509_crq_set_key}
@showfuncdesc{gnutls_x509_crq_sign2}

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.

@anchor{ex-crq}
@verbatiminclude examples/ex-crq.c

@node PKIX certificate revocation lists
@subsection PKIX certificate revocation lists
@cindex certificate revocation lists
@cindex CRL

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 @ref{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.

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.

@float Table,tab:crl
@multitable @columnfractions .2 .7

@headitem Field @tab Description

@item version @tab
The field that indicates the version of the CRL structure.

@item signature @tab
A signature by the issuing authority.

@item issuer @tab
Holds the issuer's distinguished name.

@item thisUpdate @tab
The issuing time of the revocation list.

@item nextUpdate @tab
The issuing time of the revocation list that will update that one.

@item revokedCertificates @tab
List of revoked certificates serial numbers.

@item extensions @tab
Optional CRL structure extensions.

@end multitable
@caption{Certificate revocation list fields.}
@end float

The basic CRL structure functions follow.

@showfuncD{gnutls_x509_crl_init,gnutls_x509_crl_import,gnutls_x509_crl_export,gnutls_x509_crl_export}

@subsubheading Reading a CRL

The most important function that extracts the certificate revocation
information from a CRL is @funcref{gnutls_x509_crl_get_crt_serial}. Other
functions that return other fields of the CRL structure are also provided.

@showfuncdesc{gnutls_x509_crl_get_crt_serial}

@showfuncF{gnutls_x509_crl_get_version,gnutls_x509_crl_get_issuer_dn,gnutls_x509_crl_get_issuer_dn2,gnutls_x509_crl_get_this_update,gnutls_x509_crl_get_next_update,gnutls_x509_crl_get_crt_count}

@subsubheading Generation of a CRL

The following functions can be used to generate a CRL.

@showfuncB{gnutls_x509_crl_set_version,gnutls_x509_crl_set_crt_serial}
@showfuncC{gnutls_x509_crl_set_crt,gnutls_x509_crl_set_next_update,gnutls_x509_crl_set_this_update}

The @funcref{gnutls_x509_crl_sign2} and @funcref{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.

@showfuncdesc{gnutls_x509_crl_sign2}
@showfuncdesc{gnutls_x509_crl_privkey_sign}

Few extensions on the CRL structure are supported, including the
CRL number extension and the authority key identifier.

@showfuncB{gnutls_x509_crl_set_number,gnutls_x509_crl_set_authority_key_id}

@node OCSP certificate status checking
@subsection @acronym{OCSP} certificate status checking
@cindex certificate status
@cindex Online Certificate Status Protocol
@cindex OCSP

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 @xcite{RIVESTCRL}.

The Online Certificate Status Protocol, or @acronym{OCSP} @xcite{RFC2560}, 
is a widely implemented protocol which performs 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.

Applications are typically expected to contact the OCSP server in order to
request the certificate validity status. The OCSP server replies with an OCSP
response. This section describes this online communication (which can be avoided
when using OCSP stapled responses, for that, see @ref{OCSP stapling}).

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.  When stored in a certificate
the OCSP server is in the extension field called the Authority Information 
Access (AIA). The following function
extracts this information from a certificate.

@showfuncA{gnutls_x509_crt_get_authority_info_access}

There are several functions in GnuTLS for creating and manipulating
OCSP requests and responses.  The general idea is that a client
application creates an OCSP request object, stores some information
about the certificate to check in the request, and then exports 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.

@example
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 @}
@end example

The basic functions to initialize, import, export and deallocate OCSP
requests are the following.

@showfuncE{gnutls_ocsp_req_init,gnutls_ocsp_req_deinit,gnutls_ocsp_req_import,gnutls_ocsp_req_export,gnutls_ocsp_req_print}

To generate an OCSP request the issuer name hash, issuer key hash, and 
the checked certificate's serial number are required. There are two
interfaces available for setting those in an OCSP request.
The is a low-level function when you have the
issuer name hash, issuer key hash, and certificate serial number in
binary form.  The second is more useful if you have the
certificate (and its issuer) in a @code{gnutls_x509_crt_t} type.
There is also a function to extract this information from existing an OCSP
request.

@showfuncC{gnutls_ocsp_req_add_cert_id,gnutls_ocsp_req_add_cert,gnutls_ocsp_req_get_cert_id}

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. You can extract or
set those extensions using the following functions.

@showfuncB{gnutls_ocsp_req_get_extension,gnutls_ocsp_req_set_extension}

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.

@showfuncC{gnutls_ocsp_req_get_nonce,gnutls_ocsp_req_set_nonce,gnutls_ocsp_req_randomize_nonce}

The OCSP response structures is a complex structure. A simplified overview
of it is in @ref{tab:ocsp-response}. Note that a response may contain 
information on multiple certificates.

@float Table,tab:ocsp-response
@multitable @columnfractions .2 .7

@headitem Field @tab Description

@item version @tab
The OCSP response version number (typically 1).

@item responder ID @tab
An identifier of the responder (DN name or a hash of its key).

@item issue time @tab
The time the response was generated.

@item thisUpdate @tab
The issuing time of the revocation information.

@item nextUpdate @tab
The issuing time of the revocation information that will update that one.

@item @tab Revoked certificates

@item certificate status @tab
The status of the certificate.

@item certificate serial @tab
The certificate's serial number.

@item revocationTime @tab
The time the certificate was revoked.

@item revocationReason @tab
The reason the certificate was revoked.

@end multitable
@caption{The most important OCSP response fields.}
@end float


We provide basic functions for initialization, importing, exporting
and deallocating OCSP responses.  

@showfuncE{gnutls_ocsp_resp_init,gnutls_ocsp_resp_deinit,gnutls_ocsp_resp_import,gnutls_ocsp_resp_export,gnutls_ocsp_resp_print}

The utility function that extracts the revocation as well as other information
from a response is shown below.

@showfuncdesc{gnutls_ocsp_resp_get_single}

The possible revocation reasons available in an OCSP response are shown
below.

@showenumdesc{gnutls_x509_crl_reason_t,The revocation reasons}

Note, that the OCSP response needs to be verified against some set of trust
anchors before it can be relied upon. It is also important to check
whether the received OCSP response corresponds to the certificate being checked.

@showfuncC{gnutls_ocsp_resp_verify,gnutls_ocsp_resp_verify_direct,gnutls_ocsp_resp_check_crt}

@node OCSP stapling
@subsection OCSP stapling
@cindex certificate status
@cindex Online Certificate Status Protocol
@cindex OCSP stapling

To avoid applications contacting the OCSP server directly, TLS servers
can provide a "stapled" OCSP response in the TLS handshake. That way
the client application needs to do nothing more. GnuTLS will automatically
consider the stapled OCSP response during the TLS certificate verification
(see @funcref{gnutls_certificate_verify_peers2}). To disable the automatic
OCSP verification the flag @code{GNUTLS_VERIFY_DISABLE_CRL_CHECKS} should be
specified to @funcref{gnutls_certificate_set_verify_flags}.

Since GnuTLS 3.5.1 the client certificate verification will consider the @xcite{RFC7633}
OCSP-Must-staple certificate extension, and will consider it while checking for stapled
OCSP responses. If the extension is present and no OCSP staple is found, the certificate
verification will fail and the status code @code{GNUTLS_CERT_MISSING_OCSP_STATUS} will
returned from the verification function.

Under TLS 1.2 only one stapled response can be sent by a server, the OCSP
response associated with the end-certificate. Under TLS 1.3 a server can
send multiple OCSP responses, typically one for each certificate in the
certificate chain. The following functions can be used by a client
application to retrieve the OCSP responses as sent by the server.

@showfuncB{gnutls_ocsp_status_request_get,gnutls_ocsp_status_request_get2}

GnuTLS servers can provide OCSP responses to their clients using the following functions.

@showfuncC{gnutls_certificate_set_retrieve_function3,gnutls_certificate_set_ocsp_status_request_file2,gnutls_ocsp_status_request_is_checked}

A server is expected to provide the relevant certificate's OCSP responses using
@funcref{gnutls_certificate_set_ocsp_status_request_file2}, and ensure a
periodic reload/renew of the credentials. An estimation of the OCSP responses
expiration can be obtained using the @funcref{gnutls_certificate_get_ocsp_expiration} function.

@showfuncdesc{gnutls_certificate_get_ocsp_expiration}

Prior to GnuTLS 3.6.4, the functions
@funcref{gnutls_certificate_set_ocsp_status_request_function2}
@funcref{gnutls_certificate_set_ocsp_status_request_file} were provided
to set OCSP responses. These functions are still functional, but cannot be used
to set multiple OCSP responses as allowed by TLS1.3.

The responses can be updated periodically using the 'ocsptool' command
(see also @ref{ocsptool Invocation}).

@example
ocsptool --ask --load-cert server_cert.pem --load-issuer the_issuer.pem
         --load-signer the_issuer.pem --outfile ocsp.resp
@end example

In order to allow multiple OCSP responses to be concatenated, GnuTLS
supports PEM-encoded OCSP responses. These can be generated using
'ocsptool' with the '--no-outder' parameter.


@node Managing encrypted keys
@subsection Managing encrypted keys
@cindex Encrypted keys

Transferring or storing private keys in plain may not be a
good idea, since any compromise is irreparable.
Storing the keys in hardware security modules (see @ref{Smart cards and HSMs})
could solve the storage problem but it is not always practical
or efficient enough. This section describes ways to store and
transfer encrypted private keys.

There are methods for key encryption, namely the
PKCS #8, PKCS #12 and OpenSSL's custom encrypted private key formats. 
The PKCS #8 and the OpenSSL's method allow encryption of the private key, 
while the PKCS #12 method allows, in addition, the bundling of accompanying 
data into the structure. That is typically the corresponding certificate, as 
well as a trusted CA certificate.

@subsubheading High level functionality
Generic and higher level private key import functions are available, that
import plain or encrypted keys and will auto-detect the encrypted key format.

@showfuncdesc{gnutls_privkey_import_x509_raw}

@showfuncdesc{gnutls_x509_privkey_import2}

Any keys imported using those functions can be imported to a certificate
credentials structure using @funcref{gnutls_certificate_set_key}, or alternatively
they can be directly imported using @funcref{gnutls_certificate_set_x509_key_file2}.

@subsubheading @acronym{PKCS} #8 structures
@cindex PKCS #8

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 @code{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.

@showfuncC{gnutls_x509_privkey_import_pkcs8,gnutls_x509_privkey_export_pkcs8,gnutls_x509_privkey_export2_pkcs8}

@showenumdesc{gnutls_pkcs_encrypt_flags_t,Encryption flags}

@subsubheading @acronym{PKCS} #12 structures
@cindex PKCS #12

A @acronym{PKCS} #12 structure @xcite{PKCS12} usually contains a user's
private keys and certificates. It is commonly used in browsers to
export and import the user's identities. A file containing such a key can 
be directly imported to a certificate credentials structure by using 
@funcref{gnutls_certificate_set_x509_simple_pkcs12_file}.

In @acronym{GnuTLS} the @acronym{PKCS} #12 structures are handled
using the @code{gnutls_pkcs12_t} type. This is an abstract type that
may hold several @code{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.

To reduce the complexity in parsing the structures the simple 
helper function @funcref{gnutls_pkcs12_simple_parse} is provided. For more
advanced uses, manual parsing of the structure is required using the
functions below.

@showfuncD{gnutls_pkcs12_get_bag,gnutls_pkcs12_verify_mac,gnutls_pkcs12_bag_decrypt,gnutls_pkcs12_bag_get_count}

@showfuncdesc{gnutls_pkcs12_simple_parse}
@showfuncC{gnutls_pkcs12_bag_get_data,gnutls_pkcs12_bag_get_key_id,gnutls_pkcs12_bag_get_friendly_name}

The functions below are used to generate a PKCS #12 structure. An example
of their usage is shown at @ref{PKCS12 structure generation example}.

@showfuncC{gnutls_pkcs12_set_bag,gnutls_pkcs12_bag_encrypt,gnutls_pkcs12_generate_mac}
@showfuncE{gnutls_pkcs12_bag_set_data,gnutls_pkcs12_bag_set_crl,gnutls_pkcs12_bag_set_crt,gnutls_pkcs12_bag_set_key_id,gnutls_pkcs12_bag_set_friendly_name}

@subsubheading OpenSSL encrypted keys
@cindex OpenSSL encrypted keys
Unfortunately the structures discussed in the previous sections are
not the only structures that may hold an encrypted private key. For example
the OpenSSL library offers a custom key encryption method. Those structures
are also supported in GnuTLS with @funcref{gnutls_x509_privkey_import_openssl}.

@showfuncdesc{gnutls_x509_privkey_import_openssl}

@include invoke-certtool.texi

@include invoke-ocsptool.texi

@include invoke-danetool.texi