Exemplo n.º 1
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;
  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;
}
Exemplo n.º 2
0
Arquivo: gpgtar.c Projeto: gpg/gnupg
/* Write the RECORD of size RECORDSIZE to STREAM.  FILENAME is the
   name of the file used for diagnostics.  */
gpg_error_t
write_record (estream_t stream, const void *record)
{
    gpg_error_t err;
    size_t nwritten;

    nwritten = es_fwrite (record, 1, RECORDSIZE, stream);
    if (nwritten != RECORDSIZE)
    {
        err = gpg_error_from_syserror ();
        log_error ("error writing '%s': %s\n",
                   es_fname_get (stream), gpg_strerror (err));
    }
    else
        err = 0;

    return err;
}
Exemplo n.º 3
0
Arquivo: ocsp.c Projeto: FMayzek/gnupg
/* Construct an OCSP request, send it to the configured OCSP responder
   and parse the response. On success the OCSP context may be used to
   further process the reponse. */
static gpg_error_t
do_ocsp_request (ctrl_t ctrl, ksba_ocsp_t ocsp, gcry_md_hd_t md,
                 const char *url, ksba_cert_t cert, ksba_cert_t issuer_cert)
{
  gpg_error_t err;
  unsigned char *request, *response;
  size_t requestlen, responselen;
  http_t http;
  ksba_ocsp_response_status_t response_status;
  const char *t;
  int redirects_left = 2;
  char *free_this = NULL;

  (void)ctrl;

  if (opt.disable_http)
    {
      log_error (_("OCSP request not possible due to disabled HTTP\n"));
      return gpg_error (GPG_ERR_NOT_SUPPORTED);
    }

  err = ksba_ocsp_add_target (ocsp, cert, issuer_cert);
  if (err)
    {
      log_error (_("error setting OCSP target: %s\n"), gpg_strerror (err));
      return err;
    }

  {
    size_t n;
    unsigned char nonce[32];

    n = ksba_ocsp_set_nonce (ocsp, NULL, 0);
    if (n > sizeof nonce)
      n = sizeof nonce;
    gcry_create_nonce (nonce, n);
    ksba_ocsp_set_nonce (ocsp, nonce, n);
  }

  err = ksba_ocsp_build_request (ocsp, &request, &requestlen);
  if (err)
    {
      log_error (_("error building OCSP request: %s\n"), gpg_strerror (err));
      return err;
    }

 once_more:
  err = http_open (&http, HTTP_REQ_POST, url, NULL,
                   (opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY:0),
                   opt.http_proxy, NULL, NULL, NULL);
  if (err)
    {
      log_error (_("error connecting to '%s': %s\n"), url, gpg_strerror (err));
      xfree (free_this);
      return err;
    }

  es_fprintf (http_get_write_ptr (http),
	      "Content-Type: application/ocsp-request\r\n"
	      "Content-Length: %lu\r\n",
	      (unsigned long)requestlen );
  http_start_data (http);
  if (es_fwrite (request, requestlen, 1, http_get_write_ptr (http)) != 1)
    {
      err = gpg_error_from_errno (errno);
      log_error ("error sending request to '%s': %s\n", url, strerror (errno));
      http_close (http, 0);
      xfree (request);
      xfree (free_this);
      return err;
    }
  xfree (request);
  request = NULL;

  err = http_wait_response (http);
  if (err || http_get_status_code (http) != 200)
    {
      if (err)
        log_error (_("error reading HTTP response for '%s': %s\n"),
                   url, gpg_strerror (err));
      else
        {
          switch (http_get_status_code (http))
            {
            case 301:
            case 302:
              {
                const char *s = http_get_header (http, "Location");

                log_info (_("URL '%s' redirected to '%s' (%u)\n"),
                          url, s?s:"[none]", http_get_status_code (http));
                if (s && *s && redirects_left-- )
                  {
                    xfree (free_this); url = NULL;
                    free_this = xtrystrdup (s);
                    if (!free_this)
                      err = gpg_error_from_errno (errno);
                    else
                      {
                        url = free_this;
                        http_close (http, 0);
                        goto once_more;
                      }
                  }
                else
                  err = gpg_error (GPG_ERR_NO_DATA);
                log_error (_("too many redirections\n"));
              }
              break;

            default:
              log_error (_("error accessing '%s': http status %u\n"),
                         url, http_get_status_code (http));
              err = gpg_error (GPG_ERR_NO_DATA);
              break;
            }
        }
      http_close (http, 0);
      xfree (free_this);
      return err;
    }

  err = read_response (http_get_read_ptr (http), &response, &responselen);
  http_close (http, 0);
  if (err)
    {
      log_error (_("error reading HTTP response for '%s': %s\n"),
                 url, gpg_strerror (err));
      xfree (free_this);
      return err;
    }

  err = ksba_ocsp_parse_response (ocsp, response, responselen,
                                  &response_status);
  if (err)
    {
      log_error (_("error parsing OCSP response for '%s': %s\n"),
                 url, gpg_strerror (err));
      xfree (response);
      xfree (free_this);
      return err;
    }

  switch (response_status)
    {
    case KSBA_OCSP_RSPSTATUS_SUCCESS:      t = "success"; break;
    case KSBA_OCSP_RSPSTATUS_MALFORMED:    t = "malformed"; break;
    case KSBA_OCSP_RSPSTATUS_INTERNAL:     t = "internal error"; break;
    case KSBA_OCSP_RSPSTATUS_TRYLATER:     t = "try later"; break;
    case KSBA_OCSP_RSPSTATUS_SIGREQUIRED:  t = "must sign request"; break;
    case KSBA_OCSP_RSPSTATUS_UNAUTHORIZED: t = "unauthorized"; break;
    case KSBA_OCSP_RSPSTATUS_REPLAYED:     t = "replay detected"; break;
    case KSBA_OCSP_RSPSTATUS_OTHER:        t = "other (unknown)"; break;
    case KSBA_OCSP_RSPSTATUS_NONE:         t = "no status"; break;
    default:                               t = "[unknown status]"; break;
    }
  if (response_status == KSBA_OCSP_RSPSTATUS_SUCCESS)
    {
      if (opt.verbose)
        log_info (_("OCSP responder at '%s' status: %s\n"), url, t);

      err = ksba_ocsp_hash_response (ocsp, response, responselen,
                                     HASH_FNC, md);
      if (err)
        log_error (_("hashing the OCSP response for '%s' failed: %s\n"),
                   url, gpg_strerror (err));
    }
  else
    {
      log_error (_("OCSP responder at '%s' status: %s\n"), url, t);
      err = gpg_error (GPG_ERR_GENERAL);
    }

  xfree (response);
  xfree (free_this);
  return err;
}
Exemplo n.º 4
0
/*
 * Write a status line with a buffer using %XX escapes.  If WRAP is >
 * 0 wrap the line after this length.  If STRING is not NULL it will
 * be prepended to the buffer, no escaping is done for string.
 * A wrap of -1 forces spaces not to be encoded as %20.
 */
