예제 #1
0
파일: certdump.c 프로젝트: FMayzek/gnupg
/* Create a key description for the CERT, this may be passed to the
   pinentry.  The caller must free the returned string.  NULL may be
   returned on error. */
char *
gpgsm_format_keydesc (ksba_cert_t cert)
{
  char *name, *subject, *buffer;
  ksba_isotime_t t;
  char created[20];
  char expires[20];
  char *sn;
  ksba_sexp_t sexp;
  char *orig_codeset;

  name = ksba_cert_get_subject (cert, 0);
  subject = name? gpgsm_format_name2 (name, 0) : NULL;
  ksba_free (name); name = NULL;

  sexp = ksba_cert_get_serial (cert);
  sn = sexp? gpgsm_format_serial (sexp) : NULL;
  ksba_free (sexp);

  ksba_cert_get_validity (cert, 0, t);
  if (*t)
    sprintf (created, "%.4s-%.2s-%.2s", t, t+4, t+6);
  else
    *created = 0;
  ksba_cert_get_validity (cert, 1, t);
  if (*t)
    sprintf (expires, "%.4s-%.2s-%.2s", t, t+4, t+6);
  else
    *expires = 0;

  orig_codeset = i18n_switchto_utf8 ();

  name = xtryasprintf (_("Please enter the passphrase to unlock the"
                         " secret key for the X.509 certificate:\n"
                         "\"%s\"\n"
                         "S/N %s, ID 0x%08lX,\n"
                         "created %s, expires %s.\n" ),
                       subject? subject:"?",
                       sn? sn: "?",
                       gpgsm_get_short_fingerprint (cert, NULL),
                       created, expires);

  i18n_switchback (orig_codeset);

  if (!name)
    {
      xfree (subject);
      xfree (sn);
      return NULL;
    }

  xfree (subject);
  xfree (sn);

  buffer = percent_plus_escape (name);
  xfree (name);
  return buffer;
}
예제 #2
0
/* Ask the agent to pop up a confirmation dialog with the text DESC
   and an okay and cancel button. */
gpg_error_t
gpg_agent_get_confirmation (const char *desc)
{
    int rc;
    char *tmp;
    char line[ASSUAN_LINELENGTH];

    rc = start_agent (0);
    if (rc)
        return rc;

    tmp = percent_plus_escape (desc);
    if (!tmp)
        return gpg_error_from_syserror ();
    snprintf (line, DIM(line)-1, "GET_CONFIRMATION %s", tmp);
    line[DIM(line)-1] = 0;
    xfree (tmp);

    rc = assuan_transact (agent_ctx, line, NULL, NULL,
                          default_inq_cb, NULL, NULL, NULL);
    return rc;
}
예제 #3
0
/* Note: All strings shall be UTF-8. On success the caller needs to
   free the string stored at R_PASSPHRASE. On error NULL will be
   stored at R_PASSPHRASE and an appropriate fpf error code
   returned. */
gpg_error_t
agent_get_passphrase (const char *cache_id,
                      const char *err_msg,
                      const char *prompt,
                      const char *desc_msg,
                      int repeat,
                      int check,
                      char **r_passphrase)
{
    int rc;
    char line[ASSUAN_LINELENGTH];
    char *arg1 = NULL;
    char *arg2 = NULL;
    char *arg3 = NULL;
    char *arg4 = NULL;
    membuf_t data;

    *r_passphrase = NULL;

    rc = start_agent (0);
    if (rc)
        return rc;

    /* Check that the gpg-agent understands the repeat option.  */
    if (assuan_transact (agent_ctx,
                         "GETINFO cmd_has_option GET_PASSPHRASE repeat",
                         NULL, NULL, NULL, NULL, NULL, NULL))
        return gpg_error (GPG_ERR_NOT_SUPPORTED);

    if (cache_id && *cache_id)
        if (!(arg1 = percent_plus_escape (cache_id)))
            goto no_mem;
    if (err_msg && *err_msg)
        if (!(arg2 = percent_plus_escape (err_msg)))
            goto no_mem;
    if (prompt && *prompt)
        if (!(arg3 = percent_plus_escape (prompt)))
            goto no_mem;
    if (desc_msg && *desc_msg)
        if (!(arg4 = percent_plus_escape (desc_msg)))
            goto no_mem;

    snprintf (line, DIM(line)-1,
              "GET_PASSPHRASE --data --repeat=%d%s -- %s %s %s %s",
              repeat,
              check? " --check --qualitybar":"",
              arg1? arg1:"X",
              arg2? arg2:"X",
              arg3? arg3:"X",
              arg4? arg4:"X");
    line[DIM(line)-1] = 0;
    xfree (arg1);
    xfree (arg2);
    xfree (arg3);
    xfree (arg4);

    init_membuf_secure (&data, 64);
    rc = assuan_transact (agent_ctx, line,
                          membuf_data_cb, &data,
                          default_inq_cb, NULL, NULL, NULL);

    if (rc)
        xfree (get_membuf (&data, NULL));
    else
    {
        put_membuf (&data, "", 1);
        *r_passphrase = get_membuf (&data, NULL);
        if (!*r_passphrase)
            rc = gpg_error_from_syserror ();
    }
    return rc;
no_mem:
    rc = gpg_error_from_syserror ();
    xfree (arg1);
    xfree (arg2);
    xfree (arg3);
    xfree (arg4);
    return rc;
}
예제 #4
0
파일: passphrase.c 프로젝트: cuidi/gnupg
/* Return an allocated utf-8 string describing the key PK.  If ESCAPED
   is true spaces and control characters are percent or plus escaped.
   MODE describes the use of the key description; use one of the
   FORMAT_KEYDESC_ macros. */
