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 Web interface, if it has access to the private key of the certificate authority.

Index of commands

To manage certificate, use the following 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 manage.py subcommands, you can run manage.py <subcomand> -h to get a list of available parameters.

Signing certificates

Signing certificates is done using 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 (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:

$ 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:

$ 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:

$ 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 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:

$ python manage.py sign_cert --alt example.com --csr example.csr --out example.pub --client

Please see 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.

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 subjectAltName:

$ 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 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 names, so you can also use e.g.:

$ python manage.py sign_cert --alt IP:127.0.0.1

You can also disable adding the CommonName as subjectAlternativeName:

$ 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 ASN1_GENERATE_NCONF(3SSL):

$ 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 CA_PROFILES setting. The default profile is configured by the CA_DEFAULT_PROFILE setting.

Override extensions

You can override some extensions using command-line parameters. Currently, this includes keyUsage, extendedKeyUsage and TLSFeature. In every case, prefixing the value with critical marks the extension as critical (meaning a TLS client that does not understand the extension will reject the connection):

$ python manage.py sign_cert \
   --key-usage critical,keyCertSign \
   --ext-key-usage serverAuth,clientAuth \
   --tls-feature OCSPMustStaple \
   ...

For more information on these extensions, their meaning and typical values, see x509 extensions.

Revoke certificates

To revoke a certificate, use:

$ 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:

$ python manage.py --sign-cert --watch user@example.com --watch user@example.net ...

Or modify to add/remove watchers later:

$ 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