void
write_status_text_and_buffer (int no, const char *string,
                              const char *buffer, size_t len, int wrap)
{
  const char *s, *text;
  int esc, first;
  int lower_limit = ' ';
  size_t n, count, dowrap;

  if (!statusfp || !status_currently_allowed (no))
    return;  /* Not enabled or allowed. */

  if (wrap == -1)
    {
      lower_limit--;
      wrap = 0;
    }

  text = get_status_string (no);
  count = dowrap = first = 1;
  do
    {
      if (dowrap)
        {
          es_fprintf (statusfp, "[GNUPG:] %s ", text);
          count = dowrap = 0;
          if (first && string)
            {
              es_fputs (string, statusfp);
              count += strlen (string);
              /* Make sure that there is a space after the string.  */
              if (*string && string[strlen (string)-1] != ' ')
                {
                  es_putc (' ', statusfp);
                  count++;
                }
            }
          first = 0;
        }
      for (esc=0, s=buffer, n=len; n && !esc; s++, n--)
        {
          if (*s == '%' || *(const byte*)s <= lower_limit
              || *(const byte*)s == 127 )
            esc = 1;
          if (wrap && ++count > wrap)
            {
              dowrap=1;
              break;
            }
        }
      if (esc)
        {
          s--; n++;
        }
      if (s != buffer)
        es_fwrite (buffer, s-buffer, 1, statusfp);
      if ( esc )
        {
          es_fprintf (statusfp, "%%%02X", *(const byte*)s );
          s++; n--;
        }
      buffer = s;
      len = n;
      if (dowrap && len)
        es_putc ('\n', statusfp);
    }
  while (len);

  es_putc ('\n',statusfp);
  if (es_fflush (statusfp) && opt.exit_on_status_write_error)
    g10_exit (0);
}
Exemplo n.º 5
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;
  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;
}