@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