aboutsummaryrefslogtreecommitdiff
path: root/files/es/mozilla/security/x509_certificates/index.html
blob: cdad565f6d76af0fd4a3e3f05c286d84437af031 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
---
title: A Web PKI x509 certificate primer
slug: Mozilla/Security/x509_Certificates
translation_of: Mozilla/Security/x509_Certificates
---
<p><span class="seoSummary">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.</span></p>

<p>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:</p>

<ol>
 <li>There is a verification path from the site certificate to a trusted certificate of the user agent (ie if you follow the issuer path you will end on a self-signed certificate that is considered trusted by the browser).</li>
 <li>The attributes of the certificates in the verification path have valid parameters for that verification (for example the validity period of all the certificates are valid for the time the verification is being done)</li>
 <li>Revocation checks are considered OK for that particular validation.</li>
</ol>

<p>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).</p>

<h2 id="Extensions_2"><span class="mw-headline" id="Extensions">Extensions</span></h2>

<p>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.</p>

<h3 id="Subject_alternate_name"><span class="mw-headline" id="Subject_Alternate_Name">Subject alternate name</span></h3>

<p>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 <a class="external text" href="http://www.tech-faq.com/fqdn.html" rel="nofollow">FQDN</a>, for example you can have a certificate that is valid for both a.example.com and b.example.com</p>

<h3 id="Basic_constraints"><span class="mw-headline" id="Basic_Constraints">Basic constraints</span></h3>

<p>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.</p>

<h3 id="Key_usage"><span class="mw-headline" id="Key_Usage">Key usage</span></h3>

<p>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: <code>digitalSignature</code>, <code>keyEncipherment</code>, <code>dataEncipherment</code>, <code>keyCertSign</code>, and <code>cRLSign</code>. For CA certificates the <code>keyCertSign</code> bit <strong>must</strong> be set.</p>

<h3 id="Extended_key_usages"><span class="mw-headline" id="Extended_Key_Usages">Extended key usages</span></h3>

<p>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: <code>serverAuth</code>, <code>clientAuth</code>, and <code>OCSPSigning</code>. For end-entity certificates for PKI this extension is required to exist with the <code>serverAuth</code> bit asserted.</p>

<h3 id="Name_constraints"><span class="mw-headline" id="Name_Constraints">Name constraints</span></h3>

<p>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.</p>

<h3 id="Authority_information_access"><span class="mw-headline" id="Authority_Information_Access">Authority information access</span></h3>

<p>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.</p>

<h2 id="Self-signed_certificates"><span class="mw-headline" id="Self_Signed_Certs">Self-signed certificates</span></h2>

<p>These are the steps to generate a certificate for www.example.com. Replace this value with the actual server name in the steps below.<br>
 1. Generate the key using the following command:</p>

<ul>
 <li><code>openssl genpkey -algorithm RSA -out key.pem -pkeyopt rsa_keygen_bits:2048</code></li>
 <li>2048 is considered secure for the next 4 years.</li>
</ul>

<dl>
</dl>

<p>2. Generate CSR using this command:</p>

<ul>
 <li><code>openssl req -new -key key.pem -days 1096 -extensions v3_ca -batch -out example.csr -utf8 -subj '/CN=www.example.com'</code></li>
 <li>This creates a new Certificate Signing Request (CSR) that will be valid for 3 years.</li>
</ul>

<dl>
</dl>

<p>3. Write extensions file by creating a new file with name <code>openssl.ss.cnf</code> with the following contents:</p>

<ul>
 <li>basicConstraints = CA:FALSE</li>
 <li>subjectAltName =DNS:www.example.com</li>
 <li>extendedKeyUsage =serverAuth</li>
</ul>

<dl>
</dl>

<p>4. Self-sign csr (using SHA256) and append the extensions described in the file</p>

<ul>
 <li>"openssl x509 -req -sha256 -days 3650 -in example.csr -signkey key.pem -set_serial $ANY_INTEGER -extfile openssl.ss.cnf -out example.pem"</li>
</ul>

<dl>
</dl>

<p>You can now use example.pem as your certfile</p>

<h2 id="CAs_included_in_Firefox"><span class="mw-headline" id="CAs_Included_in_Firefox">CAs included in Firefox</span></h2>

<p>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.</p>

<p>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.</p>

