Esempio n. 1
0
static int
import_one (ctrl_t ctrl, struct stats_s *stats, int in_fd)
{
  int rc;
  Base64Context b64reader = NULL;
  ksba_reader_t reader;
  ksba_cert_t cert = NULL;
  ksba_cms_t cms = NULL;
  estream_t fp = NULL;
  ksba_content_type_t ct;
  int any = 0;

  fp = es_fdopen_nc (in_fd, "rb");
  if (!fp)
    {
      rc = gpg_error_from_syserror ();
      log_error ("fdopen() failed: %s\n", strerror (errno));
      goto leave;
    }

  rc = gpgsm_create_reader (&b64reader, ctrl, fp, 1, &reader);
  if (rc)
    {
      log_error ("can't create reader: %s\n", gpg_strerror (rc));
      goto leave;
    }


  /* We need to loop here to handle multiple PEM objects in one
     file. */
  do
    {
      ksba_cms_release (cms); cms = NULL;
      ksba_cert_release (cert); cert = NULL;

      ct = ksba_cms_identify (reader);
      if (ct == KSBA_CT_SIGNED_DATA)
        { /* This is probably a signed-only message - import the certs */
          ksba_stop_reason_t stopreason;
          int i;

          rc = ksba_cms_new (&cms);
          if (rc)
            goto leave;

          rc = ksba_cms_set_reader_writer (cms, reader, NULL);
          if (rc)
            {
              log_error ("ksba_cms_set_reader_writer failed: %s\n",
                         gpg_strerror (rc));
              goto leave;
            }

          do
            {
              rc = ksba_cms_parse (cms, &stopreason);
              if (rc)
                {
                  log_error ("ksba_cms_parse failed: %s\n", gpg_strerror (rc));
                  goto leave;
                }

              if (stopreason == KSBA_SR_BEGIN_DATA)
                log_info ("not a certs-only message\n");
            }
          while (stopreason != KSBA_SR_READY);

          for (i=0; (cert=ksba_cms_get_cert (cms, i)); i++)
            {
              check_and_store (ctrl, stats, cert, 0);
              ksba_cert_release (cert);
              cert = NULL;
            }
          if (!i)
            log_error ("no certificate found\n");
          else
            any = 1;
        }
      else if (ct == KSBA_CT_PKCS12)
        {
          /* This seems to be a pkcs12 message. */
          rc = parse_p12 (ctrl, reader, stats);
          if (!rc)
            any = 1;
        }
      else if (ct == KSBA_CT_NONE)
        { /* Failed to identify this message - assume a certificate */

          rc = ksba_cert_new (&cert);
          if (rc)
            goto leave;

          rc = ksba_cert_read_der (cert, reader);
          if (rc)
            goto leave;

          check_and_store (ctrl, stats, cert, 0);
          any = 1;
        }
      else
        {
          log_error ("can't extract certificates from input\n");
          rc = gpg_error (GPG_ERR_NO_DATA);
        }

      ksba_reader_clear (reader, NULL, NULL);
    }
  while (!gpgsm_reader_eof_seen (b64reader));

 leave:
  if (any && gpg_err_code (rc) == GPG_ERR_EOF)
    rc = 0;
  ksba_cms_release (cms);
  ksba_cert_release (cert);
  gpgsm_destroy_reader (b64reader);
  es_fclose (fp);
  return rc;
}
Esempio n. 2
0
static int
import_one (ctrl_t ctrl, struct stats_s *stats, int in_fd)
{
  int rc;
  Base64Context b64reader = NULL;
  ksba_reader_t reader;
  ksba_cert_t cert = NULL;
  ksba_cms_t cms = NULL;
  FILE *fp = NULL;
  ksba_content_type_t ct;
  int any = 0;

  fp = fdopen ( dup (in_fd), "rb");
  if (!fp)
    {
      rc = gpg_error (gpg_err_code_from_errno (errno));
      log_error ("fdopen() failed: %s\n", strerror (errno));
      goto leave;
    }

  rc = gpgsm_create_reader (&b64reader, ctrl, fp, 1, &reader);
  if (rc)
    {
      log_error ("can't create reader: %s\n", gpg_strerror (rc));
      goto leave;
    }
  
  
  /* We need to loop here to handle multiple PEM objects in one
     file. */
  do
    {
      ksba_cms_release (cms); cms = NULL;
      ksba_cert_release (cert); cert = NULL;
      
      ct = ksba_cms_identify (reader);
      if (ct == KSBA_CT_SIGNED_DATA)
        { /* This is probably a signed-only message - import the certs */
          ksba_stop_reason_t stopreason;
          int i;
          
          rc = ksba_cms_new (&cms);
          if (rc)
            goto leave;
          
          rc = ksba_cms_set_reader_writer (cms, reader, NULL);
          if (rc)
            {
              log_error ("ksba_cms_set_reader_writer failed: %s\n",
                         gpg_strerror (rc));
              goto leave;
            }

          do 
            {
              rc = ksba_cms_parse (cms, &stopreason);
              if (rc)
                {
                  log_error ("ksba_cms_parse failed: %s\n", gpg_strerror (rc));
                  goto leave;
                }

              if (stopreason == KSBA_SR_BEGIN_DATA)
                log_info ("not a certs-only message\n");
            }
          while (stopreason != KSBA_SR_READY);   
      
          for (i=0; (cert=ksba_cms_get_cert (cms, i)); i++)
            {
              check_and_store (ctrl, stats, cert, 0);
              ksba_cert_release (cert); 
              cert = NULL;
            }
          if (!i)
            log_error ("no certificate found\n");
          else
            any = 1;
        }
      else if (ct == KSBA_CT_PKCS12)
        { /* This seems to be a pkcs12 message.  We use an external
             tool to parse the message and to store the private keys.
             We need to use a another reader here to parse the
             certificate we included in the p12 file; then we continue
             to look for other pkcs12 files (works only if they are in
             PEM format. */
          FILE *certfp;
          Base64Context b64p12rdr;
          ksba_reader_t p12rdr;
          
          rc = parse_p12 (ctrl, reader, &certfp, stats);
          if (!rc)
            {
              any = 1;
              
              rewind (certfp);
              rc = gpgsm_create_reader (&b64p12rdr, ctrl, certfp, 1, &p12rdr);
              if (rc)
                {
                  log_error ("can't create reader: %s\n", gpg_strerror (rc));
                  fclose (certfp);
                  goto leave;
                }

              do
                {
                  ksba_cert_release (cert); cert = NULL;
                  rc = ksba_cert_new (&cert);
                  if (!rc)
                    {
                      rc = ksba_cert_read_der (cert, p12rdr);
                      if (!rc)
                        check_and_store (ctrl, stats, cert, 0);
                    }
                  ksba_reader_clear (p12rdr, NULL, NULL);
                }
              while (!rc && !gpgsm_reader_eof_seen (b64p12rdr));

              if (gpg_err_code (rc) == GPG_ERR_EOF)
                rc = 0;
              gpgsm_destroy_reader (b64p12rdr);
              fclose (certfp);
              if (rc)
                goto leave;
            }
        }
      else if (ct == KSBA_CT_NONE)
        { /* Failed to identify this message - assume a certificate */

          rc = ksba_cert_new (&cert);
          if (rc)
            goto leave;

          rc = ksba_cert_read_der (cert, reader);
          if (rc)
            goto leave;

          check_and_store (ctrl, stats, cert, 0);
          any = 1;
        }
      else
        {
          log_error ("can't extract certificates from input\n");
          rc = gpg_error (GPG_ERR_NO_DATA);
        }
      
      ksba_reader_clear (reader, NULL, NULL);
    }
  while (!gpgsm_reader_eof_seen (b64reader));

 leave:
  if (any && gpg_err_code (rc) == GPG_ERR_EOF)
    rc = 0;
  ksba_cms_release (cms);
  ksba_cert_release (cert);
  gpgsm_destroy_reader (b64reader);
  if (fp)
    fclose (fp);
  return rc;
}
Esempio n. 3
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;
}