/* Put CERT into the certificate cache and store the fingerprint of the certificate into FPR_BUFFER. If the certificate is already in the cache do not print a warning; just store the fingerprint. FPR_BUFFER needs to be at least 20 bytes. */ gpg_error_t cache_cert_silent (ksba_cert_t cert, void *fpr_buffer) { gpg_error_t err; acquire_cache_write_lock (); err = put_cert (cert, 0, 0, fpr_buffer); release_cache_lock (); if (gpg_err_code (err) == GPG_ERR_DUP_VALUE) err = 0; if (err) log_error (_("error caching certificate: %s\n"), gpg_strerror (err)); return err; }
/* Put CERT into the certificate cache. */ gpg_error_t cache_cert (ksba_cert_t cert) { gpg_error_t err; acquire_cache_write_lock (); err = put_cert (cert, 0, 0, NULL); release_cache_lock (); if (gpg_err_code (err) == GPG_ERR_DUP_VALUE) log_info (_("certificate already cached\n")); else if (!err) log_info (_("certificate cached\n")); else log_error (_("error caching certificate: %s\n"), gpg_strerror (err)); return err; }
/* Load all certificates from the Windows store named STORENAME. All * certificates are considered to be system provided trusted * certificates. The cache should be in a locked state when calling * this function. */ static void load_certs_from_w32_store (const char *storename) { static int init_done; static CERTOPENSYSTEMSTORE pCertOpenSystemStore; static CERTENUMCERTIFICATESINSTORE pCertEnumCertificatesInStore; static CERTCLOSESTORE pCertCloseStore; gpg_error_t err; HCERTSTORE w32store; const CERT_CONTEXT *w32cert; ksba_cert_t cert = NULL; unsigned int count = 0; /* Initialize on the first use. */ if (!init_done) { static HANDLE hCrypt32; init_done = 1; hCrypt32 = LoadLibrary ("Crypt32.dll"); if (!hCrypt32) { log_error ("can't load Crypt32.dll: %s\n", w32_strerror (-1)); return; } pCertOpenSystemStore = (CERTOPENSYSTEMSTORE) GetProcAddress (hCrypt32, "CertOpenSystemStoreA"); pCertEnumCertificatesInStore = (CERTENUMCERTIFICATESINSTORE) GetProcAddress (hCrypt32, "CertEnumCertificatesInStore"); pCertCloseStore = (CERTCLOSESTORE) GetProcAddress (hCrypt32, "CertCloseStore"); if ( !pCertOpenSystemStore || !pCertEnumCertificatesInStore || !pCertCloseStore) { log_error ("can't load crypt32.dll: %s\n", "missing function"); pCertOpenSystemStore = NULL; } } if (!pCertOpenSystemStore) return; /* Not initialized. */ w32store = pCertOpenSystemStore (0, storename); if (!w32store) { log_error ("can't open certificate store '%s': %s\n", storename, w32_strerror (-1)); return; } w32cert = NULL; while ((w32cert = pCertEnumCertificatesInStore (w32store, w32cert))) { if (w32cert->dwCertEncodingType == X509_ASN_ENCODING) { ksba_cert_release (cert); cert = NULL; err = ksba_cert_new (&cert); if (!err) err = ksba_cert_init_from_mem (cert, w32cert->pbCertEncoded, w32cert->cbCertEncoded); if (err) { log_error (_("can't parse certificate '%s': %s\n"), storename, gpg_strerror (err)); break; } err = put_cert (cert, 1, CERTTRUST_CLASS_SYSTEM, NULL); if (!err) count++; if (gpg_err_code (err) == GPG_ERR_DUP_VALUE) { if (DBG_X509) log_debug (_("certificate '%s' already cached\n"), storename); } else if (err) log_error (_("error loading certificate '%s': %s\n"), storename, gpg_strerror (err)); else if (opt.verbose > 1) { char *p; log_info (_("trusted certificate '%s' loaded\n"), storename); p = get_fingerprint_hexstring_colon (cert); log_info (_(" SHA1 fingerprint = %s\n"), p); xfree (p); cert_log_name (_(" issuer ="), cert); cert_log_subject (_(" subject ="), cert); } } } ksba_cert_release (cert); pCertCloseStore (w32store, 0); if (DBG_X509) log_debug ("number of certs loaded from store '%s': %u\n", storename, count); }
/* Load certificates from the directory DIRNAME. All certificates matching the pattern "*.crt" or "*.der" are loaded. We assume that certificates are DER encoded and not PEM encapsulated. The cache should be in a locked state when calling this function. */ static gpg_error_t load_certs_from_dir (const char *dirname, int are_trusted) { gpg_error_t err; DIR *dir; struct dirent *ep; char *p; size_t n; estream_t fp; ksba_reader_t reader; ksba_cert_t cert; char *fname = NULL; dir = opendir (dirname); if (!dir) { if (opt.system_daemon) log_info (_("can't access directory '%s': %s\n"), dirname, strerror (errno)); return 0; /* We do not consider this a severe error. */ } while ( (ep=readdir (dir)) ) { p = ep->d_name; if (*p == '.' || !*p) continue; /* Skip any hidden files and invalid entries. */ n = strlen (p); if ( n < 5 || (strcmp (p+n-4,".crt") && strcmp (p+n-4,".der"))) continue; /* Not the desired "*.crt" or "*.der" pattern. */ xfree (fname); fname = make_filename (dirname, p, NULL); fp = es_fopen (fname, "rb"); if (!fp) { log_error (_("can't open '%s': %s\n"), fname, strerror (errno)); continue; } err = create_estream_ksba_reader (&reader, fp); if (err) { es_fclose (fp); continue; } err = ksba_cert_new (&cert); if (!err) err = ksba_cert_read_der (cert, reader); ksba_reader_release (reader); es_fclose (fp); if (err) { log_error (_("can't parse certificate '%s': %s\n"), fname, gpg_strerror (err)); ksba_cert_release (cert); continue; } err = put_cert (cert, 1, are_trusted, NULL); if (gpg_err_code (err) == GPG_ERR_DUP_VALUE) log_info (_("certificate '%s' already cached\n"), fname); else if (!err) { if (are_trusted) log_info (_("trusted certificate '%s' loaded\n"), fname); else log_info (_("certificate '%s' loaded\n"), fname); if (opt.verbose) { p = get_fingerprint_hexstring_colon (cert); log_info (_(" SHA1 fingerprint = %s\n"), p); xfree (p); cert_log_name (_(" issuer ="), cert); cert_log_subject (_(" subject ="), cert); } } else log_error (_("error loading certificate '%s': %s\n"), fname, gpg_strerror (err)); ksba_cert_release (cert); } xfree (fname); closedir (dir); return 0; }
/* Load certificates from FILE. The certificates are expected to be * PEM encoded so that it is possible to load several certificates. * TRUSTCLASSES is used to mark the certificates as trusted. The * cache should be in a locked state when calling this function. * NO_ERROR repalces an error message when FNAME was not found by an * information message. */ static gpg_error_t load_certs_from_file (const char *fname, unsigned int trustclasses, int no_error) { gpg_error_t err; estream_t fp = NULL; gnupg_ksba_io_t ioctx = NULL; ksba_reader_t reader; ksba_cert_t cert = NULL; fp = es_fopen (fname, "rb"); if (!fp) { err = gpg_error_from_syserror (); if (gpg_err_code (err) == GPG_ERR_ENONET && no_error) log_info (_("can't open '%s': %s\n"), fname, gpg_strerror (err)); else log_error (_("can't open '%s': %s\n"), fname, gpg_strerror (err)); goto leave; } err = gnupg_ksba_create_reader (&ioctx, (GNUPG_KSBA_IO_AUTODETECT | GNUPG_KSBA_IO_MULTIPEM), fp, &reader); if (err) { log_error ("can't create reader: %s\n", gpg_strerror (err)); goto leave; } /* Loop to read all certificates from the file. */ do { ksba_cert_release (cert); cert = NULL; err = ksba_cert_new (&cert); if (!err) err = ksba_cert_read_der (cert, reader); if (err) { if (gpg_err_code (err) == GPG_ERR_EOF) err = 0; else log_error (_("can't parse certificate '%s': %s\n"), fname, gpg_strerror (err)); goto leave; } err = put_cert (cert, 1, trustclasses, NULL); if (gpg_err_code (err) == GPG_ERR_DUP_VALUE) log_info (_("certificate '%s' already cached\n"), fname); else if (err) log_error (_("error loading certificate '%s': %s\n"), fname, gpg_strerror (err)); else if (opt.verbose > 1) { char *p; log_info (_("trusted certificate '%s' loaded\n"), fname); p = get_fingerprint_hexstring_colon (cert); log_info (_(" SHA1 fingerprint = %s\n"), p); xfree (p); cert_log_name (_(" issuer ="), cert); cert_log_subject (_(" subject ="), cert); } ksba_reader_clear (reader, NULL, NULL); } while (!gnupg_ksba_reader_eof_seen (ioctx)); leave: ksba_cert_release (cert); gnupg_ksba_destroy_reader (ioctx); es_fclose (fp); return err; }