Пример #1
0
/* Return a GPGME key object matching PATTERN.  If no key matches or
   the match is ambiguous, return NULL. */
gpgme_key_t 
op_get_one_key (char *pattern)
{
  gpgme_error_t err;
  gpgme_ctx_t ctx;
  gpgme_key_t k, k2;

  err = gpgme_new (&ctx);
  if (err)
    return NULL; /* Error. */
  err = gpgme_op_keylist_start (ctx, pattern, 0);
  if (!err)
    {
      err = gpgme_op_keylist_next (ctx, &k);
      if (!err && !gpgme_op_keylist_next (ctx, &k2))
        {
          /* More than one matching key available.  Return an error
             instead. */
          gpgme_key_release (k);
          gpgme_key_release (k2);
          k = k2 = NULL;
        }
    }
  gpgme_op_keylist_end (ctx);
  gpgme_release (ctx);
  return k;
}
Пример #2
0
gboolean sgpgme_has_secret_key(void)
{
	gpgme_error_t err = 0;
	gpgme_ctx_t ctx;
	gpgme_key_t key;

	err = gpgme_new (&ctx);
	if (err) {
		debug_print("err : %s\n", gpgme_strerror(err));
		return TRUE;
	}
check_again:
	err = gpgme_op_keylist_start(ctx, NULL, TRUE);
	if (!err)
		err = gpgme_op_keylist_next(ctx, &key);
	gpgme_op_keylist_end(ctx);
	if (gpg_err_code(err) == GPG_ERR_EOF) {
		if (gpgme_get_protocol(ctx) != GPGME_PROTOCOL_CMS) {
			gpgme_set_protocol(ctx, GPGME_PROTOCOL_CMS);
			goto check_again;
		}
		gpgme_release(ctx);
		return FALSE;
	} else {
		gpgme_release(ctx);
		return TRUE;
	}
}
Пример #3
0
static PyObject *
pygpgme_keyiter_next(PyGpgmeKeyIter *self)
{
    gpgme_key_t key = NULL;
    gpgme_error_t err;
    PyObject *ret;

    Py_BEGIN_ALLOW_THREADS;
    err = gpgme_op_keylist_next(self->ctx->ctx, &key);
    Py_END_ALLOW_THREADS;

    /* end iteration */
    if (gpgme_err_source(err) == GPG_ERR_SOURCE_GPGME &&
        gpgme_err_code(err) == GPG_ERR_EOF) {
        PyErr_SetNone(PyExc_StopIteration);
        return NULL;
    }

    if (pygpgme_check_error(err))
        return NULL;

    if (key == NULL)
        Py_RETURN_NONE;

    ret = pygpgme_key_new(key);
    gpgme_key_unref(key);
    return ret;
}
Пример #4
0
GSList *
get_available_keys ()
{
    init_gpgme ();

    gpgme_ctx_t ctx;
    gpgme_key_t key;

    gpgme_error_t  err = gpgme_new (&ctx);
    if (err) {
        g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (err), gpgme_strerror (err));
        return GPGME_ERROR;
    }

    err = gpgme_op_keylist_start (ctx, NULL, 1);
    if (err) {
        g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (err), gpgme_strerror (err));
        gpgme_release (ctx);
        return GPGME_ERROR;
    }

    GSList *list = NULL;
    KeyInfo *key_info;

    while (1) {
        err = gpgme_op_keylist_next (ctx, &key);
        if (err) {
            break;
        }
        key_info = g_new0 (KeyInfo, 1);
        key_info->key_id = g_strdup (key->subkeys->keyid);
        if (key->uids && key->uids->name) {
            key_info->name = g_strdup (key->uids->name);
        } else {
            key_info->name = g_strdup ("none");
        }
        if (key->uids && key->uids->email) {
            key_info->email = g_strdup (key->uids->email);
        } else {
            key_info->email = g_strdup ("none");
        }
        key_info->key_fpr = g_strdup (key->subkeys->fpr);

        gssize bytes_to_copy = sizeof (KeyInfo) + g_utf8_strlen (key_info->name, -1) + g_utf8_strlen (key_info->email, -1) +
                g_utf8_strlen (key_info->key_id, -1) + g_utf8_strlen (key_info->key_fpr, -1) + 4;

        list = g_slist_append (list, g_memdup (key_info, bytes_to_copy));

        g_free (key_info);

        gpgme_key_release (key);
    }

    gpgme_release (ctx);

    return list;
}
Пример #5
0
/* ------------------
 * preferences dialog function
 * ------------------ */
