• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2  * All rights reserved.
3  *
4  * This package is an SSL implementation written
5  * by Eric Young (eay@cryptsoft.com).
6  * The implementation was written so as to conform with Netscapes SSL.
7  *
8  * This library is free for commercial and non-commercial use as long as
9  * the following conditions are aheared to.  The following conditions
10  * apply to all code found in this distribution, be it the RC4, RSA,
11  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
12  * included with this distribution is covered by the same copyright terms
13  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14  *
15  * Copyright remains Eric Young's, and as such any Copyright notices in
16  * the code are not to be removed.
17  * If this package is used in a product, Eric Young should be given attribution
18  * as the author of the parts of the library used.
19  * This can be in the form of a textual message at program startup or
20  * in documentation (online or textual) provided with the package.
21  *
22  * Redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions
24  * are met:
25  * 1. Redistributions of source code must retain the copyright
26  *    notice, this list of conditions and the following disclaimer.
27  * 2. Redistributions in binary form must reproduce the above copyright
28  *    notice, this list of conditions and the following disclaimer in the
29  *    documentation and/or other materials provided with the distribution.
30  * 3. All advertising materials mentioning features or use of this software
31  *    must display the following acknowledgement:
32  *    "This product includes cryptographic software written by
33  *     Eric Young (eay@cryptsoft.com)"
34  *    The word 'cryptographic' can be left out if the rouines from the library
35  *    being used are not cryptographic related :-).
36  * 4. If you include any Windows specific code (or a derivative thereof) from
37  *    the apps directory (application code) you must include an acknowledgement:
38  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39  *
40  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50  * SUCH DAMAGE.
51  *
52  * The licence and distribution terms for any publically available version or
53  * derivative of this code cannot be changed.  i.e. this code cannot simply be
54  * copied and put under another distribution licence
55  * [including the GNU Public Licence.] */
56 
57 #include <openssl/asn1.h>
58 #include <openssl/asn1t.h>
59 #include <openssl/digest.h>
60 #include <openssl/err.h>
61 #include <openssl/mem.h>
62 #include <openssl/obj.h>
63 #include <openssl/stack.h>
64 #include <openssl/thread.h>
65 #include <openssl/x509.h>
66 #include <openssl/x509v3.h>
67 
68 #include <assert.h>
69 
70 #include "../asn1/internal.h"
71 #include "../internal.h"
72 #include "internal.h"
73 
74 static int X509_REVOKED_cmp(const X509_REVOKED *const *a,
75                             const X509_REVOKED *const *b);
76 static int setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp);
77 
78 ASN1_SEQUENCE(X509_REVOKED) = {
79     ASN1_SIMPLE(X509_REVOKED, serialNumber, ASN1_INTEGER),
80     ASN1_SIMPLE(X509_REVOKED, revocationDate, ASN1_TIME),
81     ASN1_SEQUENCE_OF_OPT(X509_REVOKED, extensions, X509_EXTENSION),
82 } ASN1_SEQUENCE_END(X509_REVOKED)
83 
84 static int crl_lookup(X509_CRL *crl, X509_REVOKED **ret,
85                       const ASN1_INTEGER *serial, X509_NAME *issuer);
86 
87 // The X509_CRL_INFO structure needs a bit of customisation. Since we cache
88 // the original encoding the signature wont be affected by reordering of the
89 // revoked field.
crl_inf_cb(int operation,ASN1_VALUE ** pval,const ASN1_ITEM * it,void * exarg)90 static int crl_inf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
91                       void *exarg) {
92   X509_CRL_INFO *a = (X509_CRL_INFO *)*pval;
93 
94   if (!a || !a->revoked) {
95     return 1;
96   }
97   switch (operation) {
98       // Just set cmp function here. We don't sort because that would
99       // affect the output of X509_CRL_print().
100     case ASN1_OP_D2I_POST:
101       (void)sk_X509_REVOKED_set_cmp_func(a->revoked, X509_REVOKED_cmp);
102       break;
103   }
104   return 1;
105 }
106 
107 
108 ASN1_SEQUENCE_enc(X509_CRL_INFO, enc, crl_inf_cb) = {
109     ASN1_OPT(X509_CRL_INFO, version, ASN1_INTEGER),
110     ASN1_SIMPLE(X509_CRL_INFO, sig_alg, X509_ALGOR),
111     ASN1_SIMPLE(X509_CRL_INFO, issuer, X509_NAME),
112     ASN1_SIMPLE(X509_CRL_INFO, lastUpdate, ASN1_TIME),
113     ASN1_OPT(X509_CRL_INFO, nextUpdate, ASN1_TIME),
114     ASN1_SEQUENCE_OF_OPT(X509_CRL_INFO, revoked, X509_REVOKED),
115     ASN1_EXP_SEQUENCE_OF_OPT(X509_CRL_INFO, extensions, X509_EXTENSION, 0),
116 } ASN1_SEQUENCE_END_enc(X509_CRL_INFO, X509_CRL_INFO)
117 
118 // Set CRL entry issuer according to CRL certificate issuer extension. Check
119 // for unhandled critical CRL entry extensions.
120 
121 static int crl_set_issuers(X509_CRL *crl) {
122   size_t i, k;
123   int j;
124   GENERAL_NAMES *gens, *gtmp;
125   STACK_OF(X509_REVOKED) *revoked;
126 
127   revoked = X509_CRL_get_REVOKED(crl);
128 
129   gens = NULL;
130   for (i = 0; i < sk_X509_REVOKED_num(revoked); i++) {
131     X509_REVOKED *rev = sk_X509_REVOKED_value(revoked, i);
132     STACK_OF(X509_EXTENSION) *exts;
133     ASN1_ENUMERATED *reason;
134     X509_EXTENSION *ext;
135     gtmp = X509_REVOKED_get_ext_d2i(rev, NID_certificate_issuer, &j, NULL);
136     if (!gtmp && (j != -1)) {
137       crl->flags |= EXFLAG_INVALID;
138       return 1;
139     }
140 
141     if (gtmp) {
142       gens = gtmp;
143       if (!crl->issuers) {
144         crl->issuers = sk_GENERAL_NAMES_new_null();
145         if (!crl->issuers) {
146           return 0;
147         }
148       }
149       if (!sk_GENERAL_NAMES_push(crl->issuers, gtmp)) {
150         return 0;
151       }
152     }
153     rev->issuer = gens;
154 
155     reason = X509_REVOKED_get_ext_d2i(rev, NID_crl_reason, &j, NULL);
156     if (!reason && (j != -1)) {
157       crl->flags |= EXFLAG_INVALID;
158       return 1;
159     }
160 
161     if (reason) {
162       rev->reason = ASN1_ENUMERATED_get(reason);
163       ASN1_ENUMERATED_free(reason);
164     } else {
165       rev->reason = CRL_REASON_NONE;
166     }
167 
168     // Check for critical CRL entry extensions
169 
170     exts = rev->extensions;
171 
172     for (k = 0; k < sk_X509_EXTENSION_num(exts); k++) {
173       ext = sk_X509_EXTENSION_value(exts, k);
174       if (X509_EXTENSION_get_critical(ext)) {
175         if (OBJ_obj2nid(X509_EXTENSION_get_object(ext)) ==
176             NID_certificate_issuer) {
177           continue;
178         }
179         crl->flags |= EXFLAG_CRITICAL;
180         break;
181       }
182     }
183   }
184 
185   return 1;
186 }
187 
188 // The X509_CRL structure needs a bit of customisation. Cache some extensions
189 // and hash of the whole CRL.
crl_cb(int operation,ASN1_VALUE ** pval,const ASN1_ITEM * it,void * exarg)190 static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
191                   void *exarg) {
192   X509_CRL *crl = (X509_CRL *)*pval;
193   STACK_OF(X509_EXTENSION) *exts;
194   X509_EXTENSION *ext;
195   size_t idx;
196   int i;
197 
198   switch (operation) {
199     case ASN1_OP_NEW_POST:
200       crl->idp = NULL;
201       crl->akid = NULL;
202       crl->flags = 0;
203       crl->idp_flags = 0;
204       crl->idp_reasons = CRLDP_ALL_REASONS;
205       crl->issuers = NULL;
206       crl->crl_number = NULL;
207       crl->base_crl_number = NULL;
208       break;
209 
210     case ASN1_OP_D2I_POST: {
211       // The version must be one of v1(0) or v2(1).
212       long version = X509_CRL_VERSION_1;
213       if (crl->crl->version != NULL) {
214         version = ASN1_INTEGER_get(crl->crl->version);
215         // TODO(https://crbug.com/boringssl/364): |X509_CRL_VERSION_1|
216         // should also be rejected. This means an explicitly-encoded X.509v1
217         // version. v1 is DEFAULT, so DER requires it be omitted.
218         if (version < X509_CRL_VERSION_1 || version > X509_CRL_VERSION_2) {
219           OPENSSL_PUT_ERROR(X509, X509_R_INVALID_VERSION);
220           return 0;
221         }
222       }
223 
224       // Per RFC 5280, section 5.1.2.1, extensions require v2.
225       if (version != X509_CRL_VERSION_2 && crl->crl->extensions != NULL) {
226         OPENSSL_PUT_ERROR(X509, X509_R_INVALID_FIELD_FOR_VERSION);
227         return 0;
228       }
229 
230       if (!X509_CRL_digest(crl, EVP_sha256(), crl->crl_hash, NULL)) {
231         return 0;
232       }
233 
234       crl->idp =
235           X509_CRL_get_ext_d2i(crl, NID_issuing_distribution_point, &i, NULL);
236       if (crl->idp != NULL) {
237         if (!setup_idp(crl, crl->idp)) {
238           return 0;
239         }
240       } else if (i != -1) {
241         return 0;
242       }
243 
244       crl->akid =
245           X509_CRL_get_ext_d2i(crl, NID_authority_key_identifier, &i, NULL);
246       if (crl->akid == NULL && i != -1) {
247         return 0;
248       }
249 
250       crl->crl_number = X509_CRL_get_ext_d2i(crl, NID_crl_number, &i, NULL);
251       if (crl->crl_number == NULL && i != -1) {
252         return 0;
253       }
254 
255       crl->base_crl_number = X509_CRL_get_ext_d2i(crl, NID_delta_crl, &i, NULL);
256       if (crl->base_crl_number == NULL && i != -1) {
257         return 0;
258       }
259       // Delta CRLs must have CRL number
260       if (crl->base_crl_number && !crl->crl_number) {
261         OPENSSL_PUT_ERROR(X509, X509_R_DELTA_CRL_WITHOUT_CRL_NUMBER);
262         return 0;
263       }
264 
265       // See if we have any unhandled critical CRL extensions and indicate
266       // this in a flag. We only currently handle IDP so anything else
267       // critical sets the flag. This code accesses the X509_CRL structure
268       // directly: applications shouldn't do this.
269 
270       exts = crl->crl->extensions;
271 
272       for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++) {
273         int nid;
274         ext = sk_X509_EXTENSION_value(exts, idx);
275         nid = OBJ_obj2nid(X509_EXTENSION_get_object(ext));
276         if (nid == NID_freshest_crl) {
277           crl->flags |= EXFLAG_FRESHEST;
278         }
279         if (X509_EXTENSION_get_critical(ext)) {
280           // We handle IDP and deltas
281           if ((nid == NID_issuing_distribution_point) ||
282               (nid == NID_authority_key_identifier) || (nid == NID_delta_crl)) {
283             continue;
284           }
285           crl->flags |= EXFLAG_CRITICAL;
286           break;
287         }
288       }
289 
290       if (!crl_set_issuers(crl)) {
291         return 0;
292       }
293 
294       break;
295     }
296 
297     case ASN1_OP_FREE_POST:
298       AUTHORITY_KEYID_free(crl->akid);
299       ISSUING_DIST_POINT_free(crl->idp);
300       ASN1_INTEGER_free(crl->crl_number);
301       ASN1_INTEGER_free(crl->base_crl_number);
302       sk_GENERAL_NAMES_pop_free(crl->issuers, GENERAL_NAMES_free);
303       break;
304   }
305   return 1;
306 }
307 
308 // Convert IDP into a more convenient form
309 
setup_idp(X509_CRL * crl,ISSUING_DIST_POINT * idp)310 static int setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp) {
311   int idp_only = 0;
312   // Set various flags according to IDP
313   crl->idp_flags |= IDP_PRESENT;
314   if (idp->onlyuser > 0) {
315     idp_only++;
316     crl->idp_flags |= IDP_ONLYUSER;
317   }
318   if (idp->onlyCA > 0) {
319     idp_only++;
320     crl->idp_flags |= IDP_ONLYCA;
321   }
322   if (idp->onlyattr > 0) {
323     idp_only++;
324     crl->idp_flags |= IDP_ONLYATTR;
325   }
326 
327   if (idp_only > 1) {
328     crl->idp_flags |= IDP_INVALID;
329   }
330 
331   if (idp->indirectCRL > 0) {
332     crl->idp_flags |= IDP_INDIRECT;
333   }
334 
335   if (idp->onlysomereasons) {
336     crl->idp_flags |= IDP_REASONS;
337     if (idp->onlysomereasons->length > 0) {
338       crl->idp_reasons = idp->onlysomereasons->data[0];
339     }
340     if (idp->onlysomereasons->length > 1) {
341       crl->idp_reasons |= (idp->onlysomereasons->data[1] << 8);
342     }
343     crl->idp_reasons &= CRLDP_ALL_REASONS;
344   }
345 
346   return DIST_POINT_set_dpname(idp->distpoint, X509_CRL_get_issuer(crl));
347 }
348 
349 ASN1_SEQUENCE_ref(X509_CRL, crl_cb) = {
350     ASN1_SIMPLE(X509_CRL, crl, X509_CRL_INFO),
351     ASN1_SIMPLE(X509_CRL, sig_alg, X509_ALGOR),
352     ASN1_SIMPLE(X509_CRL, signature, ASN1_BIT_STRING),
353 } ASN1_SEQUENCE_END_ref(X509_CRL, X509_CRL)
354 
355 // Although |X509_REVOKED| contains an |X509_NAME|, it can be const. It is not
356 // affected by https://crbug.com/boringssl/407 because the  |X509_NAME| does
357 // not participate in serialization.
358 IMPLEMENT_ASN1_FUNCTIONS_const(X509_REVOKED)
359 IMPLEMENT_ASN1_DUP_FUNCTION_const(X509_REVOKED)
360 
361 IMPLEMENT_ASN1_FUNCTIONS(X509_CRL_INFO)
362 IMPLEMENT_ASN1_FUNCTIONS(X509_CRL)
363 IMPLEMENT_ASN1_DUP_FUNCTION(X509_CRL)
364 
365 static int X509_REVOKED_cmp(const X509_REVOKED *const *a,
366                             const X509_REVOKED *const *b) {
367   return ASN1_STRING_cmp((*a)->serialNumber, (*b)->serialNumber);
368 }
369 
X509_CRL_add0_revoked(X509_CRL * crl,X509_REVOKED * rev)370 int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev) {
371   X509_CRL_INFO *inf;
372   inf = crl->crl;
373   if (!inf->revoked) {
374     inf->revoked = sk_X509_REVOKED_new(X509_REVOKED_cmp);
375   }
376   if (!inf->revoked || !sk_X509_REVOKED_push(inf->revoked, rev)) {
377     return 0;
378   }
379   asn1_encoding_clear(&inf->enc);
380   return 1;
381 }
382 
X509_CRL_verify(X509_CRL * crl,EVP_PKEY * pkey)383 int X509_CRL_verify(X509_CRL *crl, EVP_PKEY *pkey) {
384   if (X509_ALGOR_cmp(crl->sig_alg, crl->crl->sig_alg) != 0) {
385     OPENSSL_PUT_ERROR(X509, X509_R_SIGNATURE_ALGORITHM_MISMATCH);
386     return 0;
387   }
388 
389   return ASN1_item_verify(ASN1_ITEM_rptr(X509_CRL_INFO), crl->sig_alg,
390                           crl->signature, crl->crl, pkey);
391 }
392 
X509_CRL_get0_by_serial(X509_CRL * crl,X509_REVOKED ** ret,const ASN1_INTEGER * serial)393 int X509_CRL_get0_by_serial(X509_CRL *crl, X509_REVOKED **ret,
394                             const ASN1_INTEGER *serial) {
395   return crl_lookup(crl, ret, serial, NULL);
396 }
397 
X509_CRL_get0_by_cert(X509_CRL * crl,X509_REVOKED ** ret,X509 * x)398 int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x) {
399   return crl_lookup(crl, ret, X509_get_serialNumber(x),
400                     X509_get_issuer_name(x));
401 }
402 
crl_revoked_issuer_match(X509_CRL * crl,X509_NAME * nm,X509_REVOKED * rev)403 static int crl_revoked_issuer_match(X509_CRL *crl, X509_NAME *nm,
404                                     X509_REVOKED *rev) {
405   size_t i;
406 
407   if (!rev->issuer) {
408     if (!nm) {
409       return 1;
410     }
411     if (!X509_NAME_cmp(nm, X509_CRL_get_issuer(crl))) {
412       return 1;
413     }
414     return 0;
415   }
416 
417   if (!nm) {
418     nm = X509_CRL_get_issuer(crl);
419   }
420 
421   for (i = 0; i < sk_GENERAL_NAME_num(rev->issuer); i++) {
422     GENERAL_NAME *gen = sk_GENERAL_NAME_value(rev->issuer, i);
423     if (gen->type != GEN_DIRNAME) {
424       continue;
425     }
426     if (!X509_NAME_cmp(nm, gen->d.directoryName)) {
427       return 1;
428     }
429   }
430   return 0;
431 }
432 
433 static CRYPTO_MUTEX g_crl_sort_lock = CRYPTO_MUTEX_INIT;
434 
crl_lookup(X509_CRL * crl,X509_REVOKED ** ret,const ASN1_INTEGER * serial,X509_NAME * issuer)435 static int crl_lookup(X509_CRL *crl, X509_REVOKED **ret,
436                       const ASN1_INTEGER *serial, X509_NAME *issuer) {
437   // Use an assert, rather than a runtime error, because returning nothing for a
438   // CRL is arguably failing open, rather than closed.
439   assert(serial->type == V_ASN1_INTEGER || serial->type == V_ASN1_NEG_INTEGER);
440   X509_REVOKED rtmp, *rev;
441   size_t idx;
442   rtmp.serialNumber = (ASN1_INTEGER *)serial;
443   // Sort revoked into serial number order if not already sorted. Do this
444   // under a lock to avoid race condition.
445 
446   CRYPTO_MUTEX_lock_read(&g_crl_sort_lock);
447   const int is_sorted = sk_X509_REVOKED_is_sorted(crl->crl->revoked);
448   CRYPTO_MUTEX_unlock_read(&g_crl_sort_lock);
449 
450   if (!is_sorted) {
451     CRYPTO_MUTEX_lock_write(&g_crl_sort_lock);
452     if (!sk_X509_REVOKED_is_sorted(crl->crl->revoked)) {
453       sk_X509_REVOKED_sort(crl->crl->revoked);
454     }
455     CRYPTO_MUTEX_unlock_write(&g_crl_sort_lock);
456   }
457 
458   if (!sk_X509_REVOKED_find(crl->crl->revoked, &idx, &rtmp)) {
459     return 0;
460   }
461   // Need to look for matching name
462   for (; idx < sk_X509_REVOKED_num(crl->crl->revoked); idx++) {
463     rev = sk_X509_REVOKED_value(crl->crl->revoked, idx);
464     if (ASN1_INTEGER_cmp(rev->serialNumber, serial)) {
465       return 0;
466     }
467     if (crl_revoked_issuer_match(crl, issuer, rev)) {
468       if (ret) {
469         *ret = rev;
470       }
471       if (rev->reason == CRL_REASON_REMOVE_FROM_CRL) {
472         return 2;
473       }
474       return 1;
475     }
476   }
477   return 0;
478 }
479