<p>Firefox uses a default set of X.509v3 root certificates for various <a class="external text" href="http://www.mozilla.org/projects/security/certs/included/" rel="nofollow">Certification Authorities (CAs)</a>. 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.</p>

<p>CAs apply to have their root certificates <a class="external text" href="http://www.mozilla.org/projects/security/certs/included/" rel="nofollow">included by default in Mozilla products</a> by following the <a class="external text" href="http://www.mozilla.org/projects/security/certs/policy/" rel="nofollow">Mozilla CA Certificate Policy</a> and applying for inclusion as per <a href="https://wiki.mozilla.org/CA:How_to_apply" title="CA:How to apply">CA:How_to_apply</a>. Users may override the default root certificate settings using the <a class="external text" href="https://wiki.mozilla.org/CA:UserCertDB" rel="nofollow">Certificate Manager</a>.</p>

<p>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 <a href="https://wiki.mozilla.org/CA:FAQ#Can_I_use_Mozilla.27s_set_of_CA_certificates.3F">Mozilla CA FAQ</a> before doing so.</p>

<h2 id="Running_your_Own_CA_2"><span class="mw-headline" id="Running_your_Own_CA">Running your Own CA</span></h2>

<p>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.</p>

<h2 id="Generate_your_CA_Root_2"><span class="mw-headline" id="Generate_your_CA_Root">Generate your CA Root</span></h2>

<p>Update *.example.com and *.example.net below to match your domains.</p>

<p>Assumptions:</p>

<ul>
 <li>You are the domain owner of *.example.com and *.example.net.</li>
 <li>Your computer is <strong>not</strong> connected to the internet.</li>
</ul>

<p>Steps to generate your CA root certificate:</p>

<ol>
 <li>Generate key
  <ul>
   <li>"openssl genpkey -algorithm RSA -out rootkey.pem -pkeyopt rsa_keygen_bits:4096"</li>
   <li>4096 is considered secure for the next 15 years.</li>
  </ul>
 </li>
 <li>Generate csr
  <ul>
   <li>"openssl req -new -key rootkey.pem -days 5480 -extensions v3_ca -batch -out root.csr -utf8 -subj '/C=US/O=Orgname/OU=SomeInternalName'</li>
   <li>Make a new Certificate Signing Request (CSR) that will be valid for 15 years.</li>
  </ul>
 </li>
 <li>Write extensions File (openssl.root.cnf)
  <ul>
   <li>basicConstraints = critical, CA:TRUE</li>
   <li>keyUsage = keyCertSign, cRLSign</li>
   <li>subjectKeyIdentifier = hash</li>
   <li>nameConstraints = permitted;DNS:example.com,permitted;DNS:example.net</li>
  </ul>
 </li>
 <li>Self-sign csr (using SHA256) and append the extensions described in the file
  <ul>
   <li>"openssl x509 -req -sha256 -days 3650 -in root.csr -signkey rootkey.pem -set_serial $ANY_SMALL_INTEGER -extfile openssl.root.cnf -out root.pem"</li>
  </ul>
 </li>
</ol>

<p>Now you have CA pem file with its associated key.</p>

<h2 id="Generate_your_Intermediate_cert_2"><span class="mw-headline" id="Generate_your_Intermediate_cert">Generate your Intermediate cert</span></h2>

<p>The following steps create an intermediate cert that is valid for 8 years.</p>

<ol>
 <li>Generate key
  <ul>
   <li>"openssl genpkey -algorithm RSA -out r=intkey.pem -pkeyopt rsa_keygen_bits: 3072"</li>
   <li>A 3072 bit key is considered secure for the next 8 years.</li>
  </ul>
 </li>
 <li>Generate csr
  <ul>
   <li>"openssl req -new -key intkey.pem -days 2922 -extensions v3_ca -batch -out int.csr - utf8 -subj '/C=US/O=Orgname/OU=SomeInternalName2'</li>
   <li>Make a new Certificate Signing Request (CSR) that will be valid for 8 years.</li>
  </ul>
 </li>
 <li>Write extensions File (openssl.int.cnf)
  <ul>
   <li>basicConstraints = critical, CA:TRUE</li>
   <li>authorityKeyIdentifier = keyid, issuer</li>
   <li>subjectKeyIdentifier = hash</li>
   <li>keyUsage = keyCertSign, cRLSign</li>
   <li>extendedKeyUsage =serverAuth</li>
   <li>authorityInfoAccess = OCSP;URI:<a class="external free" href="http://ocsp.example.com:8888/" rel="nofollow">http://ocsp.example.com:8888/</a></li>
  </ul>
 </li>
 <li>Sign the intermediate csr with the root key and the intermediate extensions
  <ul>
   <li>"openssl x509 -req -sha256 -days 2922 -in int.csr -CAkey rootkey.pem -CA root.pem -set_serial $SOME_LARGE_INTEGER -out int.pem -extfile openssl.int.cnf"</li>
  </ul>
 </li>
