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 <http://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 (opt.system_daemon? "crls.d" : "dirmngr-cache.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 orginal 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 fucntion 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_printhex ("", sn, snlen);
1349 : }
1350 0 : else if (opt.verbose)
1351 : {
1352 : unsigned char record[16];
1353 0 : char *tmp = hexify_data (sn, snlen);
1354 :
1355 0 : if (cdb_read (cdb, record, n, cdb_datapos (cdb)))
1356 0 : log_error (_("problem reading cache record for S/N %s: %s\n"),
1357 0 : tmp, strerror (errno));
1358 : else
1359 0 : log_info (_("S/N %s is not valid; reason=%02X date=%.15s\n"),
1360 0 : tmp, *record, record+1);
1361 0 : xfree (tmp);
1362 : }
1363 0 : retval = CRL_CACHE_INVALID;
1364 : }
1365 0 : else if (!rc)
1366 : {
1367 0 : if (opt.verbose)
1368 : {
1369 0 : char *serialno = hexify_data (sn, snlen);
1370 0 : log_info (_("S/N %s is valid, it is not listed in the CRL\n"),
1371 : serialno );
1372 0 : xfree (serialno);
1373 : }
1374 0 : retval = CRL_CACHE_VALID;
1375 : }
1376 : else
1377 : {
1378 0 : log_error (_("error getting data from cache file: %s\n"),
1379 0 : strerror (errno));
1380 0 : retval = CRL_CACHE_DONTKNOW;
1381 : }
1382 :
1383 :
1384 0 : if (entry->user_trust_req
1385 0 : && (retval == CRL_CACHE_VALID || retval == CRL_CACHE_INVALID))
1386 : {
1387 0 : if (!entry->check_trust_anchor)
1388 : {
1389 0 : log_error ("inconsistent data on user trust check\n");
1390 0 : retval = CRL_CACHE_CANTUSE;
1391 : }
1392 0 : else if (get_istrusted_from_client (ctrl, entry->check_trust_anchor))
1393 : {
1394 0 : if (opt.verbose)
1395 0 : log_info ("no system trust and client does not trust either\n");
1396 0 : retval = CRL_CACHE_CANTUSE;
1397 : }
1398 : else
1399 : {
1400 : /* Okay, the CRL is considered valid by the client and thus
1401 : we can return the result as is. */
1402 : }
1403 : }
1404 :
1405 0 : unlock_db_file (cache, entry);
1406 :
1407 0 : return retval;
1408 : }
1409 :
1410 :
1411 : /* Check whether the certificate identified by ISSUER_HASH and
1412 : SERIALNO is valid; i.e. not listed in our cache. With
1413 : FORCE_REFRESH set to true, a new CRL will be retrieved even if the
1414 : cache has not yet expired. We use a 30 minutes threshold here so
1415 : that invoking this function several times won't load the CRL over
1416 : and over. */
1417 : crl_cache_result_t
1418 0 : crl_cache_isvalid (ctrl_t ctrl, const char *issuer_hash, const char *serialno,
1419 : int force_refresh)
1420 : {
1421 : crl_cache_result_t result;
1422 : unsigned char snbuf_buffer[50];
1423 : unsigned char *snbuf;
1424 : size_t n;
1425 :
1426 0 : n = strlen (serialno)/2+1;
1427 0 : if (n < sizeof snbuf_buffer - 1)
1428 0 : snbuf = snbuf_buffer;
1429 : else
1430 : {
1431 0 : snbuf = xtrymalloc (n);
1432 0 : if (!snbuf)
1433 0 : return CRL_CACHE_DONTKNOW;
1434 : }
1435 :
1436 0 : n = unhexify (snbuf, serialno);
1437 :
1438 0 : result = cache_isvalid (ctrl, issuer_hash, snbuf, n, force_refresh);
1439 :
1440 0 : if (snbuf != snbuf_buffer)
1441 0 : xfree (snbuf);
1442 :
1443 0 : return result;
1444 : }
1445 :
1446 :
1447 : /* Check whether the certificate CERT is valid; i.e. not listed in our
1448 : cache. With FORCE_REFRESH set to true, a new CRL will be retrieved
1449 : even if the cache has not yet expired. We use a 30 minutes
1450 : threshold here so that invoking this function several times won't
1451 : load the CRL over and over. */
1452 : gpg_error_t
1453 0 : crl_cache_cert_isvalid (ctrl_t ctrl, ksba_cert_t cert,
1454 : int force_refresh)
1455 : {
1456 : gpg_error_t err;
1457 : crl_cache_result_t result;
1458 : unsigned char issuerhash[20];
1459 : char issuerhash_hex[41];
1460 : ksba_sexp_t serial;
1461 : unsigned char *sn;
1462 : size_t snlen;
1463 : char *endp, *tmp;
1464 : int i;
1465 :
1466 : /* Compute the hash value of the issuer name. */
1467 0 : tmp = ksba_cert_get_issuer (cert, 0);
1468 0 : if (!tmp)
1469 : {
1470 0 : log_error ("oops: issuer missing in certificate\n");
1471 0 : return gpg_error (GPG_ERR_INV_CERT_OBJ);
1472 : }
1473 0 : gcry_md_hash_buffer (GCRY_MD_SHA1, issuerhash, tmp, strlen (tmp));
1474 0 : xfree (tmp);
1475 0 : for (i=0,tmp=issuerhash_hex; i < 20; i++, tmp += 2)
1476 0 : sprintf (tmp, "%02X", issuerhash[i]);
1477 :
1478 : /* Get the serial number. */
1479 0 : serial = ksba_cert_get_serial (cert);
1480 0 : if (!serial)
1481 : {
1482 0 : log_error ("oops: S/N missing in certificate\n");
1483 0 : return gpg_error (GPG_ERR_INV_CERT_OBJ);
1484 : }
1485 0 : sn = serial;
1486 0 : if (*sn != '(')
1487 : {
1488 0 : log_error ("oops: invalid S/N\n");
1489 0 : xfree (serial);
1490 0 : return gpg_error (GPG_ERR_INV_CERT_OBJ);
1491 : }
1492 0 : sn++;
1493 0 : snlen = strtoul (sn, &endp, 10);
1494 0 : sn = endp;
1495 0 : if (*sn != ':')
1496 : {
1497 0 : log_error ("oops: invalid S/N\n");
1498 0 : xfree (serial);
1499 0 : return gpg_error (GPG_ERR_INV_CERT_OBJ);
1500 : }
1501 0 : sn++;
1502 :
1503 : /* Check the cache. */
1504 0 : result = cache_isvalid (ctrl, issuerhash_hex, sn, snlen, force_refresh);
1505 0 : switch (result)
1506 : {
1507 : case CRL_CACHE_VALID:
1508 0 : err = 0;
1509 0 : break;
1510 : case CRL_CACHE_INVALID:
1511 0 : err = gpg_error (GPG_ERR_CERT_REVOKED);
1512 0 : break;
1513 : case CRL_CACHE_DONTKNOW:
1514 0 : err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
1515 : case CRL_CACHE_CANTUSE:
1516 0 : err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
1517 0 : break;
1518 : default:
1519 0 : log_fatal ("cache_isvalid returned invalid status code %d\n", result);
1520 : }
1521 :
1522 0 : xfree (serial);
1523 0 : return err;
1524 : }
1525 :
1526 :
1527 : /* Prepare a hash context for the signature verification. Input is
1528 : the CRL and the output is the hash context MD as well as the uses
1529 : algorithm identifier ALGO. */
1530 : static gpg_error_t
1531 0 : start_sig_check (ksba_crl_t crl, gcry_md_hd_t *md, int *algo)
1532 : {
1533 : gpg_error_t err;
1534 : const char *algoid;
1535 :
1536 0 : algoid = ksba_crl_get_digest_algo (crl);
1537 0 : *algo = gcry_md_map_name (algoid);
1538 0 : if (!*algo)
1539 : {
1540 0 : log_error (_("unknown hash algorithm '%s'\n"), algoid? algoid:"?");
1541 0 : return gpg_error (GPG_ERR_DIGEST_ALGO);
1542 : }
1543 :
1544 0 : err = gcry_md_open (md, *algo, 0);
1545 0 : if (err)
1546 : {
1547 0 : log_error (_("gcry_md_open for algorithm %d failed: %s\n"),
1548 : *algo, gcry_strerror (err));
1549 0 : return err;
1550 : }
1551 0 : if (DBG_HASHING)
1552 0 : gcry_md_debug (*md, "hash.cert");
1553 :
1554 0 : ksba_crl_set_hash_function (crl, HASH_FNC, *md);
1555 0 : return 0;
1556 : }
1557 :
1558 :
1559 : /* Finish a hash context and verify the signature. This function
1560 : should return 0 on a good signature, GPG_ERR_BAD_SIGNATURE if the
1561 : signature does not verify or any other error code. CRL is the CRL
1562 : object we are working on, MD the hash context and ISSUER_CERT the
1563 : certificate of the CRL issuer. This function closes MD. */
1564 : static gpg_error_t
1565 0 : finish_sig_check (ksba_crl_t crl, gcry_md_hd_t md, int algo,
1566 : ksba_cert_t issuer_cert)
1567 : {
1568 : gpg_error_t err;
1569 0 : ksba_sexp_t sigval = NULL, pubkey = NULL;
1570 : const char *s;
1571 : char algoname[50];
1572 : size_t n;
1573 0 : gcry_sexp_t s_sig = NULL, s_hash = NULL, s_pkey = NULL;
1574 : unsigned int i;
1575 :
1576 : /* This also stops debugging on the MD. */
1577 0 : gcry_md_final (md);
1578 :
1579 : /* Get and convert the signature value. */
1580 0 : sigval = ksba_crl_get_sig_val (crl);
1581 0 : n = gcry_sexp_canon_len (sigval, 0, NULL, NULL);
1582 0 : if (!n)
1583 : {
1584 0 : log_error (_("got an invalid S-expression from libksba\n"));
1585 0 : err = gpg_error (GPG_ERR_INV_SEXP);
1586 0 : goto leave;
1587 : }
1588 0 : err = gcry_sexp_sscan (&s_sig, NULL, sigval, n);
1589 0 : if (err)
1590 : {
1591 0 : log_error (_("converting S-expression failed: %s\n"),
1592 : gcry_strerror (err));
1593 0 : goto leave;
1594 : }
1595 :
1596 : /* Get and convert the public key for the issuer certificate. */
1597 0 : if (DBG_X509)
1598 0 : dump_cert ("crl_issuer_cert", issuer_cert);
1599 0 : pubkey = ksba_cert_get_public_key (issuer_cert);
1600 0 : n = gcry_sexp_canon_len (pubkey, 0, NULL, NULL);
1601 0 : if (!n)
1602 : {
1603 0 : log_error (_("got an invalid S-expression from libksba\n"));
1604 0 : err = gpg_error (GPG_ERR_INV_SEXP);
1605 0 : goto leave;
1606 : }
1607 0 : err = gcry_sexp_sscan (&s_pkey, NULL, pubkey, n);
1608 0 : if (err)
1609 : {
1610 0 : log_error (_("converting S-expression failed: %s\n"),
1611 : gcry_strerror (err));
1612 0 : goto leave;
1613 : }
1614 :
1615 : /* Create an S-expression with the actual hash value. */
1616 0 : s = gcry_md_algo_name (algo);
1617 0 : for (i = 0; *s && i < sizeof(algoname) - 1; s++, i++)
1618 0 : algoname[i] = ascii_tolower (*s);
1619 0 : algoname[i] = 0;
1620 0 : err = gcry_sexp_build (&s_hash, NULL, "(data(flags pkcs1)(hash %s %b))",
1621 : algoname,
1622 : gcry_md_get_algo_dlen (algo), gcry_md_read (md, algo));
1623 0 : if (err)
1624 : {
1625 0 : log_error (_("creating S-expression failed: %s\n"), gcry_strerror (err));
1626 0 : goto leave;
1627 : }
1628 :
1629 : /* Pass this on to the signature verification. */
1630 0 : err = gcry_pk_verify (s_sig, s_hash, s_pkey);
1631 0 : if (DBG_X509)
1632 0 : log_debug ("gcry_pk_verify: %s\n", gpg_strerror (err));
1633 :
1634 : leave:
1635 0 : xfree (sigval);
1636 0 : xfree (pubkey);
1637 0 : gcry_sexp_release (s_sig);
1638 0 : gcry_sexp_release (s_hash);
1639 0 : gcry_sexp_release (s_pkey);
1640 0 : gcry_md_close (md);
1641 :
1642 0 : return err;
1643 : }
1644 :
1645 :
1646 : /* Call this to match a start_sig_check that can not be completed
1647 : normally. */
1648 : static void
1649 0 : abort_sig_check (ksba_crl_t crl, gcry_md_hd_t md)
1650 : {
1651 : (void)crl;
1652 0 : gcry_md_close (md);
1653 0 : }
1654 :
1655 :
1656 : /* Workhorse of the CRL loading machinery. The CRL is read using the
1657 : CRL object and stored in the data base file DB with the name FNAME
1658 : (only used for printing error messages). That DB should be a
1659 : temporary one and not the actual one. If the function fails the
1660 : caller should delete this temporary database file. CTRL is
1661 : required to retrieve certificates using the general dirmngr
1662 : callback service. R_CRLISSUER returns an allocated string with the
1663 : crl-issuer DN, THIS_UPDATE and NEXT_UPDATE are filled with the
1664 : corresponding data from the CRL. Note that these values might get
1665 : set even if the CRL processing fails at a later step; thus the
1666 : caller should free *R_ISSUER even if the function returns with an
1667 : error. R_TRUST_ANCHOR is set on exit to NULL or a string with the
1668 : hexified fingerprint of the root certificate, if checking this
1669 : certificate for trustiness is required.
1670 : */
1671 : static int
1672 0 : crl_parse_insert (ctrl_t ctrl, ksba_crl_t crl,
1673 : struct cdb_make *cdb, const char *fname,
1674 : char **r_crlissuer,
1675 : ksba_isotime_t thisupdate, ksba_isotime_t nextupdate,
1676 : char **r_trust_anchor)
1677 : {
1678 : gpg_error_t err;
1679 : ksba_stop_reason_t stopreason;
1680 0 : ksba_cert_t crlissuer_cert = NULL;
1681 0 : gcry_md_hd_t md = NULL;
1682 0 : int algo = 0;
1683 : size_t n;
1684 :
1685 : (void)fname;
1686 :
1687 0 : *r_crlissuer = NULL;
1688 0 : *thisupdate = *nextupdate = 0;
1689 0 : *r_trust_anchor = NULL;
1690 :
1691 : /* Start of the KSBA parser loop. */
1692 : do
1693 : {
1694 0 : err = ksba_crl_parse (crl, &stopreason);
1695 0 : if (err)
1696 : {
1697 0 : log_error (_("ksba_crl_parse failed: %s\n"), gpg_strerror (err) );
1698 0 : goto failure;
1699 : }
1700 :
1701 0 : switch (stopreason)
1702 : {
1703 : case KSBA_SR_BEGIN_ITEMS:
1704 : {
1705 0 : err = start_sig_check (crl, &md, &algo);
1706 0 : if (err)
1707 0 : goto failure;
1708 :
1709 0 : err = ksba_crl_get_update_times (crl, thisupdate, nextupdate);
1710 0 : if (err)
1711 : {
1712 0 : log_error (_("error getting update times of CRL: %s\n"),
1713 : gpg_strerror (err));
1714 0 : err = gpg_error (GPG_ERR_INV_CRL);
1715 0 : goto failure;
1716 : }
1717 :
1718 0 : if (opt.verbose || !*nextupdate)
1719 0 : log_info (_("update times of this CRL: this=%s next=%s\n"),
1720 : thisupdate, nextupdate);
1721 0 : if (!*nextupdate)
1722 : {
1723 0 : log_info (_("nextUpdate not given; "
1724 : "assuming a validity period of one day\n"));
1725 0 : gnupg_copy_time (nextupdate, thisupdate);
1726 0 : add_seconds_to_isotime (nextupdate, 86400);
1727 : }
1728 : }
1729 0 : break;
1730 :
1731 : case KSBA_SR_GOT_ITEM:
1732 : {
1733 : ksba_sexp_t serial;
1734 : const unsigned char *p;
1735 : ksba_isotime_t rdate;
1736 : ksba_crl_reason_t reason;
1737 : int rc;
1738 : unsigned char record[1+15];
1739 :
1740 0 : err = ksba_crl_get_item (crl, &serial, rdate, &reason);
1741 0 : if (err)
1742 : {
1743 0 : log_error (_("error getting CRL item: %s\n"),
1744 : gpg_strerror (err));
1745 0 : err = gpg_error (GPG_ERR_INV_CRL);
1746 0 : ksba_free (serial);
1747 0 : goto failure;
1748 : }
1749 0 : p = serial_to_buffer (serial, &n);
1750 0 : if (!p)
1751 0 : BUG ();
1752 0 : record[0] = (reason & 0xff);
1753 0 : memcpy (record+1, rdate, 15);
1754 0 : rc = cdb_make_add (cdb, p, n, record, 1+15);
1755 0 : if (rc)
1756 : {
1757 0 : err = gpg_error_from_errno (errno);
1758 0 : log_error (_("error inserting item into "
1759 : "temporary cache file: %s\n"),
1760 0 : strerror (errno));
1761 0 : goto failure;
1762 : }
1763 :
1764 0 : ksba_free (serial);
1765 : }
1766 0 : break;
1767 :
1768 : case KSBA_SR_END_ITEMS:
1769 0 : break;
1770 :
1771 : case KSBA_SR_READY:
1772 : {
1773 : char *crlissuer;
1774 : ksba_name_t authid;
1775 : ksba_sexp_t authidsn;
1776 : ksba_sexp_t keyid;
1777 :
1778 : /* We need to look for the issuer only after having read
1779 : all items. The issuer itselfs comes before the items
1780 : but the optional authorityKeyIdentifier comes after the
1781 : items. */
1782 0 : err = ksba_crl_get_issuer (crl, &crlissuer);
1783 0 : if( err )
1784 : {
1785 0 : log_error (_("no CRL issuer found in CRL: %s\n"),
1786 : gpg_strerror (err) );
1787 0 : err = gpg_error (GPG_ERR_INV_CRL);
1788 0 : goto failure;
1789 : }
1790 : /* Note: This should be released by ksba_free, not xfree.
1791 : May need a memory reallocation dance. */
1792 0 : *r_crlissuer = crlissuer; /* (Do it here so we don't need
1793 : to free it later) */
1794 :
1795 0 : if (!ksba_crl_get_auth_key_id (crl, &keyid, &authid, &authidsn))
1796 : {
1797 : const char *s;
1798 :
1799 0 : if (opt.verbose)
1800 0 : log_info (_("locating CRL issuer certificate by "
1801 : "authorityKeyIdentifier\n"));
1802 :
1803 0 : s = ksba_name_enum (authid, 0);
1804 0 : if (s && *authidsn)
1805 0 : crlissuer_cert = find_cert_bysn (ctrl, s, authidsn);
1806 0 : if (!crlissuer_cert && keyid)
1807 0 : crlissuer_cert = find_cert_bysubject (ctrl,
1808 : crlissuer, keyid);
1809 :
1810 0 : if (!crlissuer_cert)
1811 : {
1812 0 : log_info ("CRL issuer certificate ");
1813 0 : if (keyid)
1814 : {
1815 0 : log_printf ("{");
1816 0 : dump_serial (keyid);
1817 0 : log_printf ("} ");
1818 : }
1819 0 : if (authidsn)
1820 : {
1821 0 : log_printf ("(#");
1822 0 : dump_serial (authidsn);
1823 0 : log_printf ("/");
1824 0 : dump_string (s);
1825 0 : log_printf (") ");
1826 : }
1827 0 : log_printf ("not found\n");
1828 : }
1829 0 : ksba_name_release (authid);
1830 0 : xfree (authidsn);
1831 0 : xfree (keyid);
1832 : }
1833 : else
1834 0 : crlissuer_cert = find_cert_bysubject (ctrl, crlissuer, NULL);
1835 0 : err = 0;
1836 0 : if (!crlissuer_cert)
1837 : {
1838 0 : err = gpg_error (GPG_ERR_MISSING_CERT);
1839 0 : goto failure;
1840 : }
1841 :
1842 0 : err = finish_sig_check (crl, md, algo, crlissuer_cert);
1843 0 : if (err)
1844 : {
1845 0 : log_error (_("CRL signature verification failed: %s\n"),
1846 : gpg_strerror (err));
1847 0 : goto failure;
1848 : }
1849 0 : md = NULL;
1850 :
1851 0 : err = validate_cert_chain (ctrl, crlissuer_cert, NULL,
1852 : VALIDATE_MODE_CRL_RECURSIVE,
1853 : r_trust_anchor);
1854 0 : if (err)
1855 : {
1856 0 : log_error (_("error checking validity of CRL "
1857 : "issuer certificate: %s\n"),
1858 : gpg_strerror (err));
1859 0 : goto failure;
1860 : }
1861 :
1862 : }
1863 0 : break;
1864 :
1865 : default:
1866 0 : log_debug ("crl_parse_insert: unknown stop reason\n");
1867 0 : err = gpg_error (GPG_ERR_BUG);
1868 0 : goto failure;
1869 : }
1870 : }
1871 0 : while (stopreason != KSBA_SR_READY);
1872 0 : assert (!err);
1873 :
1874 :
1875 : failure:
1876 0 : if (md)
1877 0 : abort_sig_check (crl, md);
1878 0 : ksba_cert_release (crlissuer_cert);
1879 0 : return err;
1880 : }
1881 :
1882 :
1883 :
1884 : /* Return the crlNumber extension as an allocated hex string or NULL
1885 : if there is none. */
1886 : static char *
1887 0 : get_crl_number (ksba_crl_t crl)
1888 : {
1889 : gpg_error_t err;
1890 : ksba_sexp_t number;
1891 : char *string;
1892 :
1893 0 : err = ksba_crl_get_crl_number (crl, &number);
1894 0 : if (err)
1895 0 : return NULL;
1896 0 : string = serial_hex (number);
1897 0 : ksba_free (number);
1898 0 : return string;
1899 : }
1900 :
1901 :
1902 : /* Return the authorityKeyIdentifier or NULL if it is not available.
1903 : The issuer name may consists of several parts - they are delimted by
1904 : 0x01. */
1905 : static char *
1906 0 : get_auth_key_id (ksba_crl_t crl, char **serialno)
1907 : {
1908 : gpg_error_t err;
1909 : ksba_name_t name;
1910 : ksba_sexp_t sn;
1911 : int idx;
1912 : const char *s;
1913 : char *string;
1914 : size_t length;
1915 :
1916 0 : *serialno = NULL;
1917 0 : err = ksba_crl_get_auth_key_id (crl, NULL, &name, &sn);
1918 0 : if (err)
1919 0 : return NULL;
1920 0 : *serialno = serial_hex (sn);
1921 0 : ksba_free (sn);
1922 :
1923 0 : if (!name)
1924 0 : return xstrdup ("");
1925 :
1926 0 : length = 0;
1927 0 : for (idx=0; (s = ksba_name_enum (name, idx)); idx++)
1928 : {
1929 0 : char *p = ksba_name_get_uri (name, idx);
1930 0 : length += strlen (p?p:s) + 1;
1931 0 : xfree (p);
1932 : }
1933 0 : string = xtrymalloc (length+1);
1934 0 : if (string)
1935 : {
1936 0 : *string = 0;
1937 0 : for (idx=0; (s = ksba_name_enum (name, idx)); idx++)
1938 : {
1939 0 : char *p = ksba_name_get_uri (name, idx);
1940 0 : if (*string)
1941 0 : strcat (string, "\x01");
1942 0 : strcat (string, p?p:s);
1943 0 : xfree (p);
1944 : }
1945 : }
1946 0 : ksba_name_release (name);
1947 0 : return string;
1948 : }
1949 :
1950 :
1951 :
1952 : /* Insert the CRL retrieved using URL into the cache specified by
1953 : CACHE. The CRL itself will be read from the stream FP and is
1954 : expected in binary format.
1955 :
1956 : Called by:
1957 : crl_cache_load
1958 : cmd_loadcrl
1959 : --load-crl
1960 : crl_cache_reload_crl
1961 : cmd_isvalid
1962 : cmd_checkcrl
1963 : cmd_loadcrl
1964 : --fetch-crl
1965 :
1966 : */
1967 : gpg_error_t
1968 0 : crl_cache_insert (ctrl_t ctrl, const char *url, ksba_reader_t reader)
1969 : {
1970 0 : crl_cache_t cache = get_current_cache ();
1971 : gpg_error_t err, err2;
1972 : ksba_crl_t crl;
1973 0 : char *fname = NULL;
1974 0 : char *newfname = NULL;
1975 : struct cdb_make cdb;
1976 0 : int fd_cdb = -1;
1977 0 : char *issuer = NULL;
1978 0 : char *issuer_hash = NULL;
1979 : ksba_isotime_t thisupdate, nextupdate;
1980 0 : crl_cache_entry_t entry = NULL;
1981 : crl_cache_entry_t e;
1982 : gnupg_isotime_t current_time;
1983 0 : char *checksum = NULL;
1984 0 : int invalidate_crl = 0;
1985 : int idx;
1986 : const char *oid;
1987 : int critical;
1988 0 : char *trust_anchor = NULL;
1989 :
1990 : /* FIXME: We should acquire a mutex for the URL, so that we don't
1991 : simultaneously enter the same CRL twice. However this needs to be
1992 : interweaved with the checking function.*/
1993 :
1994 0 : err2 = 0;
1995 :
1996 0 : err = ksba_crl_new (&crl);
1997 0 : if (err)
1998 : {
1999 0 : log_error (_("ksba_crl_new failed: %s\n"), gpg_strerror (err));
2000 0 : goto leave;
2001 : }
2002 :
2003 0 : err = ksba_crl_set_reader (crl, reader);
2004 0 : if ( err )
2005 : {
2006 0 : log_error (_("ksba_crl_set_reader failed: %s\n"), gpg_strerror (err));
2007 0 : goto leave;
2008 : }
2009 :
2010 : /* Create a temporary cache file to load the CRL into. */
2011 : {
2012 : char *tmpfname, *p;
2013 : const char *nodename;
2014 : #ifndef HAVE_W32_SYSTEM
2015 : struct utsname utsbuf;
2016 : #endif
2017 :
2018 : #ifdef HAVE_W32_SYSTEM
2019 : nodename = "unknown";
2020 : #else
2021 0 : if (uname (&utsbuf))
2022 0 : nodename = "unknown";
2023 : else
2024 0 : nodename = utsbuf.nodename;
2025 : #endif
2026 :
2027 0 : gpgrt_asprintf (&tmpfname, "crl-tmp-%s-%u-%p.db.tmp",
2028 0 : nodename, (unsigned int)getpid (), &tmpfname);
2029 0 : if (!tmpfname)
2030 : {
2031 0 : err = gpg_error_from_syserror ();
2032 0 : goto leave;
2033 : }
2034 0 : for (p=tmpfname; *p; p++)
2035 0 : if (*p == '/')
2036 0 : *p = '.';
2037 0 : fname = make_filename (opt.homedir_cache, DBDIR_D, tmpfname, NULL);
2038 0 : xfree (tmpfname);
2039 0 : if (!gnupg_remove (fname))
2040 0 : log_info (_("removed stale temporary cache file '%s'\n"), fname);
2041 0 : else if (errno != ENOENT)
2042 : {
2043 0 : err = gpg_error_from_syserror ();
2044 0 : log_error (_("problem removing stale temporary cache file '%s': %s\n"),
2045 : fname, gpg_strerror (err));
2046 0 : goto leave;
2047 : }
2048 : }
2049 :
2050 0 : fd_cdb = open (fname, O_WRONLY | O_CREAT | O_TRUNC, 0644);
2051 0 : if (fd_cdb == -1)
2052 : {
2053 0 : err = gpg_error_from_errno (errno);
2054 0 : log_error (_("error creating temporary cache file '%s': %s\n"),
2055 0 : fname, strerror (errno));
2056 0 : goto leave;
2057 : }
2058 0 : cdb_make_start(&cdb, fd_cdb);
2059 :
2060 0 : err = crl_parse_insert (ctrl, crl, &cdb, fname,
2061 : &issuer, thisupdate, nextupdate, &trust_anchor);
2062 0 : if (err)
2063 : {
2064 0 : log_error (_("crl_parse_insert failed: %s\n"), gpg_strerror (err));
2065 : /* Error in cleanup ignored. */
2066 0 : cdb_make_finish (&cdb);
2067 0 : goto leave;
2068 : }
2069 :
2070 : /* Finish the database. */
2071 0 : if (cdb_make_finish (&cdb))
2072 : {
2073 0 : err = gpg_error_from_errno (errno);
2074 0 : log_error (_("error finishing temporary cache file '%s': %s\n"),
2075 0 : fname, strerror (errno));
2076 0 : goto leave;
2077 : }
2078 0 : if (close (fd_cdb))
2079 : {
2080 0 : err = gpg_error_from_errno (errno);
2081 0 : log_error (_("error closing temporary cache file '%s': %s\n"),
2082 0 : fname, strerror (errno));
2083 0 : goto leave;
2084 : }
2085 0 : fd_cdb = -1;
2086 :
2087 :
2088 : /* Create a checksum. */
2089 : {
2090 : unsigned char md5buf[16];
2091 :
2092 0 : if (hash_dbfile (fname, md5buf))
2093 : {
2094 0 : err = gpg_error (GPG_ERR_CHECKSUM);
2095 0 : goto leave;
2096 : }
2097 0 : checksum = hexify_data (md5buf, 16);
2098 : }
2099 :
2100 :
2101 : /* Check whether that new CRL is still not expired. */
2102 0 : gnupg_get_isotime (current_time);
2103 0 : if (strcmp (nextupdate, current_time) < 0 )
2104 : {
2105 0 : if (opt.force)
2106 0 : log_info (_("WARNING: new CRL still too old; it expired on %s "
2107 : "- loading anyway\n"), nextupdate);
2108 : else
2109 : {
2110 0 : log_error (_("new CRL still too old; it expired on %s\n"),
2111 : nextupdate);
2112 0 : if (!err2)
2113 0 : err2 = gpg_error (GPG_ERR_CRL_TOO_OLD);
2114 0 : invalidate_crl |= 1;
2115 : }
2116 : }
2117 :
2118 : /* Check for unknown critical extensions. */
2119 0 : for (idx=0; !(err=ksba_crl_get_extension (crl, idx, &oid, &critical,
2120 0 : NULL, NULL)); idx++)
2121 : {
2122 0 : if (!critical
2123 0 : || !strcmp (oid, oidstr_authorityKeyIdentifier)
2124 0 : || !strcmp (oid, oidstr_crlNumber) )
2125 0 : continue;
2126 0 : log_error (_("unknown critical CRL extension %s\n"), oid);
2127 0 : if (!err2)
2128 0 : err2 = gpg_error (GPG_ERR_INV_CRL);
2129 0 : invalidate_crl |= 2;
2130 : }
2131 0 : if (gpg_err_code (err) == GPG_ERR_EOF
2132 0 : || gpg_err_code (err) == GPG_ERR_NO_DATA )
2133 0 : err = 0;
2134 0 : if (err)
2135 : {
2136 0 : log_error (_("error reading CRL extensions: %s\n"), gpg_strerror (err));
2137 0 : err = gpg_error (GPG_ERR_INV_CRL);
2138 : }
2139 :
2140 :
2141 : /* Create an hex encoded SHA-1 hash of the issuer DN to be
2142 : used as the key for the cache. */
2143 0 : issuer_hash = hashify_data (issuer, strlen (issuer));
2144 :
2145 : /* Create an ENTRY. */
2146 0 : entry = xtrycalloc (1, sizeof *entry);
2147 0 : if (!entry)
2148 : {
2149 0 : err = gpg_error_from_syserror ();
2150 0 : goto leave;
2151 : }
2152 0 : entry->release_ptr = xtrymalloc (strlen (issuer_hash) + 1
2153 : + strlen (issuer) + 1
2154 : + strlen (url) + 1
2155 : + strlen (checksum) + 1);
2156 0 : if (!entry->release_ptr)
2157 : {
2158 0 : err = gpg_error_from_syserror ();
2159 0 : xfree (entry);
2160 0 : entry = NULL;
2161 0 : goto leave;
2162 : }
2163 0 : entry->issuer_hash = entry->release_ptr;
2164 0 : entry->issuer = stpcpy (entry->issuer_hash, issuer_hash) + 1;
2165 0 : entry->url = stpcpy (entry->issuer, issuer) + 1;
2166 0 : entry->dbfile_hash = stpcpy (entry->url, url) + 1;
2167 0 : strcpy (entry->dbfile_hash, checksum);
2168 0 : gnupg_copy_time (entry->this_update, thisupdate);
2169 0 : gnupg_copy_time (entry->next_update, nextupdate);
2170 0 : gnupg_copy_time (entry->last_refresh, current_time);
2171 0 : entry->crl_number = get_crl_number (crl);
2172 0 : entry->authority_issuer = get_auth_key_id (crl, &entry->authority_serialno);
2173 0 : entry->invalid = invalidate_crl;
2174 0 : entry->user_trust_req = !!trust_anchor;
2175 0 : entry->check_trust_anchor = trust_anchor;
2176 0 : trust_anchor = NULL;
2177 :
2178 : /* Check whether we already have an entry for this issuer and mark
2179 : it as deleted. We better use a loop, just in case duplicates got
2180 : somehow into the list. */
2181 0 : for (e = cache->entries; (e=find_entry (e, entry->issuer_hash)); e = e->next)
2182 0 : e->deleted = 1;
2183 :
2184 : /* Rename the temporary DB to the real name. */
2185 0 : newfname = make_db_file_name (entry->issuer_hash);
2186 0 : if (opt.verbose)
2187 0 : log_info (_("creating cache file '%s'\n"), newfname);
2188 :
2189 : /* Just in case close unused matching files. Actually we need this
2190 : only under Windows but saving file descriptors is never bad. */
2191 : {
2192 : int any;
2193 : do
2194 : {
2195 0 : any = 0;
2196 0 : for (e = cache->entries; e; e = e->next)
2197 0 : if (!e->cdb_use_count && e->cdb
2198 0 : && !strcmp (e->issuer_hash, entry->issuer_hash))
2199 : {
2200 0 : int fd = cdb_fileno (e->cdb);
2201 0 : cdb_free (e->cdb);
2202 0 : xfree (e->cdb);
2203 0 : e->cdb = NULL;
2204 0 : if (close (fd))
2205 0 : log_error (_("error closing cache file: %s\n"),
2206 0 : strerror(errno));
2207 0 : any = 1;
2208 0 : break;
2209 : }
2210 : }
2211 0 : while (any);
2212 : }
2213 : #ifdef HAVE_W32_SYSTEM
2214 : gnupg_remove (newfname);
2215 : #endif
2216 0 : if (rename (fname, newfname))
2217 : {
2218 0 : err = gpg_error_from_syserror ();
2219 0 : log_error (_("problem renaming '%s' to '%s': %s\n"),
2220 : fname, newfname, gpg_strerror (err));
2221 0 : goto leave;
2222 : }
2223 0 : xfree (fname); fname = NULL; /*(let the cleanup code not try to remove it)*/
2224 :
2225 : /* Link the new entry in. */
2226 0 : entry->next = cache->entries;
2227 0 : cache->entries = entry;
2228 0 : entry = NULL;
2229 :
2230 0 : err = update_dir (cache);
2231 0 : if (err)
2232 : {
2233 0 : log_error (_("updating the DIR file failed - "
2234 : "cache entry will get lost with the next program start\n"));
2235 0 : err = 0; /* Keep on running. */
2236 : }
2237 :
2238 :
2239 : leave:
2240 0 : release_one_cache_entry (entry);
2241 0 : if (fd_cdb != -1)
2242 0 : close (fd_cdb);
2243 0 : if (fname)
2244 : {
2245 0 : gnupg_remove (fname);
2246 0 : xfree (fname);
2247 : }
2248 0 : xfree (newfname);
2249 0 : ksba_crl_release (crl);
2250 0 : xfree (issuer);
2251 0 : xfree (issuer_hash);
2252 0 : xfree (checksum);
2253 0 : xfree (trust_anchor);
2254 0 : return err ? err : err2;
2255 : }
2256 :
2257 :
2258 : /* Print one cached entry E in a human readable format to stream
2259 : FP. Return 0 on success. */
2260 : static gpg_error_t
2261 0 : list_one_crl_entry (crl_cache_t cache, crl_cache_entry_t e, estream_t fp)
2262 : {
2263 : struct cdb_find cdbfp;
2264 : struct cdb *cdb;
2265 : int rc;
2266 0 : int warn = 0;
2267 : const unsigned char *s;
2268 :
2269 0 : es_fputs ("--------------------------------------------------------\n", fp );
2270 0 : es_fprintf (fp, _("Begin CRL dump (retrieved via %s)\n"), e->url );
2271 0 : es_fprintf (fp, " Issuer:\t%s\n", e->issuer );
2272 0 : es_fprintf (fp, " Issuer Hash:\t%s\n", e->issuer_hash );
2273 0 : es_fprintf (fp, " This Update:\t%s\n", e->this_update );
2274 0 : es_fprintf (fp, " Next Update:\t%s\n", e->next_update );
2275 0 : es_fprintf (fp, " CRL Number :\t%s\n", e->crl_number? e->crl_number: "none");
2276 0 : es_fprintf (fp, " AuthKeyId :\t%s\n",
2277 0 : e->authority_serialno? e->authority_serialno:"none");
2278 0 : if (e->authority_serialno && e->authority_issuer)
2279 : {
2280 0 : es_fputs (" \t", fp);
2281 0 : for (s=e->authority_issuer; *s; s++)
2282 0 : if (*s == '\x01')
2283 0 : es_fputs ("\n \t", fp);
2284 : else
2285 0 : es_putc (*s, fp);
2286 0 : es_putc ('\n', fp);
2287 : }
2288 0 : es_fprintf (fp, " Trust Check:\t%s\n",
2289 0 : !e->user_trust_req? "[system]" :
2290 0 : e->check_trust_anchor? e->check_trust_anchor:"[missing]");
2291 :
2292 0 : if ((e->invalid & 1))
2293 0 : es_fprintf (fp, _(" ERROR: The CRL will not be used "
2294 : "because it was still too old after an update!\n"));
2295 0 : if ((e->invalid & 2))
2296 0 : es_fprintf (fp, _(" ERROR: The CRL will not be used "
2297 : "due to an unknown critical extension!\n"));
2298 0 : if ((e->invalid & ~3))
2299 0 : es_fprintf (fp, _(" ERROR: The CRL will not be used\n"));
2300 :
2301 0 : cdb = lock_db_file (cache, e);
2302 0 : if (!cdb)
2303 0 : return gpg_error (GPG_ERR_GENERAL);
2304 :
2305 0 : if (!e->dbfile_checked)
2306 0 : es_fprintf (fp, _(" ERROR: This cached CRL may have been tampered with!\n"));
2307 :
2308 0 : es_putc ('\n', fp);
2309 :
2310 0 : rc = cdb_findinit (&cdbfp, cdb, NULL, 0);
2311 0 : while (!rc && (rc=cdb_findnext (&cdbfp)) > 0 )
2312 : {
2313 : unsigned char keyrecord[256];
2314 : unsigned char record[16];
2315 : int reason;
2316 0 : int any = 0;
2317 : cdbi_t n;
2318 : cdbi_t i;
2319 :
2320 0 : rc = 0;
2321 0 : n = cdb_datalen (cdb);
2322 0 : if (n != 16)
2323 : {
2324 0 : log_error (_(" WARNING: invalid cache record length\n"));
2325 0 : warn = 1;
2326 0 : continue;
2327 : }
2328 :
2329 0 : if (cdb_read (cdb, record, n, cdb_datapos (cdb)))
2330 : {
2331 0 : log_error (_("problem reading cache record: %s\n"),
2332 0 : strerror (errno));
2333 0 : warn = 1;
2334 0 : continue;
2335 : }
2336 :
2337 0 : n = cdb_keylen (cdb);
2338 0 : if (n > sizeof keyrecord)
2339 0 : n = sizeof keyrecord;
2340 0 : if (cdb_read (cdb, keyrecord, n, cdb_keypos (cdb)))
2341 : {
2342 0 : log_error (_("problem reading cache key: %s\n"), strerror (errno));
2343 0 : warn = 1;
2344 0 : continue;
2345 : }
2346 :
2347 0 : reason = *record;
2348 0 : es_fputs (" ", fp);
2349 0 : for (i = 0; i < n; i++)
2350 0 : es_fprintf (fp, "%02X", keyrecord[i]);
2351 0 : es_fputs (":\t reasons( ", fp);
2352 :
2353 0 : if (reason & KSBA_CRLREASON_UNSPECIFIED)
2354 0 : es_fputs( "unspecified ", fp ), any = 1;
2355 0 : if (reason & KSBA_CRLREASON_KEY_COMPROMISE )
2356 0 : es_fputs( "key_compromise ", fp ), any = 1;
2357 0 : if (reason & KSBA_CRLREASON_CA_COMPROMISE )
2358 0 : es_fputs( "ca_compromise ", fp ), any = 1;
2359 0 : if (reason & KSBA_CRLREASON_AFFILIATION_CHANGED )
2360 0 : es_fputs( "affiliation_changed ", fp ), any = 1;
2361 0 : if (reason & KSBA_CRLREASON_SUPERSEDED )
2362 0 : es_fputs( "superseeded", fp ), any = 1;
2363 0 : if (reason & KSBA_CRLREASON_CESSATION_OF_OPERATION )
2364 0 : es_fputs( "cessation_of_operation", fp ), any = 1;
2365 0 : if (reason & KSBA_CRLREASON_CERTIFICATE_HOLD )
2366 0 : es_fputs( "certificate_hold", fp ), any = 1;
2367 0 : if (reason && !any)
2368 0 : es_fputs( "other", fp );
2369 :
2370 0 : es_fprintf (fp, ") rdate: %.15s\n", record+1);
2371 : }
2372 0 : if (rc)
2373 0 : log_error (_("error reading cache entry from db: %s\n"), strerror (rc));
2374 :
2375 0 : unlock_db_file (cache, e);
2376 0 : es_fprintf (fp, _("End CRL dump\n") );
2377 0 : es_putc ('\n', fp);
2378 :
2379 0 : return (rc||warn)? gpg_error (GPG_ERR_GENERAL) : 0;
2380 : }
2381 :
2382 :
2383 : /* Print the contents of the CRL CACHE in a human readable format to
2384 : stream FP. */
2385 : gpg_error_t
2386 0 : crl_cache_list (estream_t fp)
2387 : {
2388 0 : crl_cache_t cache = get_current_cache ();
2389 : crl_cache_entry_t entry;
2390 0 : gpg_error_t err = 0;
2391 :
2392 0 : for (entry = cache->entries;
2393 0 : entry && !entry->deleted && !err;
2394 0 : entry = entry->next )
2395 0 : err = list_one_crl_entry (cache, entry, fp);
2396 :
2397 0 : return err;
2398 : }
2399 :
2400 :
2401 : /* Load the CRL containing the file named FILENAME into our CRL cache. */
2402 : gpg_error_t
2403 0 : crl_cache_load (ctrl_t ctrl, const char *filename)
2404 : {
2405 : gpg_error_t err;
2406 : estream_t fp;
2407 : ksba_reader_t reader;
2408 :
2409 0 : fp = es_fopen (filename, "r");
2410 0 : if (!fp)
2411 : {
2412 0 : err = gpg_error_from_errno (errno);
2413 0 : log_error (_("can't open '%s': %s\n"), filename, strerror (errno));
2414 0 : return err;
2415 : }
2416 :
2417 0 : err = create_estream_ksba_reader (&reader, fp);
2418 0 : if (!err)
2419 : {
2420 0 : err = crl_cache_insert (ctrl, filename, reader);
2421 0 : ksba_reader_release (reader);
2422 : }
2423 0 : es_fclose (fp);
2424 0 : return err;
2425 : }
2426 :
2427 :
2428 : /* Locate the corresponding CRL for the certificate CERT, read and
2429 : verify the CRL and store it in the cache. */
2430 : gpg_error_t
2431 0 : crl_cache_reload_crl (ctrl_t ctrl, ksba_cert_t cert)
2432 : {
2433 : gpg_error_t err;
2434 0 : ksba_reader_t reader = NULL;
2435 0 : char *issuer = NULL;
2436 0 : ksba_name_t distpoint = NULL;
2437 0 : ksba_name_t issuername = NULL;
2438 0 : char *distpoint_uri = NULL;
2439 0 : char *issuername_uri = NULL;
2440 0 : int any_dist_point = 0;
2441 : int seq;
2442 :
2443 : /* Loop over all distribution points, get the CRLs and put them into
2444 : the cache. */
2445 0 : if (opt.verbose)
2446 0 : log_info ("checking distribution points\n");
2447 0 : seq = 0;
2448 0 : while ( !(err = ksba_cert_get_crl_dist_point (cert, seq++,
2449 : &distpoint,
2450 : &issuername, NULL )))
2451 : {
2452 : int name_seq;
2453 0 : gpg_error_t last_err = 0;
2454 :
2455 0 : if (!distpoint && !issuername)
2456 : {
2457 0 : if (opt.verbose)
2458 0 : log_info ("no issuer name and no distribution point\n");
2459 0 : break; /* Not allowed; i.e. an invalid certificate. We give
2460 : up here and hope that the default method returns a
2461 : suitable CRL. */
2462 : }
2463 :
2464 0 : xfree (issuername_uri); issuername_uri = NULL;
2465 :
2466 : /* Get the URIs. We do this in a loop to iterate over all names
2467 : in the crlDP. */
2468 0 : for (name_seq=0; ksba_name_enum (distpoint, name_seq); name_seq++)
2469 : {
2470 0 : xfree (distpoint_uri); distpoint_uri = NULL;
2471 0 : distpoint_uri = ksba_name_get_uri (distpoint, name_seq);
2472 0 : if (!distpoint_uri)
2473 0 : continue;
2474 :
2475 0 : if (!strncmp (distpoint_uri, "ldap:", 5)
2476 0 : || !strncmp (distpoint_uri, "ldaps:", 6))
2477 : {
2478 0 : if (opt.ignore_ldap_dp)
2479 0 : continue;
2480 : }
2481 0 : else if (!strncmp (distpoint_uri, "http:", 5)
2482 0 : || !strncmp (distpoint_uri, "https:", 6))
2483 : {
2484 0 : if (opt.ignore_http_dp)
2485 0 : continue;
2486 : }
2487 : else
2488 0 : continue; /* Skip unknown schemes. */
2489 :
2490 0 : any_dist_point = 1;
2491 :
2492 0 : if (opt.verbose)
2493 0 : log_info ("fetching CRL from '%s'\n", distpoint_uri);
2494 0 : err = crl_fetch (ctrl, distpoint_uri, &reader);
2495 0 : if (err)
2496 : {
2497 0 : log_error (_("crl_fetch via DP failed: %s\n"),
2498 : gpg_strerror (err));
2499 0 : last_err = err;
2500 0 : continue; /* with the next name. */
2501 : }
2502 :
2503 0 : if (opt.verbose)
2504 0 : log_info ("inserting CRL (reader %p)\n", reader);
2505 0 : err = crl_cache_insert (ctrl, distpoint_uri, reader);
2506 0 : if (err)
2507 : {
2508 0 : log_error (_("crl_cache_insert via DP failed: %s\n"),
2509 : gpg_strerror (err));
2510 0 : last_err = err;
2511 0 : continue; /* with the next name. */
2512 : }
2513 0 : last_err = 0;
2514 0 : break; /* Ready. */
2515 : }
2516 0 : if (last_err)
2517 : {
2518 0 : err = last_err;
2519 0 : goto leave;
2520 : }
2521 :
2522 0 : ksba_name_release (distpoint); distpoint = NULL;
2523 :
2524 : /* We don't do anything with issuername_uri yet but we keep the
2525 : code for documentation. */
2526 0 : issuername_uri = ksba_name_get_uri (issuername, 0);
2527 0 : ksba_name_release (issuername); issuername = NULL;
2528 :
2529 : /* Close the reader. */
2530 0 : crl_close_reader (reader);
2531 0 : reader = NULL;
2532 : }
2533 0 : if (gpg_err_code (err) == GPG_ERR_EOF)
2534 0 : err = 0;
2535 :
2536 : /* If we did not found any distpoint, try something reasonable. */
2537 0 : if (!any_dist_point )
2538 : {
2539 0 : if (opt.verbose)
2540 0 : log_info ("no distribution point - trying issuer name\n");
2541 :
2542 0 : crl_close_reader (reader);
2543 0 : reader = NULL;
2544 :
2545 0 : issuer = ksba_cert_get_issuer (cert, 0);
2546 0 : if (!issuer)
2547 : {
2548 0 : log_error ("oops: issuer missing in certificate\n");
2549 0 : err = gpg_error (GPG_ERR_INV_CERT_OBJ);
2550 0 : goto leave;
2551 : }
2552 :
2553 0 : if (opt.verbose)
2554 0 : log_info ("fetching CRL from default location\n");
2555 0 : err = crl_fetch_default (ctrl, issuer, &reader);
2556 0 : if (err)
2557 : {
2558 0 : log_error ("crl_fetch via issuer failed: %s\n",
2559 : gpg_strerror (err));
2560 0 : goto leave;
2561 : }
2562 :
2563 0 : if (opt.verbose)
2564 0 : log_info ("inserting CRL (reader %p)\n", reader);
2565 0 : err = crl_cache_insert (ctrl, "default location(s)", reader);
2566 0 : if (err)
2567 : {
2568 0 : log_error (_("crl_cache_insert via issuer failed: %s\n"),
2569 : gpg_strerror (err));
2570 0 : goto leave;
2571 : }
2572 : }
2573 :
2574 : leave:
2575 0 : crl_close_reader (reader);
2576 0 : xfree (distpoint_uri);
2577 0 : xfree (issuername_uri);
2578 0 : ksba_name_release (distpoint);
2579 0 : ksba_name_release (issuername);
2580 0 : ksba_free (issuer);
2581 0 : return err;
2582 : }
|