X.509 (in this document referred as x509) is an ITU standard to describe certificates. This article provides an overview of what these are and how they work.
Three versions of the x509 standard have been defined for web-pki. In this document we will be referring to the current standard in use for web pki: x509 v3, which is described in detail in RFC 5280. In general, x509 certificates bind a signature to a validity period, a public key, a subject, an issuer, and a set of extensions. The extensions define extra properties of the certificate such as extra attributes of the certificate or constraints on the use of the certificate. In order for a certificate to be valid these three requirements must be met:
One issue that is not commonly known is that the x509 trust graph is not a forest (a bunch of trees where each root is a trusted root) but a cyclic graph, where the same key/issuer can be a root or an intermediate for another root in the browsers key store (when roots create intermediates for each other it is called cross-signing).
While RFC 5280 defines 16 extensions for webpki in this document we will be describing the six extensions we considered critical for understanding. Certificates can have other extensions not described on RFC 5280, but that is out of the scope of this document. Extensions can be marked as critical or non-critical, conforming certificate verification libraries should stop processing verification when encountering a critical extension that they do not understand ( and should continue processing if the extension is marked as non-critical) mozila::pkix has this behavior.
This extension defines what other names (such as DNS names) are valid for this certificate. This allows for a certificate to be used for more than one FQDN, for example you can have a certificate that is valid for both a.example.com and b.example.com
This allows certificates to be asserted as issuing certificates (it is mandatory for CA certificates). It can also be used to express the maximum depth of the trust path from the CA.
This extension is used to constrain the purpose for the key in the certificate. More than one key usage can be asserted. Examples of key usages are: digitalSignature
, keyEncipherment
, dataEncipherment
, keyCertSign
, and cRLSign
. For CA certificates the keyCertSign
bit must be set.
This is another bitfield to constrain the usages of the key of the certificate. Its is directed mostly at what type of application the certificate was issued for. Examples of extended key usages are: serverAuth
, clientAuth
, and OCSPSigning
. For end-entity certificates for PKI this extension is required to exist with the serverAuth
bit asserted.
This is an extension exclusive for CA and indicates limits on the name space for its children. This is one of the most powerful extensions for businesses to have to help limit risk imposed by losing the private key of the CA.
This extension is primarily used to to describe the OCSP location for revocation checking. It is mandatory for certificates that chain up to a root in the Mozilla CA program.
These are the steps to generate a certificate for www.example.com. Replace this value with the actual server name in the steps below.
1. Generate the key using the following command:
openssl genpkey -algorithm RSA -out key.pem -pkeyopt rsa_keygen_bits:2048
2. Generate CSR using this command:
openssl req -new -key key.pem -days 1096 -extensions v3_ca -batch -out example.csr -utf8 -subj '/CN=www.example.com'
3. Write extensions file by creating a new file with name openssl.ss.cnf
with the following contents:
4. Self-sign csr (using SHA256) and append the extensions described in the file
You can now use example.pem as your certfile
When you visit a secure website, Firefox will validate the website’s certificate by checking that the certificate that signed it is valid, and checking that the certificate that signed the parent certificate is valid and so forth up to a root certificate that is known to be valid. This chain of certificates is called the Certificate Hierarchy.
If your certificates will only be used to verify one domain (e.g. *.yourcompany.com) but you want others outside of your organization to be able to browse to your website using https without having to manually import a root certificate, then you can get an SSL certificate from one of the CAs who already have a root certificate included in the major browsers.
Firefox uses a default set of X.509v3 root certificates for various Certification Authorities (CAs). The root certificates included by default have their "trust bits" set to indicate if the CA's root certificates may be used to verify certificates for SSL servers, S/MIME email users, and/or digitally-signed code objects without having to ask users for further permission or information.
CAs apply to have their root certificates included by default in Mozilla products by following the Mozilla CA Certificate Policy and applying for inclusion as per CA:How_to_apply. Users may override the default root certificate settings using the Certificate Manager.
Some organizations make use of the set of CAs included in Mozilla's products. If you wish to do this, you should read the relevant part of the Mozilla CA FAQ before doing so.
If you are going to have your own CA, we recommend building 3 certificates: a long term root cert, a medium term intermediate cert, and a short term end-entity cert. This type of hierarchy allows for a relatively simple long term root to be distributed to clients, and some flexibility on the intermediate cert so that you can change parameters based on best practices and security research.
Update *.example.com and *.example.net below to match your domains.
Assumptions:
Steps to generate your CA root certificate:
Now you have CA pem file with its associated key.
The following steps create an intermediate cert that is valid for 8 years.
Update www.example.com below to match your domain.
There are several organizations that provide recommendations regarding the security parameters for key/hash sizes given current computational power. For the end date of the root cert created following the instructions in this page (year 2017). These are the recomendations of bit sizes (from http://www.keylength.com/):
Asymmetric | ECC(Key) | Hash | |
---|---|---|---|
Linestra(2004) | 1902 | 172 | 172 |
Ecrypt 2012 | 2432 | 224 | 224 |
NIST 2012 | 2048 | 224 | 224 |
ANSSI 2010 | 4096 | 200 | 256 |
RFC 3766 | 2358 | 200 | --- |
BSI | 1976 | 256 | 256 |
In other words, SHA1 is now deprecated for new uses. We should use at least 3072 key sizes and at least a 256 ECC curve. Thus the recommendation here is for the root to be 4096 if using RSA and p384 for the root key. (p384 also chosen for compatibility as most SSL/TLS implementations support this part of suite B).
Here are some common errors that might be encountered when working with certificates in Firefox.
Error Code | What It Means | What Can I Do |
---|---|---|
SEC_ERROR_BAD_DER | A certificate is not properly encoded according to ASN.1 (DER) encoding | Re-generate the improperly-encoded certificate |
SEC_ERROR_CA_CERT_INVALID | An end-entity certificate is being used to issue another certificate | Ensure that any certificate intended to issue certificates has a basic constraints extension with cA: TRUE |
SEC_ERROR_BAD_SIGNATURE | A signature on a certificate is improperly formatted or the certificate has been tampered with | Re-issue the certificate with the bad signature |
SEC_ERROR_CERT_BAD_ACCESS_LOCATION | The OCSP URI in the authorityInformationAccess extension is improperly formed | Re-generate the certificate with a well-formed OCSP URI |
SEC_ERROR_CERT_NOT_IN_NAME_SPACE | A certificate has a common name or subject alternative name that is not in the namespace of an issuing certificate | Re-issue the certificate with names that are within the namespace of all certificates in the chain |
SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED | A certificate has been signed with an obsolete algorithm | Re-sign the certificate using a modern algorithm |
SEC_ERROR_EXPIRED_CERTIFICATE | A certificate is too old to be used | Re-generate the certificate |
SEC_ERROR_EXTENSION_VALUE_INVALID | A certificate has an extension with an empty value | Re-generate the certificate without the extension, or re-generate it with a non-empty value |
SEC_ERROR_INADEQUATE_CERT_TYPE | A certificate has an extended key usage extension that does not assert a required usage, or an end-entity certificate asserts the id-kp-OCSPSigning usage when it shouldn't | Re-generate the certificate with the appropriate extended key usage values |
SEC_ERROR_INADEQUATE_KEY_USAGE | A certificate has a key usage extension that does not assert a required usage | Re-generate the certificate with the appropriate key usage values |
SEC_ERROR_INVALID_ALGORITHM | A certificate has been signed with an unknown algorithm | Re-sign the certificate with a standardized certificate signing algorithm |
SEC_ERROR_INVALID_TIME | A time field in a certificate has an invalid value | Re-generate the certificate with valid encodings for time fields |
MOZILLA_PKIX_ERROR_KEY_PINNING_FAILURE | ||
SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID | ||
SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION | A certificate contains an extension marked as critical that is not handled by mozilla::pkix | Re-generate the certificate without the extension or with it not marked as critical |
SEC_ERROR_UNKNOWN_ISSUER | Either a missing intermediate or root certificate is necessary to verify the certificate | Import the root certificate into Firefox or have the server send the intermediate |
SEC_ERROR_INVALID_KEY | ||
SEC_ERROR_UNSUPPORTED_KEYALG | ||
SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE | An issuer certificate is too old | Re-issue the issuer certificate |
MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY | A certificate with a basic constraints extension with cA:TRUE is being used as an end-entity certificate | Re-generate the end-entity certificate without the basic constraints extension |
MOZILLA_PKIX_ERROR_INADEQUATE_KEY_SIZE | A certificate has a key that is too small to be secure | Re-generate a larger key and issue a certificate using that key |