</ol>

<h2 id="Generate_the_end_entity_certificate_2"><span class="mw-headline" id="Generate_the_end_entity_certificate">Generate the end entity certificate</span></h2>

<p>Update www.example.com below to match your domain.</p>

<ol>
 <li>Generate key
  <ul>
   <li>"openssl genpkey -algorithm RSA -out eekey.pem -pkeyopt rsa_keygen_bits: 2048"</li>
   <li>2048 is considered secure for the next 4 years.</li>
  </ul>
 </li>
 <li>Generate csr
  <ul>
   <li>"openssl req -new -key key.pem -days 1096 -extensions v3_ca -batch -out example.csr - utf8 -subj '/CN=www.example.com'</li>
   <li>Make a new Certificate Signing Request (CSR) that will be valid for 3 years.</li>
  </ul>
 </li>
 <li>Write extensions file (make a new file with name openssl.ss.cnf with the following contents)
  <ul>
   <li>basicConstraints = CA:FALSE</li>
   <li>subjectAltName =DNS:www.example.com</li>
   <li>extendedKeyUsage =serverAuth</li>
   <li>authorityInfoAccess = OCSP;URI:<a class="external free" href="http://ocsp.example.com:80/" rel="nofollow">http://ocsp.example.com:80/</a></li>
  </ul>
 </li>
 <li>Intermediate sings the csr (using SHA256) and appends the extensions described in the file
  <ul>
   <li>"openssl x509 -req -sha256 -days 1096 -in example.csr -CAkey intkey.pem -CA int.pem -set_serial $SOME_LARGE_INTEGER -out www.example.com.pem -extfile openssl.int.cnf"</li>
  </ul>
 </li>
</ol>

<h1 id="Security_Notes_2"><span class="mw-headline" id="Security_Notes">Security Notes</span></h1>

<p>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 <a class="external free" href="http://www.keylength.com/" rel="nofollow">http://www.keylength.com/</a>):</p>

<table class="wikitable">
 <tbody>
  <tr>
   <th></th>
   <th>Asymmetric</th>
   <th>ECC(Key)</th>
   <th>Hash</th>
  </tr>
  <tr>
   <td>Linestra(2004)</td>
   <td>1902</td>
   <td>172</td>
   <td>172</td>
  </tr>
  <tr>
   <td>Ecrypt 2012</td>
   <td>2432</td>
   <td>224</td>
   <td>224</td>
  </tr>
  <tr>
   <td>NIST 2012</td>
   <td>2048</td>
   <td>224</td>
   <td>224</td>
  </tr>
  <tr>
   <td>ANSSI 2010</td>
   <td>4096</td>
   <td>200</td>
   <td>256</td>
  </tr>
  <tr>
   <td><a class="external mw-magiclink-rfc" href="https://tools.ietf.org/html/rfc3766" rel="nofollow">RFC 3766</a></td>
   <td>2358</td>
   <td>200</td>
   <td>---</td>
  </tr>
  <tr>
   <td>BSI</td>
   <td>1976</td>
   <td>256</td>
   <td>256</td>
  </tr>
 </tbody>
</table>

<p>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).</p>

<h1 id="Error_Codes_in_Firefox_2"><span class="mw-headline" id="Error_Codes_in_Firefox">Error Codes in Firefox</span></h1>

<p>Here are some common errors that might be encountered when working with certificates in Firefox.</p>

