コード例 #1
0
ファイル: app.c プロジェクト: Juul/gnupg
/* Read the key with ID KEYID.  On success a canonical encoded
   S-expression with the public key will get stored at PK and its
   length (for assertions) at PKLEN; the caller must release that
   buffer. On error NULL will be stored at PK and PKLEN and an error
   code returned.

   This function might not be supported by all applications.  */
gpg_error_t
app_readkey (app_t app, const char *keyid, unsigned char **pk, size_t *pklen)
{
  gpg_error_t err;

  if (pk)
    *pk = NULL;
  if (pklen)
    *pklen = 0;

  if (!app || !keyid || !pk || !pklen)
    return gpg_error (GPG_ERR_INV_VALUE);
  if (!app->ref_count)
    return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
  if (!app->fnc.readkey)
    return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
  err = lock_reader (app->slot, NULL /*FIXME*/);
  if (err)
    return err;
  err= app->fnc.readkey (app, keyid, pk, pklen);
  unlock_reader (app->slot);
  return err;
}
コード例 #2
0
ファイル: app.c プロジェクト: Juul/gnupg
/* Write out the application specifig status lines for the LEARN
   command. */
gpg_error_t
app_write_learn_status (app_t app, ctrl_t ctrl, unsigned int flags)
{
  gpg_error_t err;

  if (!app)
    return gpg_error (GPG_ERR_INV_VALUE);
  if (!app->ref_count)
    return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
  if (!app->fnc.learn_status)
    return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);

  /* We do not send APPTYPE if only keypairinfo is requested.  */
  if (app->apptype && !(flags & 1))
    send_status_info (ctrl, "APPTYPE",
                      app->apptype, strlen (app->apptype), NULL, 0);
  err = lock_reader (app->slot, ctrl);
  if (err)
    return err;
  err = app->fnc.learn_status (app, ctrl, flags);
  unlock_reader (app->slot);
  return err;
}
コード例 #3
0
ファイル: gpuvm.c プロジェクト: canonizer/libgpuvm
/** pre-unlinks the host array by synchronizing it back to host and unprotecting
		it 
		@param hostptr the address of the host array to be synchronized and
		unprotected
		@returns 0 if successful and a negative error code if not
*/
static int gpuvm_pre_unlink(void *hostptr) {
	if(lock_reader())
		return GPUVM_ERROR;

	// get the array
	host_array_t *host_array = host_array_find_by_ptr(hostptr);
	if(!host_array) {
		unlock_reader();
		fprintf(stderr, "gpuvm_pre_unlink: not a valid pointer\n");
		return GPUVM_EHOSTPTR;
	}
	
	// tap into the beginning of each array subregion, to cause readback if
	// mprotected 
	unsigned isubreg;
	int err;
	for(isubreg = 0; isubreg < host_array->nsubregs; isubreg++) {
		err += *(char*)host_array->subregs[isubreg]->range.ptr;
	}
	
	unlock_reader();
	return 0;
}  // gpuvm_pre_unlink()
コード例 #4
0
ファイル: app.c プロジェクト: FMayzek/gnupg
/* Perform a CHANGE REFERENCE DATA or RESET RETRY COUNTER operation.  */
gpg_error_t
app_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, int reset_mode,
                gpg_error_t (*pincb)(void*, const char *, char **),
                void *pincb_arg)
{
  gpg_error_t err;

  if (!app || !chvnostr || !*chvnostr || !pincb)
    return gpg_error (GPG_ERR_INV_VALUE);
  if (!app->ref_count)
    return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
  if (!app->fnc.change_pin)
    return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
  err = lock_reader (app->slot, ctrl);
  if (err)
    return err;
  err = app->fnc.change_pin (app, ctrl, chvnostr, reset_mode,
                             pincb, pincb_arg);
  unlock_reader (app->slot);
  if (opt.verbose)
    log_info ("operation change_pin result: %s\n", gpg_strerror (err));
  return err;
}
コード例 #5
0
ファイル: app.c プロジェクト: Juul/gnupg
/* Perform a SETATTR operation.  */
gpg_error_t
app_genkey (app_t app, ctrl_t ctrl, const char *keynostr, unsigned int flags,
            time_t createtime,
            gpg_error_t (*pincb)(void*, const char *, char **),
            void *pincb_arg)
{
  gpg_error_t err;

  if (!app || !keynostr || !*keynostr || !pincb)
    return gpg_error (GPG_ERR_INV_VALUE);
  if (!app->ref_count)
    return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED);
  if (!app->fnc.genkey)
    return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
  err = lock_reader (app->slot, ctrl);
  if (err)
    return err;
  err = app->fnc.genkey (app, ctrl, keynostr, flags,
                         createtime, pincb, pincb_arg);
  unlock_reader (app->slot);
  if (opt.verbose)
    log_info ("operation genkey result: %s\n", gpg_strerror (err));
  return err;
}
コード例 #6
0
ファイル: app.c プロジェクト: Juul/gnupg
/* If called with NAME as NULL, select the best fitting application
   and return a context; otherwise select the application with NAME
   and return a context.  SLOT identifies the reader device. Returns
   an error code and stores NULL at R_APP if no application was found
   or no card is present. */
