예제 #1
0
파일: findkey.c 프로젝트: wertarbyte/gnupg
/* Write an S-expression formatted key to our key storage.  With FORCE
   passed as true an existing key with the given GRIP will get
   overwritten.  */
int
agent_write_private_key (const unsigned char *grip,
                         const void *buffer, size_t length, int force)
{
  char *fname;
  estream_t fp;
  char hexgrip[40+4+1];

  bin2hex (grip, 20, hexgrip);
  strcpy (hexgrip+40, ".key");

  fname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL);

  /* FIXME: Write to a temp file first so that write failures during
     key updates won't lead to a key loss.  */

  if (!force && !access (fname, F_OK))
    {
      log_error ("secret key file '%s' already exists\n", fname);
      xfree (fname);
      return gpg_error (GPG_ERR_EEXIST);
    }

  fp = es_fopen (fname, force? "wb,mode=-rw" : "wbx,mode=-rw");
  if (!fp)
    {
      gpg_error_t tmperr = gpg_error_from_syserror ();
      log_error ("can't create '%s': %s\n", fname, gpg_strerror (tmperr));
      xfree (fname);
      return tmperr;
    }

  if (es_fwrite (buffer, length, 1, fp) != 1)
    {
      gpg_error_t tmperr = gpg_error_from_syserror ();
      log_error ("error writing '%s': %s\n", fname, gpg_strerror (tmperr));
      es_fclose (fp);
      gnupg_remove (fname);
      xfree (fname);
      return tmperr;
    }
  if (es_fclose (fp))
    {
      gpg_error_t tmperr = gpg_error_from_syserror ();
      log_error ("error closing '%s': %s\n", fname, gpg_strerror (tmperr));
      gnupg_remove (fname);
      xfree (fname);
      return tmperr;
    }
  bump_key_eventcounter ();
  xfree (fname);
  return 0;
}
예제 #2
0
/* This function may be called to force reloading of the
   trustlist.  */
void
agent_reload_trustlist (void)
{
  /* All we need to do is to delete the trusttable.  At the next
     access it will get re-read. */
  lock_trusttable ();
  xfree (trusttable);
  trusttable = NULL;
  trusttablesize = 0;
  unlock_trusttable ();
  bump_key_eventcounter ();
}
예제 #3
0
/* Write an S-expression formatted key to our key storage.  With FORCE
   passed as true an existing key with the given GRIP will get
   overwritten.  */
int
agent_write_private_key (const unsigned char *grip,
                         const void *buffer, size_t length, int force)
{
  char *fname;
  FILE *fp;
  char hexgrip[40+4+1];
  int fd;

  bin2hex (grip, 20, hexgrip);
  strcpy (hexgrip+40, ".key");

  fname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL);

  if (!force && !access (fname, F_OK))
    {
      log_error ("secret key file `%s' already exists\n", fname);
      xfree (fname);
      return gpg_error (GPG_ERR_GENERAL);
    }

  /* In FORCE mode we would like to create FNAME but only if it does
     not already exist.  We cannot make this guarantee just using
     POSIX (GNU provides the "x" opentype for fopen, however, this is
     not portable).  Thus, we use the more flexible open function and
     then use fdopen to obtain a stream. */
  fd = open (fname, force? (O_CREAT | O_TRUNC | O_WRONLY | O_BINARY)
                         : (O_CREAT | O_EXCL | O_WRONLY | O_BINARY),
             S_IRUSR | S_IWUSR
#ifndef HAVE_W32_SYSTEM
                 | S_IRGRP
#endif
                 );
  if (fd < 0)
    fp = NULL;
  else
    {
      fp = fdopen (fd, "wb");
      if (!fp)
        {
          int save_e = errno;
          close (fd);
          errno = save_e;
        }
    }

  if (!fp)
    {
      gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
      log_error ("can't create `%s': %s\n", fname, strerror (errno));
      xfree (fname);
      return tmperr;
    }

  if (fwrite (buffer, length, 1, fp) != 1)
    {
      gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
      log_error ("error writing `%s': %s\n", fname, strerror (errno));
      fclose (fp);
      remove (fname);
      xfree (fname);
      return tmperr;
    }
  if ( fclose (fp) )
    {
      gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
      log_error ("error closing `%s': %s\n", fname, strerror (errno));
      remove (fname);
      xfree (fname);
      return tmperr;
    }
  bump_key_eventcounter ();
  xfree (fname);
  return 0;
}
예제 #4
0
파일: findkey.c 프로젝트: cuidi/gnupg
static gpg_error_t
write_extended_private_key (char *fname, estream_t fp,
                            const void *buf, size_t len)
{
  gpg_error_t err;
  pkc_t pk = NULL;
  gcry_sexp_t key = NULL;
  int remove = 0;
  int line;

  err = pkc_parse (&pk, &line, fp);
  if (err)
    {
      log_error ("error parsing '%s' line %d: %s\n",
                 fname, line, gpg_strerror (err));
      goto leave;
    }

  err = gcry_sexp_sscan (&key, NULL, buf, len);
  if (err)
    goto leave;

  err = pkc_set_private_key (pk, key);
  if (err)
    goto leave;

  err = es_fseek (fp, 0, SEEK_SET);
  if (err)
    goto leave;

  err = pkc_write (pk, fp);
  if (err)
    {
      log_error ("error writing '%s': %s\n", fname, gpg_strerror (err));
      remove = 1;
      goto leave;
    }

  if (ftruncate (es_fileno (fp), es_ftello (fp)))
    {
      err = gpg_error_from_syserror ();
      log_error ("error truncating '%s': %s\n", fname, gpg_strerror (err));
      remove = 1;
      goto leave;
    }

  if (es_fclose (fp))
    {
      err = gpg_error_from_syserror ();
      log_error ("error closing '%s': %s\n", fname, gpg_strerror (err));
      remove = 1;
      goto leave;
    }
  else
    fp = NULL;

  bump_key_eventcounter ();

 leave:
  if (fp)
    es_fclose (fp);
  if (remove)
    gnupg_remove (fname);
  xfree (fname);
  gcry_sexp_release (key);
  pkc_release (pk);
  return err;
}
예제 #5
0
파일: findkey.c 프로젝트: cuidi/gnupg
/* Write an S-expression formatted key to our key storage.  With FORCE
   passed as true an existing key with the given GRIP will get
   overwritten.  */