<table class="wikitable">
 <tbody>
  <tr>
   <th>Error Code</th>
   <th>What It Means</th>
   <th>What Can I Do</th>
  </tr>
  <tr>
   <td>SEC_ERROR_BAD_DER</td>
   <td>A certificate is not properly encoded according to ASN.1 (DER) encoding</td>
   <td>Re-generate the improperly-encoded certificate</td>
  </tr>
  <tr>
   <td>SEC_ERROR_CA_CERT_INVALID</td>
   <td>An end-entity certificate is being used to issue another certificate</td>
   <td>Ensure that any certificate intended to issue certificates has a basic constraints extension with cA: TRUE</td>
  </tr>
  <tr>
   <td>SEC_ERROR_BAD_SIGNATURE</td>
   <td>A signature on a certificate is improperly formatted or the certificate has been tampered with</td>
   <td>Re-issue the certificate with the bad signature</td>
  </tr>
  <tr>
   <td>SEC_ERROR_CERT_BAD_ACCESS_LOCATION</td>
   <td>The OCSP URI in the authorityInformationAccess extension is improperly formed</td>
   <td>Re-generate the certificate with a well-formed OCSP URI</td>
  </tr>
  <tr>
   <td>SEC_ERROR_CERT_NOT_IN_NAME_SPACE</td>
   <td>A certificate has a common name or subject alternative name that is not in the namespace of an issuing certificate</td>
   <td>Re-issue the certificate with names that are within the namespace of all certificates in the chain</td>
  </tr>
  <tr>
   <td>SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED</td>
   <td>A certificate has been signed with an obsolete algorithm</td>
   <td>Re-sign the certificate using a modern algorithm</td>
  </tr>
  <tr>
   <td>SEC_ERROR_EXPIRED_CERTIFICATE</td>
   <td>A certificate is too old to be used</td>
   <td>Re-generate the certificate</td>
  </tr>
  <tr>
   <td>SEC_ERROR_EXTENSION_VALUE_INVALID</td>
   <td>A certificate has an extension with an empty value</td>
   <td>Re-generate the certificate without the extension, or re-generate it with a non-empty value</td>
  </tr>
  <tr>
   <td>SEC_ERROR_INADEQUATE_CERT_TYPE</td>
   <td>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</td>
   <td>Re-generate the certificate with the appropriate extended key usage values</td>
  </tr>
  <tr>
   <td>SEC_ERROR_INADEQUATE_KEY_USAGE</td>
   <td>A certificate has a key usage extension that does not assert a required usage</td>
   <td>Re-generate the certificate with the appropriate key usage values</td>
  </tr>
  <tr>
   <td>SEC_ERROR_INVALID_ALGORITHM</td>
   <td>A certificate has been signed with an unknown algorithm</td>
   <td>Re-sign the certificate with a standardized certificate signing algorithm</td>
  </tr>
  <tr>
   <td>SEC_ERROR_INVALID_TIME</td>
   <td>A time field in a certificate has an invalid value</td>
   <td>Re-generate the certificate with valid encodings for time fields</td>
  </tr>
  <tr>
   <td>MOZILLA_PKIX_ERROR_KEY_PINNING_FAILURE</td>
   <td></td>
   <td></td>
  </tr>
  <tr>
   <td>SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID</td>
   <td></td>
   <td></td>
  </tr>
  <tr>
   <td>SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION</td>
   <td>A certificate contains an extension marked as critical that is not handled by mozilla::pkix</td>
   <td>Re-generate the certificate without the extension or with it not marked as critical</td>
  </tr>
  <tr>
   <td>SEC_ERROR_UNKNOWN_ISSUER</td>
   <td>Either a missing intermediate or root certificate is necessary to verify the certificate</td>
   <td>Import the root certificate into Firefox or have the server send the intermediate</td>
  </tr>
  <tr>
   <td>SEC_ERROR_INVALID_KEY</td>
   <td></td>
   <td></td>
  </tr>
  <tr>
   <td>SEC_ERROR_UNSUPPORTED_KEYALG</td>
   <td></td>
   <td></td>
  </tr>
  <tr>
   <td>SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE</td>
   <td>An issuer certificate is too old</td>
   <td>Re-issue the issuer certificate</td>
  </tr>
  <tr>
   <td>MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY</td>
   <td>A certificate with a basic constraints extension with cA:TRUE is being used as an end-entity certificate</td>
   <td>Re-generate the end-entity certificate without the basic constraints extension</td>
  </tr>
  <tr>
   <td>MOZILLA_PKIX_ERROR_INADEQUATE_KEY_SIZE</td>
   <td>A certificate has a key that is too small to be secure</td>
   <td>Re-generate a larger key and issue a certificate using that key</td>
  </tr>
 </tbody>
</table>