static PurplePluginPrefFrame *
get_plugin_pref_frame(PurplePlugin *plugin) {
	PurplePluginPrefFrame *frame;
	PurplePluginPref *ppref;
	gpgme_error_t error;
	gpgme_ctx_t ctx;
	gpgme_key_t key;

	// create preferences frame
	frame = purple_plugin_pref_frame_new();
	
	// connect to gpgme
	gpgme_check_version (NULL);
	error = gpgme_new(&ctx);
	if (error)
	{
		purple_debug_error(PLUGIN_ID,"gpgme_new failed: %s %s\n",gpgme_strsource (error), gpgme_strerror (error));
		return NULL;
	}

	// create key chooser preference
	ppref = purple_plugin_pref_new_with_name_and_label(PREF_MY_KEY,"My key");
	purple_plugin_pref_set_type(ppref, PURPLE_PLUGIN_PREF_CHOICE);
	purple_plugin_pref_add_choice(ppref, "None", "");

	// list keys (secret keys)
	error = gpgme_op_keylist_start (ctx,NULL,1);
	if (error == GPG_ERR_NO_ERROR)
	{
		while (!error)
		{
			error = gpgme_op_keylist_next (ctx, &key);
			if (error) break;
			// add key to preference chooser
			//TODO: find something better for g_strdup, or some possibility to free memory after preferences dialog closed
			purple_plugin_pref_add_choice(ppref, g_strdup(key->uids->uid), g_strdup(key->subkeys->fpr));
			purple_debug_info(PLUGIN_ID,"Found secret key for: %s has fpr %s\n",key->uids->uid,key->subkeys->fpr);
			gpgme_key_release (key);
		}
	}else
	{
		purple_debug_error(PLUGIN_ID,"gpgme_op_keylist_start failed: %s %s\n",gpgme_strsource (error), gpgme_strerror (error));
	}
	// close gpgme connection
	gpgme_release (ctx);

	purple_plugin_pref_frame_add(frame, ppref);

	return frame;
}
Пример #6
0
gpgme_key_t GPGWrapper::getKey(const char * identifier, bool isPrivate)
{
    gpgme_key_t result;

    gpgme_error_t error = gpgme_op_keylist_start(context, identifier, isPrivate ? 1 : 0);
    fail_if_err(error, L"Nie uda³o siê zainicjowaæ pobierania klucza.");

    error = gpgme_op_keylist_next(context, &result);
    fail_if_err(error, L"Nie uda³o siê pobraæ klucza.");

    reciversIdToKey[identifier] = result;

    error = gpgme_op_keylist_end(context);
    fail_if_err(error, L"Nie uda³o siê zakoñczyæ pobieranie klucza.");

    return result;
}
Пример #7
0
int main(void)
{
   gpgme_ctx_t ctx;
   gpgme_error_t err;

   int setup_res = setup(&ctx);
   if(setup_res) return setup_res;

   /* Change mode to list sigs and */
   gpgme_keylist_mode_t mode = gpgme_get_keylist_mode(ctx);
   mode |= GPGME_KEYLIST_MODE_SIGS | GPGME_KEYLIST_MODE_SIG_NOTATIONS;
   err = gpgme_set_keylist_mode(ctx, mode);
   if (err != GPG_ERR_NO_ERROR) return 6;

   /* List all keys */
   /* (context, pattern, secret_only) */
   err = gpgme_op_keylist_start(ctx, NULL, 0);
   if (err != GPG_ERR_NO_ERROR) return 7;

   gpgme_key_t key;
   while ((err = gpgme_op_keylist_next(ctx, &key)) == GPG_ERR_NO_ERROR) {
      printf("Got a key\n");
      printf ("%s:", key->subkeys->keyid);
      if (key->uids && key->uids->name)
        printf (" %s", key->uids->name);
      if (key->uids && key->uids->email)
        printf (" <%s>", key->uids->email);
      if (key->uids && key->uids->signatures) {
        printf("First signature: %s\n", key->uids->signatures->keyid);
      }
      putchar ('\n');
      gpgme_key_release (key);
   }
   if (gpg_err_code(err) == GPG_ERR_EOF) {
      printf("%xu\n", err);
      printf("End of keylist.\n");
   } else {
      print_gpg_error(err);
      return 8;
   }

   /* free context */
   gpgme_release(ctx);

   return 0;
}
Пример #8
0
KGpgKeyList KGpgMe::keys(bool privateKeys /* = false */) const
{
	KGpgKeyList keys;
	gpgme_error_t err = 0, err2 = 0;
	gpgme_key_t key = 0;
	gpgme_keylist_result_t result = 0;

	if(m_ctx) {
		err = gpgme_op_keylist_start(m_ctx, NULL, privateKeys);
		if(!err) {
			while(!(err = gpgme_op_keylist_next(m_ctx, &key))) {
				KGpgKey gpgkey;

				if(!key->subkeys)
					continue;
				gpgkey.id = key->subkeys->keyid;
				if(key->uids) {
					gpgkey.name = key->uids->name;
					gpgkey.email = key->uids->email;
				}
				keys.append(gpgkey);
				gpgme_key_unref(key);
			}

			if (gpg_err_code (err) == GPG_ERR_EOF)
				err = 0;
			err2 = gpgme_op_keylist_end(m_ctx);
			if(!err)
				err = err2;
		}
	}

	if(err) {
		KMessageBox::error(kapp->activeWindow(), QString("%1: %2")
			.arg(gpgme_strsource(err)).arg(gpgme_strerror(err)));
	}
	else {
		result = gpgme_op_keylist_result(m_ctx);
		if (result->truncated) {
			KMessageBox::error(kapp->activeWindow(),
				i18n("Key listing unexpectedly truncated."));
		}
	}
	return keys;
}
Пример #9
0
int gpg_list_keys(key_entry_t **head) {
    gpgme_ctx_t ctx;
    gpgme_error_t err;
    gpgme_keylist_mode_t mode = 0;

    *head = 0;
    err = gpgme_new(&ctx);
    if (err) {
        return 0;
    }
    gpgme_set_protocol(ctx, GPGME_PROTOCOL_OpenPGP);
    gpgme_set_keylist_mode(ctx, mode);
    err = gpgme_op_keylist_start(ctx, 0, 0);
    if (err) {
        return 0;
    }
    
    int count = 0;
    key_entry_t *key_entry_prev = 0;
    while (1) {
        gpgme_key_t key;
        err = gpgme_op_keylist_next(ctx, &key);
        if (err) {
            break;
        }
        
        key_entry_t *key_entry = g_new(key_entry_t, 1);
        key_entry->next = 0;
        key_entry->key = key;
        
        if (key_entry_prev)
            key_entry_prev->next = key_entry;

        key_entry_prev = key_entry;
        if (!*head) *head = key_entry;
        
        ++count;
    }
    
    gpgme_op_keylist_end(ctx);
    gpgme_release(ctx);
    return count;
}
Пример #10
0
int get_next_key(char *buf, int buf_size) {
    gpgme_key_t key;
    int tmp_size = buf_size - 1;

    _cf_err = gpgme_op_keylist_next (_cf_ctx, &key);

    if(!_cf_err) {
        strcpy(buf,"");

        /* copy fingerprint and add ":" at the end */
        strncat(buf, key->subkeys->fpr, tmp_size);
        tmp_size -= strlen(key->subkeys->fpr) - 1; /* subtract 1 for the ":" character */
        strncat(buf, ":", tmp_size);

        /* Try to copy name */
        if (key->uids && key->uids->name) {
            strncat(buf, key->uids->name, tmp_size);
            tmp_size -= strlen(key->uids->name);
        }

        /* Try to copy email */
        if (key->uids && key->uids->email) {
            strncat(buf, " <", tmp_size);
            tmp_size -= 2;
            strncat(buf, key->uids->email, tmp_size);
            tmp_size -= strlen(key->uids->email);
            strncat(buf, ">", tmp_size);
            tmp_size -= 1;
        }

        gpgme_key_release (key);
        return 1;
    } else {
        gpgme_release(_cf_ctx);
        return 0;
    }
}
Пример #11
0
int geanypg_get_secret_keys(encrypt_data * ed)
{
    gpgme_error_t err;
    unsigned long size = SIZE;
    /* initialize idx to 0 */
    unsigned long idx = 0;
    /* allocate array of size 1N */
    gpgme_key_t * key;
    ed->skey_array = (gpgme_key_t*) malloc(SIZE * sizeof(gpgme_key_t));
    err = gpgme_op_keylist_start(ed->ctx, NULL, 1);
    while (!err)
    {
        key = ed->skey_array + idx;
        err = gpgme_op_keylist_next(ed->ctx, key);
        if (err)
            break;
        if ((*key)->revoked  || /* key cannot be used */
            (*key)->expired  ||
            (*key)->disabled ||
            (*key)->invalid)
           gpgme_key_unref(*key);
        else /* key is valid */
            ++idx;
        if (idx >= size)
        {
            size += SIZE;
            ed->skey_array = (gpgme_key_t*) realloc(ed->skey_array, size * sizeof(gpgme_key_t));
        }
    }
    ed->nskeys = idx;
    if (gpg_err_code(err) != GPG_ERR_EOF)
    {
        geanypg_show_err_msg(err);
        return 0;
    }
    return 1;
}
Пример #12
0
int 
main (int argc, char **argv)
{
  gpgme_error_t err;
  gpgme_ctx_t ctx;
  gpgme_key_t key;
  gpgme_keylist_result_t result;
  int i = 0;

  init_gpgme (GPGME_PROTOCOL_CMS);

  err = gpgme_new (&ctx);
  fail_if_err (err);
  gpgme_set_protocol (ctx, GPGME_PROTOCOL_CMS);

  err = gpgme_op_keylist_start (ctx, NULL, 0);
  fail_if_err (err);
    
  while (!(err = gpgme_op_keylist_next (ctx, &key)))
    {
      if (!keys[i].fpr)
	{
	  fprintf (stderr, "More keys returned than expected\n");
	  exit (1);
	}

      if (strcmp (key->subkeys->fpr, keys[i].fpr))
	{
	  fprintf (stderr, "Warning: Skipping unknown key %s\n",
		   key->subkeys->fpr);
	  continue;
	}
      else
	printf ("Checking key %s\n", key->subkeys->fpr);

      /* Global key flags.  */
      if (key->revoked)
	{
	  fprintf (stderr, "Key unexpectedly revoked\n");
	  exit (1);
	}
      if (key->expired)
	{
	  fprintf (stderr, "Key unexpectedly expired\n");
	  exit (1);
	}
      if (key->disabled)
	{
	  fprintf (stderr, "Key unexpectedly disabled\n");
	  exit (1);
	}
      if (key->invalid)
	{
	  fprintf (stderr, "Key unexpectedly invalid\n");
	  exit (1);
	}
      if (key->can_encrypt != keys[i].secret)
	{
	  fprintf (stderr, "Key unexpectedly%s usable for encryption\n",
		   key->can_encrypt ? "" : " not");
	  exit (1);
	}
      if (key->can_sign != keys[i].secret)
	{
	  fprintf (stderr, "Key unexpectedly%s usable for signing\n",
		   key->can_sign ? "" : " not");
	  exit (1);
	}
      if (!key->can_certify)
	{
	  fprintf (stderr, "Key unexpectedly unusable for certifications\n");
	  exit (1);
	}
      if (key->secret != keys[i].secret)
	{
	  fprintf (stderr, "Key unexpectedly%s secret\n",
		   key->secret ? "" : " not");
	  exit (1);
	}
      if (key->protocol != GPGME_PROTOCOL_CMS)
	{
	  fprintf (stderr, "Key has unexpected protocol: %s\n",
		   gpgme_get_protocol_name (key->protocol));
	  exit (1);
	}
      if (!key->issuer_serial)
	{
	  fprintf (stderr, "Key unexpectedly misses issuer serial\n");
	  exit (1);
	}
      if (strcmp (key->issuer_serial, keys[i].issuer_serial))
	{
	  fprintf (stderr, "Key has unexpected issuer serial: %s\n",
		   key->issuer_serial);
	  exit (1);
	}
      if (!key->issuer_name)
	{
	  fprintf (stderr, "Key unexpectedly misses issuer name\n");
	  exit (1);
	}
      if (strcmp (key->issuer_name, keys[i].issuer_name))
	{
	  fprintf (stderr, "Key has unexpected issuer name: %s\n",
		   key->issuer_name);
	  exit (1);
	}
      if (key->chain_id && !keys[i].chain_id)
	{
	  fprintf (stderr, "Key unexpectedly carries chain ID: %s\n",
		   key->chain_id);
	  exit (1);
	}
      if (!key->chain_id && keys[i].chain_id)
	{
	  fprintf (stderr, "Key unexpectedly carries no chain ID\n");
	  exit (1);
	}
      if (key->chain_id && strcmp (key->chain_id, keys[i].chain_id))
	{
	  fprintf (stderr, "Key carries unexpected chain ID: %s\n",
		   key->chain_id);
	  exit (1);
	}
      if (key->owner_trust != GPGME_VALIDITY_UNKNOWN)
	{
	  fprintf (stderr, "Key has unexpected owner trust: %i\n",
		   key->owner_trust);
	  exit (1);
	}
      if (!key->subkeys || key->subkeys->next)
	{
	  fprintf (stderr, "Key has unexpected number of subkeys\n");
	  exit (1);
	}

      /* Primary key.  */
      if (key->subkeys->revoked)
	{
	  fprintf (stderr, "Primary key unexpectedly revoked\n");
	  exit (1);
	}
      if (key->subkeys->expired)
	{
	  fprintf (stderr, "Primary key unexpectedly expired\n");
	  exit (1);
	}
      if (key->subkeys->disabled)
	{
	  fprintf (stderr, "Primary key unexpectedly disabled\n");
	  exit (1);
	}
      if (key->subkeys->invalid)
	{
	  fprintf (stderr, "Primary key unexpectedly invalid\n");
	  exit (1);
	}
      if (key->subkeys->can_encrypt != keys[i].secret)
	{
	  fprintf (stderr, "Key unexpectedly%s usable for encryption\n",
		   key->subkeys->can_encrypt ? "" : " not");
	  exit (1);
	}
      if (key->subkeys->can_sign != keys[i].secret)
	{
	  fprintf (stderr, "Key unexpectedly%s usable for signing\n",
		   key->subkeys->can_sign ? "" : " not");
	  exit (1);
	}
      if (!key->subkeys->can_certify)
	{
	  fprintf (stderr, "Primary key unexpectedly unusable for certifications\n");
	  exit (1);
	}
      if (key->subkeys->secret != keys[i].secret)
	{
	  fprintf (stderr, "Primary Key unexpectedly%s secret\n",
		   key->secret ? "" : " not");
	  exit (1);
	}
      if (key->subkeys->pubkey_algo != GPGME_PK_RSA)
	{
	  fprintf (stderr, "Primary key has unexpected public key algo: %s\n",
		   gpgme_pubkey_algo_name (key->subkeys->pubkey_algo));
	  exit (1);
	}
      if (key->subkeys->length != keys[i].key_length)
	{
	  fprintf (stderr, "Primary key has unexpected length: %i\n",
		   key->subkeys->length);
	  exit (1);
	}
      if (strcmp (key->subkeys->keyid, &keys[i].fpr[40 - 16]))
	{
	  fprintf (stderr, "Primary key has unexpected key ID: %s\n",
		   key->subkeys->keyid);
	  exit (1);
	}
      if (strcmp (key->subkeys->fpr, keys[i].fpr))
	{
	  fprintf (stderr, "Primary key has unexpected fingerprint: %s\n",
		   key->subkeys->fpr);
	  exit (1);
	}
      if (key->subkeys->timestamp != keys[i].timestamp)
	{
	  fprintf (stderr, "Primary key unexpected timestamp: %lu\n",
		   key->subkeys->timestamp);
	  exit (1);
	}
      if (key->subkeys->expires != keys[i].expires)
	{
	  fprintf (stderr, "Primary key unexpectedly expires: %lu\n",
		   key->subkeys->expires);
	  exit (1);
	}

      /* Be tolerant against a missing email (ie, older gpgsm versions).  */
      if (!key->uids || (key->uids->next && !keys[i].email))
	{
	  fprintf (stderr, "Key has unexpected number of user IDs\n");
	  exit (1);
	}
      if (key->uids->revoked)
	{
	  fprintf (stderr, "User ID unexpectedly revoked\n");
	  exit (1);
	}
      if (key->uids->invalid)
	{
	  fprintf (stderr, "User ID unexpectedly invalid\n");
	  exit (1);
	}
      if (key->uids->validity != keys[i].validity)
	{
	  fprintf (stderr, "User ID unexpectedly validity: %i\n",
		   key->uids->validity);
	  exit (1);
	}
      if (key->uids->signatures)
	{
	  fprintf (stderr, "User ID unexpectedly signed\n");
	  exit (1);
	}
      if (!key->uids->name || key->uids->name[0])
	{
	  fprintf (stderr, "Unexpected name in user ID: %s\n",
		   key->uids->name);
	  exit (1);
	}
      if (!key->uids->comment || key->uids->comment[0])
	{
	  fprintf (stderr, "Unexpected comment in user ID: %s\n",
		   key->uids->comment);
	  exit (1);
	}
      if (!key->uids->email || key->uids->email[0])
	{
	  fprintf (stderr, "Unexpected email in user ID: %s\n",
		   key->uids->email);
	  exit (1);
	}
      if (!key->uids->uid || strcmp (key->uids->uid, keys[i].uid))
	{
	  fprintf (stderr, "Unexpected uid in user ID: %s\n",
		   key->uids->uid);
	  exit (1);
	}
      if (key->uids->next && strcmp (key->uids->next->uid, keys[i].email))
	{
	  fprintf (stderr, "Unexpected email in user ID: %s\n",
		   key->uids->next->uid);
	  exit (1);
	}
      if (key->uids->next && strcmp (key->uids->next->uid, keys[i].email))
	{
	  fprintf (stderr, "Unexpected email in user ID: %s\n",
		   key->uids->next->uid);
	  exit (1);
	}



      gpgme_key_unref (key);
      i++;
    }
  if (gpg_err_code (err) != GPG_ERR_EOF)
    fail_if_err (err);
  err = gpgme_op_keylist_end (ctx);
  fail_if_err (err);

  result = gpgme_op_keylist_result (ctx);
  if (result->truncated)
    {
      fprintf (stderr, "Key listing unexpectedly truncated\n");
      exit (1);
    }

  if (keys[i].fpr)
    {
      fprintf (stderr, "Less keys returned than expected\n");
      exit (1);
    }

  gpgme_release (ctx);
  return 0;
}
Пример #13
0
int main()
{
   int fd;

   gpgme_ctx_t g_context;
   gpgme_engine_info_t enginfo;
   gpgme_data_t data;

   gpgme_error_t gerr;
   gpg_err_code_t gpg_err;

   gpgme_data_t g_plain;
   gpgme_data_t g_plain_recv;
   gpgme_data_t g_encrypt;
   gpgme_data_t g_encrypt_send;

   gpgme_key_t g_recipient[MAX_RCP+1];
   char *p;
   char b_encrypt[BIGBUF+1];

   char msg[EOF_L_MESSAGE];
   char msg_in[EOF_L_MESSAGE];

   int i, tmp;

   for(i=0;i<EOF_L_MESSAGE; i++) msg_in[i] = 0;
   for(i=0;i<EOF_L_MESSAGE; i++) msg[i] = 0;
   for(i=0;i<=BIGBUF; i++) b_encrypt[i] = 0;

   gpgme_check_version(NULL);

   gerr = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP);
   if(gerr != GPG_ERR_NO_ERROR) return 10;

   p = (char *) gpgme_get_protocol_name(GPGME_PROTOCOL_OpenPGP);
   printf("Version: %s\n",p);

   gerr = gpgme_set_engine_info(GPGME_PROTOCOL_OpenPGP, NULL, home);

   if(gerr == GPG_ERR_NO_ERROR) {
      printf("gpgme_set_engine_info: ok\n");
   } else {
      printf("gpgme_set_engine_info: err\n");
   }

   /* get engine information */
   gerr = gpgme_get_engine_info(&enginfo);
   if(gerr != GPG_ERR_NO_ERROR) return 3;

   printf("file=%s, home=%s\n",enginfo->file_name,enginfo->home_dir);

   /* create our own context */
   gerr = gpgme_new(&g_context);
   if(gerr != GPG_ERR_NO_ERROR) return 1;

   /* FIXME: both needed? */
   /* FIXME: why is the path (FILE_NAME) needed? */
   /* FIXME: /usr/bin/gpg must be changed to ~/.ceof/gpg/binary or similar */
   gerr = gpgme_ctx_set_engine_info (g_context, GPGME_PROTOCOL_OpenPGP,
               "/usr/bin/gpg",home);
   if(gerr != GPG_ERR_NO_ERROR) return 4;

   /* do not ascii armor data; use 1 for testing */
   //gpgme_set_armor(g_context, 0);
   gpgme_set_armor(g_context, 1);

   /* create buffers */
   gerr = gpgme_data_new(&data);
   if(gerr != GPG_ERR_NO_ERROR) return 12;

   gerr = gpgme_data_new(&g_plain_recv);
   if(gerr != GPG_ERR_NO_ERROR) return 20;

   gerr = gpgme_data_new(&g_encrypt);
   if(gerr != GPG_ERR_NO_ERROR) return 14;

   gerr = gpgme_data_new(&g_encrypt_send);
   if(gerr != GPG_ERR_NO_ERROR) return 24;

   /* fill buffers */
   /* gerr = gpgme_data_new(&g_plain);
   if(gerr != GPG_ERR_NO_ERROR) return 13;

   printf("strlen(%s) = %d\n",msg,i);
   i -= gpgme_data_write(g_plain, msg, i);
   if(i) {
      printf("size mismatch\n");
      return 12;
   } */
   strncpy(msg, "==> Erste Nachricht\n\n", EOF_L_MESSAGE);
   i = strlen(msg);
   gerr = gpgme_data_new_from_mem (&g_plain, msg, i, 0);


   /* setup recipient */
   gerr = gpgme_op_keylist_start(g_context, "nico schottelius", 0);
   if(gerr != GPG_ERR_NO_ERROR) return 11;

   i=0;
   gerr = gpgme_op_keylist_next(g_context, &g_recipient[0]);
   while((gpg_err = gpg_err_code(gerr)) != GPG_ERR_EOF) {
      /* for testing: one call of gpgme_op_keylist_next is enough */
      break;
      if(gerr == GPG_ERR_INV_VALUE) {
         printf("invalid pointer\n");
         return 15;
      } else if(gerr == GPG_ERR_ENOMEM) {
         printf("no mem\n");
         return 16;
      }

      printf ("%s: %s <%s> (%d)\n", g_recipient[0]->subkeys->keyid, g_recipient[0]->uids->name, g_recipient[0]->uids->email, i);
      i++;

      /* FIXME: this resets the good filled buffer ... */
      gerr = gpgme_op_keylist_next(g_context, &g_recipient[0]);
   }
   g_recipient[1] = NULL;

   /* all above seems to be wrong ... */
   gerr = gpgme_get_key(g_context,"775506B45998BF57D0D4AFF27C6E747C38616ADC", &g_recipient[0], 0);
   if(gerr != GPG_ERR_NO_ERROR) return 32;


   /* en/decrypt message */
   //gerr = gpgme_op_encrypt_sign(g_context, g_recipient, 0, g_plain, g_encrypt);
   gerr = gpgme_op_encrypt(g_context, g_recipient, 0, g_plain, g_encrypt);
   if(gerr != GPG_ERR_NO_ERROR) {
      printf("gerr=%d\n",gerr);
      return 18;
   }

   /* transfer the data into our own buffer,
    * so the data is saved; you cannot
    * reuse the gpgme buffers directly as in
    *    gerr = gpgme_op_decrypt(g_context, g_encrypt, g_plain_recv);
    *
    */
   i = gpgme_data_seek(g_encrypt, 0, SEEK_END);

   if(i > BIGBUF) return 22;
   printf("buflen: %d\n",i);
   
   /* reset to the beginning */
   gpgme_data_seek(g_encrypt, 0, SEEK_SET);

   if(gpgme_data_read(g_encrypt, b_encrypt, i) == -1) {
      perror("pgme_data_read");
      return 23;
   }
   printf("crypt:\n%s\n", b_encrypt);
   fd = open("testcrypt",O_RDWR|O_CREAT);
   if(fd == -1) return 40;
   if(write_all(fd, b_encrypt, BIGBUF) <= 0) return 41;
   close(fd);

   /* until here it works, testcrypt contains
    * data and can be decrypted ...
    *
    * perhaps the context needs some reset?
    */

   if((tmp = gpgme_data_write(g_encrypt_send, b_encrypt, i)) == -1) {
      perror("pgme_data_write");
      return 23;
   }
   printf("crypt-wrote:%d\n", tmp);

   /* look for contexts */

   gerr = gpgme_op_decrypt(g_context, g_encrypt_send, g_plain_recv);
   if(gerr != GPG_ERR_NO_ERROR) {
      printf("gerr=%d\n",gerr);
      return 19;
   }

   /* open communication channel: netcat */

   /* listen for input from:
    * stdin
    * communication channel
    */

   /* de/encode data from comm channel */

   return 1;
}
Пример #14
0
/* Get the GPG key for the given name or ID.
*/
int
get_gpg_key(fko_ctx_t fko_ctx, gpgme_key_t *mykey, const int signer)
{
    int             res;
    const char     *name;

    gpgme_ctx_t     list_ctx    = NULL;
    gpgme_key_t     key         = NULL;
    gpgme_key_t     key2        = NULL;
    gpgme_error_t   err;

    /* Create a gpgme context for the list
    */
    /* Initialize gpgme
    */
    res = init_gpgme(fko_ctx);
    if(res != FKO_SUCCESS)
    {
        if(signer)
            return(FKO_ERROR_GPGME_CONTEXT_SIGNER_KEY);
        else
            return(FKO_ERROR_GPGME_CONTEXT_RECIPIENT_KEY);
    }

    list_ctx = fko_ctx->gpg_ctx;

    if(signer)
        name = fko_ctx->gpg_signer;
    else
        name = fko_ctx->gpg_recipient;

    err = gpgme_op_keylist_start(list_ctx, name, signer);
    if (err)
    {
        gpgme_release(list_ctx);

        fko_ctx->gpg_err = err;

        if(signer)
            return(FKO_ERROR_GPGME_SIGNER_KEYLIST_START);
        else
            return(FKO_ERROR_GPGME_RECIPIENT_KEYLIST_START);
    }

    /* Grab the first key in the list (we hope it is the only one).
    */
    err = gpgme_op_keylist_next(list_ctx, &key);
    if(gpg_err_code(err) != GPG_ERR_NO_ERROR)
    {
        /* Key not found
        */
        fko_ctx->gpg_err = err;

        if(signer)
            return(FKO_ERROR_GPGME_SIGNER_KEY_NOT_FOUND);
        else
            return(FKO_ERROR_GPGME_RECIPIENT_KEY_NOT_FOUND);
    }

    /* We try to get the next key match. If we do, then the name is
     * ambiguous, so we return an error.
    */
    err = gpgme_op_keylist_next(list_ctx, &key2);
    if(gpg_err_code(err) == GPG_ERR_NO_ERROR) /* Note: look for NO error */
    {
        /* Ambiguous specfication of key
        */
        gpgme_key_unref(key);
        gpgme_key_unref(key2);

        fko_ctx->gpg_err = err;

        if(signer)
            return(FKO_ERROR_GPGME_SIGNER_KEY_AMBIGUOUS);
        else
            return(FKO_ERROR_GPGME_RECIPIENT_KEY_AMBIGUOUS);
    }

    gpgme_op_keylist_end(list_ctx);

    gpgme_key_unref(key2);

    *mykey = key;

    return(FKO_SUCCESS);
}
Пример #15
0
static gpgme_key_t
get_key_from_name(gpgme_ctx_t ctx, const gchar * name, gboolean secret,
		  gboolean accept_all, GtkWindow * parent, GError ** error)
{
    GList *keys = NULL;
    gpgme_key_t key;
    gpgme_error_t err;
    gboolean found_bad;
    time_t now = time(NULL);

    /* let gpgme list keys */
    if ((err =
	 gpgme_op_keylist_start(ctx, name, secret)) != GPG_ERR_NO_ERROR) {
	gchar *msg =
	    g_strdup_printf(_("could not list keys for \"%s\""), name);

	g_set_error_from_gpgme(error, err, msg);
	g_free(msg);
	return NULL;
    }

    found_bad = FALSE;
    while ((err = gpgme_op_keylist_next(ctx, &key)) == GPG_ERR_NO_ERROR) {
	/* check if this key and the relevant subkey are usable */
	if (KEY_IS_OK(key)) {
	    gpgme_subkey_t subkey = key->subkeys;

	    while (subkey && ((secret && !subkey->can_sign) ||
			      (!secret && !subkey->can_encrypt)))
		subkey = subkey->next;

	    if (subkey && KEY_IS_OK(subkey) &&
		(subkey->expires == 0 || subkey->expires > now))
		keys = g_list_append(keys, key);
	    else
		found_bad = TRUE;
	} else
	    found_bad = TRUE;
    }

    if (gpg_err_code(err) != GPG_ERR_EOF) {
	gchar *msg =
	    g_strdup_printf(_("could not list keys for \"%s\""), name);

	g_set_error_from_gpgme(error, err, msg);
	g_free(msg);
	gpgme_op_keylist_end(ctx);
	g_list_foreach(keys, (GFunc) gpgme_key_unref, NULL);
	g_list_free(keys);
	return NULL;
    }
    gpgme_op_keylist_end(ctx);

    if (!keys) {
	if (error) {
	    if (strchr(name, '@')) {
		if (found_bad)
		    g_set_error(error, GPGME_ERROR_QUARK,
				GPG_ERR_KEY_SELECTION,
				_
				("%s: a key for %s is present, but it is expired, disabled, revoked or invalid"),
				"gmime-gpgme", name);
		else
		    g_set_error(error, GPGME_ERROR_QUARK,
				GPG_ERR_KEY_SELECTION,
				_("%s: could not find a key for %s"),
				"gmime-gpgme", name);
	    } else {
		if (found_bad)
		    g_set_error(error, GPGME_ERROR_QUARK,
				GPG_ERR_KEY_SELECTION,
				_
				("%s: a key with id %s is present, but it is expired, disabled, revoked or invalid"),
				"gmime-gpgme", name);
		else
		    g_set_error(error, GPGME_ERROR_QUARK,
				GPG_ERR_KEY_SELECTION,
				_("%s: could not find a key with id %s"),
				"gmime-gpgme", name);
	    }
	}
	return NULL;
    }

    /* let the user select a key from the list if there is more than one */
    if (g_list_length(keys) > 1) {
	if (select_key_cb)
	    key =
		select_key_cb(name, secret, keys, gpgme_get_protocol(ctx),
			      parent);
	else {
	    if (error)
		g_set_error(error, GPGME_ERROR_QUARK,
			    GPG_ERR_KEY_SELECTION,
			    _("%s: multiple keys for %s"), "gmime-gpgme",
			    name);
	    key = NULL;
	}
	if (key)
	    gpgme_key_ref(key);
	g_list_foreach(keys, (GFunc) gpgme_key_unref, NULL);
    } else
	key = (gpgme_key_t) keys->data;
    g_list_free(keys);

    /* OpenPGP: ask the user if a low-validity key should be trusted for
     * encryption */
    // FIXME - shouldn't we do the same for S/MIME?
    if (key && !secret && !accept_all
	&& gpgme_get_protocol(ctx) == GPGME_PROTOCOL_OpenPGP) {
	gpgme_user_id_t uid = key->uids;
	gchar *upcase_name = g_ascii_strup(name, -1);
	gboolean found = FALSE;

	while (!found && uid) {
	    /* check the email field which may or may not be present */
	    if (uid->email && !g_ascii_strcasecmp(uid->email, name))
		found = TRUE;
	    else {
		/* no email or no match, check the uid */
		gchar *upcase_uid = g_ascii_strup(uid->uid, -1);

		if (strstr(upcase_uid, upcase_name))
		    found = TRUE;
		else
		    uid = uid->next;
		g_free(upcase_uid);
	    }
	}
	g_free(upcase_name);

	/* ask the user if a low-validity key shall be used */
	if (uid && uid->validity < GPGME_VALIDITY_FULL) {
	    if (!accept_low_trust_cb
		|| !accept_low_trust_cb(name, uid, parent)) {
		gpgme_key_unref(key);
		key = NULL;
		if (error)
		    g_set_error(error, GPGME_ERROR_QUARK,
				GPG_ERR_KEY_SELECTION,
				_("%s: insufficient validity for uid %s"),
				"gmime-gpgme", name);
	    }
	}
    }

    return key;
}
Пример #16
0
Файл: gpg.c Проект: comotion/cpm
/* #############################################################################
 *
 * Description    validate the given encryption key
 * Author         Harry Brueckner
 * Date           2005-03-31
 * Arguments      char* key   - the key to validate
 * Return         char* NULL on error, otherwise the name and mail address
 */
