Exemple #1
0
static gpgme_error_t
gpgsm_genkey (void *engine, gpgme_data_t help_data, int use_armor,
	      gpgme_data_t pubkey, gpgme_data_t seckey)
{
  engine_gpgsm_t gpgsm = engine;
  gpgme_error_t err;

  if (!gpgsm || !pubkey || seckey)
    return gpg_error (GPG_ERR_INV_VALUE);

  gpgsm->input_cb.data = help_data;
  err = gpgsm_set_fd (gpgsm, INPUT_FD, map_data_enc (gpgsm->input_cb.data));
  if (err)
    return err;
  gpgsm->output_cb.data = pubkey;
  err = gpgsm_set_fd (gpgsm, OUTPUT_FD, use_armor ? "--armor"
		      : map_data_enc (gpgsm->output_cb.data));
  if (err)
    return err;
  gpgsm_clear_fd (gpgsm, MESSAGE_FD);
  gpgsm->inline_data = NULL;

  err = start (gpgsm, "GENKEY");
  return err;
}
Exemple #2
0
static gpgme_error_t
gpgsm_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text,
	      gpgme_data_t plaintext)
{
  engine_gpgsm_t gpgsm = engine;
  gpgme_error_t err;

  if (!gpgsm)
    return gpg_error (GPG_ERR_INV_VALUE);

  gpgsm->input_cb.data = sig;
  err = gpgsm_set_fd (gpgsm, INPUT_FD, map_data_enc (gpgsm->input_cb.data));
  if (err)
    return err;
  if (plaintext)
    {
      /* Normal or cleartext signature.  */
      gpgsm->output_cb.data = plaintext;
      err = gpgsm_set_fd (gpgsm, OUTPUT_FD, 0);
      gpgsm_clear_fd (gpgsm, MESSAGE_FD);
    }
  else
    {
      /* Detached signature.  */
      gpgsm->message_cb.data = signed_text;
      err = gpgsm_set_fd (gpgsm, MESSAGE_FD, 0);
      gpgsm_clear_fd (gpgsm, OUTPUT_FD);
    }
  gpgsm->inline_data = NULL;

  if (!err)
    err = start (gpgsm, "VERIFY");

  return err;
}
Exemple #3
0
static gpgme_error_t
gpgsm_encrypt(void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
              gpgme_data_t plain, gpgme_data_t ciph, int use_armor)
{
    engine_gpgsm_t gpgsm = engine;
    gpgme_error_t err;

    if(!gpgsm)
        return gpg_error(GPG_ERR_INV_VALUE);
    if(!recp)
        return gpg_error(GPG_ERR_NOT_IMPLEMENTED);

    gpgsm->input_cb.data = plain;
    err = gpgsm_set_fd(gpgsm, INPUT_FD, map_input_enc(gpgsm->input_cb.data));
    if(err)
        return err;
    gpgsm->output_cb.data = ciph;
    err = gpgsm_set_fd(gpgsm, OUTPUT_FD, use_armor ? "--armor" : 0);
    if(err)
        return err;
    gpgsm_clear_fd(gpgsm, MESSAGE_FD);

    err = set_recipients(gpgsm, recp);

    if(!err)
        err = start(gpgsm, "ENCRYPT");

    return err;
}
Exemple #4
0
/* Send the GETAUDITLOG command.  The result is saved to a gpgme data
   object.  */
