Profiles¶
A profile defines default properties, including certificate extensions, for TLS certificates. These properties define who can use the certificate for what purpose, how a peer can validate it and what clients are compatible with the certificates.
django-ca defines a set of default profiles that should be sufficient for most use cases:
Name |
Purpose |
---|---|
|
Certificate can be used for TLS client authentication. |
|
Certificate can be used for TLS client authentication and code and email signing. |
|
Certificate can be used for a OCSP responder, marked as automatically generated by default. |
|
Certificate can be used for both a TLS server and a TLS client. |
|
(default) Certificate can be used for a TLS server but not for TLS client authentication. |
You can configure the default profile to use using the CA_DEFAULT_PROFILE setting. You can also add new profiles or modify existing ones using the CA_PROFILES setting.
Using profiles¶
You can use a profile when signing certificates:
When you use the command line:
$ python manage.py sign_cert --client ...
In the Web interface you can select a profile when adding a certificate.
In the Python API:
>>> from django_ca.models import Certificate >>> Certificate.objects.create_cert(ca, csr, profile='client')
or by even defining a temporary profile just for this certificate:
>>> from django_ca.profiles import Profile >>> prof = Profile(...) >>> Certificate.objects.create_cert(ca, csr, profile=prof)
Configure profiles¶
You can add new profiles with the CA_PROFILES setting. The setting a dictionary with the key identifying the certificate and the values configuring various aspects of certificates signed using this profile. A simple profile might look like this:
CA_PROFILES = {
'example': { # actually a duplicate of the predefined "client" profile
'description': _('An example profile.'),
'extensions': {
'key_usage': {'value': ['digitalSignature']},
'extended_key_usage': {'value': ['clientAuth']},
},
},
}
After defining a profile, it can be immediately used with the Python API, the Admin web interface (WSGI servers typically need to reload the code to see the new profile) or the command line:
$ python manage.py sign_cert -h
...
profiles:
Sign certificate based on the given profile. A profile only sets the the default values, options like --key-
usage still override the profile.
--client A certificate for a client.
--server A certificate for a server, allows client and server authentication.
--webserver A certificate for a webserver.
--enduser A certificate for an enduser, allows client authentication, code and email signing.
--ocsp A certificate for an OCSP responder.
--example An example profile.
Available options¶
There are many available options for a profile, of course all of them are optional:
Option |
Default |
Description |
---|---|---|
|
|
Set to |
|
|
Set to |
|
|
Set to |
|
|
Set to |
|
The algorithm used for signing, defaults to CA_DIGEST_ALGORITHM. |
|
|
|
Set to |
|
|
If the CommonName should be added as Subject Alternative Name. |
|
|
Informal text explaining what the profile is. |
|
A |
|
|
|
A dictionary of extensions to add. Please see below for more details. |
|
|
Set an alternative issuer name from the CA. Note that this will usually break any certificate validation, so this is definitely for experts only. |
|
The default subject to use, overrides CA_DEFAULT_SUBJECT. |
Configure extensions¶
Many extensions (such as the Authority Key Identifier and Basic Constraints extensions) are added by default
since they are required to create a useful certificate. Further extensions (such as the CRL Distribution
Points and Authority Information Access) are added depending on the values for the CA you are using and the
add_{...}_url
settings described below.
You can define any extension in a profile with a dictionary.
Use the key
from EXTENSION_KEYS
as a dictionary key and a dictionary as a
value describing the extension.
The dictionary has an optional critical
key. If it is not defined, the critical value will come from
EXTENSION_DEFAULT_CRITICAL
.
All extensions use a value
key to describe the extension value. It is usually a dict
for convenience,
but can also be a Extension
or ExtensionType
for convenience (or special cases). For example, for the Key
Usage extension, use:
CA_PROFILES = {
'example': {
# ...
'extensions': {
'key_usage': {
'critical': False, # usually critical, but not here for some reason
'value': ['digitalSignature']
},
},
},
}
Find how to specify the value
key for the most important extensions below.
Certificate Policies¶
Note
Configuring a Certificate Policies extension in a profile is currently the only way to add this extension to a certificate.
The value
is a list of dicts describing the policy information. Each dict has the mandatory
policy_identifier
key that names an Object Identifier as dotted string. The policy_qualifiers
object
is optional and a list of policy qualifiers.
A policy_qualifiers
item is either a string, or a dict describing a user notice. A user notice is a dict
with the optional explicit_text
key with a string value and the optional notice_reference
key
describing a notice reference. A notice_reference
is a dict with the optional organization
key as a
string, and the notice_numbers
key as a list of integers.
Example:
[
{"policy_identifier": "1.1.1"},
{
"policy_identifier": "1.3.3",
"policy_qualifiers": [
"A policy qualifier as a string",
{
"explicit_text": "An explicit text",
"notice_reference": {
"organization": "some org",
"notice_numbers": [1, 2, 3],
}
},
],
},
]
CRL Distribution Points¶
The value
is a list of dicts describing distribution points. Each distribution point has either a
full_name
or a relative_name
key (they are mutually exclusive). full_name
is a list of names as
described in Names on the command-line, relative_name
is a string with a relative name, e.g.
/CN=example.com
. A distribution point may also have a list of names in crl_issuers
and a list of
reasons in reasons
as named in ReasonFlags
.
Please note that in practice, the extension typically only uses a single full_name
entry, all other
values are not used:
[{'full_name': ['URI:http://crl.example.com']}]
Here is a full example:
[
{
'full_name': ['URI:http://crl1.example.com', 'URI:http://crl2.example.com'],
'crl_issuer': ['URI:http://crl-issuer.example.com'],
'reasons': ['key_compromise'],
}
]
It is unusual to specify this extension in a profile, as the values should come from the certificate
authority. If you do specify it, it will be merged with values from the certificate authority if you create a
certificate from the command line or via ACMEv2 (unless the profile specifies add_crl_url=False
).
If you create a certificate via the admin interface, selecting the profile will set the value for this
extension (profiles are only used to fill the form, not when actually signing the certificate).
Extended Key Usage¶
The value
is a list of extended key usages as defined in RFC 5280, section 4.2.1.12. Example:
["serverAuth", "clientAuth"]
Freshest CRL¶
The syntax is the same as for the CRL Distribution Points extension.
Key Usage¶
The value
is a list of key usages as defined in RFC 5280, section 4.2.1.3. Example:
["digitalSignature", "keyEncipherment"]
OCSP No Check¶
The value
is optional, as the extension has no value (besides being present).
TLS Feature¶
The value
is a list of features as defined in RFC 7633
<https://datatracker.ietf.org/doc/html/rfc7633.html (so status_request
and status_request_v2
). For
convenience, OCSPMustStaple
and MultipleCertStatusRequest
is also supported. Example:
["OCSPMustStaple"]
The add_..._url
settings¶
By default, certificates will include some extensions based on the CA used to sign it. The CA usually defines
CRL and OCSP URLs that can be used to retrieve information if the certificate is still valid. This is usually
what you want, but there are some exceptions. For example, a certificate for an OCSP responder should not
include the OCSP URL, as it makes no sense to validate the OCSP responder certificate using the OCSP responder
itself. The ocsp
profile thus already sets add_ocsp_url
to False
.
If your profile defines a CRL Distribution Points or Authority Information Access extension, CRL, OCSP and
Issuer URLs from the CA will be appended if the add_..._url
setting is True
.
Update existing profile¶
You can update an existing profile the same way as configuring a new profile. Any values will replace existing
values. To update the default subject for the (predefined) enduser
profile:
CA_PROFILES = {
'enduser': {
'subject': '/C=AT/L=Vienna/', # base for the subject when creating a new cert
},
}
Note that django-ca also replaces the whole extensions
value. That means you cannot update one extension
from the profile, you’ll have to specify all extensions.
Remove a profile¶
You can remove a predefined profile by just setting the value to None
:
CA_PROFILES = {
'client': None # we really don't need this one
}