char* gpgValidateEncryptionKey(char* keyname)
  {
    gpgme_ctx_t         context;
    gpgme_key_t         key;
    gpgme_error_t       error;
    int                 secret,
                        size;
    char*               identifier = NULL;
    char*               tcomment;
    char*               tname;

    TRACE(99, "gpgValidateEncryptionKey()", NULL);

    if (!config -> encryptdata)
      { return NULL; }

    /* get a new context */
    error = gpgme_new(&context);
    if (error)
      {
        gpgme_release(context);
        gpgError(error);
        return NULL;
      }

    for (secret = 1; secret >= 0 && !identifier; secret--)
      {
        /* start cycling through the list of keys */
        error = gpgme_op_keylist_start(context, keyname,
            (secret == 1) ? LIST_SECRET : LIST_ALL);
        if (error)
          {
            gpgme_release(context);
            gpgError(error);
            return NULL;
          }

        while (!(error = gpgme_op_keylist_next(context, &key)))
          {   /* take the first key we find */
#ifdef TEST_OPTION
  #ifdef KEY_DEBUG
            gpgDebugKey(key);
  #endif
#endif
            if (key -> can_encrypt &&
                !key -> disabled &&
                !key -> expired &&
                !key -> invalid &&
                !key -> revoked)
              {   /* we just use keys we can encrypt for and sign with */
                tname = convert2terminal((unsigned char*)key -> uids -> name);
                if (key -> uids -> comment)
                  { tcomment = key -> uids -> comment; }
                else
                  { tcomment = NULL; }

                if (tcomment && strlen(tcomment))
                  {   /* a comment exists for this key */
                    size = strlen(key -> subkeys -> keyid) + 1 +
                        strlen(tname) + 1 +
                        strlen(tcomment) + 2 + 1 +
                        strlen(key -> uids -> email) + 2 + 1;
                    identifier = memAlloc(__FILE__, __LINE__, size);
                    snprintf(identifier, size, "%s %s (%s) <%s>",
                        key -> subkeys -> keyid,
                        tname,
                        tcomment,
                        key -> uids -> email);
                  }
                else
                  {   /* no comment exists */
                    size = strlen(key -> subkeys -> keyid) + 1 +
                        strlen(tname) + 1 +
                        strlen(key -> uids -> email) + 2 + 1;
                    identifier = memAlloc(__FILE__, __LINE__, size);
                    snprintf(identifier, size, "%s %s <%s>",
                        key -> subkeys -> keyid,
                        tname,
                        key -> uids -> email);
                  }
              }

            gpgme_key_unref(key);

            if (identifier)
              { break; }
          }

        if (error &&
            gpg_err_code(error) != GPG_ERR_EOF)
          {    /* we validate the last value of the 'next' operation */
            gpgme_release(context);
            gpgError(error);
            return NULL;
          }
      }

    /* finish the key listing */
    error = gpgme_op_keylist_end(context);
    if (error)
      {
        gpgme_release(context);
        gpgError(error);
        return NULL;
      }

    gpgme_release(context);

    return identifier;
  }
