diff options
Diffstat (limited to 'doc/cha-cert-auth2.texi')
-rw-r--r-- | doc/cha-cert-auth2.texi | 452 |
1 files changed, 452 insertions, 0 deletions
diff --git a/doc/cha-cert-auth2.texi b/doc/cha-cert-auth2.texi new file mode 100644 index 0000000..e325b61 --- /dev/null +++ b/doc/cha-cert-auth2.texi @@ -0,0 +1,452 @@ +@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 |