##################### Managing certificates ##################### All certificate operations can be done via the command line. You do not have to use this interface, all functionality is also available via the :doc:`/web_interface`, if it has access to the private key of the certificate authority. ***************** Index of commands ***************** To manage certificate, use the following :command:`manage.py` commands: ===================== =============================================================== Command Description ===================== =============================================================== cert_watchers Add/remove addresses to be notified of an expiring certificate. dump_cert Dump a certificate to a file. import_cert Import an existing certificate. list_certs List all certificates. notify_expiring_certs Send notifications about expiring certificates to watchers. revoke_cert Revoke a certificate. sign_cert Sign a certificate. view_cert View a certificate. ===================== =============================================================== Like all :command:`manage.py` subcommands, you can run ``manage.py -h`` to get a list of available parameters. .. _cli_sign_certs: ******************** Signing certificates ******************** Signing certificates is done using :command:`manage.py sign_cert`. The only requirements are that you provide either a full subject and/or one or more alternative names. Obviously, you also need to create at least one certificate authority first (:doc:`documentation `). Like any good certificate authority, **django-ca** never handles private keys of signed certificates. Instead, you sign certificates from a Certificate Signing Request (CSR) that you generate from the private key. Using the OpenSSL command-line tools, you can create a CSR *on the host that should use the certificate*: .. code-block:: console $ openssl genrsa -out example.key 4096 $ openssl req -new -key example.key -out example.csr -utf8 Next, simply copy the CSR file (``example.csr`` in the above example) to the host where you installed **django-ca**. You can now create a signed certificate using: .. code-block:: console $ python manage.py sign_cert --alt example.com --csr example.csr --out example.pub If you have defined multiple CAs, you also have to name the CA: .. code-block:: console $ python manage.py list_cas 4E:1E:2A:29:F9:4C:45:CF:12:2F:2B:17:9E:BF:D4:80:29:C6:37:C7 - Root CA 32:BE:A9:E8:7E:21:BF:3E:E9:A1:F3:F9:E4:06:14:B4:C4:9D:B2:6C - Child CA $ python manage.py sign_cert --ca 32:BE:A9 --alt example.com --csr example.csr --out example.pub Profiles ======== Use :doc:`profiles ` to configure how your certificates can be used. You can set a profile by simply passing it via the command-line. For example, to use the **client** profile: .. code-block:: console $ python manage.py sign_cert --alt example.com --csr example.csr --out example.pub --client Please see :doc:`the documentation ` the documentation on what profiles are available and how you can update existing profiles and even add new ones. Subject and alternative names ============================= The certificate's subject (that is, it's CommonName) and the names given in the ``SubjectAlternativeName`` extension define where the certificate is valid. For format for subjects is documented at :ref:`subjects_on_cli`, the format used for names in the ``SubjectAlternativeName`` name extension is described in :ref:`names_on_cli`. The CommonName is usually added to the ``SubjectAlternativeName`` extension as well and vice versa. This means that these two will give the same CommonName and ``SubjectAlternativeName``: .. code-block:: console $ python manage.py sign_cert --subject C=AT,...,CN=example.com $ python manage.py sign_cert --alt example.com A given CommonName is only added to the ``SubjectAlternativeName`` extension if it is a valid :ref:`name `. If you give multiple names via ``--alt`` but no CommonName, the first one will be used as CommonName. Names passed via ``--alt`` are parsed as :ref:`names `, so you can also use e.g.: .. code-block:: console $ python manage.py sign_cert --alt IP:127.0.0.1 You can also disable adding the CommonName as ``subjectAlternativeName``: .. code-block:: console $ python manage.py sign_cert --cn-not-in-san --subject C=AT,...,CN=example.com --alt=example.net ... this will only have "example.net" but not example.com as ``subjectAlternativeName``. Advanced subject alternative names ---------------------------------- You can add ``OtherName`` values to ``SubjectAlternativeName`` via the same format used by OpenSSL described in :manpage:`ASN1_GENERATE_NCONF(3SSL)`: .. code-block:: console $ python manage.py sign_cert --subject CN=example.com --alt="otherName:1.3.6.1.4.1.311.20.2.3;UTF8:dummy@domain.tld" Note that currently only UTF8 strings are supported. Using profiles ============== Certificates have extensions that define certain aspects of how/why/where/when a certificate can be used. Some extensions are added based on how the Certificate Authority is configured, e.g. CRL/OCSP URLs. Extensions that define for what purposes are a certificate can be used can be configured on a per-certificate basis. The easiest way is to use profiles that define what extensions are added to any certificate. **django-ca** adds these predefined profiles: ============== ========================================================================================== Name Purpose ============== ========================================================================================== ``client`` Allows the certificate to be used on the client-side of a TLS connection. ``server`` Allows the certificate to be used on the client- and server-side of a connections. ``enduser`` Allows client authentication and code and email signing. ``webserver`` Allows only the server-side of a TLS connection, it can't be used as a client certificate. ``ocsp`` Allows the certificate to be used for signing OCSP responses. ============== ========================================================================================== You can add and modify profiles using the :ref:`CA_PROFILES ` setting. The default profile is configured by the :ref:`CA_DEFAULT_PROFILE ` setting. Signature hash algorithms ========================= When using a certificate authority based on an RSA and Elliptic Curve (EC) private key, you can override the signature hash algorithm used for signing the certificate with the ``--algorithm`` parameter. By default, the hash algorithm that was used to sign the certificate authority will be used. See :py:attr:`~django_ca.typehints.HashAlgorithms` for a list of supported hash algorithms. For example, to sign a certificate using SHA-384: .. code-block:: console $ python manage.py sign_cert --algorithm=SHA-384 ... Certificate authorities that use an Ed448- or Ed25519-based private key, do not use a hash algorithm when signing certificates, so an error will be raised if you pass the ``--algorithm`` option with such certificate authorities. .. _override-extensions: Override extensions =================== You can add custom extensions to the certificate in the command-line. The syntax is generally the same as :ref:`for certificate authorities `, however you can only add extensions that make sense in the context of an end-entity certificate (for example, RFC 5280 specifies that the Name Constraints extension can occur only in CA certificates). When you add extensions via the command-line, they will override any extension set by profiles or by the certificate authority. For example, to set a custom OCSP responder in a certificate:: $ python manage.py sign_cert --ocsp-responder http://ocsp.example.com ... Note again that this will disable the OCSP responder that usually would be set based on the certificate authority. :ref:`cli_cas_string_formatting` can be used in the same way as with certificate authorities. For example, to use the default URIs in addition to your own endpoint(s), you can use the ``CRL_PATH`` variable:: $ python manage.py sign_cert \ > --crl-full-name http://example.com/{CRL_PATH} \ > --crl-full-name ... \ > ... ******************* Revoke certificates ******************* To revoke a certificate, use: .. code-block:: console $ python manage.py list_certs 49:BC:F2:FE:FA:31:03:B6:E0:CC:3D:16:93:4E:2D:B0:8A:D2:C5:87 - localhost (expires: 2019-04-18) ... $ python manage.py revoke_cert 49:BC:F2:FE:FA:31:03:B6:E0:CC:3D:16:93:4E:2D:B0:8A:D2:C5:87 ********************* Expiring certificates ********************* You can add email addresses to be notified of expiring certificates using the ``--watch`` parameter: .. code-block:: console $ python manage.py --sign-cert --watch user@example.com --watch user@example.net ... Or modify to add/remove watchers later: .. code-block:: console $ python manage.py list_certs 49:BC:F2:FE:FA:31:03:B6:E0:CC:3D:16:93:4E:2D:B0:8A:D2:C5:87 - localhost (expires: 2019-04-18) ... $ python manage.py cert_watchers -a add@example.com -r user@example.net 49:BC:F2