int
agent_write_private_key (const unsigned char *grip,
                         const void *buffer, size_t length, int force)
{
  char *fname;
  estream_t fp;
  char hexgrip[40+4+1];

  bin2hex (grip, 20, hexgrip);
  strcpy (hexgrip+40, ".key");

  fname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL);

  /* FIXME: Write to a temp file first so that write failures during
     key updates won't lead to a key loss.  */

  if (!force && !access (fname, F_OK))
    {
      log_error ("secret key file '%s' already exists\n", fname);
      xfree (fname);
      return gpg_error (GPG_ERR_EEXIST);
    }

  fp = es_fopen (fname, force? "rb+,mode=-rw" : "wbx,mode=-rw");
  if (!fp)
    {
      gpg_error_t tmperr = gpg_error_from_syserror ();
      log_error ("can't create '%s': %s\n", fname, gpg_strerror (tmperr));
      xfree (fname);
      return tmperr;
    }

  /* See if an existing key is in extended format.  */
  if (force)
    {
      gpg_error_t rc;
      char first;

      if (es_fread (&first, 1, 1, fp) != 1)
        {
          rc = gpg_error_from_syserror ();
          log_error ("error reading first byte from '%s': %s\n",
                     fname, strerror (errno));
          xfree (fname);
          es_fclose (fp);
          return rc;
        }

      rc = es_fseek (fp, 0, SEEK_SET);
      if (rc)
        {
          log_error ("error seeking in '%s': %s\n", fname, strerror (errno));
          xfree (fname);
          es_fclose (fp);
          return rc;
        }

      if (first != '(')
        {
          /* Key is in extended format.  */
          return write_extended_private_key (fname, fp, buffer, length);
        }
    }

  if (es_fwrite (buffer, length, 1, fp) != 1)
    {
      gpg_error_t tmperr = gpg_error_from_syserror ();
      log_error ("error writing '%s': %s\n", fname, gpg_strerror (tmperr));
      es_fclose (fp);
      gnupg_remove (fname);
      xfree (fname);
      return tmperr;
    }

  /* When force is given, the file might have to be truncated.  */
  if (force && ftruncate (es_fileno (fp), es_ftello (fp)))
    {
      gpg_error_t tmperr = gpg_error_from_syserror ();
      log_error ("error truncating '%s': %s\n", fname, gpg_strerror (tmperr));
      es_fclose (fp);
      gnupg_remove (fname);
      xfree (fname);
      return tmperr;
    }

  if (es_fclose (fp))
    {
      gpg_error_t tmperr = gpg_error_from_syserror ();
      log_error ("error closing '%s': %s\n", fname, gpg_strerror (tmperr));
      gnupg_remove (fname);
      xfree (fname);
      return tmperr;
    }
  bump_key_eventcounter ();
  xfree (fname);
  return 0;
}