Пример #17
0
char *CGPGHelper::Encrypt(const char *szPlain, const char *szId,
                          unsigned long nPPID)
{
#ifdef HAVE_LIBGPGME
  if (!mCtx) return 0;
  if (!szPlain) return 0;

  char szUser[MAX_LINE_LEN], buf[MAX_LINE_LEN];
  buf[0] = '\0';
  sprintf(szUser, "%s.%lu", szId, nPPID);
  mKeysIni.SetSection("keys");

  ICQUser *u = gUserManager.FetchUser( szId, nPPID, LOCK_R );
  if ( u )
  {
    const char *tmp = u->GPGKey();
    if ( tmp && tmp[0]!='\0' )
      strncpy( buf, tmp, MAX_LINE_LEN-1 );
    gUserManager.DropUser( u );
  }
  if ( !buf[0] && !mKeysIni.ReadStr(szUser, buf) ) return 0;
	
  gLog.Info("[GPG] Encrypting message to %s.\n", szId);

  CGPGMEMutex mutex;
  if (!mutex.Lock()) return 0;
  gpgme_key_t rcps[2];
  gpgme_data_t plain = 0, cipher = 0;
  gpgme_error_t err;
  char *szCipher = 0;
  size_t nRead = 0;

  rcps[1] = 0;
  // Still use the old method, gpgme_get_key requires the fingerprint, which
  // actually isn't very helpful.
  if (gpgme_op_keylist_start (mCtx, buf, 0) != GPG_ERR_NO_ERROR)
    gLog.Error("%s[GPG] Couldn't use gpgme recipient: %s\n", L_ERRORxSTR, buf);
  else
  {
    if (gpgme_op_keylist_next(mCtx, rcps) != GPG_ERR_NO_ERROR)
      gLog.Error("%s[GPG] Couldn't get key: %s\n", L_ERRORxSTR, buf);
    else
    {
      if (gpgme_data_new_from_mem(&plain, szPlain, strlen(szPlain), 0) == GPG_ERR_NO_ERROR &&
          gpgme_data_new(&cipher) == GPG_ERR_NO_ERROR)
      {
        if ((err = gpgme_op_encrypt(mCtx, rcps, GPGME_ENCRYPT_ALWAYS_TRUST, plain, cipher)) == GPG_ERR_NO_ERROR)
        {
          szCipher = gpgme_data_release_and_get_mem(cipher, &nRead);
          cipher = 0;
          szCipher = (char *)realloc(szCipher, nRead + 1);
          szCipher[nRead] = 0;
        }
        else
          gLog.Error("%s[GPG] Encryption failed: %s\n", L_ERRORxSTR, gpgme_strerror(err));
      }
    }

    if (cipher) gpgme_data_release(cipher);
    if (plain) gpgme_data_release(plain);
  }

  gpgme_key_unref(rcps[0]);
  return szCipher;
#else
  return 0;
#endif
}
Пример #18
0
int main(void)
{
   gpgme_ctx_t ctx;
   gpgme_error_t err;

   int setup_res = setup(&ctx);
   if(setup_res) return setup_res;

   /* Change mode to extern */
   gpgme_keylist_mode_t mode = gpgme_get_keylist_mode(ctx);
   mode &= ~GPGME_KEYLIST_MODE_LOCAL;
   mode |= GPGME_KEYLIST_MODE_EXTERN;
   mode |= GPGME_KEYLIST_MODE_SIGS | GPGME_KEYLIST_MODE_SIG_NOTATIONS;
   err = gpgme_set_keylist_mode(ctx, mode);
   if (err != GPG_ERR_NO_ERROR) return 6;

   /* List all keys */
   /* (context, pattern, secret_only) */
   err = gpgme_op_keylist_start(ctx, "07E7871B", 0);
   if (err != GPG_ERR_NO_ERROR) return 7;

   gpgme_key_t key;
   size_t MAX_KEYS = 100;
   gpgme_key_t keyarray[MAX_KEYS+1]; // need a space for the NULL term
   size_t i = 0;

   while ((err = gpgme_op_keylist_next(ctx, &key)) == GPG_ERR_NO_ERROR) {
      printf("Got a key\n");
      printf ("%s:", key->subkeys->keyid);
      if (key->uids && key->uids->name)
        printf (" %s", key->uids->name);
      if (key->uids && key->uids->email)
        printf (" <%s>", key->uids->email);
      if (key->uids && key->uids->signatures) {
        printf("First signature: %s\n", key->uids->signatures->keyid);
      }
      putchar ('\n');
      if (i < MAX_KEYS) {
        keyarray[i++] = key;
      } else {
        printf("Too many keys, skipping a key\n");
      }
      //gpgme_key_release (key);
   }
   if (gpg_err_code(err) == GPG_ERR_EOF) {
      printf("%xu\n", err);
      printf("End of keylist.\n");
   } else {
      print_gpg_error(err);
      return 8;
   }

   // https://bugs.gnupg.org/gnupg/issue1670

   printf("Attempting to import %lu keys\n", i);
   err = gpgme_op_import_keys(ctx, keyarray);
   if (err != GPG_ERR_NO_ERROR) return 9;
   gpgme_import_result_t impres = gpgme_op_import_result(ctx);
   if (!impres) return 10;
   print_import_result(impres);

   /* free keys */
   for (i = 0; keyarray[i]; i++)
     gpgme_key_release(key);

   /* free context */
   gpgme_release(ctx);

   return 0;
}
Пример #19
0
    void crypto_asym::build_key_list(const vector<string> & recipients_email, gpgme_key_t * & ciphering_keys, bool signatories)
    {
	U_I size = recipients_email.size() + 1;

	ciphering_keys = new (nothrow) gpgme_key_t[size];
	if(ciphering_keys == NULL)
	    throw Ememory("crypto_asym::build_key_list");

	    // clearing all fields in order to be able to know which
	    // index has been allocated and need to be restored in case of error
	for(U_I i = 0; i < size ; ++i)
	    ciphering_keys[i] = NULL;

	try
	{
	    gpgme_error_t err = GPG_ERR_NO_ERROR;
	    gpgme_user_id_t id = NULL;
	    bool found = false;
	    bool eof = false;
	    bool loop = false;
	    U_I offset = 0;

		// for each recipient, listing all keys to find a match

	    for(U_I i = 0; i < recipients_email.size(); ++i)
	    {
		err = gpgme_op_keylist_start(context, NULL, 0);
		switch(gpgme_err_code(err))
		{
		case GPG_ERR_NO_ERROR:
		    break;
		case GPG_ERR_INV_VALUE:
		    throw SRC_BUG;
		default:
		    throw Erange("crypto_asym::decrypt", string(gettext("Unexpected error reported by GPGME: ")) + tools_gpgme_strerror_r(err));
		}

		found = false;
		eof = false;
		do
		{
			// getting the next key

		    err = gpgme_op_keylist_next(context, &(ciphering_keys[i - offset]));
		    switch(gpgme_err_code(err))
		    {
		    case GPG_ERR_EOF:
			eof = true;
			break;
		    case GPG_ERR_NO_ERROR:
			id = ciphering_keys[i - offset]->uids;
			loop = true;

			    // for each key, listing all identies associated with it to find a match
			do
			{
			    found = (strncmp(recipients_email[i].c_str(), id->email, recipients_email[i].size()) == 0);

			    if(found)
			    {
				if(ciphering_keys[i - offset]->revoked
				   || ciphering_keys[i - offset]->expired
				   || ciphering_keys[i - offset]->disabled
				   || ciphering_keys[i - offset]->invalid)
				    found = false;
				if(signatories)
				{
				    if(!ciphering_keys[i - offset]->can_sign)
					found = false;
				}
				else
				{
				    if(!ciphering_keys[i - offset]->can_encrypt)
					found = false;
				}
			    }

			    if(!found && id->next != NULL)
				id = id->next;
			    else
				loop = false;
			}
			while(loop);

			    // if not identity match found for that key deleting the key

			if(!found)
			{
			    gpgme_key_unref(ciphering_keys[i - offset]);
			    ciphering_keys[i - offset] = NULL;
			}
			break;
		    default:
			throw Erange("crypto_asym::decrypt", string(gettext("Unexpected error reported by GPGME: ")) + tools_gpgme_strerror_r(err));
		    }
		}
		while(!found && !eof);

		    // if we exit before gpgme_op_keylist_next() return GPG_ERR_EOF
		    // we must update the state of the context to end the key listing operation

		if(!eof)
		    (void)gpgme_op_keylist_end(context);

		if(!found)
		{
		    if(signatories)
			get_ui().printf(gettext("No valid signing key could be find for %S"), &(recipients_email[i]));
		    else
			get_ui().printf(gettext("No valid encryption key could be find for %S"), &(recipients_email[i]));
		    get_ui().pause("Do you want to continue without this recipient?");
		    ++offset;
		}
	    }

		// if no recipient could be found at all aborting the operation

	    if(offset + 1 >= size)
	    {
		if(signatories)
		    throw Erange("crypto_asym::build_key_list", gettext("No signatory remain with a valid key, signing is impossible, aborting"));
		else
		    throw Erange("crypto_asym::build_key_list", gettext("No recipient remain with a valid key, encryption is impossible, aborting"));
	    }

		// the key list must end wth a NULL entry

	    if(ciphering_keys[size - 1 - offset] != NULL)
		throw SRC_BUG;
	}
	catch(...)
	{
	    release_key_list(ciphering_keys);
	    throw;
	}
    }