gpg_error_t
select_application (ctrl_t ctrl, int slot, const char *name, app_t *r_app)
{
  gpg_error_t err;
  app_t app = NULL;
  unsigned char *result = NULL;
  size_t resultlen;
  int want_undefined;

  (void)ctrl;

  *r_app = NULL;

  want_undefined = (name && !strcmp (name, "undefined"));

  err = lock_reader (slot, ctrl);
  if (err)
    return err;

  /* First check whether we already have an application to share. */
  app = lock_table[slot].initialized ? lock_table[slot].app : NULL;
  if (app && name)
    if (!app->apptype || ascii_strcasecmp (app->apptype, name))
      {
        unlock_reader (slot);
        if (app->apptype)
          log_info ("application '%s' in use by reader %d - can't switch\n",
                    app->apptype, slot);
        return gpg_error (GPG_ERR_CONFLICT);
      }

  /* Don't use a non-reusable marked application.  */
  if (app && app->no_reuse)
    {
      unlock_reader (slot);
      log_info ("lingering application '%s' in use by reader %d"
                " - can't switch\n",
                app->apptype? app->apptype:"?", slot);
      return gpg_error (GPG_ERR_CONFLICT);
    }

  /* If we don't have an app, check whether we have a saved
     application for that slot.  This is useful so that a card does
     not get reset even if only one session is using the card - this
     way the PIN cache and other cached data are preserved.  */
  if (!app && lock_table[slot].initialized && lock_table[slot].last_app)
    {
      app = lock_table[slot].last_app;
      if (!name || (app->apptype && !ascii_strcasecmp (app->apptype, name)) )
        {
          /* Yes, we can reuse this application - either the caller
             requested an unspecific one or the requested one matches
             the saved one. */
          lock_table[slot].app = app;
          lock_table[slot].last_app = NULL;
        }
      else
        {
          /* No, this saved application can't be used - deallocate it. */
          lock_table[slot].last_app = NULL;
          deallocate_app (app);
          app = NULL;
        }
    }

  /* If we can reuse an application, bump the reference count and
     return it.  */
  if (app)
    {
      if (app->slot != slot)
        log_bug ("slot mismatch %d/%d\n", app->slot, slot);
      app->slot = slot;

      app->ref_count++;
      *r_app = app;
      unlock_reader (slot);
      return 0; /* Okay: We share that one. */
    }

  /* Need to allocate a new one.  */
  app = xtrycalloc (1, sizeof *app);
  if (!app)
    {
      err = gpg_error_from_syserror ();
      log_info ("error allocating context: %s\n", gpg_strerror (err));
      unlock_reader (slot);
      return err;
    }
  app->slot = slot;


  /* Fixme: We should now first check whether a card is at all
     present. */

  /* Try to read the GDO file first to get a default serial number.
     We skip this if the undefined application has been requested. */
  if (!want_undefined)
    {
      err = iso7816_select_file (slot, 0x3F00, 1, NULL, NULL);
      if (!err)
        err = iso7816_select_file (slot, 0x2F02, 0, NULL, NULL);
      if (!err)
        err = iso7816_read_binary (slot, 0, 0, &result, &resultlen);
      if (!err)
        {
          size_t n;
          const unsigned char *p;

          p = find_tlv_unchecked (result, resultlen, 0x5A, &n);
          if (p)
            resultlen -= (p-result);
          if (p && n > resultlen && n == 0x0d && resultlen+1 == n)
            {
              /* The object it does not fit into the buffer.  This is an
                 invalid encoding (or the buffer is too short.  However, I
                 have some test cards with such an invalid encoding and
                 therefore I use this ugly workaround to return something
                 I can further experiment with. */
              log_info ("enabling BMI testcard workaround\n");
              n--;
            }

          if (p && n <= resultlen)
            {
              /* The GDO file is pretty short, thus we simply reuse it for
                 storing the serial number. */
              memmove (result, p, n);
              app->serialno = result;
              app->serialnolen = n;
              err = app_munge_serialno (app);
              if (err)
                goto leave;
            }
          else
            xfree (result);
          result = NULL;
        }
    }

  /* For certain error codes, there is no need to try more.  */
  if (gpg_err_code (err) == GPG_ERR_CARD_NOT_PRESENT
      || gpg_err_code (err) == GPG_ERR_ENODEV)
    goto leave;

  /* Figure out the application to use.  */
  if (want_undefined)
    {
      /* We switch to the "undefined" application only if explicitly
         requested.  */
      app->apptype = "UNDEFINED";
      err = 0;
    }
  else
    err = gpg_error (GPG_ERR_NOT_FOUND);

  if (err && is_app_allowed ("openpgp")
          && (!name || !strcmp (name, "openpgp")))
    err = app_select_openpgp (app);
  if (err && is_app_allowed ("nks") && (!name || !strcmp (name, "nks")))
    err = app_select_nks (app);
  if (err && is_app_allowed ("p15") && (!name || !strcmp (name, "p15")))
    err = app_select_p15 (app);
  if (err && is_app_allowed ("geldkarte")
      && (!name || !strcmp (name, "geldkarte")))
    err = app_select_geldkarte (app);
  if (err && is_app_allowed ("dinsig") && (!name || !strcmp (name, "dinsig")))
    err = app_select_dinsig (app);
  if (err && name)
    err = gpg_error (GPG_ERR_NOT_SUPPORTED);

 leave:
  if (err)
    {
      if (name)
        log_info ("can't select application '%s': %s\n",
                  name, gpg_strerror (err));
      else
        log_info ("no supported card application found: %s\n",
                  gpg_strerror (err));
      xfree (app);
      unlock_reader (slot);
      return err;
    }

  app->ref_count = 1;

  lock_table[slot].app = app;
  *r_app = app;
  unlock_reader (slot);
  return 0;
}