static int _ocsp_db_save(mget_hashmap_t *map, const char *fname, int save_hosts) { FILE *fp; int ret = -1, size; if ((size = mget_hashmap_size(map)) <= 0) return -1; if ((fp = fopen(fname, "w"))) { fputs("#OCSP 1.0 file\n", fp); fputs("#Generated by Mget " PACKAGE_VERSION ". Edit at your own risk.\n", fp); if (save_hosts) { fputs("<hostname> <time_t maxage> <time_t mtime>\n\n", fp); mget_hashmap_browse(map, (int(*)(void *, const void *, void *))_ocsp_save_host, fp); } else { fputs("<sha256 fingerprint of cert> <time_t maxage> <time_t mtime> <valid>\n\n", fp); mget_hashmap_browse(map, (int(*)(void *, const void *, void *))_ocsp_save_entry, fp); } if (!ferror(fp)) ret = 0; if (fclose(fp)) ret = -1; if (ret) error_printf(_("Failed to write to OCSP file '%s' (%d)\n"), fname, errno); else debug_printf(_("saved %d OCSP entr%s into '%s'\n"), size, size != 1 ? "ies" : "y", fname); } else error_printf(_("Failed to open OCSP file '%s' (%d)\n"), fname, errno); return ret; }
int mget_stringmap_size(const mget_stringmap_t *h) { return mget_hashmap_size(h); }
static int _ocsp_db_load(mget_ocsp_db_t *ocsp_db, const char *fname, int load_hosts) { mget_ocsp_t ocsp; FILE *fp; char *buf = NULL, *linep, *p; size_t bufsize = 0; ssize_t buflen; time_t now = time(NULL); int ok, nentries = 0; if ((fp = fopen(fname, "r"))) { while ((buflen = mget_getline(&buf, &bufsize, fp)) >= 0) { linep = buf; while (isspace(*linep)) linep++; // ignore leading whitespace if (!*linep) continue; // skip empty lines if (*linep == '#') continue; // skip comments // strip off \r\n while (buflen > 0 && (buf[buflen] == '\n' || buf[buflen] == '\r')) buf[--buflen] = 0; mget_ocsp_init(&ocsp); ok = 0; // parse cert's sha-256 checksum if (*linep) { for (p = linep; *linep && !isspace(*linep);) linep++; ocsp.key = strndup(p, linep - p); } // parse max age if (*linep) { for (p = ++linep; *linep && !isspace(*linep);) linep++; ocsp.maxage = atol(p); if (ocsp.maxage < now) { // drop expired entry mget_ocsp_deinit(&ocsp); continue; } ok = 1; } // parse mtime (age of this entry) if (*linep) { for (p = ++linep; *linep && !isspace(*linep);) linep++; ocsp.mtime = atol(p); } // parse mtime (age of this entry) if (*linep) { for (p = ++linep; *linep && !isspace(*linep);) linep++; ocsp.valid = atoi(p); } if (ok) { if (load_hosts) mget_ocsp_db_add_host(ocsp_db, mget_memdup(&ocsp, sizeof(ocsp))); else mget_ocsp_db_add_fingerprint(ocsp_db, mget_memdup(&ocsp, sizeof(ocsp))); } else { mget_ocsp_deinit(&ocsp); error_printf(_("Failed to parse OCSP line: '%s'\n"), buf); } } xfree(buf); fclose(fp); nentries = mget_hashmap_size(load_hosts ? ocsp_db->hosts : ocsp_db->fingerprints); debug_printf(_("have %d OCSP %s%s in cache\n"), nentries, load_hosts ? "host" : "fingerprint", nentries !=1 ? "ies" : "y"); } else if (errno != ENOENT) error_printf(_("Failed to open OCSP file '%s' (%d)\n"), fname, errno); return nentries; }