char *
gpg_format_keydesc (PKT_public_key *pk, int mode, int escaped)
{
  char *uid;
  size_t uidlen;
  const char *algo_name;
  const char *timestr;
  char *orig_codeset;
  char *maink;
  char *desc;
  const char *prompt;
  const char *trailer = "";
  int is_subkey;

  is_subkey = (pk->main_keyid[0] && pk->main_keyid[1]
               && pk->keyid[0] != pk->main_keyid[0]
               && pk->keyid[1] != pk->main_keyid[1]);
  algo_name = openpgp_pk_algo_name (pk->pubkey_algo);
  timestr = strtimestamp (pk->timestamp);
  uid = get_user_id (is_subkey? pk->main_keyid:pk->keyid, &uidlen);

  orig_codeset = i18n_switchto_utf8 ();

  if (is_subkey)
    maink = xtryasprintf (_(" (main key ID %s)"), keystr (pk->main_keyid));
  else
    maink = NULL;

  switch (mode)
    {
    case FORMAT_KEYDESC_NORMAL:
      prompt = _("Please enter the passphrase to unlock the"
                 " OpenPGP secret key:");
      break;
    case FORMAT_KEYDESC_IMPORT:
      prompt = _("Please enter the passphrase to import the"
                 " OpenPGP secret key:");
      break;
    case FORMAT_KEYDESC_EXPORT:
      if (is_subkey)
        prompt = _("Please enter the passphrase to export the"
                   " OpenPGP secret subkey:");
      else
        prompt = _("Please enter the passphrase to export the"
                   " OpenPGP secret key:");
      break;
    case FORMAT_KEYDESC_DELKEY:
      if (is_subkey)
        prompt = _("Do you really want to permanently delete the"
                   " OpenPGP secret subkey key:");
      else
        prompt = _("Do you really want to permanently delete the"
                   " OpenPGP secret key:");
      trailer = "?";
      break;
    default:
      prompt = "?";
      break;
    }

  desc = xtryasprintf (_("%s\n"
                         "\"%.*s\"\n"
                         "%u-bit %s key, ID %s,\n"
                         "created %s%s.\n%s"),
                       prompt,
                       (int)uidlen, uid,
                       nbits_from_pk (pk), algo_name,
                       keystr (pk->keyid), timestr,
                       maink?maink:"", trailer);
  xfree (maink);
  xfree (uid);

  i18n_switchback (orig_codeset);

  if (escaped)
    {
      char *tmp = percent_plus_escape (desc);
      xfree (desc);
      desc = tmp;
    }

  return desc;
}
예제 #5
0
/* Mount the container with name FILENAME at MOUNTPOINT.  */
gpg_error_t
g13_mount_container (ctrl_t ctrl, const char *filename, const char *mountpoint)
{
  gpg_error_t err;
  dotlock_t lock;
  void *enckeyblob = NULL;
  size_t enckeybloblen;
  void *keyblob = NULL;
  size_t keybloblen;
  tupledesc_t tuples = NULL;
  size_t n;
  const unsigned char *value;
  int conttype;
  unsigned int rid;
  char *mountpoint_buffer = NULL;

  /* A quick check to see whether the container exists.  */
  if (access (filename, R_OK))
    return gpg_error_from_syserror ();

  if (!mountpoint)
    {
      mountpoint_buffer = xtrystrdup ("/tmp/g13-XXXXXX");
      if (!mountpoint_buffer)
        return gpg_error_from_syserror ();
      if (!gnupg_mkdtemp (mountpoint_buffer))
        {
          err = gpg_error_from_syserror ();
          log_error (_("can't create directory '%s': %s\n"),
                     "/tmp/g13-XXXXXX", gpg_strerror (err));
          xfree (mountpoint_buffer);
          return err;
        }
      mountpoint = mountpoint_buffer;
    }

  /* Try to take a lock.  */
  lock = dotlock_create (filename, 0);
  if (!lock)
    {
      xfree (mountpoint_buffer);
      return gpg_error_from_syserror ();
    }

  if (dotlock_take (lock, 0))
    {
      err = gpg_error_from_syserror ();
      goto leave;
    }
  else
    err = 0;

  /* Check again that the file exists.  */
  {
    struct stat sb;

    if (stat (filename, &sb))
      {
        err = gpg_error_from_syserror ();
        goto leave;
      }
  }

  /* Read the encrypted keyblob.  */
  err = read_keyblob (filename, &enckeyblob, &enckeybloblen);
  if (err)
    goto leave;

  /* Decrypt that keyblob and store it in a tuple descriptor.  */
  err = decrypt_keyblob (ctrl, enckeyblob, enckeybloblen,
                         &keyblob, &keybloblen);
  if (err)
    goto leave;
  xfree (enckeyblob);
  enckeyblob = NULL;

  err = create_tupledesc (&tuples, keyblob, keybloblen);
  if (!err)
    keyblob = NULL;
  else
    {
      if (gpg_err_code (err) == GPG_ERR_NOT_SUPPORTED)
        log_error ("unknown keyblob version\n");
      goto leave;
    }
  if (opt.verbose)
    dump_keyblob (tuples);

  value = find_tuple (tuples, KEYBLOB_TAG_CONTTYPE, &n);
  if (!value || n != 2)
    conttype = 0;
  else
    conttype = (value[0] << 8 | value[1]);
  if (!be_is_supported_conttype (conttype))
    {
      log_error ("content type %d is not supported\n", conttype);
      err = gpg_error (GPG_ERR_NOT_SUPPORTED);
      goto leave;
    }
  err = be_mount_container (ctrl, conttype, filename, mountpoint, tuples, &rid);
  if (!err)
    {
      err = mountinfo_add_mount (filename, mountpoint, conttype, rid,
                                 !!mountpoint_buffer);
      /* Fixme: What shall we do if this fails?  Add a provisional
         mountinfo entry first and remove it on error? */
      if (!err)
        {
          char *tmp = percent_plus_escape (mountpoint);
          if (!tmp)
            err = gpg_error_from_syserror ();
          else
            {
              g13_status (ctrl, STATUS_MOUNTPOINT, tmp, NULL);
              xfree (tmp);
            }
        }
    }

 leave:
  destroy_tupledesc (tuples);
  xfree (keyblob);
  xfree (enckeyblob);
  dotlock_destroy (lock);
  xfree (mountpoint_buffer);
  return err;
}
예제 #6
0
static void
test_percent_plus_escape (void)
{
  static struct {
    const char *string;
    const char *expect;
  } tbl[] = {
    { 
      "",
      "" 
    }, { 
      "a",
      "a",
    }, { 
      " ",
      "+",
    }, { 
      "  ",
      "++"
    }, { 
      "+ +",
      "%2B+%2B"
    }, { 
      "\" \"",
      "%22+%22"
    }, { 
      "%22",
      "%2522"
    }, { 
      "%% ",
      "%25%25+"
    }, { 
      "\n ABC\t",
      "%0A+ABC%09"
    }, { NULL, NULL }
  };
  char *buf, *buf2;
  int i;
  size_t len;
  
  for (i=0; tbl[i].string; i++)
    {
      buf = percent_plus_escape (tbl[i].string);
      if (!buf)
        {
          fprintf (stderr, "out of core: %s\n", strerror (errno));
          exit (2);
        }
      if (strcmp (buf, tbl[i].expect))
        fail (i);
      buf2 = percent_plus_unescape (buf, 0);
      if (!buf2)
        {
          fprintf (stderr, "out of core: %s\n", strerror (errno));
          exit (2);
        }
      if (strcmp (buf2, tbl[i].string))
        fail (i);
      xfree (buf2);
      /* Now test the inplace conversion.  */
      len = percent_plus_unescape_inplace (buf, 0);
      buf[len] = 0;
      if (strcmp (buf, tbl[i].string))
        fail (i);
      xfree (buf);
    }
}
예제 #7
0
/* Ask for a passphrase via gpg-agent.  On success the caller needs to
   free the string stored at R_PASSPHRASE.  On error NULL will be
   stored at R_PASSPHRASE and an appropriate gpg error code is
   returned.  With REPEAT set to 1, gpg-agent will ask the user to
   repeat the just entered passphrase.  CACHE_ID is a gpg-agent style
   passphrase cache id or NULL.  ERR_MSG is a error message to be
   presented to the user (e.g. "bad passphrase - try again") or NULL.
   PROMPT is the prompt string to label the entry box, it may be NULL
   for a default one.  DESC_MSG is a longer description to be
   displayed above the entry box, if may be NULL for a default one.
   If USE_SECMEM is true, the returned passphrase is retruned in
   secure memory.  The length of all these strings is limited; they
   need to fit in their encoded form into a standard Assuan line (i.e
   less then about 950 characters).  All strings shall be UTF-8.  */
