Line data Source code
1 : /* crlcache.c - LDAP access
2 : * Copyright (C) 2002 Klarälvdalens Datakonsult AB
3 : * Copyright (C) 2003, 2004, 2005, 2008 g10 Code GmbH
4 : *
5 : * This file is part of DirMngr.
6 : *
7 : * DirMngr is free software; you can redistribute it and/or modify
8 : * it under the terms of the GNU General Public License as published by
9 : * the Free Software Foundation; either version 2 of the License, or
10 : * (at your option) any later version.
11 : *
12 : * DirMngr is distributed in the hope that it will be useful,
13 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : * GNU General Public License for more details.
16 : *
17 : * You should have received a copy of the GNU General Public License
18 : * along with this program; if not, see <https://www.gnu.org/licenses/>.
19 : */
20 :
21 : /*
22 :
23 : 1. To keep track of the CRLs actually cached and to store the meta
24 : information of the CRLs a simple record oriented text file is
25 : used. Fields in the file are colon (':') separated and values
26 : containing colons or linefeeds are percent escaped (e.g. a colon
27 : itself is represented as "%3A").
28 :
29 : The first field is a record type identifier, so that the file is
30 : useful to keep track of other meta data too.
31 :
32 : The name of the file is "DIR.txt".
33 :
34 :
35 : 1.1. Comment record
36 :
37 : Field 1: Constant beginning with "#".
38 :
39 : Other fields are not defined and such a record is simply
40 : skipped during processing.
41 :
42 : 1.2. Version record
43 :
44 : Field 1: Constant "v"
45 : Field 2: Version number of this file. Must be 1.
46 :
47 : This record must be the first non-comment record record and
48 : there shall only exist one record of this type.
49 :
50 : 1.3. CRL cache record
51 :
52 : Field 1: Constant "c", "u" or "i".
53 : A "c" or "u" indicate a valid cache entry, however
54 : "u" requires that a user root certificate check needs
55 : to be done.
56 : An "i" indicates an invalid cache entry which should
57 : not be used but still exists so that it can be
58 : updated at NEXT_UPDATE.
59 : Field 2: Hexadecimal encoded SHA-1 hash of the issuer DN using
60 : uppercase letters.
61 : Field 3: Issuer DN in RFC-2253 notation.
62 : Field 4: URL used to retrieve the corresponding CRL.
63 : Field 5: 15 character ISO timestamp with THIS_UPDATE.
64 : Field 6: 15 character ISO timestamp with NEXT_UPDATE.
65 : Field 7: Hexadecimal encoded MD-5 hash of the DB file to detect
66 : accidental modified (i.e. deleted and created) cache files.
67 : Field 8: optional CRL number as a hex string.
68 : Field 9: AuthorityKeyID.issuer, each Name separated by 0x01
69 : Field 10: AuthorityKeyID.serial
70 : Field 11: Hex fingerprint of trust anchor if field 1 is 'u'.
71 :
72 : 2. Layout of the standard CRL Cache DB file:
73 :
74 : We use records of variable length with this structure
75 :
76 : n bytes Serialnumber (binary) used as key
77 : thus there is no need to store the length explicitly with DB2.
78 : 1 byte Reason for revocation
79 : (currently the KSBA reason flags are used)
80 : 15 bytes ISO date of revocation (e.g. 19980815T142000)
81 : Note that there is no terminating 0 stored.
82 :
83 : The filename used is the hexadecimal (using uppercase letters)
84 : SHA-1 hash value of the issuer DN prefixed with a "crl-" and
85 : suffixed with a ".db". Thus the length of the filename is 47.
86 :
87 :
88 : */
89 :
90 : #include <config.h>
91 :
92 : #include <stdio.h>
93 : #include <stdlib.h>
94 : #include <errno.h>
95 : #include <string.h>
96 : #include <sys/stat.h>
97 : #include <assert.h>
98 : #include <dirent.h>
99 : #include <fcntl.h>
100 : #include <unistd.h>
101 : #ifndef HAVE_W32_SYSTEM
102 : #include <sys/utsname.h>
103 : #endif
104 : #ifdef MKDIR_TAKES_ONE_ARG
105 : #undef mkdir
106 : #define mkdir(a,b) mkdir(a)
107 : #endif
108 :
109 : #include "dirmngr.h"
110 : #include "validate.h"
111 : #include "certcache.h"
112 : #include "crlcache.h"
113 : #include "crlfetch.h"
114 : #include "misc.h"
115 : #include "cdb.h"
116 :
117 : /* Change this whenever the format changes */
118 : #define DBDIR_D "crls.d"
119 : #define DBDIRFILE "DIR.txt"
120 : #define DBDIRVERSION 1
121 :
122 : /* The number of DB files we may have open at one time. We need to
123 : limit this because there is no guarantee that the number of issuers
124 : has a upper limit. We are currently using mmap, so it is a good
125 : idea anyway to limit the number of opened cache files. */
126 : #define MAX_OPEN_DB_FILES 5
127 :
128 :
129 : static const char oidstr_crlNumber[] = "2.5.29.20";
130 : static const char oidstr_issuingDistributionPoint[] = "2.5.29.28";
131 : static const char oidstr_authorityKeyIdentifier[] = "2.5.29.35";
132 :
133 :
134 : /* Definition of one cached item. */
135 : struct crl_cache_entry_s
136 : {
137 : struct crl_cache_entry_s *next;
138 : int deleted; /* True if marked for deletion. */
139 : int mark; /* Internally used by update_dir. */
140 : unsigned int lineno;/* A 0 indicates a new entry. */
141 : char *release_ptr; /* The actual allocated memory. */
142 : char *url; /* Points into RELEASE_PTR. */
143 : char *issuer; /* Ditto. */
144 : char *issuer_hash; /* Ditto. */
145 : char *dbfile_hash; /* MD5 sum of the cache file, points into RELEASE_PTR.*/
146 : int invalid; /* Can't use this CRL. */
147 : int user_trust_req; /* User supplied root certificate required. */
148 : char *check_trust_anchor; /* Malloced fingerprint. */
149 : ksba_isotime_t this_update;
150 : ksba_isotime_t next_update;
151 : ksba_isotime_t last_refresh; /* Use for the force_crl_refresh feature. */
152 : char *crl_number;
153 : char *authority_issuer;
154 : char *authority_serialno;
155 :
156 : struct cdb *cdb; /* The cache file handle or NULL if not open. */
157 :
158 : unsigned int cdb_use_count; /* Current use count. */
159 : unsigned int cdb_lru_count; /* Used for LRU purposes. */
160 : int dbfile_checked; /* Set to true if the dbfile_hash value has
161 : been checked one. */
162 : };
163 :
164 :
165 : /* Definition of the entire cache object. */
166 : struct crl_cache_s
167 : {
168 : crl_cache_entry_t entries;
169 : };
170 :
171 : typedef struct crl_cache_s *crl_cache_t;
172 :
173 :
174 : /* Prototypes. */
175 : static crl_cache_entry_t find_entry (crl_cache_entry_t first,
176 : const char *issuer_hash);
177 :
178 :
179 :
180 : /* The currently loaded cache object. This is usually initialized
181 : right at startup. */
182 : static crl_cache_t current_cache;
183 :
184 :
185 :
186 :
187 :
188 : /* Return the current cache object or bail out if it is has not yet
189 : been initialized. */
190 : static crl_cache_t
191 0 : get_current_cache (void)
192 : {
193 0 : if (!current_cache)
194 0 : log_fatal ("CRL cache has not yet been initialized\n");
195 0 : return current_cache;
196 : }
197 :
198 :
199 : /*
200 : Create ae directory if it does not yet exists. Returns on
201 : success, or -1 on error.
202 : */
203 : static int
204 0 : create_directory_if_needed (const char *name)
205 : {
206 : DIR *dir;
207 : char *fname;
208 :
209 0 : fname = make_filename (opt.homedir_cache, name, NULL);
210 0 : dir = opendir (fname);
211 0 : if (!dir)
212 : {
213 0 : log_info (_("creating directory '%s'\n"), fname);
214 0 : if (mkdir (fname, S_IRUSR|S_IWUSR|S_IXUSR) )
215 : {
216 0 : int save_errno = errno;
217 0 : log_error (_("error creating directory '%s': %s\n"),
218 0 : fname, strerror (errno));
219 0 : xfree (fname);
220 0 : gpg_err_set_errno (save_errno);
221 0 : return -1;
222 : }
223 : }
224 : else
225 0 : closedir (dir);
226 0 : xfree (fname);
227 0 : return 0;
228 : }
229 :
230 : /* Remove all files from the cache directory. If FORCE is not true,
231 : some sanity checks on the filenames are done. Return 0 if
232 : everything went fine. */
233 : static int
234 0 : cleanup_cache_dir (int force)
235 : {
236 0 : char *dname = make_filename (opt.homedir_cache, DBDIR_D, NULL);
237 : DIR *dir;
238 : struct dirent *de;
239 0 : int problem = 0;
240 :
241 0 : if (!force)
242 : { /* Very minor sanity checks. */
243 0 : if (!strcmp (dname, "~/") || !strcmp (dname, "/" ))
244 : {
245 0 : log_error (_("ignoring database dir '%s'\n"), dname);
246 0 : xfree (dname);
247 0 : return -1;
248 : }
249 : }
250 :
251 0 : dir = opendir (dname);
252 0 : if (!dir)
253 : {
254 0 : log_error (_("error reading directory '%s': %s\n"),
255 0 : dname, strerror (errno));
256 0 : xfree (dname);
257 0 : return -1;
258 : }
259 :
260 0 : while ((de = readdir (dir)))
261 : {
262 0 : if (strcmp (de->d_name, "." ) && strcmp (de->d_name, ".."))
263 : {
264 0 : char *cdbname = make_filename (dname, de->d_name, NULL);
265 : int okay;
266 : struct stat sbuf;
267 :
268 0 : if (force)
269 0 : okay = 1;
270 : else
271 0 : okay = (!stat (cdbname, &sbuf) && S_ISREG (sbuf.st_mode));
272 :
273 0 : if (okay)
274 : {
275 0 : log_info (_("removing cache file '%s'\n"), cdbname);
276 0 : if (gnupg_remove (cdbname))
277 : {
278 0 : log_error ("failed to remove '%s': %s\n",
279 0 : cdbname, strerror (errno));
280 0 : problem = -1;
281 : }
282 : }
283 : else
284 0 : log_info (_("not removing file '%s'\n"), cdbname);
285 0 : xfree (cdbname);
286 : }
287 : }
288 0 : xfree (dname);
289 0 : closedir (dir);
290 0 : return problem;
291 : }
292 :
293 :
294 : /* Read the next line from the file FP and return the line in an
295 : malloced buffer. Return NULL on error or EOF. There is no
296 : limitation os the line length. The trailing linefeed has been
297 : removed, the function will read the last line of a file, even if
298 : that is not terminated by a LF. */
299 : static char *
300 0 : next_line_from_file (estream_t fp, gpg_error_t *r_err)
301 : {
302 : char buf[300];
303 0 : char *largebuf = NULL;
304 : size_t buflen;
305 0 : size_t len = 0;
306 : unsigned char *p;
307 : int c;
308 : char *tmpbuf;
309 :
310 0 : *r_err = 0;
311 0 : p = buf;
312 0 : buflen = sizeof buf - 1;
313 0 : while ((c=es_getc (fp)) != EOF && c != '\n')
314 : {
315 0 : if (len >= buflen)
316 : {
317 0 : if (!largebuf)
318 : {
319 0 : buflen += 1024;
320 0 : largebuf = xtrymalloc ( buflen + 1 );
321 0 : if (!largebuf)
322 : {
323 0 : *r_err = gpg_error_from_syserror ();
324 0 : return NULL;
325 : }
326 0 : memcpy (largebuf, buf, len);
327 : }
328 : else
329 : {
330 0 : buflen += 1024;
331 0 : tmpbuf = xtryrealloc (largebuf, buflen + 1);
332 0 : if (!tmpbuf)
333 : {
334 0 : *r_err = gpg_error_from_syserror ();
335 0 : xfree (largebuf);
336 0 : return NULL;
337 : }
338 0 : largebuf = tmpbuf;
339 : }
340 0 : p = largebuf;
341 : }
342 0 : p[len++] = c;
343 : }
344 0 : if (c == EOF && !len)
345 0 : return NULL;
346 0 : p[len] = 0;
347 :
348 0 : if (largebuf)
349 0 : tmpbuf = xtryrealloc (largebuf, len+1);
350 : else
351 0 : tmpbuf = xtrystrdup (buf);
352 0 : if (!tmpbuf)
353 : {
354 0 : *r_err = gpg_error_from_syserror ();
355 0 : xfree (largebuf);
356 : }
357 0 : return tmpbuf;
358 : }
359 :
360 :
361 : /* Release one cache entry. */
362 : static void
363 0 : release_one_cache_entry (crl_cache_entry_t entry)
364 : {
365 0 : if (entry)
366 : {
367 0 : if (entry->cdb)
368 : {
369 0 : int fd = cdb_fileno (entry->cdb);
370 0 : cdb_free (entry->cdb);
371 0 : xfree (entry->cdb);
372 0 : if (close (fd))
373 0 : log_error (_("error closing cache file: %s\n"), strerror(errno));
374 : }
375 0 : xfree (entry->release_ptr);
376 0 : xfree (entry->check_trust_anchor);
377 0 : xfree (entry);
378 : }
379 0 : }
380 :
381 :
382 : /* Release the CACHE object. */
383 : static void
384 0 : release_cache (crl_cache_t cache)
385 : {
386 : crl_cache_entry_t entry, entry2;
387 :
388 0 : if (!cache)
389 0 : return;
390 :
391 0 : for (entry = cache->entries; entry; entry = entry2)
392 : {
393 0 : entry2 = entry->next;
394 0 : release_one_cache_entry (entry);
395 : }
396 0 : cache->entries = NULL;
397 0 : xfree (cache);
398 : }
399 :
400 :
401 : /* Open the dir file FNAME or create a new one if it does not yet
402 : exist. */
403 : static estream_t
404 0 : open_dir_file (const char *fname)
405 : {
406 : estream_t fp;
407 :
408 0 : fp = es_fopen (fname, "r");
409 0 : if (!fp)
410 : {
411 0 : log_error (_("failed to open cache dir file '%s': %s\n"),
412 0 : fname, strerror (errno));
413 :
414 : /* Make sure that the directory exists, try to create if otherwise. */
415 0 : if (create_directory_if_needed (NULL)
416 0 : || create_directory_if_needed (DBDIR_D))
417 0 : return NULL;
418 0 : fp = es_fopen (fname, "w");
419 0 : if (!fp)
420 : {
421 0 : log_error (_("error creating new cache dir file '%s': %s\n"),
422 0 : fname, strerror (errno));
423 0 : return NULL;
424 : }
425 0 : es_fprintf (fp, "v:%d:\n", DBDIRVERSION);
426 0 : if (es_ferror (fp))
427 : {
428 0 : log_error (_("error writing new cache dir file '%s': %s\n"),
429 0 : fname, strerror (errno));
430 0 : es_fclose (fp);
431 0 : return NULL;
432 : }
433 0 : if (es_fclose (fp))
434 : {
435 0 : log_error (_("error closing new cache dir file '%s': %s\n"),
436 0 : fname, strerror (errno));
437 0 : return NULL;
438 : }
439 :
440 0 : log_info (_("new cache dir file '%s' created\n"), fname);
441 :
442 0 : fp = es_fopen (fname, "r");
443 0 : if (!fp)
444 : {
445 0 : log_error (_("failed to re-open cache dir file '%s': %s\n"),
446 0 : fname, strerror (errno));
447 0 : return NULL;
448 : }
449 : }
450 :
451 0 : return fp;
452 : }
453 :
454 : /* Helper for open_dir. */
455 : static gpg_error_t
456 0 : check_dir_version (estream_t *fpadr, const char *fname,
457 : unsigned int *lineno,
458 : int cleanup_on_mismatch)
459 : {
460 : char *line;
461 0 : gpg_error_t lineerr = 0;
462 0 : estream_t fp = *fpadr;
463 0 : int created = 0;
464 :
465 : retry:
466 0 : while ((line = next_line_from_file (fp, &lineerr)))
467 : {
468 0 : ++*lineno;
469 0 : if (*line == 'v' && line[1] == ':')
470 : break;
471 0 : else if (*line != '#')
472 : {
473 0 : log_error (_("first record of '%s' is not the version\n"), fname);
474 0 : xfree (line);
475 0 : return gpg_error (GPG_ERR_CONFIGURATION);
476 : }
477 0 : xfree (line);
478 : }
479 0 : if (lineerr)
480 0 : return lineerr;
481 :
482 : /* The !line catches the case of an empty DIR file. We handle this
483 : the same as a non-matching version. */
484 0 : if (!line || strtol (line+2, NULL, 10) != DBDIRVERSION)
485 : {
486 0 : if (!created && cleanup_on_mismatch)
487 : {
488 0 : log_error (_("old version of cache directory - cleaning up\n"));
489 0 : es_fclose (fp);
490 0 : *fpadr = NULL;
491 0 : if (!cleanup_cache_dir (1))
492 : {
493 0 : *lineno = 0;
494 0 : fp = *fpadr = open_dir_file (fname);
495 0 : if (!fp)
496 : {
497 0 : xfree (line);
498 0 : return gpg_error (GPG_ERR_CONFIGURATION);
499 : }
500 0 : created = 1;
501 0 : goto retry;
502 : }
503 : }
504 0 : log_error (_("old version of cache directory - giving up\n"));
505 0 : xfree (line);
506 0 : return gpg_error (GPG_ERR_CONFIGURATION);
507 : }
508 0 : xfree (line);
509 0 : return 0;
510 : }
511 :
512 :
513 : /* Open the dir file and read in all available information. Store
514 : that in a newly allocated cache object and return that if
515 : everything worked out fine. Create the cache directory and the dir
516 : if it does not yet exist. Remove all files in that directory if
517 : the version does not match. */
518 : static gpg_error_t
519 0 : open_dir (crl_cache_t *r_cache)
520 : {
521 : crl_cache_t cache;
522 : char *fname;
523 0 : char *line = NULL;
524 0 : gpg_error_t lineerr = 0;
525 : estream_t fp;
526 : crl_cache_entry_t entry, *entrytail;
527 : unsigned int lineno;
528 0 : gpg_error_t err = 0;
529 0 : int anyerr = 0;
530 :
531 0 : cache = xtrycalloc (1, sizeof *cache);
532 0 : if (!cache)
533 0 : return gpg_error_from_syserror ();
534 :
535 0 : fname = make_filename (opt.homedir_cache, DBDIR_D, DBDIRFILE, NULL);
536 :
537 0 : lineno = 0;
538 0 : fp = open_dir_file (fname);
539 0 : if (!fp)
540 : {
541 0 : err = gpg_error (GPG_ERR_CONFIGURATION);
542 0 : goto leave;
543 : }
544 :
545 0 : err = check_dir_version (&fp, fname, &lineno, 1);
546 0 : if (err)
547 0 : goto leave;
548 :
549 :
550 : /* Read in all supported entries from the dir file. */
551 0 : cache->entries = NULL;
552 0 : entrytail = &cache->entries;
553 0 : xfree (line);
554 0 : while ((line = next_line_from_file (fp, &lineerr)))
555 : {
556 : int fieldno;
557 : char *p, *endp;
558 :
559 0 : lineno++;
560 0 : if ( *line == 'c' || *line == 'u' || *line == 'i' )
561 : {
562 0 : entry = xtrycalloc (1, sizeof *entry);
563 0 : if (!entry)
564 : {
565 0 : err = gpg_error_from_syserror ();
566 0 : goto leave;
567 : }
568 0 : entry->lineno = lineno;
569 0 : entry->release_ptr = line;
570 0 : if (*line == 'i')
571 : {
572 0 : entry->invalid = atoi (line+1);
573 0 : if (entry->invalid < 1)
574 0 : entry->invalid = 1;
575 : }
576 0 : else if (*line == 'u')
577 0 : entry->user_trust_req = 1;
578 :
579 0 : for (fieldno=1, p = line; p; p = endp, fieldno++)
580 : {
581 0 : endp = strchr (p, ':');
582 0 : if (endp)
583 0 : *endp++ = '\0';
584 :
585 0 : switch (fieldno)
586 : {
587 0 : case 1: /* record type */ break;
588 0 : case 2: entry->issuer_hash = p; break;
589 0 : case 3: entry->issuer = unpercent_string (p); break;
590 0 : case 4: entry->url = unpercent_string (p); break;
591 : case 5:
592 0 : strncpy (entry->this_update, p, 15);
593 0 : entry->this_update[15] = 0;
594 0 : break;
595 : case 6:
596 0 : strncpy (entry->next_update, p, 15);
597 0 : entry->next_update[15] = 0;
598 0 : break;
599 0 : case 7: entry->dbfile_hash = p; break;
600 0 : case 8: if (*p) entry->crl_number = p; break;
601 : case 9:
602 0 : if (*p)
603 0 : entry->authority_issuer = unpercent_string (p);
604 0 : break;
605 : case 10:
606 0 : if (*p)
607 0 : entry->authority_serialno = unpercent_string (p);
608 0 : break;
609 : case 11:
610 0 : if (*p)
611 0 : entry->check_trust_anchor = xtrystrdup (p);
612 0 : break;
613 : default:
614 0 : if (*p)
615 0 : log_info (_("extra field detected in crl record of "
616 : "'%s' line %u\n"), fname, lineno);
617 0 : break;
618 : }
619 : }
620 :
621 0 : if (!entry->issuer_hash)
622 : {
623 0 : log_info (_("invalid line detected in '%s' line %u\n"),
624 : fname, lineno);
625 0 : xfree (entry);
626 0 : entry = NULL;
627 : }
628 0 : else if (find_entry (cache->entries, entry->issuer_hash))
629 : {
630 : /* Fixme: The duplicate checking used is not very
631 : effective for large numbers of issuers. */
632 0 : log_info (_("duplicate entry detected in '%s' line %u\n"),
633 : fname, lineno);
634 0 : xfree (entry);
635 0 : entry = NULL;
636 : }
637 : else
638 : {
639 0 : line = NULL;
640 0 : *entrytail = entry;
641 0 : entrytail = &entry->next;
642 : }
643 : }
644 0 : else if (*line == '#')
645 : ;
646 : else
647 0 : log_info (_("unsupported record type in '%s' line %u skipped\n"),
648 : fname, lineno);
649 :
650 0 : if (line)
651 0 : xfree (line);
652 : }
653 0 : if (lineerr)
654 : {
655 0 : err = lineerr;
656 0 : log_error (_("error reading '%s': %s\n"), fname, gpg_strerror (err));
657 0 : goto leave;
658 : }
659 0 : if (es_ferror (fp))
660 : {
661 0 : log_error (_("error reading '%s': %s\n"), fname, strerror (errno));
662 0 : err = gpg_error (GPG_ERR_CONFIGURATION);
663 0 : goto leave;
664 : }
665 :
666 : /* Now do some basic checks on the data. */
667 0 : for (entry = cache->entries; entry; entry = entry->next)
668 : {
669 0 : assert (entry->lineno);
670 0 : if (strlen (entry->issuer_hash) != 40)
671 : {
672 0 : anyerr++;
673 0 : log_error (_("invalid issuer hash in '%s' line %u\n"),
674 : fname, entry->lineno);
675 : }
676 0 : else if ( !*entry->issuer )
677 : {
678 0 : anyerr++;
679 0 : log_error (_("no issuer DN in '%s' line %u\n"),
680 : fname, entry->lineno);
681 : }
682 0 : else if ( check_isotime (entry->this_update)
683 0 : || check_isotime (entry->next_update))
684 : {
685 0 : anyerr++;
686 0 : log_error (_("invalid timestamp in '%s' line %u\n"),
687 : fname, entry->lineno);
688 : }
689 :
690 : /* Checks not leading to an immediate fail. */
691 0 : if (strlen (entry->dbfile_hash) != 32)
692 0 : log_info (_("WARNING: invalid cache file hash in '%s' line %u\n"),
693 : fname, entry->lineno);
694 : }
695 :
696 0 : if (anyerr)
697 : {
698 0 : log_error (_("detected errors in cache dir file\n"));
699 0 : log_info (_("please check the reason and manually delete that file\n"));
700 0 : err = gpg_error (GPG_ERR_CONFIGURATION);
701 : }
702 :
703 :
704 : leave:
705 0 : es_fclose (fp);
706 0 : xfree (line);
707 0 : xfree (fname);
708 0 : if (err)
709 : {
710 0 : release_cache (cache);
711 0 : cache = NULL;
712 : }
713 0 : *r_cache = cache;
714 0 : return err;
715 : }
716 :
717 : static void
718 0 : write_percented_string (const char *s, estream_t fp)
719 : {
720 0 : for (; *s; s++)
721 0 : if (*s == ':')
722 0 : es_fputs ("%3A", fp);
723 0 : else if (*s == '\n')
724 0 : es_fputs ("%0A", fp);
725 0 : else if (*s == '\r')
726 0 : es_fputs ("%0D", fp);
727 : else
728 0 : es_putc (*s, fp);
729 0 : }
730 :
731 :
732 : static void
733 0 : write_dir_line_crl (estream_t fp, crl_cache_entry_t e)
734 : {
735 0 : if (e->invalid)
736 0 : es_fprintf (fp, "i%d", e->invalid);
737 0 : else if (e->user_trust_req)
738 0 : es_putc ('u', fp);
739 : else
740 0 : es_putc ('c', fp);
741 0 : es_putc (':', fp);
742 0 : es_fputs (e->issuer_hash, fp);
743 0 : es_putc (':', fp);
744 0 : write_percented_string (e->issuer, fp);
745 0 : es_putc (':', fp);
746 0 : write_percented_string (e->url, fp);
747 0 : es_putc (':', fp);
748 0 : es_fwrite (e->this_update, 15, 1, fp);
749 0 : es_putc (':', fp);
750 0 : es_fwrite (e->next_update, 15, 1, fp);
751 0 : es_putc (':', fp);
752 0 : es_fputs (e->dbfile_hash, fp);
753 0 : es_putc (':', fp);
754 0 : if (e->crl_number)
755 0 : es_fputs (e->crl_number, fp);
756 0 : es_putc (':', fp);
757 0 : if (e->authority_issuer)
758 0 : write_percented_string (e->authority_issuer, fp);
759 0 : es_putc (':', fp);
760 0 : if (e->authority_serialno)
761 0 : es_fputs (e->authority_serialno, fp);
762 0 : es_putc (':', fp);
763 0 : if (e->check_trust_anchor && e->user_trust_req)
764 0 : es_fputs (e->check_trust_anchor, fp);
765 0 : es_putc ('\n', fp);
766 0 : }
767 :
768 :
769 : /* Update the current dir file using the cache. */
770 : static gpg_error_t
771 0 : update_dir (crl_cache_t cache)
772 : {
773 0 : char *fname = NULL;
774 0 : char *tmpfname = NULL;
775 0 : char *line = NULL;
776 0 : gpg_error_t lineerr = 0;
777 : estream_t fp;
778 0 : estream_t fpout = NULL;
779 : crl_cache_entry_t e;
780 : unsigned int lineno;
781 0 : gpg_error_t err = 0;
782 :
783 0 : fname = make_filename (opt.homedir_cache, DBDIR_D, DBDIRFILE, NULL);
784 :
785 : /* Fixme: Take an update file lock here. */
786 :
787 0 : for (e= cache->entries; e; e = e->next)
788 0 : e->mark = 1;
789 :
790 0 : lineno = 0;
791 0 : fp = es_fopen (fname, "r");
792 0 : if (!fp)
793 : {
794 0 : err = gpg_error_from_errno (errno);
795 0 : log_error (_("failed to open cache dir file '%s': %s\n"),
796 0 : fname, strerror (errno));
797 0 : goto leave;
798 : }
799 0 : err = check_dir_version (&fp, fname, &lineno, 0);
800 0 : if (err)
801 0 : goto leave;
802 0 : es_rewind (fp);
803 0 : lineno = 0;
804 :
805 : /* Create a temporary DIR file. */
806 : {
807 : char *tmpbuf, *p;
808 : const char *nodename;
809 : #ifndef HAVE_W32_SYSTEM
810 : struct utsname utsbuf;
811 : #endif
812 :
813 : #ifdef HAVE_W32_SYSTEM
814 : nodename = "unknown";
815 : #else
816 0 : if (uname (&utsbuf))
817 0 : nodename = "unknown";
818 : else
819 0 : nodename = utsbuf.nodename;
820 : #endif
821 :
822 0 : gpgrt_asprintf (&tmpbuf, "DIR-tmp-%s-%u-%p.txt.tmp",
823 0 : nodename, (unsigned int)getpid (), &tmpbuf);
824 0 : if (!tmpbuf)
825 : {
826 0 : err = gpg_error_from_errno (errno);
827 0 : log_error (_("failed to create temporary cache dir file '%s': %s\n"),
828 0 : tmpfname, strerror (errno));
829 0 : goto leave;
830 : }
831 0 : for (p=tmpbuf; *p; p++)
832 0 : if (*p == '/')
833 0 : *p = '.';
834 0 : tmpfname = make_filename (opt.homedir_cache, DBDIR_D, tmpbuf, NULL);
835 0 : xfree (tmpbuf);
836 : }
837 0 : fpout = es_fopen (tmpfname, "w");
838 0 : if (!fpout)
839 : {
840 0 : err = gpg_error_from_errno (errno);
841 0 : log_error (_("failed to create temporary cache dir file '%s': %s\n"),
842 0 : tmpfname, strerror (errno));
843 0 : goto leave;
844 : }
845 :
846 0 : while ((line = next_line_from_file (fp, &lineerr)))
847 : {
848 0 : lineno++;
849 0 : if (*line == 'c' || *line == 'u' || *line == 'i')
850 0 : {
851 : /* Extract the issuer hash field. */
852 : char *fieldp, *endp;
853 :
854 0 : fieldp = strchr (line, ':');
855 0 : endp = fieldp? strchr (++fieldp, ':') : NULL;
856 0 : if (endp)
857 : {
858 : /* There should be no percent within the issuer hash
859 : field, thus we can compare it pretty easily. */
860 0 : *endp = 0;
861 0 : e = find_entry ( cache->entries, fieldp);
862 0 : *endp = ':'; /* Restore original line. */
863 0 : if (e && e->deleted)
864 : {
865 : /* Marked for deletion, so don't write it. */
866 0 : e->mark = 0;
867 : }
868 0 : else if (e)
869 : {
870 : /* Yep, this is valid entry we know about; write it out */
871 0 : write_dir_line_crl (fpout, e);
872 0 : e->mark = 0;
873 : }
874 : else
875 : { /* We ignore entries we don't have in our cache
876 : because they may have been added in the meantime
877 : by other instances of dirmngr. */
878 0 : es_fprintf (fpout, "# Next line added by "
879 : "another process; our pid is %lu\n",
880 0 : (unsigned long)getpid ());
881 0 : es_fputs (line, fpout);
882 0 : es_putc ('\n', fpout);
883 : }
884 : }
885 : else
886 : {
887 0 : es_fputs ("# Invalid line detected: ", fpout);
888 0 : es_fputs (line, fpout);
889 0 : es_putc ('\n', fpout);
890 : }
891 : }
892 : else
893 : {
894 : /* Write out all non CRL lines as they are. */
895 0 : es_fputs (line, fpout);
896 0 : es_putc ('\n', fpout);
897 : }
898 :
899 0 : xfree (line);
900 : }
901 0 : if (!es_ferror (fp) && !es_ferror (fpout) && !lineerr)
902 : {
903 : /* Write out the remaining entries. */
904 0 : for (e= cache->entries; e; e = e->next)
905 0 : if (e->mark)
906 : {
907 0 : if (!e->deleted)
908 0 : write_dir_line_crl (fpout, e);
909 0 : e->mark = 0;
910 : }
911 : }
912 0 : if (lineerr)
913 : {
914 0 : err = lineerr;
915 0 : log_error (_("error reading '%s': %s\n"), fname, gpg_strerror (err));
916 0 : goto leave;
917 : }
918 0 : if (es_ferror (fp))
919 : {
920 0 : err = gpg_error_from_errno (errno);
921 0 : log_error (_("error reading '%s': %s\n"), fname, strerror (errno));
922 : }
923 0 : if (es_ferror (fpout))
924 : {
925 0 : err = gpg_error_from_errno (errno);
926 0 : log_error (_("error writing '%s': %s\n"), tmpfname, strerror (errno));
927 : }
928 0 : if (err)
929 0 : goto leave;
930 :
931 : /* Rename the files. */
932 0 : es_fclose (fp);
933 0 : fp = NULL;
934 0 : if (es_fclose (fpout))
935 : {
936 0 : err = gpg_error_from_errno (errno);
937 0 : log_error (_("error closing '%s': %s\n"), tmpfname, strerror (errno));
938 0 : goto leave;
939 : }
940 0 : fpout = NULL;
941 :
942 : #ifdef HAVE_W32_SYSTEM
943 : /* No atomic mv on W32 systems. */
944 : gnupg_remove (fname);
945 : #endif
946 0 : if (rename (tmpfname, fname))
947 : {
948 0 : err = gpg_error_from_errno (errno);
949 0 : log_error (_("error renaming '%s' to '%s': %s\n"),
950 0 : tmpfname, fname, strerror (errno));
951 0 : goto leave;
952 : }
953 :
954 : leave:
955 : /* Fixme: Relinquish update lock. */
956 0 : xfree (line);
957 0 : es_fclose (fp);
958 0 : xfree (fname);
959 0 : if (fpout)
960 : {
961 0 : es_fclose (fpout);
962 0 : if (err && tmpfname)
963 0 : gnupg_remove (tmpfname);
964 : }
965 0 : xfree (tmpfname);
966 0 : return err;
967 : }
968 :
969 :
970 :
971 :
972 : /* Create the filename for the cache file from the 40 byte ISSUER_HASH
973 : string. Caller must release the return string. */
974 : static char *
975 0 : make_db_file_name (const char *issuer_hash)
976 : {
977 : char bname[50];
978 :
979 0 : assert (strlen (issuer_hash) == 40);
980 0 : memcpy (bname, "crl-", 4);
981 0 : memcpy (bname + 4, issuer_hash, 40);
982 0 : strcpy (bname + 44, ".db");
983 0 : return make_filename (opt.homedir_cache, DBDIR_D, bname, NULL);
984 : }
985 :
986 :
987 : /* Hash the file FNAME and return the MD5 digest in MD5BUFFER. The
988 : caller must allocate MD%buffer wityh at least 16 bytes. Returns 0
989 : on success. */
990 : static int
991 0 : hash_dbfile (const char *fname, unsigned char *md5buffer)
992 : {
993 : estream_t fp;
994 : char *buffer;
995 : size_t n;
996 : gcry_md_hd_t md5;
997 : gpg_error_t err;
998 :
999 0 : buffer = xtrymalloc (65536);
1000 0 : fp = buffer? es_fopen (fname, "rb") : NULL;
1001 0 : if (!fp)
1002 : {
1003 0 : log_error (_("can't hash '%s': %s\n"), fname, strerror (errno));
1004 0 : xfree (buffer);
1005 0 : return -1;
1006 : }
1007 :
1008 0 : err = gcry_md_open (&md5, GCRY_MD_MD5, 0);
1009 0 : if (err)
1010 : {
1011 0 : log_error (_("error setting up MD5 hash context: %s\n"),
1012 : gpg_strerror (err));
1013 0 : xfree (buffer);
1014 0 : es_fclose (fp);
1015 0 : return -1;
1016 : }
1017 :
1018 : /* We better hash some information about the cache file layout in. */
1019 0 : sprintf (buffer, "%.100s/%.100s:%d", DBDIR_D, DBDIRFILE, DBDIRVERSION);
1020 0 : gcry_md_write (md5, buffer, strlen (buffer));
1021 :
1022 : for (;;)
1023 : {
1024 0 : n = es_fread (buffer, 1, 65536, fp);
1025 0 : if (n < 65536 && es_ferror (fp))
1026 : {
1027 0 : log_error (_("error hashing '%s': %s\n"), fname, strerror (errno));
1028 0 : xfree (buffer);
1029 0 : es_fclose (fp);
1030 0 : gcry_md_close (md5);
1031 0 : return -1;
1032 : }
1033 0 : if (!n)
1034 0 : break;
1035 0 : gcry_md_write (md5, buffer, n);
1036 0 : }
1037 0 : es_fclose (fp);
1038 0 : xfree (buffer);
1039 0 : gcry_md_final (md5);
1040 :
1041 0 : memcpy (md5buffer, gcry_md_read (md5, GCRY_MD_MD5), 16);
1042 0 : gcry_md_close (md5);
1043 0 : return 0;
1044 : }
1045 :
1046 : /* Compare the file FNAME against the dexified MD5 hash MD5HASH and
1047 : return 0 if they match. */
1048 : static int
1049 0 : check_dbfile (const char *fname, const char *md5hexvalue)
1050 : {
1051 : unsigned char buffer1[16], buffer2[16];
1052 :
1053 0 : if (strlen (md5hexvalue) != 32)
1054 : {
1055 0 : log_error (_("invalid formatted checksum for '%s'\n"), fname);
1056 0 : return -1;
1057 : }
1058 0 : unhexify (buffer1, md5hexvalue);
1059 :
1060 0 : if (hash_dbfile (fname, buffer2))
1061 0 : return -1;
1062 :
1063 0 : return memcmp (buffer1, buffer2, 16);
1064 : }
1065 :
1066 :
1067 : /* Open the cache file for ENTRY. This function implements a caching
1068 : strategy and might close unused cache files. It is required to use
1069 : unlock_db_file after using the file. */
1070 : static struct cdb *
1071 0 : lock_db_file (crl_cache_t cache, crl_cache_entry_t entry)
1072 : {
1073 : char *fname;
1074 : int fd;
1075 : int open_count;
1076 : crl_cache_entry_t e;
1077 :
1078 0 : if (entry->cdb)
1079 : {
1080 0 : entry->cdb_use_count++;
1081 0 : return entry->cdb;
1082 : }
1083 :
1084 0 : for (open_count = 0, e = cache->entries; e; e = e->next)
1085 : {
1086 0 : if (e->cdb)
1087 0 : open_count++;
1088 : /* log_debug ("CACHE: cdb=%p use_count=%u lru_count=%u\n", */
1089 : /* e->cdb,e->cdb_use_count,e->cdb_lru_count); */
1090 : }
1091 :
1092 : /* If there are too many file open, find the least recent used DB
1093 : file and close it. Note that for Pth thread safeness we need to
1094 : use a loop here. */
1095 0 : while (open_count >= MAX_OPEN_DB_FILES )
1096 : {
1097 0 : crl_cache_entry_t last_e = NULL;
1098 0 : unsigned int last_lru = (unsigned int)(-1);
1099 :
1100 0 : for (e = cache->entries; e; e = e->next)
1101 0 : if (e->cdb && !e->cdb_use_count && e->cdb_lru_count < last_lru)
1102 : {
1103 0 : last_lru = e->cdb_lru_count;
1104 0 : last_e = e;
1105 : }
1106 0 : if (!last_e)
1107 : {
1108 0 : log_error (_("too many open cache files; can't open anymore\n"));
1109 0 : return NULL;
1110 : }
1111 :
1112 : /* log_debug ("CACHE: closing file at cdb=%p\n", last_e->cdb); */
1113 :
1114 0 : fd = cdb_fileno (last_e->cdb);
1115 0 : cdb_free (last_e->cdb);
1116 0 : xfree (last_e->cdb);
1117 0 : last_e->cdb = NULL;
1118 0 : if (close (fd))
1119 0 : log_error (_("error closing cache file: %s\n"), strerror(errno));
1120 0 : open_count--;
1121 : }
1122 :
1123 :
1124 0 : fname = make_db_file_name (entry->issuer_hash);
1125 0 : if (opt.verbose)
1126 0 : log_info (_("opening cache file '%s'\n"), fname );
1127 :
1128 0 : if (!entry->dbfile_checked)
1129 : {
1130 0 : if (!check_dbfile (fname, entry->dbfile_hash))
1131 0 : entry->dbfile_checked = 1;
1132 : /* Note, in case of an error we don't print an error here but
1133 : let require the caller to do that check. */
1134 : }
1135 :
1136 0 : entry->cdb = xtrycalloc (1, sizeof *entry->cdb);
1137 0 : if (!entry->cdb)
1138 : {
1139 0 : xfree (fname);
1140 0 : return NULL;
1141 : }
1142 0 : fd = open (fname, O_RDONLY);
1143 0 : if (fd == -1)
1144 : {
1145 0 : log_error (_("error opening cache file '%s': %s\n"),
1146 0 : fname, strerror (errno));
1147 0 : xfree (entry->cdb);
1148 0 : entry->cdb = NULL;
1149 0 : xfree (fname);
1150 0 : return NULL;
1151 : }
1152 0 : if (cdb_init (entry->cdb, fd))
1153 : {
1154 0 : log_error (_("error initializing cache file '%s' for reading: %s\n"),
1155 0 : fname, strerror (errno));
1156 0 : xfree (entry->cdb);
1157 0 : entry->cdb = NULL;
1158 0 : close (fd);
1159 0 : xfree (fname);
1160 0 : return NULL;
1161 : }
1162 0 : xfree (fname);
1163 :
1164 0 : entry->cdb_use_count = 1;
1165 0 : entry->cdb_lru_count = 0;
1166 :
1167 0 : return entry->cdb;
1168 : }
1169 :
1170 : /* Unlock a cache file, so that it can be reused. */
1171 : static void
1172 0 : unlock_db_file (crl_cache_t cache, crl_cache_entry_t entry)
1173 : {
1174 0 : if (!entry->cdb)
1175 0 : log_error (_("calling unlock_db_file on a closed file\n"));
1176 0 : else if (!entry->cdb_use_count)
1177 0 : log_error (_("calling unlock_db_file on an unlocked file\n"));
1178 : else
1179 : {
1180 0 : entry->cdb_use_count--;
1181 0 : entry->cdb_lru_count++;
1182 : }
1183 :
1184 : /* If the entry was marked for deletion in the meantime do it now.
1185 : We do this for the sake of Pth thread safeness. */
1186 0 : if (!entry->cdb_use_count && entry->deleted)
1187 : {
1188 : crl_cache_entry_t eprev, enext;
1189 :
1190 0 : enext = entry->next;
1191 0 : for (eprev = cache->entries;
1192 0 : eprev && eprev->next != entry; eprev = eprev->next)
1193 : ;
1194 0 : assert (eprev);
1195 0 : if (eprev == cache->entries)
1196 0 : cache->entries = enext;
1197 : else
1198 0 : eprev->next = enext;
1199 : /* FIXME: Do we leak ENTRY? */
1200 : }
1201 0 : }
1202 :
1203 :
1204 : /* Find ISSUER_HASH in our cache FIRST. This may be used to enumerate
1205 : the linked list we use to keep the CRLs of an issuer. */
1206 : static crl_cache_entry_t
1207 0 : find_entry (crl_cache_entry_t first, const char *issuer_hash)
1208 : {
1209 0 : while (first && (first->deleted || strcmp (issuer_hash, first->issuer_hash)))
1210 0 : first = first->next;
1211 0 : return first;
1212 : }
1213 :
1214 :
1215 : /* Create a new CRL cache. This function is usually called only once.
1216 : never fail. */
1217 : void
1218 0 : crl_cache_init(void)
1219 : {
1220 0 : crl_cache_t cache = NULL;
1221 : gpg_error_t err;
1222 :
1223 0 : if (current_cache)
1224 : {
1225 0 : log_error ("crl cache has already been initialized - not doing twice\n");
1226 0 : return;
1227 : }
1228 :
1229 0 : err = open_dir (&cache);
1230 0 : if (err)
1231 0 : log_fatal (_("failed to create a new cache object: %s\n"),
1232 : gpg_strerror (err));
1233 0 : current_cache = cache;
1234 : }
1235 :
1236 :
1237 : /* Remove the cache information and all its resources. Note that we
1238 : still keep the cache on disk. */
1239 : void
1240 0 : crl_cache_deinit (void)
1241 : {
1242 0 : if (current_cache)
1243 : {
1244 0 : release_cache (current_cache);
1245 0 : current_cache = NULL;
1246 : }
1247 0 : }
1248 :
1249 :
1250 : /* Delete the cache from disk. Return 0 on success.*/
1251 : int
1252 0 : crl_cache_flush (void)
1253 : {
1254 : int rc;
1255 :
1256 0 : rc = cleanup_cache_dir (0)? -1 : 0;
1257 :
1258 0 : return rc;
1259 : }
1260 :
1261 :
1262 : /* Check whether the certificate identified by ISSUER_HASH and
1263 : SN/SNLEN is valid; i.e. not listed in our cache. With
1264 : FORCE_REFRESH set to true, a new CRL will be retrieved even if the
1265 : cache has not yet expired. We use a 30 minutes threshold here so
1266 : that invoking this function several times won't load the CRL over
1267 : and over. */
1268 : static crl_cache_result_t
1269 0 : cache_isvalid (ctrl_t ctrl, const char *issuer_hash,
1270 : const unsigned char *sn, size_t snlen,
1271 : int force_refresh)
1272 : {
1273 0 : crl_cache_t cache = get_current_cache ();
1274 : crl_cache_result_t retval;
1275 : struct cdb *cdb;
1276 : int rc;
1277 : crl_cache_entry_t entry;
1278 : gnupg_isotime_t current_time;
1279 : size_t n;
1280 :
1281 : (void)ctrl;
1282 :
1283 0 : entry = find_entry (cache->entries, issuer_hash);
1284 0 : if (!entry)
1285 : {
1286 0 : log_info (_("no CRL available for issuer id %s\n"), issuer_hash );
1287 0 : return CRL_CACHE_DONTKNOW;
1288 : }
1289 :
1290 0 : gnupg_get_isotime (current_time);
1291 0 : if (strcmp (entry->next_update, current_time) < 0 )
1292 : {
1293 0 : log_info (_("cached CRL for issuer id %s too old; update required\n"),
1294 : issuer_hash);
1295 0 : return CRL_CACHE_DONTKNOW;
1296 : }
1297 0 : if (force_refresh)
1298 : {
1299 : gnupg_isotime_t tmptime;
1300 :
1301 0 : if (*entry->last_refresh)
1302 : {
1303 0 : gnupg_copy_time (tmptime, entry->last_refresh);
1304 0 : add_seconds_to_isotime (tmptime, 30 * 60);
1305 0 : if (strcmp (tmptime, current_time) < 0 )
1306 : {
1307 0 : log_info (_("force-crl-refresh active and %d minutes passed for"
1308 : " issuer id %s; update required\n"),
1309 : 30, issuer_hash);
1310 0 : return CRL_CACHE_DONTKNOW;
1311 : }
1312 : }
1313 : else
1314 : {
1315 0 : log_info (_("force-crl-refresh active for"
1316 : " issuer id %s; update required\n"),
1317 : issuer_hash);
1318 0 : return CRL_CACHE_DONTKNOW;
1319 : }
1320 : }
1321 :
1322 0 : if (entry->invalid)
1323 : {
1324 0 : log_info (_("available CRL for issuer ID %s can't be used\n"),
1325 : issuer_hash);
1326 0 : return CRL_CACHE_CANTUSE;
1327 : }
1328 :
1329 0 : cdb = lock_db_file (cache, entry);
1330 0 : if (!cdb)
1331 0 : return CRL_CACHE_DONTKNOW; /* Hmmm, not the best error code. */
1332 :
1333 0 : if (!entry->dbfile_checked)
1334 : {
1335 0 : log_error (_("cached CRL for issuer id %s tampered; we need to update\n")
1336 : , issuer_hash);
1337 0 : unlock_db_file (cache, entry);
1338 0 : return CRL_CACHE_DONTKNOW;
1339 : }
1340 :
1341 0 : rc = cdb_find (cdb, sn, snlen);
1342 0 : if (rc == 1)
1343 : {
1344 0 : n = cdb_datalen (cdb);
1345 0 : if (n != 16)
1346 : {
1347 0 : log_error (_("WARNING: invalid cache record length for S/N "));
1348 0 : log_printf ("0x");
1349 0 : log_printhex ("", sn, snlen);
1350 : }
1351 0 : else if (opt.verbose)
1352 : {
1353 : unsigned char record[16];
1354 0 : char *tmp = hexify_data (sn, snlen, 1);
1355 :
1356 0 : if (cdb_read (cdb, record, n, cdb_datapos (cdb)))
1357 0 : log_error (_("problem reading cache record for S/N %s: %s\n"),
1358 0 : tmp, strerror (errno));
1359 : else
1360 0 : log_info (_("S/N %s is not valid; reason=%02X date=%.15s\n"),
1361 0 : tmp, *record, record+1);
1362 0 : xfree (tmp);
1363 : }
1364 0 : retval = CRL_CACHE_INVALID;
1365 : }
1366 0 : else if (!rc)
1367 : {
1368 0 : if (opt.verbose)
1369 : {
1370 0 : char *serialno = hexify_data (sn, snlen, 1);
1371 0 : log_info (_("S/N %s is valid, it is not listed in the CRL\n"),
1372 : serialno );
1373 0 : xfree (serialno);
1374 : }
1375 0 : retval = CRL_CACHE_VALID;
1376 : }
1377 : else
1378 : {
1379 0 : log_error (_("error getting data from cache file: %s\n"),
1380 0 : strerror (errno));
1381 0 : retval = CRL_CACHE_DONTKNOW;
1382 : }
1383 :
1384 :
1385 0 : if (entry->user_trust_req
1386 0 : && (retval == CRL_CACHE_VALID || retval == CRL_CACHE_INVALID))
1387 : {
1388 0 : if (!entry->check_trust_anchor)
1389 : {
1390 0 : log_error ("inconsistent data on user trust check\n");
1391 0 : retval = CRL_CACHE_CANTUSE;
1392 : }
1393 0 : else if (get_istrusted_from_client (ctrl, entry->check_trust_anchor))
1394 : {
1395 0 : if (opt.verbose)
1396 0 : log_info ("no system trust and client does not trust either\n");
1397 0 : retval = CRL_CACHE_CANTUSE;
1398 : }
1399 : else
1400 : {
1401 : /* Okay, the CRL is considered valid by the client and thus
1402 : we can return the result as is. */
1403 : }
1404 : }
1405 :
1406 0 : unlock_db_file (cache, entry);
1407 :
1408 0 : return retval;
1409 : }
1410 :
1411 :
1412 : /* Check whether the certificate identified by ISSUER_HASH and
1413 : SERIALNO is valid; i.e. not listed in our cache. With
1414 : FORCE_REFRESH set to true, a new CRL will be retrieved even if the
1415 : cache has not yet expired. We use a 30 minutes threshold here so
1416 : that invoking this function several times won't load the CRL over
1417 : and over. */
1418 : crl_cache_result_t
1419 0 : crl_cache_isvalid (ctrl_t ctrl, const char *issuer_hash, const char *serialno,
1420 : int force_refresh)
1421 : {
1422 : crl_cache_result_t result;
1423 : unsigned char snbuf_buffer[50];
1424 : unsigned char *snbuf;
1425 : size_t n;
1426 :
1427 0 : n = strlen (serialno)/2+1;
1428 0 : if (n < sizeof snbuf_buffer - 1)
1429 0 : snbuf = snbuf_buffer;
1430 : else
1431 : {
1432 0 : snbuf = xtrymalloc (n);
1433 0 : if (!snbuf)
1434 0 : return CRL_CACHE_DONTKNOW;
1435 : }
1436 :
1437 0 : n = unhexify (snbuf, serialno);
1438 :
1439 0 : result = cache_isvalid (ctrl, issuer_hash, snbuf, n, force_refresh);
1440 :
1441 0 : if (snbuf != snbuf_buffer)
1442 0 : xfree (snbuf);
1443 :
1444 0 : return result;
1445 : }
1446 :
1447 :
1448 : /* Check whether the certificate CERT is valid; i.e. not listed in our
1449 : cache. With FORCE_REFRESH set to true, a new CRL will be retrieved
1450 : even if the cache has not yet expired. We use a 30 minutes
1451 : threshold here so that invoking this function several times won't
1452 : load the CRL over and over. */
1453 : gpg_error_t
1454 0 : crl_cache_cert_isvalid (ctrl_t ctrl, ksba_cert_t cert,
1455 : int force_refresh)
1456 : {
1457 : gpg_error_t err;
1458 : crl_cache_result_t result;
1459 : unsigned char issuerhash[20];
1460 : char issuerhash_hex[41];
1461 : ksba_sexp_t serial;
1462 : unsigned char *sn;
1463 : size_t snlen;
1464 : char *endp, *tmp;
1465 : int i;
1466 :
1467 : /* Compute the hash value of the issuer name. */
1468 0 : tmp = ksba_cert_get_issuer (cert, 0);
1469 0 : if (!tmp)
1470 : {
1471 0 : log_error ("oops: issuer missing in certificate\n");
1472 0 : return gpg_error (GPG_ERR_INV_CERT_OBJ);
1473 : }
1474 0 : gcry_md_hash_buffer (GCRY_MD_SHA1, issuerhash, tmp, strlen (tmp));
1475 0 : xfree (tmp);
1476 0 : for (i=0,tmp=issuerhash_hex; i < 20; i++, tmp += 2)
1477 0 : sprintf (tmp, "%02X", issuerhash[i]);
1478 :
1479 : /* Get the serial number. */
1480 0 : serial = ksba_cert_get_serial (cert);
1481 0 : if (!serial)
1482 : {
1483 0 : log_error ("oops: S/N missing in certificate\n");
1484 0 : return gpg_error (GPG_ERR_INV_CERT_OBJ);
1485 : }
1486 0 : sn = serial;
1487 0 : if (*sn != '(')
1488 : {
1489 0 : log_error ("oops: invalid S/N\n");
1490 0 : xfree (serial);
1491 0 : return gpg_error (GPG_ERR_INV_CERT_OBJ);
1492 : }
1493 0 : sn++;
1494 0 : snlen = strtoul (sn, &endp, 10);
1495 0 : sn = endp;
1496 0 : if (*sn != ':')
1497 : {
1498 0 : log_error ("oops: invalid S/N\n");
1499 0 : xfree (serial);
1500 0 : return gpg_error (GPG_ERR_INV_CERT_OBJ);
1501 : }
1502 0 : sn++;
1503 :
1504 : /* Check the cache. */
1505 0 : result = cache_isvalid (ctrl, issuerhash_hex, sn, snlen, force_refresh);
1506 0 : switch (result)
1507 : {
1508 : case CRL_CACHE_VALID:
1509 0 : err = 0;
1510 0 : break;
1511 : case CRL_CACHE_INVALID:
1512 0 : err = gpg_error (GPG_ERR_CERT_REVOKED);
1513 0 : break;
1514 : case CRL_CACHE_DONTKNOW:
1515 0 : err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
1516 0 : break;
1517 : case CRL_CACHE_CANTUSE:
1518 0 : err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
1519 0 : break;
1520 : default:
1521 0 : log_fatal ("cache_isvalid returned invalid status code %d\n", result);
1522 : }
1523 :
1524 0 : xfree (serial);
1525 0 : return err;
1526 : }
1527 :
1528 :
1529 : /* Prepare a hash context for the signature verification. Input is
1530 : the CRL and the output is the hash context MD as well as the uses
1531 : algorithm identifier ALGO. */
1532 : static gpg_error_t
1533 0 : start_sig_check (ksba_crl_t crl, gcry_md_hd_t *md, int *algo)
1534 : {
1535 : gpg_error_t err;
1536 : const char *algoid;
1537 :
1538 0 : algoid = ksba_crl_get_digest_algo (crl);
1539 0 : *algo = gcry_md_map_name (algoid);
1540 0 : if (!*algo)
1541 : {
1542 0 : log_error (_("unknown hash algorithm '%s'\n"), algoid? algoid:"?");
1543 0 : return gpg_error (GPG_ERR_DIGEST_ALGO);
1544 : }
1545 :
1546 0 : err = gcry_md_open (md, *algo, 0);
1547 0 : if (err)
1548 : {
1549 0 : log_error (_("gcry_md_open for algorithm %d failed: %s\n"),
1550 : *algo, gcry_strerror (err));
1551 0 : return err;
1552 : }
1553 0 : if (DBG_HASHING)
1554 0 : gcry_md_debug (*md, "hash.cert");
1555 :
1556 0 : ksba_crl_set_hash_function (crl, HASH_FNC, *md);
1557 0 : return 0;
1558 : }
1559 :
1560 :
1561 : /* Finish a hash context and verify the signature. This function
1562 : should return 0 on a good signature, GPG_ERR_BAD_SIGNATURE if the
1563 : signature does not verify or any other error code. CRL is the CRL
1564 : object we are working on, MD the hash context and ISSUER_CERT the
1565 : certificate of the CRL issuer. This function closes MD. */
1566 : static gpg_error_t
1567 0 : finish_sig_check (ksba_crl_t crl, gcry_md_hd_t md, int algo,
1568 : ksba_cert_t issuer_cert)
1569 : {
1570 : gpg_error_t err;
1571 0 : ksba_sexp_t sigval = NULL, pubkey = NULL;
1572 : const char *s;
1573 : char algoname[50];
1574 : size_t n;
1575 0 : gcry_sexp_t s_sig = NULL, s_hash = NULL, s_pkey = NULL;
1576 : unsigned int i;
1577 :
1578 : /* This also stops debugging on the MD. */
1579 0 : gcry_md_final (md);
1580 :
1581 : /* Get and convert the signature value. */
1582 0 : sigval = ksba_crl_get_sig_val (crl);
1583 0 : n = gcry_sexp_canon_len (sigval, 0, NULL, NULL);
1584 0 : if (!n)
1585 : {
1586 0 : log_error (_("got an invalid S-expression from libksba\n"));
1587 0 : err = gpg_error (GPG_ERR_INV_SEXP);
1588 0 : goto leave;
1589 : }
1590 0 : err = gcry_sexp_sscan (&s_sig, NULL, sigval, n);
1591 0 : if (err)
1592 : {
1593 0 : log_error (_("converting S-expression failed: %s\n"),
1594 : gcry_strerror (err));
1595 0 : goto leave;
1596 : }
1597 :
1598 : /* Get and convert the public key for the issuer certificate. */
1599 0 : if (DBG_X509)
1600 0 : dump_cert ("crl_issuer_cert", issuer_cert);
1601 0 : pubkey = ksba_cert_get_public_key (issuer_cert);
1602 0 : n = gcry_sexp_canon_len (pubkey, 0, NULL, NULL);
1603 0 : if (!n)
1604 : {
1605 0 : log_error (_("got an invalid S-expression from libksba\n"));
1606 0 : err = gpg_error (GPG_ERR_INV_SEXP);
1607 0 : goto leave;
1608 : }
1609 0 : err = gcry_sexp_sscan (&s_pkey, NULL, pubkey, n);
1610 0 : if (err)
1611 : {
1612 0 : log_error (_("converting S-expression failed: %s\n"),
1613 : gcry_strerror (err));
1614 0 : goto leave;
1615 : }
1616 :
1617 : /* Create an S-expression with the actual hash value. */
1618 0 : s = gcry_md_algo_name (algo);
1619 0 : for (i = 0; *s && i < sizeof(algoname) - 1; s++, i++)
1620 0 : algoname[i] = ascii_tolower (*s);
1621 0 : algoname[i] = 0;
1622 0 : err = gcry_sexp_build (&s_hash, NULL, "(data(flags pkcs1)(hash %s %b))",
1623 : algoname,
1624 : gcry_md_get_algo_dlen (algo), gcry_md_read (md, algo));
1625 0 : if (err)
1626 : {
1627 0 : log_error (_("creating S-expression failed: %s\n"), gcry_strerror (err));
1628 0 : goto leave;
1629 : }
1630 :
1631 : /* Pass this on to the signature verification. */
1632 0 : err = gcry_pk_verify (s_sig, s_hash, s_pkey);
1633 0 : if (DBG_X509)
1634 0 : log_debug ("gcry_pk_verify: %s\n", gpg_strerror (err));
1635 :
1636 : leave:
1637 0 : xfree (sigval);
1638 0 : xfree (pubkey);
1639 0 : gcry_sexp_release (s_sig);
1640 0 : gcry_sexp_release (s_hash);
1641 0 : gcry_sexp_release (s_pkey);
1642 0 : gcry_md_close (md);
1643 :
1644 0 : return err;
1645 : }
1646 :
1647 :
1648 : /* Call this to match a start_sig_check that can not be completed
1649 : normally. */
1650 : static void
1651 0 : abort_sig_check (ksba_crl_t crl, gcry_md_hd_t md)
1652 : {
1653 : (void)crl;
1654 0 : gcry_md_close (md);
1655 0 : }
1656 :
1657 :
1658 : /* Workhorse of the CRL loading machinery. The CRL is read using the
1659 : CRL object and stored in the data base file DB with the name FNAME
1660 : (only used for printing error messages). That DB should be a
1661 : temporary one and not the actual one. If the function fails the
1662 : caller should delete this temporary database file. CTRL is
1663 : required to retrieve certificates using the general dirmngr
1664 : callback service. R_CRLISSUER returns an allocated string with the
1665 : crl-issuer DN, THIS_UPDATE and NEXT_UPDATE are filled with the
1666 : corresponding data from the CRL. Note that these values might get
1667 : set even if the CRL processing fails at a later step; thus the
1668 : caller should free *R_ISSUER even if the function returns with an
1669 : error. R_TRUST_ANCHOR is set on exit to NULL or a string with the
1670 : hexified fingerprint of the root certificate, if checking this
1671 : certificate for trustiness is required.
1672 : */
1673 : static int
1674 0 : crl_parse_insert (ctrl_t ctrl, ksba_crl_t crl,
1675 : struct cdb_make *cdb, const char *fname,
1676 : char **r_crlissuer,
1677 : ksba_isotime_t thisupdate, ksba_isotime_t nextupdate,
1678 : char **r_trust_anchor)
1679 : {
1680 : gpg_error_t err;
1681 : ksba_stop_reason_t stopreason;
1682 0 : ksba_cert_t crlissuer_cert = NULL;
1683 0 : gcry_md_hd_t md = NULL;
1684 0 : int algo = 0;
1685 : size_t n;
1686 :
1687 : (void)fname;
1688 :
1689 0 : *r_crlissuer = NULL;
1690 0 : *thisupdate = *nextupdate = 0;
1691 0 : *r_trust_anchor = NULL;
1692 :
1693 : /* Start of the KSBA parser loop. */
1694 : do
1695 : {
1696 0 : err = ksba_crl_parse (crl, &stopreason);
1697 0 : if (err)
1698 : {
1699 0 : log_error (_("ksba_crl_parse failed: %s\n"), gpg_strerror (err) );
1700 0 : goto failure;
1701 : }
1702 :
1703 0 : switch (stopreason)
1704 : {
1705 : case KSBA_SR_BEGIN_ITEMS:
1706 : {
1707 0 : err = start_sig_check (crl, &md, &algo);
1708 0 : if (err)
1709 0 : goto failure;
1710 :
1711 0 : err = ksba_crl_get_update_times (crl, thisupdate, nextupdate);
1712 0 : if (err)
1713 : {
1714 0 : log_error (_("error getting update times of CRL: %s\n"),
1715 : gpg_strerror (err));
1716 0 : err = gpg_error (GPG_ERR_INV_CRL);
1717 0 : goto failure;
1718 : }
1719 :
1720 0 : if (opt.verbose || !*nextupdate)
1721 0 : log_info (_("update times of this CRL: this=%s next=%s\n"),
1722 : thisupdate, nextupdate);
1723 0 : if (!*nextupdate)
1724 : {
1725 0 : log_info (_("nextUpdate not given; "
1726 : "assuming a validity period of one day\n"));
1727 0 : gnupg_copy_time (nextupdate, thisupdate);
1728 0 : add_seconds_to_isotime (nextupdate, 86400);
1729 : }
1730 : }
1731 0 : break;
1732 :
1733 : case KSBA_SR_GOT_ITEM:
1734 : {
1735 : ksba_sexp_t serial;
1736 : const unsigned char *p;
1737 : ksba_isotime_t rdate;
1738 : ksba_crl_reason_t reason;
1739 : int rc;
1740 : unsigned char record[1+15];
1741 :
1742 0 : err = ksba_crl_get_item (crl, &serial, rdate, &reason);
1743 0 : if (err)
1744 : {
1745 0 : log_error (_("error getting CRL item: %s\n"),
1746 : gpg_strerror (err));
1747 0 : err = gpg_error (GPG_ERR_INV_CRL);
1748 0 : ksba_free (serial);
1749 0 : goto failure;
1750 : }
1751 0 : p = serial_to_buffer (serial, &n);
1752 0 : if (!p)
1753 0 : BUG ();
1754 0 : record[0] = (reason & 0xff);
1755 0 : memcpy (record+1, rdate, 15);
1756 0 : rc = cdb_make_add (cdb, p, n, record, 1+15);
1757 0 : if (rc)
1758 : {
1759 0 : err = gpg_error_from_errno (errno);
1760 0 : log_error (_("error inserting item into "
1761 : "temporary cache file: %s\n"),
1762 0 : strerror (errno));
1763 0 : goto failure;
1764 : }
1765 :
1766 0 : ksba_free (serial);
1767 : }
1768 0 : break;
1769 :
1770 : case KSBA_SR_END_ITEMS:
1771 0 : break;
1772 :
1773 : case KSBA_SR_READY:
1774 : {
1775 : char *crlissuer;
1776 : ksba_name_t authid;
1777 : ksba_sexp_t authidsn;
1778 : ksba_sexp_t keyid;
1779 :
1780 : /* We need to look for the issuer only after having read
1781 : all items. The issuer itselfs comes before the items
1782 : but the optional authorityKeyIdentifier comes after the
1783 : items. */
1784 0 : err = ksba_crl_get_issuer (crl, &crlissuer);
1785 0 : if( err )
1786 : {
1787 0 : log_error (_("no CRL issuer found in CRL: %s\n"),
1788 : gpg_strerror (err) );
1789 0 : err = gpg_error (GPG_ERR_INV_CRL);
1790 0 : goto failure;
1791 : }
1792 : /* Note: This should be released by ksba_free, not xfree.
1793 : May need a memory reallocation dance. */
1794 0 : *r_crlissuer = crlissuer; /* (Do it here so we don't need
1795 : to free it later) */
1796 :
1797 0 : if (!ksba_crl_get_auth_key_id (crl, &keyid, &authid, &authidsn))
1798 : {
1799 : const char *s;
1800 :
1801 0 : if (opt.verbose)
1802 0 : log_info (_("locating CRL issuer certificate by "
1803 : "authorityKeyIdentifier\n"));
1804 :
1805 0 : s = ksba_name_enum (authid, 0);
1806 0 : if (s && *authidsn)
1807 0 : crlissuer_cert = find_cert_bysn (ctrl, s, authidsn);
1808 0 : if (!crlissuer_cert && keyid)
1809 0 : crlissuer_cert = find_cert_bysubject (ctrl,
1810 : crlissuer, keyid);
1811 :
1812 0 : if (!crlissuer_cert)
1813 : {
1814 0 : log_info ("CRL issuer certificate ");
1815 0 : if (keyid)
1816 : {
1817 0 : log_printf ("{");
1818 0 : dump_serial (keyid);
1819 0 : log_printf ("} ");
1820 : }
1821 0 : if (authidsn)
1822 : {
1823 0 : log_printf ("(#");
1824 0 : dump_serial (authidsn);
1825 0 : log_printf ("/");
1826 0 : dump_string (s);
1827 0 : log_printf (") ");
1828 : }
1829 0 : log_printf ("not found\n");
1830 : }
1831 0 : ksba_name_release (authid);
1832 0 : xfree (authidsn);
1833 0 : xfree (keyid);
1834 : }
1835 : else
1836 0 : crlissuer_cert = find_cert_bysubject (ctrl, crlissuer, NULL);
1837 0 : err = 0;
1838 0 : if (!crlissuer_cert)
1839 : {
1840 0 : err = gpg_error (GPG_ERR_MISSING_CERT);
1841 0 : goto failure;
1842 : }
1843 :
1844 0 : err = finish_sig_check (crl, md, algo, crlissuer_cert);
1845 0 : if (err)
1846 : {
1847 0 : log_error (_("CRL signature verification failed: %s\n"),
1848 : gpg_strerror (err));
1849 0 : goto failure;
1850 : }
1851 0 : md = NULL;
1852 :
1853 0 : err = validate_cert_chain (ctrl, crlissuer_cert, NULL,
1854 : VALIDATE_MODE_CRL_RECURSIVE,
1855 : r_trust_anchor);
1856 0 : if (err)
1857 : {
1858 0 : log_error (_("error checking validity of CRL "
1859 : "issuer certificate: %s\n"),
1860 : gpg_strerror (err));
1861 0 : goto failure;
1862 : }
1863 :
1864 : }
1865 0 : break;
1866 :
1867 : default:
1868 0 : log_debug ("crl_parse_insert: unknown stop reason\n");
1869 0 : err = gpg_error (GPG_ERR_BUG);
1870 0 : goto failure;
1871 : }
1872 : }
1873 0 : while (stopreason != KSBA_SR_READY);
1874 0 : assert (!err);
1875 :
1876 :
1877 : failure:
1878 0 : if (md)
1879 0 : abort_sig_check (crl, md);
1880 0 : ksba_cert_release (crlissuer_cert);
1881 0 : return err;
1882 : }
1883 :
1884 :
1885 :
1886 : /* Return the crlNumber extension as an allocated hex string or NULL
1887 : if there is none. */
1888 : static char *
1889 0 : get_crl_number (ksba_crl_t crl)
1890 : {
1891 : gpg_error_t err;
1892 : ksba_sexp_t number;
1893 : char *string;
1894 :
1895 0 : err = ksba_crl_get_crl_number (crl, &number);
1896 0 : if (err)
1897 0 : return NULL;
1898 0 : string = serial_hex (number);
1899 0 : ksba_free (number);
1900 0 : return string;
1901 : }
1902 :
1903 :
1904 : /* Return the authorityKeyIdentifier or NULL if it is not available.
1905 : The issuer name may consists of several parts - they are delimted by
1906 : 0x01. */
1907 : static char *
1908 0 : get_auth_key_id (ksba_crl_t crl, char **serialno)
1909 : {
1910 : gpg_error_t err;
1911 : ksba_name_t name;
1912 : ksba_sexp_t sn;
1913 : int idx;
1914 : const char *s;
1915 : char *string;
1916 : size_t length;
1917 :
1918 0 : *serialno = NULL;
1919 0 : err = ksba_crl_get_auth_key_id (crl, NULL, &name, &sn);
1920 0 : if (err)
1921 0 : return NULL;
1922 0 : *serialno = serial_hex (sn);
1923 0 : ksba_free (sn);
1924 :
1925 0 : if (!name)
1926 0 : return xstrdup ("");
1927 :
1928 0 : length = 0;
1929 0 : for (idx=0; (s = ksba_name_enum (name, idx)); idx++)
1930 : {
1931 0 : char *p = ksba_name_get_uri (name, idx);
1932 0 : length += strlen (p?p:s) + 1;
1933 0 : xfree (p);
1934 : }
1935 0 : string = xtrymalloc (length+1);
1936 0 : if (string)
1937 : {
1938 0 : *string = 0;
1939 0 : for (idx=0; (s = ksba_name_enum (name, idx)); idx++)
1940 : {
1941 0 : char *p = ksba_name_get_uri (name, idx);
1942 0 : if (*string)
1943 0 : strcat (string, "\x01");
1944 0 : strcat (string, p?p:s);
1945 0 : xfree (p);
1946 : }
1947 : }
1948 0 : ksba_name_release (name);
1949 0 : return string;
1950 : }
1951 :
1952 :
1953 :
1954 : /* Insert the CRL retrieved using URL into the cache specified by
1955 : CACHE. The CRL itself will be read from the stream FP and is
1956 : expected in binary format.
1957 :
1958 : Called by:
1959 : crl_cache_load
1960 : cmd_loadcrl
1961 : --load-crl
1962 : crl_cache_reload_crl
1963 : cmd_isvalid
1964 : cmd_checkcrl
1965 : cmd_loadcrl
1966 : --fetch-crl
1967 :
1968 : */
1969 : gpg_error_t
1970 0 : crl_cache_insert (ctrl_t ctrl, const char *url, ksba_reader_t reader)
1971 : {
1972 0 : crl_cache_t cache = get_current_cache ();
1973 : gpg_error_t err, err2;
1974 : ksba_crl_t crl;
1975 0 : char *fname = NULL;
1976 0 : char *newfname = NULL;
1977 : struct cdb_make cdb;
1978 0 : int fd_cdb = -1;
1979 0 : char *issuer = NULL;
1980 0 : char *issuer_hash = NULL;
1981 : ksba_isotime_t thisupdate, nextupdate;
1982 0 : crl_cache_entry_t entry = NULL;
1983 : crl_cache_entry_t e;
1984 : gnupg_isotime_t current_time;
1985 0 : char *checksum = NULL;
1986 0 : int invalidate_crl = 0;
1987 : int idx;
1988 : const char *oid;
1989 : int critical;
1990 0 : char *trust_anchor = NULL;
1991 :
1992 : /* FIXME: We should acquire a mutex for the URL, so that we don't
1993 : simultaneously enter the same CRL twice. However this needs to be
1994 : interweaved with the checking function.*/
1995 :
1996 0 : err2 = 0;
1997 :
1998 0 : err = ksba_crl_new (&crl);
1999 0 : if (err)
2000 : {
2001 0 : log_error (_("ksba_crl_new failed: %s\n"), gpg_strerror (err));
2002 0 : goto leave;
2003 : }
2004 :
2005 0 : err = ksba_crl_set_reader (crl, reader);
2006 0 : if ( err )
2007 : {
2008 0 : log_error (_("ksba_crl_set_reader failed: %s\n"), gpg_strerror (err));
2009 0 : goto leave;
2010 : }
2011 :
2012 : /* Create a temporary cache file to load the CRL into. */
2013 : {
2014 : char *tmpfname, *p;
2015 : const char *nodename;
2016 : #ifndef HAVE_W32_SYSTEM
2017 : struct utsname utsbuf;
2018 : #endif
2019 :
2020 : #ifdef HAVE_W32_SYSTEM
2021 : nodename = "unknown";
2022 : #else
2023 0 : if (uname (&utsbuf))
2024 0 : nodename = "unknown";
2025 : else
2026 0 : nodename = utsbuf.nodename;
2027 : #endif
2028 :
2029 0 : gpgrt_asprintf (&tmpfname, "crl-tmp-%s-%u-%p.db.tmp",
2030 0 : nodename, (unsigned int)getpid (), &tmpfname);
2031 0 : if (!tmpfname)
2032 : {
2033 0 : err = gpg_error_from_syserror ();
2034 0 : goto leave;
2035 : }
2036 0 : for (p=tmpfname; *p; p++)
2037 0 : if (*p == '/')
2038 0 : *p = '.';
2039 0 : fname = make_filename (opt.homedir_cache, DBDIR_D, tmpfname, NULL);
2040 0 : xfree (tmpfname);
2041 0 : if (!gnupg_remove (fname))
2042 0 : log_info (_("removed stale temporary cache file '%s'\n"), fname);
2043 0 : else if (errno != ENOENT)
2044 : {
2045 0 : err = gpg_error_from_syserror ();
2046 0 : log_error (_("problem removing stale temporary cache file '%s': %s\n"),
2047 : fname, gpg_strerror (err));
2048 0 : goto leave;
2049 : }
2050 : }
2051 :
2052 0 : fd_cdb = open (fname, O_WRONLY | O_CREAT | O_TRUNC, 0644);
2053 0 : if (fd_cdb == -1)
2054 : {
2055 0 : err = gpg_error_from_errno (errno);
2056 0 : log_error (_("error creating temporary cache file '%s': %s\n"),
2057 0 : fname, strerror (errno));
2058 0 : goto leave;
2059 : }
2060 0 : cdb_make_start(&cdb, fd_cdb);
2061 :
2062 0 : err = crl_parse_insert (ctrl, crl, &cdb, fname,
2063 : &issuer, thisupdate, nextupdate, &trust_anchor);
2064 0 : if (err)
2065 : {
2066 0 : log_error (_("crl_parse_insert failed: %s\n"), gpg_strerror (err));
2067 : /* Error in cleanup ignored. */
2068 0 : cdb_make_finish (&cdb);
2069 0 : goto leave;
2070 : }
2071 :
2072 : /* Finish the database. */
2073 0 : if (cdb_make_finish (&cdb))
2074 : {
2075 0 : err = gpg_error_from_errno (errno);
2076 0 : log_error (_("error finishing temporary cache file '%s': %s\n"),
2077 0 : fname, strerror (errno));
2078 0 : goto leave;
2079 : }
2080 0 : if (close (fd_cdb))
2081 : {
2082 0 : err = gpg_error_from_errno (errno);
2083 0 : log_error (_("error closing temporary cache file '%s': %s\n"),
2084 0 : fname, strerror (errno));
2085 0 : goto leave;
2086 : }
2087 0 : fd_cdb = -1;
2088 :
2089 :
2090 : /* Create a checksum. */
2091 : {
2092 : unsigned char md5buf[16];
2093 :
2094 0 : if (hash_dbfile (fname, md5buf))
2095 : {
2096 0 : err = gpg_error (GPG_ERR_CHECKSUM);
2097 0 : goto leave;
2098 : }
2099 0 : checksum = hexify_data (md5buf, 16, 0);
2100 : }
2101 :
2102 :
2103 : /* Check whether that new CRL is still not expired. */
2104 0 : gnupg_get_isotime (current_time);
2105 0 : if (strcmp (nextupdate, current_time) < 0 )
2106 : {
2107 0 : if (opt.force)
2108 0 : log_info (_("WARNING: new CRL still too old; it expired on %s "
2109 : "- loading anyway\n"), nextupdate);
2110 : else
2111 : {
2112 0 : log_error (_("new CRL still too old; it expired on %s\n"),
2113 : nextupdate);
2114 0 : if (!err2)
2115 0 : err2 = gpg_error (GPG_ERR_CRL_TOO_OLD);
2116 0 : invalidate_crl |= 1;
2117 : }
2118 : }
2119 :
2120 : /* Check for unknown critical extensions. */
2121 0 : for (idx=0; !(err=ksba_crl_get_extension (crl, idx, &oid, &critical,
2122 0 : NULL, NULL)); idx++)
2123 : {
2124 0 : if (!critical
2125 0 : || !strcmp (oid, oidstr_authorityKeyIdentifier)
2126 0 : || !strcmp (oid, oidstr_crlNumber) )
2127 0 : continue;
2128 0 : log_error (_("unknown critical CRL extension %s\n"), oid);
2129 0 : if (!err2)
2130 0 : err2 = gpg_error (GPG_ERR_INV_CRL);
2131 0 : invalidate_crl |= 2;
2132 : }
2133 0 : if (gpg_err_code (err) == GPG_ERR_EOF
2134 0 : || gpg_err_code (err) == GPG_ERR_NO_DATA )
2135 0 : err = 0;
2136 0 : if (err)
2137 : {
2138 0 : log_error (_("error reading CRL extensions: %s\n"), gpg_strerror (err));
2139 0 : err = gpg_error (GPG_ERR_INV_CRL);
2140 : }
2141 :
2142 :
2143 : /* Create an hex encoded SHA-1 hash of the issuer DN to be
2144 : used as the key for the cache. */
2145 0 : issuer_hash = hashify_data (issuer, strlen (issuer));
2146 :
2147 : /* Create an ENTRY. */
2148 0 : entry = xtrycalloc (1, sizeof *entry);
2149 0 : if (!entry)
2150 : {
2151 0 : err = gpg_error_from_syserror ();
2152 0 : goto leave;
2153 : }
2154 0 : entry->release_ptr = xtrymalloc (strlen (issuer_hash) + 1
2155 : + strlen (issuer) + 1
2156 : + strlen (url) + 1
2157 : + strlen (checksum) + 1);
2158 0 : if (!entry->release_ptr)
2159 : {
2160 0 : err = gpg_error_from_syserror ();
2161 0 : xfree (entry);
2162 0 : entry = NULL;
2163 0 : goto leave;
2164 : }
2165 0 : entry->issuer_hash = entry->release_ptr;
2166 0 : entry->issuer = stpcpy (entry->issuer_hash, issuer_hash) + 1;
2167 0 : entry->url = stpcpy (entry->issuer, issuer) + 1;
2168 0 : entry->dbfile_hash = stpcpy (entry->url, url) + 1;
2169 0 : strcpy (entry->dbfile_hash, checksum);
2170 0 : gnupg_copy_time (entry->this_update, thisupdate);
2171 0 : gnupg_copy_time (entry->next_update, nextupdate);
2172 0 : gnupg_copy_time (entry->last_refresh, current_time);
2173 0 : entry->crl_number = get_crl_number (crl);
2174 0 : entry->authority_issuer = get_auth_key_id (crl, &entry->authority_serialno);
2175 0 : entry->invalid = invalidate_crl;
2176 0 : entry->user_trust_req = !!trust_anchor;
2177 0 : entry->check_trust_anchor = trust_anchor;
2178 0 : trust_anchor = NULL;
2179 :
2180 : /* Check whether we already have an entry for this issuer and mark
2181 : it as deleted. We better use a loop, just in case duplicates got
2182 : somehow into the list. */
2183 0 : for (e = cache->entries; (e=find_entry (e, entry->issuer_hash)); e = e->next)
2184 0 : e->deleted = 1;
2185 :
2186 : /* Rename the temporary DB to the real name. */
2187 0 : newfname = make_db_file_name (entry->issuer_hash);
2188 0 : if (opt.verbose)
2189 0 : log_info (_("creating cache file '%s'\n"), newfname);
2190 :
2191 : /* Just in case close unused matching files. Actually we need this
2192 : only under Windows but saving file descriptors is never bad. */
2193 : {
2194 : int any;
2195 : do
2196 : {
2197 0 : any = 0;
2198 0 : for (e = cache->entries; e; e = e->next)
2199 0 : if (!e->cdb_use_count && e->cdb
2200 0 : && !strcmp (e->issuer_hash, entry->issuer_hash))
2201 : {
2202 0 : int fd = cdb_fileno (e->cdb);
2203 0 : cdb_free (e->cdb);
2204 0 : xfree (e->cdb);
2205 0 : e->cdb = NULL;
2206 0 : if (close (fd))
2207 0 : log_error (_("error closing cache file: %s\n"),
2208 0 : strerror(errno));
2209 0 : any = 1;
2210 0 : break;
2211 : }
2212 : }
2213 0 : while (any);
2214 : }
2215 : #ifdef HAVE_W32_SYSTEM
2216 : gnupg_remove (newfname);
2217 : #endif
2218 0 : if (rename (fname, newfname))
2219 : {
2220 0 : err = gpg_error_from_syserror ();
2221 0 : log_error (_("problem renaming '%s' to '%s': %s\n"),
2222 : fname, newfname, gpg_strerror (err));
2223 0 : goto leave;
2224 : }
2225 0 : xfree (fname); fname = NULL; /*(let the cleanup code not try to remove it)*/
2226 :
2227 : /* Link the new entry in. */
2228 0 : entry->next = cache->entries;
2229 0 : cache->entries = entry;
2230 0 : entry = NULL;
2231 :
2232 0 : err = update_dir (cache);
2233 0 : if (err)
2234 : {
2235 0 : log_error (_("updating the DIR file failed - "
2236 : "cache entry will get lost with the next program start\n"));
2237 0 : err = 0; /* Keep on running. */
2238 : }
2239 :
2240 :
2241 : leave:
2242 0 : release_one_cache_entry (entry);
2243 0 : if (fd_cdb != -1)
2244 0 : close (fd_cdb);
2245 0 : if (fname)
2246 : {
2247 0 : gnupg_remove (fname);
2248 0 : xfree (fname);
2249 : }
2250 0 : xfree (newfname);
2251 0 : ksba_crl_release (crl);
2252 0 : xfree (issuer);
2253 0 : xfree (issuer_hash);
2254 0 : xfree (checksum);
2255 0 : xfree (trust_anchor);
2256 0 : return err ? err : err2;
2257 : }
2258 :
2259 :
2260 : /* Print one cached entry E in a human readable format to stream
2261 : FP. Return 0 on success. */
2262 : static gpg_error_t
2263 0 : list_one_crl_entry (crl_cache_t cache, crl_cache_entry_t e, estream_t fp)
2264 : {
2265 : struct cdb_find cdbfp;
2266 : struct cdb *cdb;
2267 : int rc;
2268 0 : int warn = 0;
2269 : const unsigned char *s;
2270 :
2271 0 : es_fputs ("--------------------------------------------------------\n", fp );
2272 0 : es_fprintf (fp, _("Begin CRL dump (retrieved via %s)\n"), e->url );
2273 0 : es_fprintf (fp, " Issuer:\t%s\n", e->issuer );
2274 0 : es_fprintf (fp, " Issuer Hash:\t%s\n", e->issuer_hash );
2275 0 : es_fprintf (fp, " This Update:\t%s\n", e->this_update );
2276 0 : es_fprintf (fp, " Next Update:\t%s\n", e->next_update );
2277 0 : es_fprintf (fp, " CRL Number :\t%s\n", e->crl_number? e->crl_number: "none");
2278 0 : es_fprintf (fp, " AuthKeyId :\t%s\n",
2279 0 : e->authority_serialno? e->authority_serialno:"none");
2280 0 : if (e->authority_serialno && e->authority_issuer)
2281 : {
2282 0 : es_fputs (" \t", fp);
2283 0 : for (s=e->authority_issuer; *s; s++)
2284 0 : if (*s == '\x01')
2285 0 : es_fputs ("\n \t", fp);
2286 : else
2287 0 : es_putc (*s, fp);
2288 0 : es_putc ('\n', fp);
2289 : }
2290 0 : es_fprintf (fp, " Trust Check:\t%s\n",
2291 0 : !e->user_trust_req? "[system]" :
2292 0 : e->check_trust_anchor? e->check_trust_anchor:"[missing]");
2293 :
2294 0 : if ((e->invalid & 1))
2295 0 : es_fprintf (fp, _(" ERROR: The CRL will not be used "
2296 : "because it was still too old after an update!\n"));
2297 0 : if ((e->invalid & 2))
2298 0 : es_fprintf (fp, _(" ERROR: The CRL will not be used "
2299 : "due to an unknown critical extension!\n"));
2300 0 : if ((e->invalid & ~3))
2301 0 : es_fprintf (fp, _(" ERROR: The CRL will not be used\n"));
2302 :
2303 0 : cdb = lock_db_file (cache, e);
2304 0 : if (!cdb)
2305 0 : return gpg_error (GPG_ERR_GENERAL);
2306 :
2307 0 : if (!e->dbfile_checked)
2308 0 : es_fprintf (fp, _(" ERROR: This cached CRL may have been tampered with!\n"));
2309 :
2310 0 : es_putc ('\n', fp);
2311 :
2312 0 : rc = cdb_findinit (&cdbfp, cdb, NULL, 0);
2313 0 : while (!rc && (rc=cdb_findnext (&cdbfp)) > 0 )
2314 : {
2315 : unsigned char keyrecord[256];
2316 : unsigned char record[16];
2317 : int reason;
2318 0 : int any = 0;
2319 : cdbi_t n;
2320 : cdbi_t i;
2321 :
2322 0 : rc = 0;
2323 0 : n = cdb_datalen (cdb);
2324 0 : if (n != 16)
2325 : {
2326 0 : log_error (_(" WARNING: invalid cache record length\n"));
2327 0 : warn = 1;
2328 0 : continue;
2329 : }
2330 :
2331 0 : if (cdb_read (cdb, record, n, cdb_datapos (cdb)))
2332 : {
2333 0 : log_error (_("problem reading cache record: %s\n"),
2334 0 : strerror (errno));
2335 0 : warn = 1;
2336 0 : continue;
2337 : }
2338 :
2339 0 : n = cdb_keylen (cdb);
2340 0 : if (n > sizeof keyrecord)
2341 0 : n = sizeof keyrecord;
2342 0 : if (cdb_read (cdb, keyrecord, n, cdb_keypos (cdb)))
2343 : {
2344 0 : log_error (_("problem reading cache key: %s\n"), strerror (errno));
2345 0 : warn = 1;
2346 0 : continue;
2347 : }
2348 :
2349 0 : reason = *record;
2350 0 : es_fputs (" ", fp);
2351 0 : for (i = 0; i < n; i++)
2352 0 : es_fprintf (fp, "%02X", keyrecord[i]);
2353 0 : es_fputs (":\t reasons( ", fp);
2354 :
2355 0 : if (reason & KSBA_CRLREASON_UNSPECIFIED)
2356 0 : es_fputs( "unspecified ", fp ), any = 1;
2357 0 : if (reason & KSBA_CRLREASON_KEY_COMPROMISE )
2358 0 : es_fputs( "key_compromise ", fp ), any = 1;
2359 0 : if (reason & KSBA_CRLREASON_CA_COMPROMISE )
2360 0 : es_fputs( "ca_compromise ", fp ), any = 1;
2361 0 : if (reason & KSBA_CRLREASON_AFFILIATION_CHANGED )
2362 0 : es_fputs( "affiliation_changed ", fp ), any = 1;
2363 0 : if (reason & KSBA_CRLREASON_SUPERSEDED )
2364 0 : es_fputs( "superseded", fp ), any = 1;
2365 0 : if (reason & KSBA_CRLREASON_CESSATION_OF_OPERATION )
2366 0 : es_fputs( "cessation_of_operation", fp ), any = 1;
2367 0 : if (reason & KSBA_CRLREASON_CERTIFICATE_HOLD )
2368 0 : es_fputs( "certificate_hold", fp ), any = 1;
2369 0 : if (reason && !any)
2370 0 : es_fputs( "other", fp );
2371 :
2372 0 : es_fprintf (fp, ") rdate: %.15s\n", record+1);
2373 : }
2374 0 : if (rc)
2375 0 : log_error (_("error reading cache entry from db: %s\n"), strerror (rc));
2376 :
2377 0 : unlock_db_file (cache, e);
2378 0 : es_fprintf (fp, _("End CRL dump\n") );
2379 0 : es_putc ('\n', fp);
2380 :
2381 0 : return (rc||warn)? gpg_error (GPG_ERR_GENERAL) : 0;
2382 : }
2383 :
2384 :
2385 : /* Print the contents of the CRL CACHE in a human readable format to
2386 : stream FP. */
2387 : gpg_error_t
2388 0 : crl_cache_list (estream_t fp)
2389 : {
2390 0 : crl_cache_t cache = get_current_cache ();
2391 : crl_cache_entry_t entry;
2392 0 : gpg_error_t err = 0;
2393 :
2394 0 : for (entry = cache->entries;
2395 0 : entry && !entry->deleted && !err;
2396 0 : entry = entry->next )
2397 0 : err = list_one_crl_entry (cache, entry, fp);
2398 :
2399 0 : return err;
2400 : }
2401 :
2402 :
2403 : /* Load the CRL containing the file named FILENAME into our CRL cache. */
2404 : gpg_error_t
2405 0 : crl_cache_load (ctrl_t ctrl, const char *filename)
2406 : {
2407 : gpg_error_t err;
2408 : estream_t fp;
2409 : ksba_reader_t reader;
2410 :
2411 0 : fp = es_fopen (filename, "rb");
2412 0 : if (!fp)
2413 : {
2414 0 : err = gpg_error_from_errno (errno);
2415 0 : log_error (_("can't open '%s': %s\n"), filename, strerror (errno));
2416 0 : return err;
2417 : }
2418 :
2419 0 : err = create_estream_ksba_reader (&reader, fp);
2420 0 : if (!err)
2421 : {
2422 0 : err = crl_cache_insert (ctrl, filename, reader);
2423 0 : ksba_reader_release (reader);
2424 : }
2425 0 : es_fclose (fp);
2426 0 : return err;
2427 : }
2428 :
2429 :
2430 : /* Locate the corresponding CRL for the certificate CERT, read and
2431 : verify the CRL and store it in the cache. */
2432 : gpg_error_t
2433 0 : crl_cache_reload_crl (ctrl_t ctrl, ksba_cert_t cert)
2434 : {
2435 : gpg_error_t err;
2436 0 : ksba_reader_t reader = NULL;
2437 0 : char *issuer = NULL;
2438 0 : ksba_name_t distpoint = NULL;
2439 0 : ksba_name_t issuername = NULL;
2440 0 : char *distpoint_uri = NULL;
2441 0 : char *issuername_uri = NULL;
2442 0 : int any_dist_point = 0;
2443 : int seq;
2444 :
2445 : /* Loop over all distribution points, get the CRLs and put them into
2446 : the cache. */
2447 0 : if (opt.verbose)
2448 0 : log_info ("checking distribution points\n");
2449 0 : seq = 0;
2450 0 : while ( !(err = ksba_cert_get_crl_dist_point (cert, seq++,
2451 : &distpoint,
2452 : &issuername, NULL )))
2453 : {
2454 : int name_seq;
2455 0 : gpg_error_t last_err = 0;
2456 :
2457 0 : if (!distpoint && !issuername)
2458 : {
2459 0 : if (opt.verbose)
2460 0 : log_info ("no issuer name and no distribution point\n");
2461 0 : break; /* Not allowed; i.e. an invalid certificate. We give
2462 : up here and hope that the default method returns a
2463 : suitable CRL. */
2464 : }
2465 :
2466 0 : xfree (issuername_uri); issuername_uri = NULL;
2467 :
2468 : /* Get the URIs. We do this in a loop to iterate over all names
2469 : in the crlDP. */
2470 0 : for (name_seq=0; ksba_name_enum (distpoint, name_seq); name_seq++)
2471 : {
2472 0 : xfree (distpoint_uri); distpoint_uri = NULL;
2473 0 : distpoint_uri = ksba_name_get_uri (distpoint, name_seq);
2474 0 : if (!distpoint_uri)
2475 0 : continue;
2476 :
2477 0 : if (!strncmp (distpoint_uri, "ldap:", 5)
2478 0 : || !strncmp (distpoint_uri, "ldaps:", 6))
2479 : {
2480 0 : if (opt.ignore_ldap_dp)
2481 0 : continue;
2482 : }
2483 0 : else if (!strncmp (distpoint_uri, "http:", 5)
2484 0 : || !strncmp (distpoint_uri, "https:", 6))
2485 : {
2486 0 : if (opt.ignore_http_dp)
2487 0 : continue;
2488 : }
2489 : else
2490 0 : continue; /* Skip unknown schemes. */
2491 :
2492 0 : any_dist_point = 1;
2493 :
2494 0 : if (opt.verbose)
2495 0 : log_info ("fetching CRL from '%s'\n", distpoint_uri);
2496 0 : err = crl_fetch (ctrl, distpoint_uri, &reader);
2497 0 : if (err)
2498 : {
2499 0 : log_error (_("crl_fetch via DP failed: %s\n"),
2500 : gpg_strerror (err));
2501 0 : last_err = err;
2502 0 : continue; /* with the next name. */
2503 : }
2504 :
2505 0 : if (opt.verbose)
2506 0 : log_info ("inserting CRL (reader %p)\n", reader);
2507 0 : err = crl_cache_insert (ctrl, distpoint_uri, reader);
2508 0 : if (err)
2509 : {
2510 0 : log_error (_("crl_cache_insert via DP failed: %s\n"),
2511 : gpg_strerror (err));
2512 0 : last_err = err;
2513 0 : continue; /* with the next name. */
2514 : }
2515 0 : last_err = 0;
2516 0 : break; /* Ready. */
2517 : }
2518 0 : if (last_err)
2519 : {
2520 0 : err = last_err;
2521 0 : goto leave;
2522 : }
2523 :
2524 0 : ksba_name_release (distpoint); distpoint = NULL;
2525 :
2526 : /* We don't do anything with issuername_uri yet but we keep the
2527 : code for documentation. */
2528 0 : issuername_uri = ksba_name_get_uri (issuername, 0);
2529 0 : ksba_name_release (issuername); issuername = NULL;
2530 :
2531 : /* Close the reader. */
2532 0 : crl_close_reader (reader);
2533 0 : reader = NULL;
2534 : }
2535 0 : if (gpg_err_code (err) == GPG_ERR_EOF)
2536 0 : err = 0;
2537 :
2538 : /* If we did not found any distpoint, try something reasonable. */
2539 0 : if (!any_dist_point )
2540 : {
2541 0 : if (opt.verbose)
2542 0 : log_info ("no distribution point - trying issuer name\n");
2543 :
2544 0 : crl_close_reader (reader);
2545 0 : reader = NULL;
2546 :
2547 0 : issuer = ksba_cert_get_issuer (cert, 0);
2548 0 : if (!issuer)
2549 : {
2550 0 : log_error ("oops: issuer missing in certificate\n");
2551 0 : err = gpg_error (GPG_ERR_INV_CERT_OBJ);
2552 0 : goto leave;
2553 : }
2554 :
2555 0 : if (opt.verbose)
2556 0 : log_info ("fetching CRL from default location\n");
2557 0 : err = crl_fetch_default (ctrl, issuer, &reader);
2558 0 : if (err)
2559 : {
2560 0 : log_error ("crl_fetch via issuer failed: %s\n",
2561 : gpg_strerror (err));
2562 0 : goto leave;
2563 : }
2564 :
2565 0 : if (opt.verbose)
2566 0 : log_info ("inserting CRL (reader %p)\n", reader);
2567 0 : err = crl_cache_insert (ctrl, "default location(s)", reader);
2568 0 : if (err)
2569 : {
2570 0 : log_error (_("crl_cache_insert via issuer failed: %s\n"),
2571 : gpg_strerror (err));
2572 0 : goto leave;
2573 : }
2574 : }
2575 :
2576 : leave:
2577 0 : crl_close_reader (reader);
2578 0 : xfree (distpoint_uri);
2579 0 : xfree (issuername_uri);
2580 0 : ksba_name_release (distpoint);
2581 0 : ksba_name_release (issuername);
2582 0 : ksba_free (issuer);
2583 0 : return err;
2584 : }
|