Пример #20
0
GHashTable*
p_gpg_list_keys(void)
{
    gpgme_error_t error;
    GHashTable *result = g_hash_table_new_full(g_str_hash, g_str_equal, free, (GDestroyNotify)_p_gpg_free_key);

    gpgme_ctx_t ctx;
    error = gpgme_new(&ctx);

    if (error) {
        log_error("GPG: Could not list keys. %s %s", gpgme_strsource(error), gpgme_strerror(error));
        return NULL;
    }

    error = gpgme_op_keylist_start(ctx, NULL, 0);
    if (error == GPG_ERR_NO_ERROR) {
        gpgme_key_t key;
        error = gpgme_op_keylist_next(ctx, &key);
        while (!error) {
            gpgme_subkey_t sub = key->subkeys;

            ProfPGPKey *p_pgpkey = _p_gpg_key_new();
            p_pgpkey->id = strdup(sub->keyid);
            p_pgpkey->name = strdup(key->uids->uid);
            p_pgpkey->fp = strdup(sub->fpr);
            if (sub->can_encrypt) p_pgpkey->encrypt = TRUE;
            if (sub->can_authenticate) p_pgpkey->authenticate = TRUE;
            if (sub->can_certify) p_pgpkey->certify = TRUE;
            if (sub->can_sign) p_pgpkey->sign = TRUE;

            sub = sub->next;
            while (sub) {
                if (sub->can_encrypt) p_pgpkey->encrypt = TRUE;
                if (sub->can_authenticate) p_pgpkey->authenticate = TRUE;
                if (sub->can_certify) p_pgpkey->certify = TRUE;
                if (sub->can_sign) p_pgpkey->sign = TRUE;

                sub = sub->next;
            }

            g_hash_table_insert(result, strdup(p_pgpkey->name), p_pgpkey);

            gpgme_key_unref(key);
            error = gpgme_op_keylist_next(ctx, &key);
        }
    }

    error = gpgme_op_keylist_start(ctx, NULL, 1);
    if (error == GPG_ERR_NO_ERROR) {
        gpgme_key_t key;
        error = gpgme_op_keylist_next(ctx, &key);
        while (!error) {
            gpgme_subkey_t sub = key->subkeys;
            while (sub) {
                if (sub->secret) {
                    ProfPGPKey *p_pgpkey = g_hash_table_lookup(result, key->uids->uid);
                    if (p_pgpkey) {
                        p_pgpkey->secret = TRUE;
                    }
                }
                sub = sub->next;
            }

            gpgme_key_unref(key);
            error = gpgme_op_keylist_next(ctx, &key);
        }
    }

    gpgme_release(ctx);

    autocomplete_clear(key_ac);
    GList *ids = g_hash_table_get_keys(result);
    GList *curr = ids;
    while (curr) {
        ProfPGPKey *key = g_hash_table_lookup(result, curr->data);
        autocomplete_add(key_ac, key->id);
        curr = curr->next;
    }
    g_list_free(ids);

    return result;
}
Пример #21
0
SEXP R_gpg_keylist(SEXP filter, SEXP secret_only, SEXP local) {
  gpgme_keylist_mode_t mode = gpgme_get_keylist_mode(ctx);
  mode |= asLogical(local) ? GPGME_KEYLIST_MODE_LOCAL : GPGME_KEYLIST_MODE_EXTERN;
  mode |= GPGME_KEYLIST_MODE_SIGS;
  mode |= GPGME_KEYLIST_MODE_SIG_NOTATIONS;
  gpgme_set_keylist_mode (ctx, mode);
  gpgme_set_protocol (ctx, GPGME_PROTOCOL_OpenPGP);

  //gpgme_set_global_flag("auto-key-locate", "hkp://pgp.mit.edu");

  bail(gpgme_op_keylist_start (ctx, CHAR(STRING_ELT(filter, 0)), asLogical(secret_only)), "starting keylist");
  struct keylist *keys = (struct keylist *)  malloc(sizeof(struct keylist));
  struct keylist *head = keys;

  gpgme_error_t err;
  int count = 0;
  while(1){
    err = gpgme_op_keylist_next (ctx, &(keys->key));
    if(gpg_err_code (err) == GPG_ERR_EOF)
      break;
    bail(err, "getting next key");
    keys->next = (struct keylist *)  malloc(sizeof(struct keylist));
    keys = keys->next;
    count++;
  }

  /* convert the linked list into vectors */
  SEXP keyid = PROTECT(allocVector(STRSXP, count));
  SEXP fpr = PROTECT(allocVector(STRSXP, count));
  SEXP name = PROTECT(allocVector(STRSXP, count));
  SEXP email = PROTECT(allocVector(STRSXP, count));
  SEXP algo = PROTECT(allocVector(STRSXP, count));
  SEXP timestamp = PROTECT(allocVector(INTSXP, count));
  SEXP expires = PROTECT(allocVector(INTSXP, count));

  gpgme_key_t key;
  for(int i = 0; i < count; i++){
    key = head->key;
    SET_STRING_ELT(keyid, i, make_char(key->subkeys->keyid));
    SET_STRING_ELT(fpr, i, make_char(key->subkeys->fpr));
    SET_STRING_ELT(algo, i, make_char(gpgme_pubkey_algo_name(key->subkeys->pubkey_algo)));

    if(key->issuer_name)
      SET_STRING_ELT(fpr, i, make_char(key->issuer_name));
    if(key->uids && key->uids->name)
      SET_STRING_ELT(name, i, make_char(key->uids->name));
    if(key->uids && key->uids->email)
      SET_STRING_ELT(email, i, make_char(key->uids->email));

    INTEGER(timestamp)[i] = (key->subkeys->timestamp > 0) ? key->subkeys->timestamp : NA_INTEGER;
    INTEGER(expires)[i] = (key->subkeys->expires > 0) ? key->subkeys->expires : NA_INTEGER;

    keys = head;
    head = head->next;
    gpgme_key_unref (key);
    free(keys);
  }

  SEXP result = PROTECT(allocVector(VECSXP, 7));
  SET_VECTOR_ELT(result, 0, keyid);
  SET_VECTOR_ELT(result, 1, fpr);
  SET_VECTOR_ELT(result, 2, name);
  SET_VECTOR_ELT(result, 3, email);
  SET_VECTOR_ELT(result, 4, algo);
  SET_VECTOR_ELT(result, 5, timestamp);
  SET_VECTOR_ELT(result, 6, expires);
  UNPROTECT(8);
  return result;
}
Пример #22
0
int main(int argc, char *argv[])
{
	char * op=(char *)0;
	char * search=(char *)0;
	char * searchdec=(char *)0;
	char * exact=(char *)0;

	gpgme_ctx_t gpgctx;
	gpgme_key_t gpgkey;
	gpgme_error_t gpgerr;
	gpgme_engine_info_t enginfo;

	char * qstring, * pchar;

	pchar=getenv("QUERY_STRING");
	if (! pchar || *pchar == '\0' ) {
		http_header(500,CTYPE_HTML_STR);
		printf("<html><head><title>Error handling request</title></head><body><h1>Error handling request: there is no query string.</h1></body></html>");
		return 1;
	}
	qstring=strndup(pchar,QSTRING_MAX); /* copy the QUERY from env to write in */
	pchar=qstring;

	while (pchar && *pchar) {
		if (!strncmp(pchar,"op=",3)) {
			pchar+=3;
			op=pchar;
		} else if (!strncmp(pchar,"search=",7)) {
			pchar+=7;
			search=pchar;
		} else if (!strncmp(pchar,"options=",8)) {
			/*this parameter is useless now, as today we only support "mr" option and always enable it (machine readable) */
			pchar+=8;
			//options=pchar;
		} else if (!strncmp(pchar,"fingerprint=",12)) {
			/*this parameter is useless now as we only support "mr" options which don't care this */
			pchar+=12;
			//fingerprints=pchar;
		} else if (!strncmp(pchar,"exact=",6)) {
			pchar+=6;
			exact=pchar;
		} /*else: Other parameter not in hkp draft are quietly ignored */
		pchar=strchr(pchar,'&');
		if (pchar) {
			*pchar='\0';
			pchar++;
		}
	}

	if (exact) {
		if (!strcmp(exact,"off")) {
			exact=(char *) 0; /* off is default */
		} else if (!strcmp(exact,"on")) {
			http_header(501,CTYPE_HTML_STR);
			printf("<html><head><title>Not implemented</title></head><body><h1>Error handling request: \"exact\" parameter is not implemented.</h1></body></html>");
			return 1;
		} else {
			http_header(500,CTYPE_HTML_STR);
			printf("<html><head><title>Error handling request</title></head><body><h1>Error handling request: \"exact\" parameter only take \"on\" or \"off\" as argument.</h1></body></html>");
			return 1;
		}
	}

	if ( ! search ) { 
		/* (mandatory parameter) */
		http_header(500,CTYPE_HTML_STR);
		printf("<html><head><title>Error handling request</title></head><body><h1>Error handling request: Missing \"search\" parameter in \"%s\".</h1></body></html>",getenv("QUERY_STRING"));
		return 1;
	} else {
		if (searchdec=malloc(strlen(search)*sizeof(char)+1)) 
			strdecode(searchdec,search);
		else {
			http_header(500,CTYPE_HTML_STR);
			printf("<html><head><title>Internal Error</title></head><body><h1>Internal malloc(%d) for search fail.</h1></body></html>",strlen(search)*sizeof(char)+1);
			return 1;
		}
	}

	if ( ! op )
		op="index"; /* defaut operation */

	/* Check gpgme version ( http://www.gnupg.org/documentation/manuals/gpgme/Library-Version-Check.html )*/
	setlocale (LC_ALL, "");
	gpgme_check_version (NULL);
	gpgme_set_locale (NULL, LC_CTYPE, setlocale (LC_CTYPE, NULL));
	/* check for OpenPGP support */
	gpgerr=gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP);
	if ( gpgerr  != GPG_ERR_NO_ERROR ) {
		http_header(500,CTYPE_HTML_STR);
		printf("<html><head><title>Internal Error</title></head><body><h1>Error handling request due to internal error (gpgme_engine_check_version).</h1></body></html>");
		return 1;
	}

	/* create context */
	gpgerr=gpgme_new(&gpgctx);
	if ( gpgerr  != GPG_ERR_NO_ERROR ) {
		http_header(500,CTYPE_HTML_STR);
		printf("<html><head><title>Internal Error</title></head><body><h1>Error handling request due to internal error (gpgme_new %d).</h1></body></html>",gpgerr);
		return 1;
	}
	/*gpgerr = gpgme_get_engine_info(&enginfo);
	gpgerr |= gpgme_ctx_set_engine_info(gpgctx, GPGME_PROTOCOL_OpenPGP, enginfo->file_name,"../../new");
	if ( gpgerr  != GPG_ERR_NO_ERROR ) {
		http_header(500,CTYPE_HTML_STR);
		printf("<html><head><title>Internal Error</title></head><body><h1>Error handling request due to internal error (gpgme_ctx_set_engine_info %d).</h1></body></html>",gpgerr);
		return 1;
	}*/

	if (!strcmp(op, "get")) {
		gpgme_data_t gpgdata;
		char buff[BUFFSIZE];
		ssize_t read_bytes;

		gpgme_set_armor(gpgctx,1);
		gpgerr = gpgme_data_new(&gpgdata);
		if (gpgerr == GPG_ERR_NO_ERROR) {
			gpgerr = gpgme_data_set_encoding(gpgdata,GPGME_DATA_ENCODING_ARMOR);
			if (gpgerr == GPG_ERR_NO_ERROR)
				gpgerr = gpgme_op_export(gpgctx,searchdec,0,gpgdata);
		}

		if ( gpgerr != GPG_ERR_NO_ERROR) {
			http_header(500,CTYPE_HTML_STR);
			printf("<html><head><title>Internal Error</title></head><body><h1>Error handling request due to internal error (%d).</h1></body></html>",gpgerr);
			return 1;
		}
		gpgme_data_seek (gpgdata, 0, SEEK_SET);
		read_bytes = gpgme_data_read (gpgdata, buff, BUFFSIZE);
		if ( read_bytes == -1 ) {
			http_header(500,CTYPE_HTML_STR);
			printf("<html><head><title>Internal Error</title></head><body><h1>Error handling request due to internal error (%s).</h1></body></html>",gpgme_strerror(errno));
			return 1;
		} else if ( read_bytes <= 0 ) {
			http_header(404,CTYPE_HTML_STR);
			printf("<html><head><title>ludd Public Key Server -- Get: %s</title></head><body><h1>Public Key Server -- Get: %s : No key found ! :-( </h1></body></html>",search,search);
			return 0;
		} else {
			http_header(200,CTYPE_HTML_STR);
			printf("<html><head><title>ludd Public Key Server -- Get: %s</title></head><body><h1>Public Key Server -- Get: %s</h1><pre>",search,search);
			fwrite(buff, sizeof(char),read_bytes,stdout); /* Now it's too late to test fwrite return value ;-) */ 
			while ( (read_bytes = gpgme_data_read (gpgdata, buff, BUFFSIZE)) > 0 )
				fwrite(buff, sizeof(char),read_bytes,stdout);
			printf("\n</pre></body></html>");
			return 0;
		}

	} else if (!strcmp(op, "index")) {
		char uidenc[BUFFSIZE];
		char begin=0;
		gpgme_user_id_t gpguid;

		/* check for the searched key(s) */
		gpgerr = gpgme_op_keylist_start(gpgctx, searchdec, 0);
		//gpgerr = gpgme_op_keylist_start(gpgctx, NULL, 0);
		if ( gpgerr  != GPG_ERR_NO_ERROR ) {
			http_header(500,CTYPE_HTML_STR);
			printf("<html><head><title>Internal Error</title></head><body><h1>Error handling request due to internal error (gpgme_op_keylist_start %d).</h1></body></html>",gpgerr);
			return 1;
		}

		gpgerr = gpgme_op_keylist_next (gpgctx, &gpgkey);
		while (gpgerr == GPG_ERR_NO_ERROR) {
			if (!begin) {
				http_header(200,"text/plain; charset=utf-8");
				begin=1;
				/* Luckily: info "header" is optionnal, see draft-shaw-openpgp-hkp-00.txt */
			}
			/* first subkey is the main key */
			printf("pub:%s:%d:%d:%d:%d\n",gpgkey->subkeys->fpr,gpgkey->subkeys->pubkey_algo,gpgkey->subkeys->length,gpgkey->subkeys->timestamp,(gpgkey->subkeys->expires?gpgkey->subkeys->expires:-1));
			gpguid=gpgkey->uids;
			while (gpguid) {
				printf("uid:%s (%s) <%s>:\n",gpguid->name,gpguid->comment,gpguid->email);
				gpguid=gpguid->next;
			}
			gpgme_key_unref(gpgkey);
			gpgerr = gpgme_op_keylist_next (gpgctx, &gpgkey);
		}
			gpgme_key_unref(gpgkey); /* ... because i don't know how "gpgme_op_keylist_next" behave when not returning GPG_ERR_NO_ERROR */
		if (!begin) {
			http_header(404,CTYPE_HTML_STR);
			printf("<html><head><title>ludd Public Key Server -- index: %s</title></head><body><h1>index Error: No keys found</h1></body></html>",search);
			return 1;
		}
		return 0;

	} else if ( !strcmp(op, "photo") || !strcmp(op, "x-photo") ) {
			http_header(501,CTYPE_HTML_STR);
			printf("<html><head><title>Not implemented</title></head><body><h1>Error handling request: \"%s\" operation is not implemented.</h1></body></html>",op);
			return 1;
	} else {
		http_header(500,CTYPE_HTML_STR);
		printf("<html><head><title>Error handling request</title></head><body><h1>Error handling request: Unrecognized action in \"%s\".</h1></body></html>",getenv("QUERY_STRING"));
		return 1;
	}
}
Пример #23
0
Файл: gpg.c Проект: comotion/cpm
/* #############################################################################
 *
 * Description    check if for the given keyname a secret key exists
 * Author         Harry Brueckner
 * Date           2005-04-25
 * Arguments      char* keyname   - the key to check
 * Return         int 1 if there is a secret key, 0 if not and -1 if a gpg
 *                      error occured
 */