gpg_error_t
gnupg_get_passphrase (const char *cache_id,
                      const char *err_msg,
                      const char *prompt,
                      const char *desc_msg,
                      int repeat,
                      int check_quality,
                      int use_secmem,
                      char **r_passphrase)
{
  gpg_error_t err;
  char line[ASSUAN_LINELENGTH];
  const char *arg1 = NULL;
  char *arg2 = NULL;
  char *arg3 = NULL;
  char *arg4 = NULL;
  membuf_t data;

  *r_passphrase = NULL;

  err = start_agent ();
  if (err)
    return err;

  /* Check that the gpg-agent understands the repeat option.  */
  if (assuan_transact (agent_ctx,
                       "GETINFO cmd_has_option GET_PASSPHRASE repeat",
                       NULL, NULL, NULL, NULL, NULL, NULL))
    return gpg_error (GPG_ERR_NOT_SUPPORTED);

  arg1 = cache_id && *cache_id? cache_id:NULL;
  if (err_msg && *err_msg)
    if (!(arg2 = percent_plus_escape (err_msg)))
      goto no_mem;
  if (prompt && *prompt)
    if (!(arg3 = percent_plus_escape (prompt)))
      goto no_mem;
  if (desc_msg && *desc_msg)
    if (!(arg4 = percent_plus_escape (desc_msg)))
      goto no_mem;

  snprintf (line, DIM(line)-1,
            "GET_PASSPHRASE --data %s--repeat=%d -- %s %s %s %s",
            check_quality? "--check ":"",
            repeat,
            arg1? arg1:"X",
            arg2? arg2:"X",
            arg3? arg3:"X",
            arg4? arg4:"X");
  line[DIM(line)-1] = 0;
  xfree (arg2);
  xfree (arg3);
  xfree (arg4);

  if (use_secmem)
    init_membuf_secure (&data, 64);
  else
    init_membuf (&data, 64);
  err = assuan_transact (agent_ctx, line,
                         membuf_data_cb, &data,
                         default_inq_cb, NULL, NULL, NULL);

  /* Older Pinentries return the old assuan error code for canceled
     which gets translated bt libassuan to GPG_ERR_ASS_CANCELED and
     not to the code for a user cancel.  Fix this here. */
  if (err && gpg_err_source (err)
      && gpg_err_code (err) == GPG_ERR_ASS_CANCELED)
    err = gpg_err_make (gpg_err_source (err), GPG_ERR_CANCELED);

  if (err)
    {
      void *p;
      size_t n;

      p = get_membuf (&data, &n);
      if (p)
        wipememory (p, n);
      xfree (p);
    }
  else
    {
      put_membuf (&data, "", 1);
      *r_passphrase = get_membuf (&data, NULL);
      if (!*r_passphrase)
        err = gpg_error_from_syserror ();
    }
  return err;
 no_mem:
  err = gpg_error_from_syserror ();
  xfree (arg2);
  xfree (arg3);
  xfree (arg4);
  return err;
}