Example #1
0
/* This simple dump function is mainly used for debugging purposes. */
void
gpgsm_dump_cert (const char *text, ksba_cert_t cert)
{
  ksba_sexp_t sexp;
  char *p;
  char *dn;
  ksba_isotime_t t;

  log_debug ("BEGIN Certificate '%s':\n", text? text:"");
  if (cert)
    {
      sexp = ksba_cert_get_serial (cert);
      log_debug ("     serial: ");
      gpgsm_dump_serial (sexp);
      ksba_free (sexp);
      log_printf ("\n");

      ksba_cert_get_validity (cert, 0, t);
      log_debug ("  notBefore: ");
      dump_isotime (t);
      log_printf ("\n");
      ksba_cert_get_validity (cert, 1, t);
      log_debug ("   notAfter: ");
      dump_isotime (t);
      log_printf ("\n");

      dn = ksba_cert_get_issuer (cert, 0);
      log_debug ("     issuer: ");
      gpgsm_dump_string (dn);
      ksba_free (dn);
      log_printf ("\n");

      dn = ksba_cert_get_subject (cert, 0);
      log_debug ("    subject: ");
      gpgsm_dump_string (dn);
      ksba_free (dn);
      log_printf ("\n");

      log_debug ("  hash algo: %s\n", ksba_cert_get_digest_algo (cert));

      p = gpgsm_get_fingerprint_string (cert, 0);
      log_debug ("  SHA1 Fingerprint: %s\n", p);
      xfree (p);
    }
  log_debug ("END Certificate\n");
}
Example #2
0
/* Call the directory manager to check whether the certificate is valid
   Returns 0 for valid or usually one of the errors:

  GPG_ERR_CERTIFICATE_REVOKED
  GPG_ERR_NO_CRL_KNOWN
  GPG_ERR_CRL_TOO_OLD

  Values for USE_OCSP:
     0 = Do CRL check.
     1 = Do an OCSP check.
     2 = Do an OCSP check using only the default responder.
 */
int
gpgsm_dirmngr_isvalid (ctrl_t ctrl,
                       ksba_cert_t cert, ksba_cert_t issuer_cert, int use_ocsp)
{
  static int did_options;
  int rc;
  char *certid;
  char line[ASSUAN_LINELENGTH];
  struct inq_certificate_parm_s parm;
  struct isvalid_status_parm_s stparm;

  rc = start_dirmngr (ctrl);
  if (rc)
    return rc;

  if (use_ocsp)
    {
      certid = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
    }
  else
    {
      certid = gpgsm_get_certid (cert);
      if (!certid)
        {
          log_error ("error getting the certificate ID\n");
	  release_dirmngr (ctrl);
          return gpg_error (GPG_ERR_GENERAL);
        }
    }

  if (opt.verbose > 1)
    {
      char *fpr = gpgsm_get_fingerprint_string (cert, GCRY_MD_SHA1);
      log_info ("asking dirmngr about %s%s\n", fpr,
                use_ocsp? " (using OCSP)":"");
      xfree (fpr);
    }

  parm.ctx = dirmngr_ctx;
  parm.ctrl = ctrl;
  parm.cert = cert;
  parm.issuer_cert = issuer_cert;

  stparm.ctrl = ctrl;
  stparm.seen = 0;
  memset (stparm.fpr, 0, 20);

  /* FIXME: If --disable-crl-checks has been set, we should pass an
     option to dirmngr, so that no fallback CRL check is done after an
     ocsp check.  It is not a problem right now as dirmngr does not
     fallback to CRL checking.  */

  /* It is sufficient to send the options only once because we have
     one connection per process only. */
  if (!did_options)
    {
      if (opt.force_crl_refresh)
        assuan_transact (dirmngr_ctx, "OPTION force-crl-refresh=1",
                         NULL, NULL, NULL, NULL, NULL, NULL);
      did_options = 1;
    }
  snprintf (line, DIM(line)-1, "ISVALID%s %s", 
            use_ocsp == 2? " --only-ocsp --force-default-responder":"",
            certid);
  line[DIM(line)-1] = 0;
  xfree (certid);

  rc = assuan_transact (dirmngr_ctx, line, NULL, NULL,
                        inq_certificate, &parm,
                        isvalid_status_cb, &stparm);
  if (opt.verbose > 1)
    log_info ("response of dirmngr: %s\n", rc? gpg_strerror (rc): "okay");
  rc = rc;

  if (!rc && stparm.seen)
    {
      /* Need to also check the certificate validity. */
      if (stparm.seen != 1)
        {
          log_error ("communication problem with dirmngr detected\n");
          rc = gpg_error (GPG_ERR_INV_CRL);
        }
      else
        {
          KEYDB_HANDLE kh;
          ksba_cert_t rspcert = NULL;

          /* Fixme: First try to get the certificate from the
             dirmngr's cache - it should be there. */
          kh = keydb_new (0);
          if (!kh)
            rc = gpg_error (GPG_ERR_ENOMEM);
          if (!rc)
            rc = keydb_search_fpr (kh, stparm.fpr);
          if (!rc)
            rc = keydb_get_cert (kh, &rspcert);
          if (rc)
            {
              log_error ("unable to find the certificate used "
                         "by the dirmngr: %s\n", gpg_strerror (rc));
              rc = gpg_error (GPG_ERR_INV_CRL);
            }
          keydb_release (kh);

          if (!rc)
            {
              rc = gpgsm_cert_use_ocsp_p (rspcert);
              if (rc)
                rc = gpg_error (GPG_ERR_INV_CRL);
              else
                {
                  /* Note the no_dirmngr flag: This avoids checking
                     this certificate over and over again. */
                  rc = gpgsm_validate_chain (ctrl, rspcert, "", NULL, 0, NULL, 
                                             VALIDATE_FLAG_NO_DIRMNGR, NULL);
                  if (rc)
                    {
                      log_error ("invalid certificate used for CRL/OCSP: %s\n",
                                 gpg_strerror (rc));
                      rc = gpg_error (GPG_ERR_INV_CRL);
                    }
                }
            }
          ksba_cert_release (rspcert);
        }
    }
  release_dirmngr (ctrl);
  return rc;
}