int gpgIsSecretKey(char* keyname)
  {
    gpgme_ctx_t         context;
    gpgme_key_t         key;
    gpgme_error_t       error;
    int                 secret = 0;

    TRACE(99, "gpgIsSecretKey()", NULL);

    if (!config -> encryptdata)
      { return 0; }

    /* get a new context */
    error = gpgme_new(&context);
    if (error)
      {
        gpgme_release(context);
        gpgError(error);
        return -1;
      }

    /* start cycling through the list of keys */
    error = gpgme_op_keylist_start(context, keyname, LIST_SECRET);
    if (error)
      {
        gpgme_release(context);
        gpgError(error);
        return -1;
      }

    while (!(error = gpgme_op_keylist_next(context, &key)))
      {   /* take the first usable key we find */
        /* TODO: only choose usable secret keys */
        if (key -> can_encrypt &&
            key -> secret &&
            !key -> disabled &&
            !key -> expired &&
            !key -> invalid &&
            !key -> revoked)
          {   /* we just use keys we can encrypt for */
            secret = 1;
          }

        gpgme_key_unref(key);

        if (secret)
          { break; }
      }

    if (error &&
        gpg_err_code(error) != GPG_ERR_EOF)
      {    /* we validate the last value of the 'next' operation */
        gpgme_release(context);
        gpgError(error);
        return -1;
      }

    /* finish the key listing */
    error = gpgme_op_keylist_end(context);
    if (error)
      {
        gpgme_release(context);
        gpgError(error);
        return -1;
      }

    gpgme_release(context);

    return secret;
  }
