/*!

\page dcmtls_certstore certificate and certification authority management in dcmtls

\section dcmtls_certstore_system_cert System certificate and private key

The TLS protocol requires that a server (that is, an application that accepts
incoming TLS network connections) \b must identify itself cryptographically
using a certificate and a private key, whereas a client (an application that
initiates outgoing TLS network connections) \b may identify itself using a
certificate and a private key, or may remain anonymous.

All DCMTK tools that support TLS encrypted network connections offer command
line options for selecting unencrypted network communication, TLS with
certificates, or (in the case of client applications) TLS in anonymous mode:

\verbatim
  -tls  --disable-tls
          use normal TCP/IP connection (default)

  +tls  --enable-tls  [p]rivate key file, [c]ertificate file: string
          use authenticated secure TLS connection

  +tla  --anonymous-tls
          use secure TLS connection without certificate
\endverbatim

Two different file formats are supported for certificates, private keys and
other cryptographic material: The text-based PEM ("Privacy Enhanced Mail")
format, which is the default, and binary ASN.1 files in DER encoding
("Distinguished Encoding Rules"). The file format can be selected through the
following options:

\verbatim
  -pem  --pem-keys
          read keys and certificates as PEM file (default)

  -der  --der-keys
          read keys and certificates as DER file
\endverbatim

Note that the PEM format supports multiple certificates in a single file, which
is an important feature when certificates issued by an intermediate CA are used
with TLS. The DER format only supports a single certificate per file.

In many cases, the private key is stored in encrypted form and a password is
needed to decrypt the private key file. In this case the following options are
provided:

\verbatim
  +ps   --std-passwd
          prompt user to type password on stdin (default)

  +pw   --use-passwd  [p]assword: string
          use password specified on the command line

  -pw   --null-passwd
          use empty string as password
\endverbatim

\section dcmtls_certstore_security_profiles Security profiles

The DICOM standard defines a number of security profiles for the use of the
DICOM network protocol over TLS. DCMTK supports the following profiles:

\verbatim
  +pg   --profile-8996
          BCP 195 RFC 8996 TLS Profile (default)

  +pm   --profile-8996-mod
          Modified BCP 195 RFC 8996 TLS Profile

          # only available if underlying TLS library supports
          # all TLS features required for this profile

  +py   --profile-bcp195-nd
          Non-downgrading BCP 195 TLS Profile (retired)

  +px   --profile-bcp195
          BCP 195 TLS Profile (retired)

  +pz   --profile-bcp195-ex
          Extended BCP 195 TLS Profile (retired)

  +pb   --profile-basic
          Basic TLS Secure Transport Connection Profile (retired)

          # only available if underlying TLS library supports 3DES

  +pa   --profile-aes
          AES TLS Secure Transport Connection Profile (retired)

  +pn   --profile-null
          Authenticated unencrypted communication
          (retired, was used in IHE ATNA)
\endverbatim

The BCP 195 RFC 8996 TLS Profile, which is selected by default, is a secure
choice while providing backward compatibility with the earlier BCP 195 profiles.
It does not support backward compatibility with the older profiles.
It uses either TLS version 1.2 or 1.3 and will default to TLS 1.3 when possible.

The Modified BCP 195 RFC 8996 TLS Profile, which adds further constraints
compared to the BCP 195 RFC 8996 TLS Profile, cannot be implemented with
OpenSSL 1.0.2 to 3.0.x because it requires support for the TLS 1.2 Camellia
ciphersuites in GCM mode, which is not available in OpenSSL. Should future
OpenSSL releases add support for these ciphersuites, then this option will
automatically be enabled when compiling DCMTK.

The Non-downgrading BCP 195 TLS Profile, which was the default in DCMTK 3.6.7,
also disables older protocol versions and cipher suites. It does, however,
support DHE ciphersuites, whereas RFC 9325 recommends that these should not
be used. It uses either TLS version 1.2 or 1.3 and will default to TLS 1.3
when possible.

The BCP 195 TLS Profile, which was the default up to DCMTK 3.6.6, will try to
negotiate cryptographic algorithms that are currently considered secure, but
provides backward compatibility to older applications implementing the retired
AES or Basic TLS profile. This profile is no longer compliant with BCP 195 as
amended by RFC 8996 (2021).

The Extended BCP 195 TLS Profile is similar to the Non-downgrading BCP 195 TLS
Profile, but uses a more restricted selection of cipher suites and is restricted
to TLS version 1.2.

The AES TLS Secure Transport Connection Profile uses AES encryption and TLS
version 1.0 and newer and has been retired from the DICOM standard. It should
only be used where backward compatibility with devices implementing this profile
is required.

The Basic TLS Secure Transport Connection Profile uses Triple DES encryption
and TLS version 1.0 and newer and has also been retired from the DICOM standard.
It should only be used where backward compatibility with devices implementing
this profile is required, in particular since the effective key length of 112
bits is not sufficiently secure against brute force attacks anymore.

Authenticated unencrypted communication finally is a retired profile that was
defined in older versions of the IHE Audit Trail and Node Authentication
profile. It uses an unencrypted communication with cryptographic checksums.
This profile should be avoided.

It should be noted that support for the Basic TLS profile will only be available
when the OpenSSL library has been compiled such that support for Triple DES is
enabled, which is not the default anymore.

The list of TLS ciphersuites offered during the TLS handshake can be extended
using the following option:

\verbatim
  +cs   --cipher  [c]iphersuite name: string
          add ciphersuite to list of negotiated suites
\endverbatim

The list of supported TLS 1.0-1.2 ciphersuites can be printed
using the following option:

\verbatim
  +cc   --list-ciphers
          show list of supported TLS ciphersuites and exit
\endverbatim

Option \c \--cipher can be specified more than once to add multiple
ciphersuites.

\section dcmtls_certstore_peer_authentication Peer authentication

By default, the TLS implementation in dcmtls will require both client and server
to provide a certificate as proof of identity, and will verify the validity and
trustworthiness of the certificate. This process has several steps:

\li The TLS handshake will require a proof that the application has access to
    the private key belonging to the public key encoded in the certificate.
\li The digital signature in the certificate will be verified.
\li The validity period of the certificate will be checked.
\li It will be checked whether the certificate was issued by a trusted
    Certification Authority (CA) (see \ref dcmtls_certstore_certification_authority).
\li Depending on the command line options, the Certificate Revocation Lists
    (CRLs) of all CAs up to the root CA may be checked to see if any certificate
    in the certificate chain has been revoked (see \ref dcmtls_certstore_crl).

This behavior can be modified with the following command line options:

\verbatim
  -rc   --require-peer-cert
          verify peer certificate, fail if absent (default)

  -vc   --verify-peer-cert
          verify peer certificate if present

  -ic   --ignore-peer-cert
          don't verify peer certificate
\endverbatim

The first option will cause the connection to fail if the peer does not present
a certificate (i.e. is working in anonymous mode) or if the certificate cannot
be fully verified. The second option will perform a certificate verification if
a certificate is present, but will also accept anonymous connections. The third
option does not perform any certificate verification and also accepts anonymous
connections.

It should be noted that the latter two modes are susceptible to
man-in-the-middle attacks and should thus be avoided.

The \c \--verify-peer-cert option is not available in client applications,
since TLS servers will always present a certificate.

\section dcmtls_certstore_certification_authority Certification authority

All tools in DCMTK that support TLS encrypted network connections need to have
a list of trusted root certificates (i.e. self-signed certificates) that are
used in the verification of the peer certificate when establishing the TLS
connection.

There are two ways of managing this list of trusted certificates: file-based and
directory-based. The command line tools in DCMTK offer the following command
line options for this purpose:

\verbatim
  certification authority:
    +cf   --add-cert-file  [f]ilename: string
            add certificate file to list of certificates

    +cd   --add-cert-dir  [d]irectory: string
            add certificates in d to list of certificates
\endverbatim

Both options can be specified more than once, also in combination.

\subsection dcmtls_certstore_certification_authority_file File-based management of trusted root certificates

The file-based option loads a file and adds all the certificates or CRLs present
in that file into the pool of trusted certificates. File format is ASCII text
containing concatenated PEM certificates and CRLs, unless ASN.1 DER format has
been selected.

\subsection dcmtls_certstore_certification_authority_dir Directory-based management of trusted root certificates

The directory-based option specifies a directory containing certificates and
CRLs. These certificates and CRLs are loaded on demand, and cached in memory
once they are loaded.

The directory should contain one certificate or CRL per file in PEM format, with
a file name of the form hash.N for a certificate, or hash.rN for a CRL. The hash
is computed from the subject name (for certificates) or the issuer name (for
CRLs). The hash value can be obtained by calling the openssl command line tool:

\verbatim
  openssl x509 -hash -noout -in <infile.pem>
\endverbatim

where <infile.pem> should be replaced by the filename of the certificate or CRL.

The .N or .rN suffix is a sequence number that starts at zero, and is
incremented consecutively for each certificate or CRL with the same hash value.
Gaps in the sequence numbers are not supported, it is assumed that there are no
more objects with the same hash beyond the first missing number in the sequence.

Sequence numbers make it possible for the directory to contain multiple
certificates with same subject name hash value. For example, it is possible to
have in the store several certificates with same subject or several CRLs with
same issuer (and, for example, different validity period).

\subsection dcmtls_certstore_certification_authority_intermed Intermediate CAs

In many cases, the system certificates are not directly signed by a root CA
(that is, a CA using a self-signed certificate), but by an intermediate CA. The
certificate of the intermediate CA will be signed by the root CA (or another
level of intermediate CA).

In the TLS handshake, an application can provide more than one certificate: it
can provide its certificate, followed by the certificates of any intermediate
CAs up to and optionally including the root CA certificate.

DCMTK tools will provide such intermediate certificates during the TLS handshake
if they are present in the same file as the system certificate, which is
provided as the second parameter of the \c \--enable-tls option. This requires
the use of the PEM format, since DER does not support multiple certificates in
one file.

The PEM format allows the certificates to simply be concatenated in a text file,
starting with the system certificate, followed by intermediate CA certificates
and optionally the root CA certificate. On Linux/Posix systems, such a file may
be created as follows:

\verbatim
  cat system_cert.pem intermediate_ca.pem root_ca.pem > fullchain.pem
\endverbatim

Users using LetsEncrypt certificates will notice that LetsEncrypt automatically
provides a "fullchain.pem" file containing such a certificate chain.

The certificates defined as trustworthy using \c \--add-cert-file or
\c \--add-cert-dir can only be root CA certificates. It is not possible to add
intermediate CA certificates to the "trust store".

\section dcmtls_certstore_crl Certificate revocation lists

The last, optional step in certificate verification is the look-up of the
certificate revocation lists (CRLs) to check whether any certificate in the
certificate chain has been revoked. CRLs cannot be transmitted in the TLS
handshake, they must be pre-configured, and it should be noted that CRLs also
have a limited validity period, defined in the file.

The following CRL options are available starting with DCMTK 3.6.7:

\verbatim
  +crl  --add-crl-file  [f]ilename: string
          add certificate revocation list file (implies --enable-crl-vfy)

  +crv  --enable-crl-vfy
          enable leaf CRL verification

  +cra  --enable-crl-all
          enable full chain CRL verification
\endverbatim

The \c \--add-crl-file option will load a CRL file that can be used for CRL
look-up. This option can be specified more than once. Alternatively, CRL files
can be located in the CA directory specified with \c \--add-cert-dir. See
\ref dcmtls_certstore_certification_authority_dir for a discussion of how CRL
files must be named in this case.

The \c \--enable-crl-vfy option will enable a look-up of the CRL of the leaf CA,
i.e. only a single CRL will be checked in order to determine whether or not the
peer's system certificate is revoked. The \c \--enable-crl-all option will
enable a look-up of all CRLs up to the root CA, which will also cover the case
where an intermediate CA certificate has been revoked.

Once CRL verification has been enabled, certificate verification will fail if
one of the required CRLs is absent.

*/