static gpgme_error_t
gpgsm_getauditlog (void *engine, gpgme_data_t output, unsigned int flags)
{
  engine_gpgsm_t gpgsm = engine;
  gpgme_error_t err = 0;

  if (!gpgsm || !output)
    return gpg_error (GPG_ERR_INV_VALUE);

#if USE_DESCRIPTOR_PASSING
  gpgsm->output_cb.data = output;
  err = gpgsm_set_fd (gpgsm, OUTPUT_FD, 0);
  if (err)
    return err;

  gpgsm_clear_fd (gpgsm, INPUT_FD);
  gpgsm_clear_fd (gpgsm, MESSAGE_FD);
  gpgsm->inline_data = NULL;
# define CMD  "GETAUDITLOG"
#else
  gpgsm_clear_fd (gpgsm, OUTPUT_FD);
  gpgsm_clear_fd (gpgsm, INPUT_FD);
  gpgsm_clear_fd (gpgsm, MESSAGE_FD);
  gpgsm->inline_data = output;
# define CMD  "GETAUDITLOG --data"
#endif

  err = start (gpgsm, (flags & GPGME_AUDITLOG_HTML)? CMD " --html" : CMD);

  return err;
}
Exemple #5
0
static gpgme_error_t
gpgsm_export(void *engine, const char *pattern, unsigned int reserved,
             gpgme_data_t keydata, int use_armor)
{
    engine_gpgsm_t gpgsm = engine;
    gpgme_error_t err = 0;
    char *cmd;

    if(!gpgsm || reserved)
        return gpg_error(GPG_ERR_INV_VALUE);

    if(!pattern)
        pattern = "";

    cmd = malloc(7 + strlen(pattern) + 1);
    if(!cmd)
        return gpg_error_from_errno(errno);
    strcpy(cmd, "EXPORT ");
    strcpy(&cmd[7], pattern);

    gpgsm->output_cb.data = keydata;
    err = gpgsm_set_fd(gpgsm, OUTPUT_FD, use_armor ? "--armor" : 0);
    if(err)
        return err;
    gpgsm_clear_fd(gpgsm, INPUT_FD);
    gpgsm_clear_fd(gpgsm, MESSAGE_FD);

    err = start(gpgsm, cmd);
    free(cmd);
    return err;
}
Exemple #6
0
static gpgme_error_t
gpgsm_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
	       gpgme_data_t plain, gpgme_data_t ciph, int use_armor)
{
  engine_gpgsm_t gpgsm = engine;
  gpgme_error_t err;

  if (!gpgsm)
    return gpg_error (GPG_ERR_INV_VALUE);
  if (!recp)
    return gpg_error (GPG_ERR_NOT_IMPLEMENTED);

  if (flags & GPGME_ENCRYPT_NO_ENCRYPT_TO)
    {
      err = gpgsm_assuan_simple_command (gpgsm->assuan_ctx,
					 "OPTION no-encrypt-to", NULL, NULL);
      if (err)
	return err;
    }

  gpgsm->input_cb.data = plain;
  err = gpgsm_set_fd (gpgsm, INPUT_FD, map_data_enc (gpgsm->input_cb.data));
  if (err)
    return err;
  gpgsm->output_cb.data = ciph;
  err = gpgsm_set_fd (gpgsm, OUTPUT_FD, use_armor ? "--armor"
		      : map_data_enc (gpgsm->output_cb.data));
  if (err)
    return err;
  gpgsm_clear_fd (gpgsm, MESSAGE_FD);
  gpgsm->inline_data = NULL;

  err = set_recipients (gpgsm, recp);

  if (!err)
    err = start (gpgsm, "ENCRYPT");

  return err;
}
Exemple #7
0
static gpgme_error_t
gpgsm_decrypt(void *engine, gpgme_data_t ciph, gpgme_data_t plain)
{
    engine_gpgsm_t gpgsm = engine;
    gpgme_error_t err;

    if(!gpgsm)
        return gpg_error(GPG_ERR_INV_VALUE);

    gpgsm->input_cb.data = ciph;
    err = gpgsm_set_fd(gpgsm, INPUT_FD, map_input_enc(gpgsm->input_cb.data));
    if(err)
        return gpg_error(GPG_ERR_GENERAL);	/* FIXME */
    gpgsm->output_cb.data = plain;
    err = gpgsm_set_fd(gpgsm, OUTPUT_FD, 0);
    if(err)
        return gpg_error(GPG_ERR_GENERAL);	/* FIXME */
    gpgsm_clear_fd(gpgsm, MESSAGE_FD);

    err = start(engine, "DECRYPT");
    return err;
}
Exemple #8
0
static gpgme_error_t
gpgsm_import(void *engine, gpgme_data_t keydata)
{
    engine_gpgsm_t gpgsm = engine;
    gpgme_error_t err;

    if(!gpgsm)
        return gpg_error(GPG_ERR_INV_VALUE);

    gpgsm->input_cb.data = keydata;
    err = gpgsm_set_fd(gpgsm, INPUT_FD, map_input_enc(gpgsm->input_cb.data));
    if(err)
        return err;
    gpgsm_clear_fd(gpgsm, OUTPUT_FD);
    gpgsm_clear_fd(gpgsm, MESSAGE_FD);

    err = start(gpgsm, "IMPORT");
    return err;
}
Exemple #9
0
static gpgme_error_t
gpgsm_export (void *engine, const char *pattern, gpgme_export_mode_t mode,
	      gpgme_data_t keydata, int use_armor)
{
  engine_gpgsm_t gpgsm = engine;
  gpgme_error_t err = 0;
  char *cmd;

  if (!gpgsm)
    return gpg_error (GPG_ERR_INV_VALUE);

  if (mode)
    return gpg_error (GPG_ERR_NOT_SUPPORTED);

  if (!pattern)
    pattern = "";

  cmd = malloc (7 + strlen (pattern) + 1);
  if (!cmd)
    return gpg_error_from_syserror ();
  strcpy (cmd, "EXPORT ");
  strcpy (&cmd[7], pattern);

  gpgsm->output_cb.data = keydata;
  err = gpgsm_set_fd (gpgsm, OUTPUT_FD, use_armor ? "--armor"
		      : map_data_enc (gpgsm->output_cb.data));
  if (err)
    return err;
  gpgsm_clear_fd (gpgsm, INPUT_FD);
  gpgsm_clear_fd (gpgsm, MESSAGE_FD);
  gpgsm->inline_data = NULL;

  err = start (gpgsm, cmd);
  free (cmd);
  return err;
}
Exemple #10
0
static gpgme_error_t
gpgsm_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
	    gpgme_sig_mode_t mode, int use_armor, int use_textmode,
	    int include_certs, gpgme_ctx_t ctx /* FIXME */)
{
  engine_gpgsm_t gpgsm = engine;
  gpgme_error_t err;
  char *assuan_cmd;
  int i;
  gpgme_key_t key;

  if (!gpgsm)
    return gpg_error (GPG_ERR_INV_VALUE);

  /* FIXME: This does not work as RESET does not reset it so we can't
     revert back to default.  */
  if (include_certs != GPGME_INCLUDE_CERTS_DEFAULT)
    {
      /* FIXME: Make sure that if we run multiple operations, that we
	 can reset any previously set value in case the default is
	 requested.  */

      if (asprintf (&assuan_cmd, "OPTION include-certs %i", include_certs) < 0)
	return gpg_error_from_syserror ();
      err = gpgsm_assuan_simple_command (gpgsm->assuan_ctx, assuan_cmd,
                                         NULL, NULL);
      free (assuan_cmd);
      if (err)
	return err;
    }

  for (i = 0; (key = gpgme_signers_enum (ctx, i)); i++)
    {
      const char *s = key->subkeys ? key->subkeys->fpr : NULL;
      if (s && strlen (s) < 80)
	{
          char buf[100];

          strcpy (stpcpy (buf, "SIGNER "), s);
          err = gpgsm_assuan_simple_command (gpgsm->assuan_ctx, buf,
                                             gpgsm->status.fnc,
                                             gpgsm->status.fnc_value);
	}
      else
        err = gpg_error (GPG_ERR_INV_VALUE);
      gpgme_key_unref (key);
      if (err)
        return err;
    }

  gpgsm->input_cb.data = in;
  err = gpgsm_set_fd (gpgsm, INPUT_FD, map_data_enc (gpgsm->input_cb.data));
  if (err)
    return err;
  gpgsm->output_cb.data = out;
  err = gpgsm_set_fd (gpgsm, OUTPUT_FD, use_armor ? "--armor"
		      : map_data_enc (gpgsm->output_cb.data));
  if (err)
    return err;
  gpgsm_clear_fd (gpgsm, MESSAGE_FD);
  gpgsm->inline_data = NULL;

  err = start (gpgsm, mode == GPGME_SIG_MODE_DETACH
	       ? "SIGN --detached" : "SIGN");
  return err;
}
Exemple #11
0
static gpgme_error_t
gpgsm_import (void *engine, gpgme_data_t keydata, gpgme_key_t *keyarray)
{
  engine_gpgsm_t gpgsm = engine;
  gpgme_error_t err;
  gpgme_data_encoding_t dataenc;
  int idx;

  if (!gpgsm)
    return gpg_error (GPG_ERR_INV_VALUE);

  if (keydata && keyarray)
    return gpg_error (GPG_ERR_INV_VALUE); /* Only one is allowed.  */

  dataenc = gpgme_data_get_encoding (keydata);

  if (keyarray)
    {
      size_t buflen;
      char *buffer, *p;

      /* Fist check whether the engine already features the
         --re-import option.  */
      err = gpgsm_assuan_simple_command
        (gpgsm->assuan_ctx,
         "GETINFO cmd_has_option IMPORT re-import", NULL, NULL);
      if (err)
	return gpg_error (GPG_ERR_NOT_SUPPORTED);

      /* Create an internal data object with a list of all
         fingerprints.  The data object and its memory (to avoid an
         extra copy by gpgme_data_new_from_mem) are stored in two
         variables which are released by the close_notify_handler.  */
      for (idx=0, buflen=0; keyarray[idx]; idx++)
        {
          if (keyarray[idx]->protocol == GPGME_PROTOCOL_CMS
              && keyarray[idx]->subkeys
              && keyarray[idx]->subkeys->fpr
              && *keyarray[idx]->subkeys->fpr)
            buflen += strlen (keyarray[idx]->subkeys->fpr) + 1;
        }
      /* Allocate a bufer with extra space for the trailing Nul
         introduced by the use of stpcpy.  */
      buffer = malloc (buflen+1);
      if (!buffer)
        return gpg_error_from_syserror ();
      for (idx=0, p = buffer; keyarray[idx]; idx++)
        {
          if (keyarray[idx]->protocol == GPGME_PROTOCOL_CMS
              && keyarray[idx]->subkeys
              && keyarray[idx]->subkeys->fpr
              && *keyarray[idx]->subkeys->fpr)
            p = stpcpy (stpcpy (p, keyarray[idx]->subkeys->fpr), "\n");
        }

      err = gpgme_data_new_from_mem (&gpgsm->input_helper_data,
                                     buffer, buflen, 0);
      if (err)
        {
          free (buffer);
          return err;
        }
      gpgsm->input_helper_memory = buffer;

      gpgsm->input_cb.data = gpgsm->input_helper_data;
      err = gpgsm_set_fd (gpgsm, INPUT_FD, map_data_enc (gpgsm->input_cb.data));
      if (err)
        {
          gpgme_data_release (gpgsm->input_helper_data);
          gpgsm->input_helper_data = NULL;
          free (gpgsm->input_helper_memory);
          gpgsm->input_helper_memory = NULL;
          return err;
        }
      gpgsm_clear_fd (gpgsm, OUTPUT_FD);
      gpgsm_clear_fd (gpgsm, MESSAGE_FD);
      gpgsm->inline_data = NULL;

      return start (gpgsm, "IMPORT --re-import");
    }
  else if (dataenc == GPGME_DATA_ENCODING_URL
           || dataenc == GPGME_DATA_ENCODING_URL0
           || dataenc == GPGME_DATA_ENCODING_URLESC)
    {
      return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
    }
  else
    {
      gpgsm->input_cb.data = keydata;
      err = gpgsm_set_fd (gpgsm, INPUT_FD, map_data_enc (gpgsm->input_cb.data));
      if (err)
        return err;
      gpgsm_clear_fd (gpgsm, OUTPUT_FD);
      gpgsm_clear_fd (gpgsm, MESSAGE_FD);
      gpgsm->inline_data = NULL;

      return start (gpgsm, "IMPORT");
    }
}
Exemple #12
0
static gpgme_error_t
gpgsm_export_ext (void *engine, const char *pattern[], gpgme_export_mode_t mode,
		  gpgme_data_t keydata, int use_armor)
{
  engine_gpgsm_t gpgsm = engine;
  gpgme_error_t err = 0;
  char *line;
  /* Length is "EXPORT " + p + '\0'.  */
  int length = 7 + 1;
  char *linep;

  if (!gpgsm)
    return gpg_error (GPG_ERR_INV_VALUE);

  if (mode)
    return gpg_error (GPG_ERR_NOT_SUPPORTED);

  if (pattern && *pattern)
    {
      const char **pat = pattern;

      while (*pat)
	{
	  const char *patlet = *pat;

	  while (*patlet)
	    {
	      length++;
	      if (*patlet == '%' || *patlet == ' ' || *patlet == '+')
		length += 2;
	      patlet++;
	    }
	  pat++;
	  length++;
	}
    }
  line = malloc (length);
  if (!line)
    return gpg_error_from_syserror ();

  strcpy (line, "EXPORT ");
  linep = &line[7];

  if (pattern && *pattern)
    {
      while (*pattern)
	{
	  const char *patlet = *pattern;

	  while (*patlet)
	    {
	      switch (*patlet)
		{
		case '%':
		  *(linep++) = '%';
		  *(linep++) = '2';
		  *(linep++) = '5';
		  break;
		case ' ':
		  *(linep++) = '%';
		  *(linep++) = '2';
		  *(linep++) = '0';
		  break;
		case '+':
		  *(linep++) = '%';
		  *(linep++) = '2';
		  *(linep++) = 'B';
		  break;
		default:
		  *(linep++) = *patlet;
		  break;
		}
	      patlet++;
	    }
	  pattern++;
          if (*pattern)
            *linep++ = ' ';
	}
    }
  *linep = '\0';

  gpgsm->output_cb.data = keydata;
  err = gpgsm_set_fd (gpgsm, OUTPUT_FD, use_armor ? "--armor"
		      : map_data_enc (gpgsm->output_cb.data));
  if (err)
    return err;
  gpgsm_clear_fd (gpgsm, INPUT_FD);
  gpgsm_clear_fd (gpgsm, MESSAGE_FD);
  gpgsm->inline_data = NULL;

  err = start (gpgsm, line);
  free (line);
  return err;
}