Пример #24
0
gboolean sgpgme_setup_signers(gpgme_ctx_t ctx, PrefsAccount *account,
			      const gchar *from_addr)
{
	GPGAccountConfig *config;
	const gchar *signer_addr = account->address;

	gpgme_signers_clear(ctx);

	if (from_addr)
		signer_addr = from_addr;
	config = prefs_gpg_account_get_config(account);

	switch(config->sign_key) {
	case SIGN_KEY_DEFAULT:
		debug_print("using default gnupg key\n");
		break;
	case SIGN_KEY_BY_FROM:
		debug_print("using key for %s\n", signer_addr);
		break;
	case SIGN_KEY_CUSTOM:
		debug_print("using key for %s\n", config->sign_key_id);
		break;
	}

	if (config->sign_key != SIGN_KEY_DEFAULT) {
		const gchar *keyid;
		gpgme_key_t key, key2;
		gpgme_error_t err;

		if (config->sign_key == SIGN_KEY_BY_FROM)
			keyid = signer_addr;
		else if (config->sign_key == SIGN_KEY_CUSTOM)
			keyid = config->sign_key_id;
		else
			goto bail;

		err = gpgme_op_keylist_start(ctx, keyid, 1);
		if (!err) {
			do {
				err = gpgme_op_keylist_next(ctx, &key);
				if (!err && key && key->protocol == gpgme_get_protocol(ctx) &&
				    !key->expired && !key->revoked && !key->disabled)
					break;
				if (!err && key && key->protocol != gpgme_get_protocol(ctx)) {
					debug_print("skipping a key (wrong protocol %d)\n", key->protocol);
					gpgme_key_release(key);
				}
				if (!err && key && (key->expired || key->revoked || key->disabled)) {
					
					debug_print("skipping a key");
					if (key->expired) 
						debug_print(" expired");
					if (key->revoked) 
						debug_print(" revoked");
					if (key->disabled) 
						debug_print(" disabled");
					debug_print("\n");
					gpgme_key_release(key);
				}
			} while (!err);
		}
		if (err) {
			g_warning("setup_signers start: %s", gpgme_strerror(err));
			privacy_set_error(_("Secret key not found (%s)"), gpgme_strerror(err));
			goto bail;
		}
		
		do {
			err = gpgme_op_keylist_next(ctx, &key2);
			if (!err && key2 && key2->protocol == gpgme_get_protocol(ctx) &&
			    !key2->expired && !key2->revoked && !key2->disabled)
				break;
			if (!err && key2 && key2->protocol != gpgme_get_protocol(ctx)) {
				debug_print("skipping a key (wrong protocol %d)\n", key2->protocol);
				gpgme_key_release(key2);
			}
			if (!err && key2 && (key2->expired || key2->revoked || key2->disabled)) {
					debug_print("skipping a key");
					if (key2->expired) 
						debug_print(" expired");
					if (key2->revoked) 
						debug_print(" revoked");
					if (key2->disabled) 
						debug_print(" disabled");
					debug_print("\n");
				gpgme_key_release(key2);
			}
		} while (!err);
		if (!err) {
			gpgme_key_release(key2);
			g_warning("ambiguous specification of secret key '%s'\n",
				keyid);
			privacy_set_error(_("Secret key specification is ambiguous"));
			goto bail;
		}
		
		gpgme_op_keylist_end(ctx);
		err = gpgme_signers_add(ctx, key);
		debug_print("got key (proto %d (pgp %d, smime %d).\n", key->protocol,
				GPGME_PROTOCOL_OpenPGP, GPGME_PROTOCOL_CMS);
		gpgme_key_release(key);
		
		if (err) {
			g_warning("error adding secret key: %s\n", gpgme_strerror(err));
			privacy_set_error(_("Error setting secret key: %s"), gpgme_strerror(err));
			goto bail;
		}
	}

	prefs_gpg_account_free_config(config);

	return TRUE;
bail:
	prefs_gpg_account_free_config(config);
	return FALSE;
}
Пример #25
0
Файл: gpg.c Проект: comotion/cpm
/* #############################################################################
 *
 * Description    find a fingerprint for the given key
 * Author         Harry Brueckner
 * Date           2005-04-07
 * Arguments      keyname       - description string
 *                secret_only   - if set to 1, only secret keys are listed
 * Return         char* with the found fingerprint; the string must be freed
 *                by the caller
 */
char* gpgGetFingerprint(char* keyname, int secret_only)
  {
    gpgme_ctx_t         context;
    gpgme_key_t         key;
    gpgme_error_t       error;
    char*               identifier = NULL;

    TRACE(99, "gpgGetFingerprint()", NULL);

    if (!config -> encryptdata)
      { return NULL; }

    /* get a new context */
    error = gpgme_new(&context);
    if (error)
      {
        gpgme_release(context);
        gpgError(error);
        return NULL;
      }

    /* start cycling through the list of keys */
    error = gpgme_op_keylist_start(context, keyname, secret_only);
    if (error)
      {
        gpgme_release(context);
        gpgError(error);
        return NULL;
      }

    /* first we look for secret keys */
    while (!identifier &&
        !(error = gpgme_op_keylist_next(context, &key)))
      {   /* take the first key we find */
        if (!identifier &&
            !key -> disabled &&
            !key -> expired &&
            !key -> invalid &&
            !key -> revoked)
          {   /* we just use keys we can encrypt for */
            identifier = memAlloc(__FILE__, __LINE__,
                strlen(key -> subkeys -> fpr) + 1);
            strStrncpy(identifier, key -> subkeys -> fpr,
                strlen(key -> subkeys -> fpr) + 1);
          }

        gpgme_key_unref(key);
      }

    if (error &&
        gpg_err_code(error) != GPG_ERR_EOF)
      {    /* we validate the last value of the 'next' operation */
        gpgme_release(context);
        gpgError(error);
        return NULL;
      }

    /* finish the key listing */
    error = gpgme_op_keylist_end(context);
    if (error)
      {
        gpgme_release(context);
        gpgError(error);
        return NULL;
      }

    gpgme_release(context);

    return identifier;
  }
