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 <subcommand> -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.

For format for subjects is documented at Subjects on the command-line, the format used for names in the SubjectAlternativeName name extension is described in Names on the command-line.

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:

$ python manage.py sign_cert --subject-format=rfc4514 --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-format=rfc4514 --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-format=rfc4514 --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.

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 HASH_ALGORITHM_NAMES for a list of supported hash algorithms.

For example, to sign a certificate using SHA-384:

$ 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

You can add custom extensions to the certificate in the command-line. The syntax is generally the same as 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.

String formatting in URIs 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:

$ 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