Пример #26
0
int
main (int argc, char **argv)
{
  int last_argc = -1;
  gpgme_error_t err;
  gpgme_ctx_t ctx;
  gpgme_key_t key;
  gpgme_keylist_result_t result;
  gpgme_key_t keyarray[100];
  int keyidx = 0;
  gpgme_data_t out;
  gpgme_protocol_t protocol = GPGME_PROTOCOL_OpenPGP;
  gpgme_export_mode_t mode = 0;

  if (argc)
    { argc--; argv++; }

  while (argc && last_argc != argc )
    {
      last_argc = argc;
      if (!strcmp (*argv, "--"))
        {
          argc--; argv++;
          break;
        }
      else if (!strcmp (*argv, "--help"))
        show_usage (0);
      else if (!strcmp (*argv, "--verbose"))
        {
          verbose = 1;
          argc--; argv++;
        }
      else if (!strcmp (*argv, "--openpgp"))
        {
          protocol = GPGME_PROTOCOL_OpenPGP;
          argc--; argv++;
        }
      else if (!strcmp (*argv, "--cms"))
        {
          protocol = GPGME_PROTOCOL_CMS;
          argc--; argv++;
        }
      else if (!strcmp (*argv, "--extern"))
        {
          mode |= GPGME_EXPORT_MODE_EXTERN;
          argc--; argv++;
        }
      else if (!strcmp (*argv, "--secret"))
        {
          mode |= GPGME_EXPORT_MODE_SECRET;
          argc--; argv++;
        }
      else if (!strcmp (*argv, "--raw"))
        {
          mode |= GPGME_EXPORT_MODE_RAW;
          argc--; argv++;
        }
      else if (!strcmp (*argv, "--pkcs12"))
        {
          mode |= GPGME_EXPORT_MODE_PKCS12;
          argc--; argv++;
        }
      else if (!strncmp (*argv, "--", 2))
        show_usage (1);

    }

  if (!argc)
    show_usage (1);

  init_gpgme (protocol);

  err = gpgme_new (&ctx);
  fail_if_err (err);
  gpgme_set_protocol (ctx, protocol);

  /* Lookup the keys.  */
  err = gpgme_op_keylist_ext_start (ctx, (const char**)argv, 0, 0);
  fail_if_err (err);

  while (!(err = gpgme_op_keylist_next (ctx, &key)))
    {
      printf ("keyid: %s  (fpr: %s)\n",
              key->subkeys?nonnull (key->subkeys->keyid):"?",
              key->subkeys?nonnull (key->subkeys->fpr):"?");

      if (keyidx < DIM (keyarray)-1)
        keyarray[keyidx++] = key;
      else
        {
          fprintf (stderr, PGM": too many keys"
                   "- skipping this key\n");
          gpgme_key_unref (key);
        }
    }
  if (gpgme_err_code (err) != GPG_ERR_EOF)
    fail_if_err (err);
  err = gpgme_op_keylist_end (ctx);
  fail_if_err (err);
  keyarray[keyidx] = NULL;

  result = gpgme_op_keylist_result (ctx);
  if (result->truncated)
    {
      fprintf (stderr, PGM ": key listing unexpectedly truncated\n");
      exit (1);
    }

  /* Now for the actual export.  */
  if ((mode & GPGME_EXPORT_MODE_EXTERN))
    printf ("sending keys to keyserver\n");
  if ((mode & GPGME_EXPORT_MODE_SECRET))
    printf ("exporting secret keys!\n");

  err = gpgme_data_new (&out);
  fail_if_err (err);

  gpgme_set_armor (ctx, 1);
  err = gpgme_op_export_keys (ctx, keyarray, mode,
                              (mode & GPGME_KEYLIST_MODE_EXTERN)? NULL:out);
  fail_if_err (err);

  fflush (NULL);
  if (!(mode & GPGME_KEYLIST_MODE_EXTERN))
    {
      fputs ("Begin Result:\n", stdout);
      print_data (out);
      fputs ("End Result.\n", stdout);
    }

  /* Cleanup.  */
  gpgme_data_release (out);

  for (keyidx=0; keyarray[keyidx]; keyidx++)
    gpgme_key_unref (keyarray[keyidx]);

  gpgme_release (ctx);
  return 0;
}
Пример #27
0
gboolean sgpgme_setup_signers(gpgme_ctx_t ctx, PrefsAccount *account,
			      const gchar *from_addr)
{
	GPGAccountConfig *config;
	const gchar *signer_addr = account->address;

	gpgme_signers_clear(ctx);

	if (from_addr)
		signer_addr = from_addr;
	config = prefs_gpg_account_get_config(account);

	switch(config->sign_key) {
	case SIGN_KEY_DEFAULT:
		debug_print("using default gnupg key\n");
		break;
	case SIGN_KEY_BY_FROM:
		debug_print("using key for %s\n", signer_addr);
		break;
	case SIGN_KEY_CUSTOM:
		debug_print("using key for %s\n", config->sign_key_id);
		break;
	}

	if (config->sign_key != SIGN_KEY_DEFAULT) {
		const gchar *keyid;
		gpgme_key_t key, found_key;
		gpgme_error_t err;

		if (config->sign_key == SIGN_KEY_BY_FROM)
			keyid = signer_addr;
		else if (config->sign_key == SIGN_KEY_CUSTOM)
			keyid = config->sign_key_id;
		else
			goto bail;

                found_key = NULL;
		/* Look for any key, not just private ones, or GPGMe doesn't
		 * correctly set the revoked flag. */
		err = gpgme_op_keylist_start(ctx, keyid, 0);
		while ((err = gpgme_op_keylist_next(ctx, &key)) == 0) {
			if (key == NULL)
				continue;

			if (!key->can_sign)
				continue;

			if (key->protocol != gpgme_get_protocol(ctx)) {
				debug_print("skipping a key (wrong protocol %d)\n", key->protocol);
				gpgme_key_release(key);
				continue;
			}

			if (key->expired) {
				debug_print("skipping a key, expired");
				gpgme_key_release(key);
				continue;
			}
			if (key->revoked) {
				debug_print("skipping a key, revoked");
				gpgme_key_release(key);
				continue;
			}
			if (key->disabled) {
				debug_print("skipping a key, disabled");
				gpgme_key_release(key);
				continue;
			}

			if (found_key != NULL) {
				gpgme_key_release(key);
				gpgme_op_keylist_end(ctx);
				g_warning("ambiguous specification of secret key '%s'\n", keyid);
				privacy_set_error(_("Secret key specification is ambiguous"));
				goto bail;
			}

			found_key = key;
                }
		gpgme_op_keylist_end(ctx);

		if (found_key == NULL) {
			g_warning("setup_signers start: %s", gpgme_strerror(err));
			privacy_set_error(_("Secret key not found (%s)"), gpgme_strerror(err));
			goto bail;
                }

		err = gpgme_signers_add(ctx, found_key);
		debug_print("got key (proto %d (pgp %d, smime %d).\n",
			    found_key->protocol, GPGME_PROTOCOL_OpenPGP,
			    GPGME_PROTOCOL_CMS);
		gpgme_key_release(found_key);

		if (err) {
			g_warning("error adding secret key: %s\n",
				  gpgme_strerror(err));
			privacy_set_error(_("Error setting secret key: %s"),
					  gpgme_strerror(err));
			goto bail;
		}
        }

	prefs_gpg_account_free_config(config);

	return TRUE;
bail:
	prefs_gpg_account_free_config(config);
	return FALSE;
}
Пример #28
0
/* Try to find a key for each item in array NAMES. Items not found are
   stored as malloced strings in the newly allocated array UNKNOWN.
   Found keys are stored in the newly allocated array KEYS.  Both
   arrays are terminated by a NULL entry.  Caller needs to release
   KEYS and UNKNOWN.

   Returns: 0 on success. However success may also be that one or all
   keys are unknown.
*/
int 
op_lookup_keys (char **names, gpgme_key_t **keys, char ***unknown)
{
  gpgme_error_t err;
  gpgme_ctx_t ctx;
  size_t n;
  int i, kpos, upos;
  gpgme_key_t k, k2;

  *keys = NULL;
  *unknown = NULL;

  err = gpgme_new (&ctx);
  if (err)
    return -1; /* Error. */

  for (n=0; names[n]; n++)
    ;

  *keys =  xcalloc (n+1, sizeof *keys);
  *unknown = xcalloc (n+1, sizeof *unknown);

  for (i=kpos=upos=0; names[i]; i++)
    {
      k = NULL;
      err = gpgme_op_keylist_start (ctx, names[i], 0);
      if (!err)
        {
          err = gpgme_op_keylist_next (ctx, &k);
          if (!err && !gpgme_op_keylist_next (ctx, &k2))
            {
              /* More than one matching key available.  Take this one
                 as unknown. */
              gpgme_key_release (k);
              gpgme_key_release (k2);
              k = k2 = NULL;
            }
        }
      gpgme_op_keylist_end (ctx);

      
      /* only useable keys will be added otherwise they will be stored
         in unknown (marked with their status). */
      if (k && !k->revoked && !k->disabled && !k->expired)
        (*keys)[kpos++] = k;
      else if (k)
	{
	  char *p, *fmt = "%s (%s)";
	  char *warn = k->revoked? "revoked" : k->expired? "expired" : "disabled";
	  
	  p = xcalloc (1, strlen (names[i]) + strlen (warn) + strlen (fmt) +1);
	  sprintf (p, fmt, names[i], warn);
	  (*unknown)[upos++] = p;
	  gpgme_key_release (k);
	}
      else if (!k)
        (*unknown)[upos++] = xstrdup (names[i]);
    }

  gpgme_release (ctx);
  return 0;
}
Пример #29
0
static gpgme_key_t 
fill_clist (struct select_keys_s *sk, const char *pattern, gpgme_protocol_t proto)
{
    GtkCMCList *clist;
    gpgme_ctx_t ctx;
    gpgme_error_t err;
    gpgme_key_t key;
    int running=0;
    int num_results = 0;
    gboolean exact_match = FALSE;
    gpgme_key_t last_key = NULL;
    gpgme_user_id_t last_uid = NULL;
    cm_return_val_if_fail (sk, NULL);
    clist = sk->clist;
    cm_return_val_if_fail (clist, NULL);

    debug_print ("select_keys:fill_clist:  pattern '%s' proto %d\n", pattern, proto);

    /*gtk_cmclist_freeze (select_keys.clist);*/
    err = gpgme_new (&ctx);
    g_assert (!err);

    gpgme_set_protocol(ctx, proto);
    sk->select_ctx = ctx;

    update_progress (sk, ++running, pattern);
    while (gtk_events_pending ())
        gtk_main_iteration ();

    err = gpgme_op_keylist_start (ctx, pattern, 0);
    if (err) {
        debug_print ("** gpgme_op_keylist_start(%s) failed: %s",
                     pattern, gpgme_strerror (err));
        sk->select_ctx = NULL;
        gpgme_release(ctx);
        return NULL;
    }
    update_progress (sk, ++running, pattern);
    while ( !(err = gpgme_op_keylist_next ( ctx, &key )) ) {
	gpgme_user_id_t uid = key->uids;
	if (!key->can_encrypt || key->revoked || key->expired || key->disabled)
		continue;
        debug_print ("%% %s:%d:  insert\n", __FILE__ ,__LINE__ );
        set_row (clist, key, proto ); 
	for (; uid; uid = uid->next) {
		gchar *raw_mail = NULL;

		if (!uid->email)
			continue;
		if (uid->revoked || uid->invalid)
			continue;
		raw_mail = g_strdup(uid->email);
		extract_address(raw_mail);
		if (!strcasecmp(pattern, raw_mail)) {
			exact_match = TRUE;
			last_uid = uid;
			g_free(raw_mail);
			break;
		}
		g_free(raw_mail);
	}
	num_results++;
	last_key = key;
	key = NULL;
        update_progress (sk, ++running, pattern);
        while (gtk_events_pending ())
            gtk_main_iteration ();
    }
 
    if (exact_match == TRUE && num_results == 1) {
	    if (last_key->uids->validity < GPGME_VALIDITY_FULL && 
		!use_untrusted(last_key, last_uid, proto))
		    exact_match = FALSE;
    }

    debug_print ("%% %s:%d:  ready\n", __FILE__ ,__LINE__ );
    if (gpgme_err_code(err) != GPG_ERR_EOF) {
        debug_print ("** gpgme_op_keylist_next failed: %s",
                     gpgme_strerror (err));
        gpgme_op_keylist_end(ctx);
    }
    if (!exact_match || num_results != 1) {
	    sk->select_ctx = NULL;
	    gpgme_release (ctx);
    }
    /*gtk_cmclist_thaw (select_keys.clist);*/
    return (exact_match == TRUE && num_results == 1 ? last_key:NULL);
}
Пример #30
0
static gpgme_key_t
pkcs7_get_key_by_name (Pkcs7Ctx *pkcs7, const char *name, gboolean secret, GError **err)
{
	time_t now = time (NULL);
	gpgme_key_t key = NULL;
	gpgme_subkey_t subkey;
	gboolean bad = FALSE;
	gpgme_error_t error;
	int errval = 0;
	
	if ((error = gpgme_op_keylist_start (pkcs7->ctx, name, secret)) != GPG_ERR_NO_ERROR) {
		if (secret)
			g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not list secret keys for \"%s\""), name);
		else
			g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not list keys for \"%s\""), name);
		return NULL;
	}
	
	while ((error = gpgme_op_keylist_next (pkcs7->ctx, &key)) == GPG_ERR_NO_ERROR) {
		/* check if this key and the relevant subkey are usable */
		if (KEY_IS_OK (key)) {
			subkey = key->subkeys;
			
			while (subkey && ((secret && !subkey->can_sign) ||
					  (!secret && !subkey->can_encrypt)))
				subkey = subkey->next;
			
			if (subkey && KEY_IS_OK (subkey) && 
			    (subkey->expires == 0 || subkey->expires > now))
				break;
			
			if (subkey->expired)
				errval = GPG_ERR_KEY_EXPIRED;
			else
				errval = GPG_ERR_BAD_KEY;
		} else {
			if (key->expired)
				errval = GPG_ERR_KEY_EXPIRED;
			else
				errval = GPG_ERR_BAD_KEY;
		}
		
		gpgme_key_unref (key);
		bad = TRUE;
		key = NULL;
	}
	
	gpgme_op_keylist_end (pkcs7->ctx);
	
	if (error != GPG_ERR_NO_ERROR && error != GPG_ERR_EOF) {
		if (secret)
			g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not list secret keys for \"%s\""), name);
		else
			g_set_error (err, GMIME_GPGME_ERROR, error, _("Could not list keys for \"%s\""), name);
		
		return NULL;
	}
	
	if (!key) {
		if (strchr (name, '@')) {
			if (bad)
				g_set_error (err, GMIME_GPGME_ERROR, errval,
					     _("A key for %s is present, but it is expired, disabled, revoked or invalid"),
					     name);
			else
				g_set_error (err, GMIME_GPGME_ERROR, GPG_ERR_NOT_FOUND,
					     _("Could not find a key for %s"), name);
		} else {
			if (bad)
				g_set_error (err, GMIME_GPGME_ERROR, errval,
					     _("A key with id %s is present, but it is expired, disabled, revoked or invalid"),
					     name);
			else
				g_set_error (err, GMIME_GPGME_ERROR, GPG_ERR_NOT_FOUND,
					     _("Could not find a key with id %s"), name);
		}
		
		return NULL;
	}
	
	return key;
}