2002-12-04 16:28:34 +00:00
|
|
|
|
/* key.c - Key objects.
|
|
|
|
|
Copyright (C) 2000 Werner Koch (dd9jn)
|
2004-12-07 Marcus Brinkmann <marcus@g10code.de>
* README: Refer to COPYING.LESSER and "each file" instead of
COPYING.
* COPYING.LESSER: New file.
* gpgme.spec.in (%doc): Add COPYING.LESSER.
* acinclude.m4, configure.ac, Makefile.am: Change license to LGPL
2.1 or later.
* TODO: Add copyright notice.
* README.CVS: Likewise.
assuan/
2004-12-07 Marcus Brinkmann <marcus@g10code.de>
* README.1st: Add copyright notice.
doc/
2004-12-07 Marcus Brinkmann <marcus@g10code.de>
* Makefile.am: Change license to LGPL.
(gpgme_TEXINFOS): Replace gpl.texi with lesser.texi.
* gpgme.texi: Change license to LGPL (also for documentation of
GPGME's license).
* lesser.texi: New file.
* gpl.texi: File removed.
gpgme/
2004-12-07 Marcus Brinkmann <marcus@g10code.de>
* putc_unlocked.c, funopen.c: I just claim copyright on these
files and change their license to LGPL, because they are totally
trivial wrapper functions.
* isascii.c: Change copyright notice to the one from ctype/ctype.h
in the GNU C Library (CVS Head 2004-10-10), where isascii is
defined as a macro doing exactly the same as the function in this
file.
* memrchr.c: Update from the GNU C Library (CVS Head 2001-07-06).
* stpcpy.c: Update from the GNU C Library (CVS Head 2004-10-10).
* ath.c, ath-compat.c, ath.h, ath-pth.c, ath-pth-compat.c,
ath-pthread.c, ath-pthread-compat.c, context.h, conversion.c,
data.c, data-compat.c, data-fd.c, data.h, data-mem.c,
data-stream.c, data-user.c, debug.c, debug.h, decrypt.c,
decrypt-verify.c, delete.c, edit.c, encrypt.c, encrypt-sign.c,
engine-backend.h, engine.c, engine-gpgsm.c, engine.h, error.c,
export.c, genkey.c, get-env.c, gpgme.c, gpgme.h, import.c, io.h,
key.c, keylist.c, mkstatus, Makefile.am, ops.h, op-support.c,
passphrase.c, posix-io.c, posix-sema.c, posix-util.c, progress.c,
rungpg.c, sema.h, sign.c, signers.c, trust-item.c, trustlist.c,
util.h, verify.c, version.c, w32-io.c, w32-sema.c, w32-util.c,
wait.c, wait-global.c, wait.h, wait-private.c, wait-user.c: Change
license to LGPL.
tests/
2004-12-07 Marcus Brinkmann <marcus@g10code.de>
* gpg/mkdemodirs: Add copyright notice.
* gpgsm/Makefile.am, gpgsm/t-support.h, gpgsm/t-decrypt.c,
gpgsm/t-encrypt.c, gpgsm/t-export.c, gpgsm/t-genkey.c,
gpgsm/t-import.c, gpgsm/t-keylist.c, gpgsm/t-sign.c,
gpgsm/t-verify.c, gpg/Makefile.am, gpg/t-decrypt.c,
gpg/t-decrypt-verify.c, gpg/t-edit.c, gpg/t-encrypt.c,
gpg/t-encrypt-sign.c, gpg/t-encrypt-sym.c, gpg/t-eventloop.c,
gpg/t-export.c, gpg/t-genkey.c, gpg/t-import.c, gpg/t-keylist.c,
gpg/t-keylist-sig.c, gpg/t-sign.c, gpg/t-signers.c,
gpg/t-support.h, gpg/t-thread1.c, gpg/t-trustlist.c,
gpg/t-verify.c, Makefile.am, t-data.c, t-engine-info.c,
t-version.c: Change license to LGPL.
2004-12-07 21:13:39 +00:00
|
|
|
|
Copyright (C) 2001, 2002, 2003, 2004 g10 Code GmbH
|
2002-12-04 16:28:34 +00:00
|
|
|
|
|
|
|
|
|
This file is part of GPGME.
|
|
|
|
|
|
|
|
|
|
GPGME is free software; you can redistribute it and/or modify it
|
2004-12-07 Marcus Brinkmann <marcus@g10code.de>
* README: Refer to COPYING.LESSER and "each file" instead of
COPYING.
* COPYING.LESSER: New file.
* gpgme.spec.in (%doc): Add COPYING.LESSER.
* acinclude.m4, configure.ac, Makefile.am: Change license to LGPL
2.1 or later.
* TODO: Add copyright notice.
* README.CVS: Likewise.
assuan/
2004-12-07 Marcus Brinkmann <marcus@g10code.de>
* README.1st: Add copyright notice.
doc/
2004-12-07 Marcus Brinkmann <marcus@g10code.de>
* Makefile.am: Change license to LGPL.
(gpgme_TEXINFOS): Replace gpl.texi with lesser.texi.
* gpgme.texi: Change license to LGPL (also for documentation of
GPGME's license).
* lesser.texi: New file.
* gpl.texi: File removed.
gpgme/
2004-12-07 Marcus Brinkmann <marcus@g10code.de>
* putc_unlocked.c, funopen.c: I just claim copyright on these
files and change their license to LGPL, because they are totally
trivial wrapper functions.
* isascii.c: Change copyright notice to the one from ctype/ctype.h
in the GNU C Library (CVS Head 2004-10-10), where isascii is
defined as a macro doing exactly the same as the function in this
file.
* memrchr.c: Update from the GNU C Library (CVS Head 2001-07-06).
* stpcpy.c: Update from the GNU C Library (CVS Head 2004-10-10).
* ath.c, ath-compat.c, ath.h, ath-pth.c, ath-pth-compat.c,
ath-pthread.c, ath-pthread-compat.c, context.h, conversion.c,
data.c, data-compat.c, data-fd.c, data.h, data-mem.c,
data-stream.c, data-user.c, debug.c, debug.h, decrypt.c,
decrypt-verify.c, delete.c, edit.c, encrypt.c, encrypt-sign.c,
engine-backend.h, engine.c, engine-gpgsm.c, engine.h, error.c,
export.c, genkey.c, get-env.c, gpgme.c, gpgme.h, import.c, io.h,
key.c, keylist.c, mkstatus, Makefile.am, ops.h, op-support.c,
passphrase.c, posix-io.c, posix-sema.c, posix-util.c, progress.c,
rungpg.c, sema.h, sign.c, signers.c, trust-item.c, trustlist.c,
util.h, verify.c, version.c, w32-io.c, w32-sema.c, w32-util.c,
wait.c, wait-global.c, wait.h, wait-private.c, wait-user.c: Change
license to LGPL.
tests/
2004-12-07 Marcus Brinkmann <marcus@g10code.de>
* gpg/mkdemodirs: Add copyright notice.
* gpgsm/Makefile.am, gpgsm/t-support.h, gpgsm/t-decrypt.c,
gpgsm/t-encrypt.c, gpgsm/t-export.c, gpgsm/t-genkey.c,
gpgsm/t-import.c, gpgsm/t-keylist.c, gpgsm/t-sign.c,
gpgsm/t-verify.c, gpg/Makefile.am, gpg/t-decrypt.c,
gpg/t-decrypt-verify.c, gpg/t-edit.c, gpg/t-encrypt.c,
gpg/t-encrypt-sign.c, gpg/t-encrypt-sym.c, gpg/t-eventloop.c,
gpg/t-export.c, gpg/t-genkey.c, gpg/t-import.c, gpg/t-keylist.c,
gpg/t-keylist-sig.c, gpg/t-sign.c, gpg/t-signers.c,
gpg/t-support.h, gpg/t-thread1.c, gpg/t-trustlist.c,
gpg/t-verify.c, Makefile.am, t-data.c, t-engine-info.c,
t-version.c: Change license to LGPL.
2004-12-07 21:13:39 +00:00
|
|
|
|
under the terms of the GNU Lesser General Public License as
|
|
|
|
|
published by the Free Software Foundation; either version 2.1 of
|
|
|
|
|
the License, or (at your option) any later version.
|
|
|
|
|
|
2002-12-04 16:28:34 +00:00
|
|
|
|
GPGME is distributed in the hope that it will be useful, but
|
|
|
|
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
2004-12-07 Marcus Brinkmann <marcus@g10code.de>
* README: Refer to COPYING.LESSER and "each file" instead of
COPYING.
* COPYING.LESSER: New file.
* gpgme.spec.in (%doc): Add COPYING.LESSER.
* acinclude.m4, configure.ac, Makefile.am: Change license to LGPL
2.1 or later.
* TODO: Add copyright notice.
* README.CVS: Likewise.
assuan/
2004-12-07 Marcus Brinkmann <marcus@g10code.de>
* README.1st: Add copyright notice.
doc/
2004-12-07 Marcus Brinkmann <marcus@g10code.de>
* Makefile.am: Change license to LGPL.
(gpgme_TEXINFOS): Replace gpl.texi with lesser.texi.
* gpgme.texi: Change license to LGPL (also for documentation of
GPGME's license).
* lesser.texi: New file.
* gpl.texi: File removed.
gpgme/
2004-12-07 Marcus Brinkmann <marcus@g10code.de>
* putc_unlocked.c, funopen.c: I just claim copyright on these
files and change their license to LGPL, because they are totally
trivial wrapper functions.
* isascii.c: Change copyright notice to the one from ctype/ctype.h
in the GNU C Library (CVS Head 2004-10-10), where isascii is
defined as a macro doing exactly the same as the function in this
file.
* memrchr.c: Update from the GNU C Library (CVS Head 2001-07-06).
* stpcpy.c: Update from the GNU C Library (CVS Head 2004-10-10).
* ath.c, ath-compat.c, ath.h, ath-pth.c, ath-pth-compat.c,
ath-pthread.c, ath-pthread-compat.c, context.h, conversion.c,
data.c, data-compat.c, data-fd.c, data.h, data-mem.c,
data-stream.c, data-user.c, debug.c, debug.h, decrypt.c,
decrypt-verify.c, delete.c, edit.c, encrypt.c, encrypt-sign.c,
engine-backend.h, engine.c, engine-gpgsm.c, engine.h, error.c,
export.c, genkey.c, get-env.c, gpgme.c, gpgme.h, import.c, io.h,
key.c, keylist.c, mkstatus, Makefile.am, ops.h, op-support.c,
passphrase.c, posix-io.c, posix-sema.c, posix-util.c, progress.c,
rungpg.c, sema.h, sign.c, signers.c, trust-item.c, trustlist.c,
util.h, verify.c, version.c, w32-io.c, w32-sema.c, w32-util.c,
wait.c, wait-global.c, wait.h, wait-private.c, wait-user.c: Change
license to LGPL.
tests/
2004-12-07 Marcus Brinkmann <marcus@g10code.de>
* gpg/mkdemodirs: Add copyright notice.
* gpgsm/Makefile.am, gpgsm/t-support.h, gpgsm/t-decrypt.c,
gpgsm/t-encrypt.c, gpgsm/t-export.c, gpgsm/t-genkey.c,
gpgsm/t-import.c, gpgsm/t-keylist.c, gpgsm/t-sign.c,
gpgsm/t-verify.c, gpg/Makefile.am, gpg/t-decrypt.c,
gpg/t-decrypt-verify.c, gpg/t-edit.c, gpg/t-encrypt.c,
gpg/t-encrypt-sign.c, gpg/t-encrypt-sym.c, gpg/t-eventloop.c,
gpg/t-export.c, gpg/t-genkey.c, gpg/t-import.c, gpg/t-keylist.c,
gpg/t-keylist-sig.c, gpg/t-sign.c, gpg/t-signers.c,
gpg/t-support.h, gpg/t-thread1.c, gpg/t-trustlist.c,
gpg/t-verify.c, Makefile.am, t-data.c, t-engine-info.c,
t-version.c: Change license to LGPL.
2004-12-07 21:13:39 +00:00
|
|
|
|
Lesser General Public License for more details.
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
|
|
|
License along with this program; if not, write to the Free Software
|
|
|
|
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
|
|
|
02111-1307, USA. */
|
2000-11-10 17:50:24 +00:00
|
|
|
|
|
2002-12-04 16:28:34 +00:00
|
|
|
|
#if HAVE_CONFIG_H
|
2000-11-10 17:50:24 +00:00
|
|
|
|
#include <config.h>
|
2002-12-04 16:28:34 +00:00
|
|
|
|
#endif
|
2000-11-10 17:50:24 +00:00
|
|
|
|
#include <stdlib.h>
|
2001-11-02 15:51:15 +00:00
|
|
|
|
#include <string.h>
|
2000-11-10 17:50:24 +00:00
|
|
|
|
#include <assert.h>
|
2003-06-05 23:20:29 +00:00
|
|
|
|
#include <errno.h>
|
2000-11-10 17:50:24 +00:00
|
|
|
|
|
|
|
|
|
#include "util.h"
|
|
|
|
|
#include "ops.h"
|
2002-05-09 03:38:12 +00:00
|
|
|
|
#include "sema.h"
|
2000-11-10 17:50:24 +00:00
|
|
|
|
|
2003-04-30 03:02:50 +00:00
|
|
|
|
|
2002-05-09 03:38:12 +00:00
|
|
|
|
/* Protects all reference counters in keys. All other accesses to a
|
2003-05-28 01:18:51 +00:00
|
|
|
|
key are read only. */
|
2002-05-09 03:38:12 +00:00
|
|
|
|
DEFINE_STATIC_LOCK (key_ref_lock);
|
|
|
|
|
|
2002-12-23 22:31:03 +00:00
|
|
|
|
|
2003-04-30 03:02:50 +00:00
|
|
|
|
/* Create a new key. */
|
2003-05-18 20:45:24 +00:00
|
|
|
|
gpgme_error_t
|
|
|
|
|
_gpgme_key_new (gpgme_key_t *r_key)
|
2000-11-10 17:50:24 +00:00
|
|
|
|
{
|
2003-05-18 20:45:24 +00:00
|
|
|
|
gpgme_key_t key;
|
2002-05-09 03:38:12 +00:00
|
|
|
|
|
2002-10-08 Marcus Brinkmann <marcus@g10code.de>
* util.h (_gpgme_malloc, _gpgme_realloc, _gpgme_calloc,
_gpgme_strdup, _gpgme_free): Remove prototypes.
(xtrymalloc, xtrycalloc, xtryrealloc, xtrystrdup, xfree): Remove
macros.
* util.c: File removed.
* Makefile.am (libgpgme_la_SOURCES): Remove util.h.
* conversion.c (_gpgme_decode_c_string): Use malloc instead of
xtrymalloc, realloc instead of xtryrealloc, calloc instead of
xtrycalloc, free instead of xfree.
(_gpgme_data_append_percentstring_for_xml): Likewise.
* data.c (_gpgme_data_new, _gpgme_data_release): Likewise.
* data-compat.c (gpgme_data_new_from_filepart): Likewise.
* data-mem.c (mem_write, mem_release, gpgme_data_new_from_mem,
_gpgme_data_get_as_string): Likewise.
* debug.c (debug_init): Likewise.
* decrypt.c (_gpgme_release_decrypt_result): Likewise.
* delete.c (_gpgme_release_delete_result): Likewise.
* edit.c (_gpgme_release_edit_result, _gpgme_op_edit_start):
Likewise.
* encrypt.c (_gpgme_release_encrypt_result): Likewise.
* engine.c (_gpgme_engine_get_info, _gpgme_engine_new,
_gpgme_engine_release): Likewise.
* engine-gpgsm.c (_gpgme_gpgsm_new, _gpgme_gpgsm_release,
_gpgme_gpgsm_op_decrypt, _gpgme_gpgsm_op_delete,
gpgsm_set_recipients, _gpgme_gpgsm_op_encrypt,
_gpgme_gpgsm_op_export, _gpgme_gpgsm_op_genkey,
_gpgme_gpgsm_op_import, _gpgme_gpgsm_op_keylist,
_gpgme_gpgsm_op_keylist_ext, _gpgme_gpgsm_op_sign,
_gpgme_gpgsm_op_verify, gpgsm_status_handler): Likewise.
* genkey.c (_gpgme_release_genkey_result): Likewise.
* gpgme.c (gpgme_new, gpgme_release): Likewise.
* import.c (_gpgme_release_import_result): Likewise.
* key.c (_gpgme_key_cache_init, _gpgme_key_cache_add, key_new,
add_subkey, gpgme_key_release, _gpgme_key_append_name): Likewise.
* keylist.c (_gpgme_release_keylist_result, keylist_colon_handler,
_gpgme_op_keylist_event_cb, gpgme_op_keylist_next): Likewise.
* ops.h (test_and_allocate_result): Likewise.
* passphrase.c (_gpgme_release_passphrase_result,
_gpgme_passphrase_status_handler,
_gpgme_passphrase_command_handler): Likewise.
* progress.c (_gpgme_progress_status_handler): Likewise.
* recipient.c (gpgme_recipients_new, gpgme_recipients_release,
gpgme_recipients_add_name_with_validity): Likewise.
* rungpg.c (_gpgme_gpg_new, _gpgme_gpg_release,
_gpgme_gpg_add_arg, _gpgme_gpg_add_data,
_gpgme_gpg_set_colon_line_handler, free_argv, free_fd_data_map,
build_argv, _gpgme_gpg_spawn, read_status, read_colon_line):
Likewise.
* sign.c (_gpgme_release_sign_result): Likewise.
* signers.c (_gpgme_signers_add): Likewise.
* trustlist.c (trust_item_new, trustlist_colon_handler,
_gpgme_op_trustlist_event_cb, gpgme_op_trustlist_next,
gpgme_trustitem_release): Likewise.
* verify.c (_gpgme_release_verify_result, finish_sig): Likewise.
* version.c (gpgme_get_engine_info, _gpgme_get_program_version):
Likewise.
* w32-io.c (create_reader, create_writer, destroy_reader,
destroy_writer, build_commandline, _gpgme_io_spawn): Likewise.
* w32-sema.c (critsect_init, _gpgme_sema_cs_destroy): Likewise.
* w32-util.c (read_w32_registry_string): Likewise.
* wait.c (_gpgme_fd_table_deinit, _gpgme_fd_table_put,
_gpgme_wait_event_cb, _gpgme_add_io_cb, _gpgme_remove_io_cb)
* data-compat.c: Include <stdlib.h>.
2002-10-09 01:08:21 +00:00
|
|
|
|
key = calloc (1, sizeof *key);
|
2002-05-09 03:38:12 +00:00
|
|
|
|
if (!key)
|
2003-06-05 23:20:29 +00:00
|
|
|
|
return gpg_error_from_errno (errno);
|
2003-04-30 03:02:50 +00:00
|
|
|
|
key->_refs = 1;
|
|
|
|
|
|
2002-05-09 03:38:12 +00:00
|
|
|
|
*r_key = key;
|
|
|
|
|
return 0;
|
2000-11-10 17:50:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-12-04 16:28:34 +00:00
|
|
|
|
|
2003-05-18 20:45:24 +00:00
|
|
|
|
gpgme_error_t
|
|
|
|
|
_gpgme_key_add_subkey (gpgme_key_t key, gpgme_subkey_t *r_subkey)
|
2000-12-19 10:07:32 +00:00
|
|
|
|
{
|
2003-05-18 20:45:24 +00:00
|
|
|
|
gpgme_subkey_t subkey;
|
2002-05-09 03:38:12 +00:00
|
|
|
|
|
2003-04-30 03:02:50 +00:00
|
|
|
|
subkey = calloc (1, sizeof *subkey);
|
|
|
|
|
if (!subkey)
|
2003-06-05 23:20:29 +00:00
|
|
|
|
return gpg_error_from_errno (errno);
|
2003-04-30 03:02:50 +00:00
|
|
|
|
subkey->keyid = subkey->_keyid;
|
|
|
|
|
subkey->_keyid[16] = '\0';
|
2000-12-19 10:07:32 +00:00
|
|
|
|
|
2003-04-30 03:02:50 +00:00
|
|
|
|
if (!key->subkeys)
|
|
|
|
|
key->subkeys = subkey;
|
|
|
|
|
if (key->_last_subkey)
|
|
|
|
|
key->_last_subkey->next = subkey;
|
|
|
|
|
key->_last_subkey = subkey;
|
2002-05-09 03:38:12 +00:00
|
|
|
|
|
2003-04-30 03:02:50 +00:00
|
|
|
|
*r_subkey = subkey;
|
|
|
|
|
return 0;
|
2001-01-30 11:01:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-05-09 03:38:12 +00:00
|
|
|
|
|
2002-12-04 16:28:34 +00:00
|
|
|
|
static char *
|
|
|
|
|
set_user_id_part (char *tail, const char *buf, size_t len)
|
|
|
|
|
{
|
|
|
|
|
while (len && (buf[len - 1] == ' ' || buf[len - 1] == '\t'))
|
|
|
|
|
len--;
|
|
|
|
|
for (; len; len--)
|
|
|
|
|
*tail++ = *buf++;
|
|
|
|
|
*tail++ = 0;
|
|
|
|
|
return tail;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
2003-04-30 03:02:50 +00:00
|
|
|
|
parse_user_id (char *src, char **name, char **email,
|
|
|
|
|
char **comment, char *tail)
|
2002-12-04 16:28:34 +00:00
|
|
|
|
{
|
|
|
|
|
const char *start = NULL;
|
|
|
|
|
int in_name = 0;
|
|
|
|
|
int in_email = 0;
|
|
|
|
|
int in_comment = 0;
|
2001-09-17 08:25:36 +00:00
|
|
|
|
|
2002-12-04 16:28:34 +00:00
|
|
|
|
while (*src)
|
|
|
|
|
{
|
|
|
|
|
if (in_email)
|
|
|
|
|
{
|
|
|
|
|
if (*src == '<')
|
|
|
|
|
/* Not legal but anyway. */
|
|
|
|
|
in_email++;
|
|
|
|
|
else if (*src == '>')
|
|
|
|
|
{
|
|
|
|
|
if (!--in_email && !*email)
|
|
|
|
|
{
|
|
|
|
|
*email = tail;
|
|
|
|
|
tail = set_user_id_part (tail, start, src - start);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (in_comment)
|
|
|
|
|
{
|
|
|
|
|
if (*src == '(')
|
|
|
|
|
in_comment++;
|
|
|
|
|
else if (*src == ')')
|
|
|
|
|
{
|
|
|
|
|
if (!--in_comment && !*comment)
|
|
|
|
|
{
|
|
|
|
|
*comment = tail;
|
|
|
|
|
tail = set_user_id_part (tail, start, src - start);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (*src == '<')
|
|
|
|
|
{
|
|
|
|
|
if (in_name)
|
|
|
|
|
{
|
|
|
|
|
if (!*name)
|
|
|
|
|
{
|
|
|
|
|
*name = tail;
|
|
|
|
|
tail = set_user_id_part (tail, start, src - start);
|
|
|
|
|
}
|
|
|
|
|
in_name = 0;
|
|
|
|
|
}
|
|
|
|
|
in_email = 1;
|
|
|
|
|
start = src + 1;
|
|
|
|
|
}
|
|
|
|
|
else if (*src == '(')
|
|
|
|
|
{
|
|
|
|
|
if (in_name)
|
|
|
|
|
{
|
|
|
|
|
if (!*name)
|
|
|
|
|
{
|
|
|
|
|
*name = tail;
|
|
|
|
|
tail = set_user_id_part (tail, start, src - start);
|
|
|
|
|
}
|
|
|
|
|
in_name = 0;
|
|
|
|
|
}
|
|
|
|
|
in_comment = 1;
|
|
|
|
|
start = src + 1;
|
|
|
|
|
}
|
|
|
|
|
else if (!in_name && *src != ' ' && *src != '\t')
|
|
|
|
|
{
|
|
|
|
|
in_name = 1;
|
|
|
|
|
start = src;
|
|
|
|
|
}
|
|
|
|
|
src++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (in_name)
|
|
|
|
|
{
|
|
|
|
|
if (!*name)
|
|
|
|
|
{
|
|
|
|
|
*name = tail;
|
|
|
|
|
tail = set_user_id_part (tail, start, src - start);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Let unused parts point to an EOS. */
|
|
|
|
|
tail--;
|
|
|
|
|
if (!*name)
|
|
|
|
|
*name = tail;
|
|
|
|
|
if (!*email)
|
|
|
|
|
*email = tail;
|
|
|
|
|
if (!*comment)
|
|
|
|
|
*comment = tail;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
2003-04-30 03:02:50 +00:00
|
|
|
|
parse_x509_user_id (char *src, char **name, char **email,
|
|
|
|
|
char **comment, char *tail)
|
2002-12-04 16:28:34 +00:00
|
|
|
|
{
|
|
|
|
|
if (*src == '<' && src[strlen (src) - 1] == '>')
|
|
|
|
|
*email = src;
|
|
|
|
|
|
|
|
|
|
/* Let unused parts point to an EOS. */
|
|
|
|
|
tail--;
|
|
|
|
|
if (!*name)
|
|
|
|
|
*name = tail;
|
|
|
|
|
if (!*email)
|
|
|
|
|
*email = tail;
|
|
|
|
|
if (!*comment)
|
|
|
|
|
*comment = tail;
|
|
|
|
|
}
|
|
|
|
|
|
2003-04-30 03:02:50 +00:00
|
|
|
|
|
|
|
|
|
/* Take a name from the --with-colon listing, remove certain escape
|
|
|
|
|
sequences sequences and put it into the list of UIDs. */
|
2003-05-18 20:45:24 +00:00
|
|
|
|
gpgme_error_t
|
|
|
|
|
_gpgme_key_append_name (gpgme_key_t key, char *src)
|
2003-04-30 03:02:50 +00:00
|
|
|
|
{
|
2003-05-18 20:45:24 +00:00
|
|
|
|
gpgme_user_id_t uid;
|
2003-04-30 03:02:50 +00:00
|
|
|
|
char *dst;
|
|
|
|
|
int src_len = strlen (src);
|
|
|
|
|
|
|
|
|
|
assert (key);
|
|
|
|
|
/* We can malloc a buffer of the same length, because the converted
|
|
|
|
|
string will never be larger. Actually we allocate it twice the
|
|
|
|
|
size, so that we are able to store the parsed stuff there too. */
|
|
|
|
|
uid = malloc (sizeof (*uid) + 2 * src_len + 3);
|
|
|
|
|
if (!uid)
|
2003-06-05 23:20:29 +00:00
|
|
|
|
return gpg_error_from_errno (errno);
|
2003-04-30 03:02:50 +00:00
|
|
|
|
memset (uid, 0, sizeof *uid);
|
|
|
|
|
|
|
|
|
|
uid->uid = ((char *) uid) + sizeof (*uid);
|
|
|
|
|
dst = uid->uid;
|
|
|
|
|
_gpgme_decode_c_string (src, &dst, src_len + 1);
|
|
|
|
|
|
2004-06-23 21:15:21 +00:00
|
|
|
|
dst += strlen (dst) + 1;
|
2003-04-30 03:02:50 +00:00
|
|
|
|
if (key->protocol == GPGME_PROTOCOL_CMS)
|
2003-05-04 22:28:33 +00:00
|
|
|
|
parse_x509_user_id (uid->uid, &uid->name, &uid->email,
|
2003-04-30 03:02:50 +00:00
|
|
|
|
&uid->comment, dst);
|
|
|
|
|
else
|
2003-05-04 22:28:33 +00:00
|
|
|
|
parse_user_id (uid->uid, &uid->name, &uid->email,
|
2003-04-30 03:02:50 +00:00
|
|
|
|
&uid->comment, dst);
|
|
|
|
|
|
|
|
|
|
if (!key->uids)
|
|
|
|
|
key->uids = uid;
|
|
|
|
|
if (key->_last_uid)
|
|
|
|
|
key->_last_uid->next = uid;
|
|
|
|
|
key->_last_uid = uid;
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2003-05-18 20:45:24 +00:00
|
|
|
|
gpgme_key_sig_t
|
|
|
|
|
_gpgme_key_add_sig (gpgme_key_t key, char *src)
|
2002-12-04 16:28:34 +00:00
|
|
|
|
{
|
|
|
|
|
int src_len = src ? strlen (src) : 0;
|
2003-05-18 20:45:24 +00:00
|
|
|
|
gpgme_user_id_t uid;
|
|
|
|
|
gpgme_key_sig_t sig;
|
2002-12-04 16:28:34 +00:00
|
|
|
|
|
|
|
|
|
assert (key); /* XXX */
|
|
|
|
|
|
2003-04-30 03:02:50 +00:00
|
|
|
|
uid = key->_last_uid;
|
2002-12-04 16:28:34 +00:00
|
|
|
|
assert (uid); /* XXX */
|
|
|
|
|
|
|
|
|
|
/* We can malloc a buffer of the same length, because the converted
|
2008-03-06 14:54:11 +00:00
|
|
|
|
string will never be larger. Actually we allocate it twice the
|
2002-12-04 16:28:34 +00:00
|
|
|
|
size, so that we are able to store the parsed stuff there too. */
|
2004-06-23 21:15:21 +00:00
|
|
|
|
sig = malloc (sizeof (*sig) + 2 * src_len + 3);
|
2003-04-30 03:02:50 +00:00
|
|
|
|
if (!sig)
|
2002-12-04 16:28:34 +00:00
|
|
|
|
return NULL;
|
2004-06-23 21:15:21 +00:00
|
|
|
|
memset (sig, 0, sizeof *sig);
|
|
|
|
|
|
2003-04-30 03:02:50 +00:00
|
|
|
|
sig->keyid = sig->_keyid;
|
|
|
|
|
sig->_keyid[16] = '\0';
|
2003-05-04 16:45:45 +00:00
|
|
|
|
sig->uid = ((char *) sig) + sizeof (*sig);
|
2002-12-04 16:28:34 +00:00
|
|
|
|
|
|
|
|
|
if (src)
|
|
|
|
|
{
|
2003-04-30 03:02:50 +00:00
|
|
|
|
char *dst = sig->uid;
|
2002-12-04 16:28:34 +00:00
|
|
|
|
_gpgme_decode_c_string (src, &dst, src_len + 1);
|
2004-06-23 21:15:21 +00:00
|
|
|
|
dst += strlen (dst) + 1;
|
2003-04-30 03:02:50 +00:00
|
|
|
|
if (key->protocol == GPGME_PROTOCOL_CMS)
|
2003-05-04 22:28:33 +00:00
|
|
|
|
parse_x509_user_id (sig->uid, &sig->name, &sig->email,
|
2003-04-30 03:02:50 +00:00
|
|
|
|
&sig->comment, dst);
|
2002-12-04 16:28:34 +00:00
|
|
|
|
else
|
2003-05-04 22:28:33 +00:00
|
|
|
|
parse_user_id (sig->uid, &sig->name, &sig->email,
|
2003-04-30 03:02:50 +00:00
|
|
|
|
&sig->comment, dst);
|
2002-12-04 16:28:34 +00:00
|
|
|
|
}
|
2008-03-06 14:54:11 +00:00
|
|
|
|
else
|
|
|
|
|
sig->uid = '\0';
|
2002-12-04 16:28:34 +00:00
|
|
|
|
|
2003-04-30 03:02:50 +00:00
|
|
|
|
if (!uid->signatures)
|
|
|
|
|
uid->signatures = sig;
|
|
|
|
|
if (uid->_last_keysig)
|
|
|
|
|
uid->_last_keysig->next = sig;
|
|
|
|
|
uid->_last_keysig = sig;
|
2002-12-04 16:28:34 +00:00
|
|
|
|
|
2003-04-30 03:02:50 +00:00
|
|
|
|
return sig;
|
2002-12-04 16:28:34 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2003-04-30 03:02:50 +00:00
|
|
|
|
/* Acquire a reference to KEY. */
|
2000-11-10 17:50:24 +00:00
|
|
|
|
void
|
2003-05-18 20:45:24 +00:00
|
|
|
|
gpgme_key_ref (gpgme_key_t key)
|
2000-11-10 17:50:24 +00:00
|
|
|
|
{
|
2003-04-30 03:02:50 +00:00
|
|
|
|
LOCK (key_ref_lock);
|
|
|
|
|
key->_refs++;
|
|
|
|
|
UNLOCK (key_ref_lock);
|
|
|
|
|
}
|
2000-11-10 17:50:24 +00:00
|
|
|
|
|
2003-04-30 03:02:50 +00:00
|
|
|
|
|
2003-05-28 01:18:51 +00:00
|
|
|
|
/* gpgme_key_unref releases the key object. Note, that this function
|
2003-04-30 03:02:50 +00:00
|
|
|
|
may not do an actual release if there are other shallow copies of
|
|
|
|
|
the objects. You have to call this function for every newly
|
|
|
|
|
created key object as well as for every gpgme_key_ref() done on the
|
|
|
|
|
key object. */
|
|
|
|
|
void
|
2003-05-18 20:45:24 +00:00
|
|
|
|
gpgme_key_unref (gpgme_key_t key)
|
2003-04-30 03:02:50 +00:00
|
|
|
|
{
|
2003-05-18 20:45:24 +00:00
|
|
|
|
gpgme_user_id_t uid;
|
|
|
|
|
gpgme_subkey_t subkey;
|
2000-11-10 17:50:24 +00:00
|
|
|
|
|
2004-04-21 18:14:12 +00:00
|
|
|
|
if (!key)
|
|
|
|
|
return;
|
|
|
|
|
|
2002-05-09 03:38:12 +00:00
|
|
|
|
LOCK (key_ref_lock);
|
2003-04-30 03:02:50 +00:00
|
|
|
|
assert (key->_refs > 0);
|
|
|
|
|
if (--key->_refs)
|
2002-05-09 03:38:12 +00:00
|
|
|
|
{
|
|
|
|
|
UNLOCK (key_ref_lock);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
UNLOCK (key_ref_lock);
|
2001-01-22 20:22:41 +00:00
|
|
|
|
|
2003-04-30 03:02:50 +00:00
|
|
|
|
subkey = key->subkeys;
|
|
|
|
|
while (subkey)
|
2002-05-09 03:38:12 +00:00
|
|
|
|
{
|
2003-05-18 20:45:24 +00:00
|
|
|
|
gpgme_subkey_t next = subkey->next;
|
2003-04-30 03:02:50 +00:00
|
|
|
|
if (subkey->fpr)
|
|
|
|
|
free (subkey->fpr);
|
2009-02-04 09:51:43 +00:00
|
|
|
|
if (subkey->card_number)
|
|
|
|
|
free (subkey->card_number);
|
2003-04-30 03:02:50 +00:00
|
|
|
|
free (subkey);
|
|
|
|
|
subkey = next;
|
2000-12-19 10:07:32 +00:00
|
|
|
|
}
|
2003-04-30 03:02:50 +00:00
|
|
|
|
|
|
|
|
|
uid = key->uids;
|
|
|
|
|
while (uid)
|
2002-05-09 03:38:12 +00:00
|
|
|
|
{
|
2003-05-18 20:45:24 +00:00
|
|
|
|
gpgme_user_id_t next_uid = uid->next;
|
|
|
|
|
gpgme_key_sig_t keysig = uid->signatures;
|
2003-04-30 03:02:50 +00:00
|
|
|
|
|
|
|
|
|
while (keysig)
|
|
|
|
|
{
|
2005-10-02 14:39:31 +00:00
|
|
|
|
gpgme_key_sig_t next_keysig = keysig->next;
|
|
|
|
|
gpgme_sig_notation_t notation = keysig->notations;
|
|
|
|
|
|
|
|
|
|
while (notation)
|
|
|
|
|
{
|
|
|
|
|
gpgme_sig_notation_t next_notation = notation->next;
|
|
|
|
|
|
|
|
|
|
_gpgme_sig_notation_free (notation);
|
|
|
|
|
notation = next_notation;
|
|
|
|
|
}
|
|
|
|
|
|
2003-04-30 03:02:50 +00:00
|
|
|
|
free (keysig);
|
2005-10-02 14:39:31 +00:00
|
|
|
|
keysig = next_keysig;
|
2002-08-14 14:01:09 +00:00
|
|
|
|
}
|
2003-04-30 03:02:50 +00:00
|
|
|
|
free (uid);
|
|
|
|
|
uid = next_uid;
|
2000-11-10 17:50:24 +00:00
|
|
|
|
}
|
2003-04-30 03:02:50 +00:00
|
|
|
|
|
|
|
|
|
if (key->issuer_serial)
|
|
|
|
|
free (key->issuer_serial);
|
|
|
|
|
if (key->issuer_name)
|
|
|
|
|
free (key->issuer_name);
|
2000-11-10 17:50:24 +00:00
|
|
|
|
|
2003-04-30 03:02:50 +00:00
|
|
|
|
if (key->chain_id)
|
|
|
|
|
free (key->chain_id);
|
2002-12-04 16:28:34 +00:00
|
|
|
|
|
2003-04-30 03:02:50 +00:00
|
|
|
|
free (key);
|
2001-01-22 20:22:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-12-04 16:28:34 +00:00
|
|
|
|
|
2003-04-30 03:02:50 +00:00
|
|
|
|
/* Compatibility interfaces. */
|
2002-12-04 16:28:34 +00:00
|
|
|
|
|
2003-04-30 03:02:50 +00:00
|
|
|
|
void
|
2003-05-18 20:45:24 +00:00
|
|
|
|
gpgme_key_release (gpgme_key_t key)
|
2000-11-15 21:36:48 +00:00
|
|
|
|
{
|
2003-04-30 03:02:50 +00:00
|
|
|
|
gpgme_key_unref (key);
|
2000-11-15 21:36:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-12-04 16:28:34 +00:00
|
|
|
|
|
2003-04-30 03:02:50 +00:00
|
|
|
|
static const char *
|
|
|
|
|
otrust_to_string (int otrust)
|
2000-11-15 21:36:48 +00:00
|
|
|
|
{
|
2003-04-30 03:02:50 +00:00
|
|
|
|
switch (otrust)
|
|
|
|
|
{
|
|
|
|
|
case GPGME_VALIDITY_NEVER:
|
|
|
|
|
return "n";
|
2002-12-04 16:28:34 +00:00
|
|
|
|
|
2003-04-30 03:02:50 +00:00
|
|
|
|
case GPGME_VALIDITY_MARGINAL:
|
|
|
|
|
return "m";
|
2000-11-15 21:36:48 +00:00
|
|
|
|
|
2003-04-30 03:02:50 +00:00
|
|
|
|
case GPGME_VALIDITY_FULL:
|
|
|
|
|
return "f";
|
2002-12-04 16:28:34 +00:00
|
|
|
|
|
2003-04-30 03:02:50 +00:00
|
|
|
|
case GPGME_VALIDITY_ULTIMATE:
|
|
|
|
|
return "u";
|
2000-11-15 21:36:48 +00:00
|
|
|
|
|
2003-04-30 03:02:50 +00:00
|
|
|
|
default:
|
|
|
|
|
return "?";
|
|
|
|
|
}
|
2000-11-15 21:36:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
2002-12-04 16:28:34 +00:00
|
|
|
|
|
2003-04-30 03:02:50 +00:00
|
|
|
|
static const char *
|
|
|
|
|
validity_to_string (int validity)
|
2001-03-13 20:17:22 +00:00
|
|
|
|
{
|
2003-04-30 03:02:50 +00:00
|
|
|
|
switch (validity)
|
|
|
|
|
{
|
|
|
|
|
case GPGME_VALIDITY_UNDEFINED:
|
|
|
|
|
return "q";
|
2002-12-04 16:28:34 +00:00
|
|
|
|
|
2003-04-30 03:02:50 +00:00
|
|
|
|
case GPGME_VALIDITY_NEVER:
|
|
|
|
|
return "n";
|
2002-12-04 16:28:34 +00:00
|
|
|
|
|
2003-04-30 03:02:50 +00:00
|
|
|
|
case GPGME_VALIDITY_MARGINAL:
|
|
|
|
|
return "m";
|
2001-03-13 20:17:22 +00:00
|
|
|
|
|
2003-04-30 03:02:50 +00:00
|
|
|
|
case GPGME_VALIDITY_FULL:
|
|
|
|
|
return "f";
|
2001-03-13 20:17:22 +00:00
|
|
|
|
|
2003-04-30 03:02:50 +00:00
|
|
|
|
case GPGME_VALIDITY_ULTIMATE:
|
|
|
|
|
return "u";
|
2002-05-09 03:38:12 +00:00
|
|
|
|
|
2003-04-30 03:02:50 +00:00
|
|
|
|
case GPGME_VALIDITY_UNKNOWN:
|
|
|
|
|
default:
|
|
|
|
|
return "?";
|
2000-12-19 10:07:32 +00:00
|
|
|
|
}
|
2000-11-15 21:36:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2001-03-15 13:09:41 +00:00
|
|
|
|
static const char *
|
2003-05-18 20:45:24 +00:00
|
|
|
|
capabilities_to_string (gpgme_subkey_t subkey)
|
2001-03-15 13:09:41 +00:00
|
|
|
|
{
|
2002-05-09 03:38:12 +00:00
|
|
|
|
static const char *const strings[8] =
|
|
|
|
|
{
|
|
|
|
|
"",
|
|
|
|
|
"c",
|
|
|
|
|
"s",
|
|
|
|
|
"sc",
|
|
|
|
|
"e",
|
|
|
|
|
"ec",
|
|
|
|
|
"es",
|
|
|
|
|
"esc"
|
2001-03-15 13:09:41 +00:00
|
|
|
|
};
|
2003-04-30 03:02:50 +00:00
|
|
|
|
return strings[(!!subkey->can_encrypt << 2)
|
|
|
|
|
| (!!subkey->can_sign << 1)
|
|
|
|
|
| (!!subkey->can_certify)];
|
2001-03-15 13:09:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-09-17 08:25:36 +00:00
|
|
|
|
|
2003-04-30 03:02:50 +00:00
|
|
|
|
/* Return the value of the attribute WHAT of ITEM, which has to be
|
|
|
|
|
representable by a string. */
|
2001-01-08 20:40:25 +00:00
|
|
|
|
const char *
|
2003-05-18 20:45:24 +00:00
|
|
|
|
gpgme_key_get_string_attr (gpgme_key_t key, _gpgme_attr_t what,
|
2002-05-09 03:38:12 +00:00
|
|
|
|
const void *reserved, int idx)
|
2001-01-08 20:40:25 +00:00
|
|
|
|
{
|
2003-05-18 20:45:24 +00:00
|
|
|
|
gpgme_subkey_t subkey;
|
|
|
|
|
gpgme_user_id_t uid;
|
2002-12-23 22:31:03 +00:00
|
|
|
|
int i;
|
2002-05-09 03:38:12 +00:00
|
|
|
|
|
2002-12-23 22:31:03 +00:00
|
|
|
|
if (!key || reserved || idx < 0)
|
2002-05-09 03:38:12 +00:00
|
|
|
|
return NULL;
|
|
|
|
|
|
2002-12-23 22:31:03 +00:00
|
|
|
|
/* Select IDXth subkey. */
|
2003-04-30 03:02:50 +00:00
|
|
|
|
subkey = key->subkeys;
|
2002-12-23 22:31:03 +00:00
|
|
|
|
for (i = 0; i < idx; i++)
|
|
|
|
|
{
|
|
|
|
|
subkey = subkey->next;
|
|
|
|
|
if (!subkey)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Select the IDXth user ID. */
|
|
|
|
|
uid = key->uids;
|
|
|
|
|
for (i = 0; i < idx; i++)
|
|
|
|
|
{
|
|
|
|
|
uid = uid->next;
|
|
|
|
|
if (!uid)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2002-05-09 03:38:12 +00:00
|
|
|
|
switch (what)
|
|
|
|
|
{
|
|
|
|
|
case GPGME_ATTR_KEYID:
|
2002-12-23 22:31:03 +00:00
|
|
|
|
return subkey ? subkey->keyid : NULL;
|
|
|
|
|
|
2002-05-09 03:38:12 +00:00
|
|
|
|
case GPGME_ATTR_FPR:
|
2003-04-30 03:02:50 +00:00
|
|
|
|
return subkey ? subkey->fpr : NULL;
|
2002-12-23 22:31:03 +00:00
|
|
|
|
|
2002-05-09 03:38:12 +00:00
|
|
|
|
case GPGME_ATTR_ALGO:
|
2003-04-30 03:02:50 +00:00
|
|
|
|
return subkey ? gpgme_pubkey_algo_name (subkey->pubkey_algo) : NULL;
|
2002-12-23 22:31:03 +00:00
|
|
|
|
|
2002-08-14 14:01:09 +00:00
|
|
|
|
case GPGME_ATTR_TYPE:
|
2003-04-30 03:02:50 +00:00
|
|
|
|
return key->protocol == GPGME_PROTOCOL_CMS ? "X.509" : "PGP";
|
2002-12-23 22:31:03 +00:00
|
|
|
|
|
|
|
|
|
case GPGME_ATTR_OTRUST:
|
2003-04-30 03:02:50 +00:00
|
|
|
|
return otrust_to_string (key->owner_trust);
|
2002-12-23 22:31:03 +00:00
|
|
|
|
|
2002-05-09 03:38:12 +00:00
|
|
|
|
case GPGME_ATTR_USERID:
|
2003-04-30 03:02:50 +00:00
|
|
|
|
return uid ? uid->uid : NULL;
|
2002-12-23 22:31:03 +00:00
|
|
|
|
|
2002-05-09 03:38:12 +00:00
|
|
|
|
case GPGME_ATTR_NAME:
|
2003-04-30 03:02:50 +00:00
|
|
|
|
return uid ? uid->name : NULL;
|
2002-12-23 22:31:03 +00:00
|
|
|
|
|
2002-05-09 03:38:12 +00:00
|
|
|
|
case GPGME_ATTR_EMAIL:
|
2003-04-30 03:02:50 +00:00
|
|
|
|
return uid ? uid->email : NULL;
|
2002-12-23 22:31:03 +00:00
|
|
|
|
|
2002-05-09 03:38:12 +00:00
|
|
|
|
case GPGME_ATTR_COMMENT:
|
2003-04-30 03:02:50 +00:00
|
|
|
|
return uid ? uid->comment : NULL;
|
2002-12-23 22:31:03 +00:00
|
|
|
|
|
2002-05-09 03:38:12 +00:00
|
|
|
|
case GPGME_ATTR_VALIDITY:
|
2003-04-25 10:59:52 +00:00
|
|
|
|
return uid ? validity_to_string (uid->validity) : NULL;
|
2002-12-23 22:31:03 +00:00
|
|
|
|
|
2002-05-09 03:38:12 +00:00
|
|
|
|
case GPGME_ATTR_KEY_CAPS:
|
2002-12-23 23:44:22 +00:00
|
|
|
|
return subkey ? capabilities_to_string (subkey) : NULL;
|
2002-12-23 22:31:03 +00:00
|
|
|
|
|
2002-05-09 03:38:12 +00:00
|
|
|
|
case GPGME_ATTR_SERIAL:
|
2002-12-23 22:31:03 +00:00
|
|
|
|
return key->issuer_serial;
|
|
|
|
|
|
2002-05-09 03:38:12 +00:00
|
|
|
|
case GPGME_ATTR_ISSUER:
|
2002-12-23 22:31:03 +00:00
|
|
|
|
return idx ? NULL : key->issuer_name;
|
|
|
|
|
|
2002-05-09 03:38:12 +00:00
|
|
|
|
case GPGME_ATTR_CHAINID:
|
2003-04-30 03:02:50 +00:00
|
|
|
|
return key->chain_id;
|
2002-12-23 22:31:03 +00:00
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
return NULL;
|
2001-01-08 20:40:25 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
unsigned long
|
2003-05-18 20:45:24 +00:00
|
|
|
|
gpgme_key_get_ulong_attr (gpgme_key_t key, _gpgme_attr_t what,
|
2002-05-09 03:38:12 +00:00
|
|
|
|
const void *reserved, int idx)
|
2001-01-08 20:40:25 +00:00
|
|
|
|
{
|
2003-05-18 20:45:24 +00:00
|
|
|
|
gpgme_subkey_t subkey;
|
|
|
|
|
gpgme_user_id_t uid;
|
2002-12-23 22:31:03 +00:00
|
|
|
|
int i;
|
2002-05-09 03:38:12 +00:00
|
|
|
|
|
2002-12-23 22:31:03 +00:00
|
|
|
|
if (!key || reserved || idx < 0)
|
2002-05-09 03:38:12 +00:00
|
|
|
|
return 0;
|
|
|
|
|
|
2002-12-23 22:31:03 +00:00
|
|
|
|
/* Select IDXth subkey. */
|
2003-04-30 03:02:50 +00:00
|
|
|
|
subkey = key->subkeys;
|
2002-12-23 22:31:03 +00:00
|
|
|
|
for (i = 0; i < idx; i++)
|
|
|
|
|
{
|
|
|
|
|
subkey = subkey->next;
|
|
|
|
|
if (!subkey)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Select the IDXth user ID. */
|
|
|
|
|
uid = key->uids;
|
|
|
|
|
for (i = 0; i < idx; i++)
|
|
|
|
|
{
|
|
|
|
|
uid = uid->next;
|
|
|
|
|
if (!uid)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2002-05-09 03:38:12 +00:00
|
|
|
|
switch (what)
|
|
|
|
|
{
|
2002-12-23 22:31:03 +00:00
|
|
|
|
case GPGME_ATTR_ALGO:
|
2003-04-30 03:02:50 +00:00
|
|
|
|
return subkey ? (unsigned long) subkey->pubkey_algo : 0;
|
2002-12-23 22:31:03 +00:00
|
|
|
|
|
|
|
|
|
case GPGME_ATTR_LEN:
|
2003-04-30 03:02:50 +00:00
|
|
|
|
return subkey ? (unsigned long) subkey->length : 0;
|
2002-12-23 22:31:03 +00:00
|
|
|
|
|
2002-08-14 14:01:09 +00:00
|
|
|
|
case GPGME_ATTR_TYPE:
|
2003-04-30 03:02:50 +00:00
|
|
|
|
return key->protocol == GPGME_PROTOCOL_CMS ? 1 : 0;
|
2002-12-23 22:31:03 +00:00
|
|
|
|
|
2003-04-30 03:02:50 +00:00
|
|
|
|
case GPGME_ATTR_CREATED:
|
2002-12-23 22:31:03 +00:00
|
|
|
|
return (subkey && subkey->timestamp >= 0)
|
|
|
|
|
? (unsigned long) subkey->timestamp : 0;
|
|
|
|
|
|
2002-05-09 03:38:12 +00:00
|
|
|
|
case GPGME_ATTR_EXPIRE:
|
2003-04-30 03:02:50 +00:00
|
|
|
|
return (subkey && subkey->expires >= 0)
|
|
|
|
|
? (unsigned long) subkey->expires : 0;
|
2002-12-23 22:31:03 +00:00
|
|
|
|
|
2002-05-09 03:38:12 +00:00
|
|
|
|
case GPGME_ATTR_VALIDITY:
|
2002-12-23 22:31:03 +00:00
|
|
|
|
return uid ? uid->validity : 0;
|
|
|
|
|
|
2002-05-10 10:42:45 +00:00
|
|
|
|
case GPGME_ATTR_OTRUST:
|
2003-04-30 03:02:50 +00:00
|
|
|
|
return key->owner_trust;
|
2002-12-23 22:31:03 +00:00
|
|
|
|
|
2002-05-09 03:38:12 +00:00
|
|
|
|
case GPGME_ATTR_IS_SECRET:
|
2002-12-23 22:31:03 +00:00
|
|
|
|
return !!key->secret;
|
|
|
|
|
|
2002-05-09 03:38:12 +00:00
|
|
|
|
case GPGME_ATTR_KEY_REVOKED:
|
2003-04-30 03:02:50 +00:00
|
|
|
|
return subkey ? subkey->revoked : 0;
|
2002-12-23 22:31:03 +00:00
|
|
|
|
|
2002-05-09 03:38:12 +00:00
|
|
|
|
case GPGME_ATTR_KEY_INVALID:
|
2003-04-30 03:02:50 +00:00
|
|
|
|
return subkey ? subkey->invalid : 0;
|
2002-12-23 22:31:03 +00:00
|
|
|
|
|
2002-05-09 03:38:12 +00:00
|
|
|
|
case GPGME_ATTR_KEY_EXPIRED:
|
2003-04-30 03:02:50 +00:00
|
|
|
|
return subkey ? subkey->expired : 0;
|
2002-12-23 22:31:03 +00:00
|
|
|
|
|
2002-05-09 03:38:12 +00:00
|
|
|
|
case GPGME_ATTR_KEY_DISABLED:
|
2003-04-30 03:02:50 +00:00
|
|
|
|
return subkey ? subkey->disabled : 0;
|
2002-12-23 22:31:03 +00:00
|
|
|
|
|
2002-05-09 03:38:12 +00:00
|
|
|
|
case GPGME_ATTR_UID_REVOKED:
|
2002-12-23 22:31:03 +00:00
|
|
|
|
return uid ? uid->revoked : 0;
|
|
|
|
|
|
2002-05-09 03:38:12 +00:00
|
|
|
|
case GPGME_ATTR_UID_INVALID:
|
2002-12-23 22:31:03 +00:00
|
|
|
|
return uid ? uid->invalid : 0;
|
|
|
|
|
|
2002-05-09 03:38:12 +00:00
|
|
|
|
case GPGME_ATTR_CAN_ENCRYPT:
|
2003-04-30 03:02:50 +00:00
|
|
|
|
return key->can_encrypt;
|
2002-12-23 22:31:03 +00:00
|
|
|
|
|
2002-05-09 03:38:12 +00:00
|
|
|
|
case GPGME_ATTR_CAN_SIGN:
|
2003-04-30 03:02:50 +00:00
|
|
|
|
return key->can_sign;
|
2002-12-23 22:31:03 +00:00
|
|
|
|
|
2002-05-09 03:38:12 +00:00
|
|
|
|
case GPGME_ATTR_CAN_CERTIFY:
|
2003-04-30 03:02:50 +00:00
|
|
|
|
return key->can_certify;
|
2002-12-23 22:31:03 +00:00
|
|
|
|
|
2002-05-09 03:38:12 +00:00
|
|
|
|
default:
|
2002-12-23 22:31:03 +00:00
|
|
|
|
return 0;
|
2001-01-08 20:40:25 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2002-08-14 14:01:09 +00:00
|
|
|
|
|
2002-12-04 16:28:34 +00:00
|
|
|
|
|
2003-05-18 20:45:24 +00:00
|
|
|
|
static gpgme_key_sig_t
|
|
|
|
|
get_keysig (gpgme_key_t key, int uid_idx, int idx)
|
2002-12-04 16:28:34 +00:00
|
|
|
|
{
|
2003-05-18 20:45:24 +00:00
|
|
|
|
gpgme_user_id_t uid;
|
|
|
|
|
gpgme_key_sig_t sig;
|
2002-12-04 16:28:34 +00:00
|
|
|
|
|
|
|
|
|
if (!key || uid_idx < 0 || idx < 0)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
uid = key->uids;
|
|
|
|
|
while (uid && uid_idx > 0)
|
|
|
|
|
{
|
|
|
|
|
uid = uid->next;
|
|
|
|
|
uid_idx--;
|
|
|
|
|
}
|
|
|
|
|
if (!uid)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
2003-04-30 03:02:50 +00:00
|
|
|
|
sig = uid->signatures;
|
|
|
|
|
while (sig && idx > 0)
|
2002-12-04 16:28:34 +00:00
|
|
|
|
{
|
2003-04-30 03:02:50 +00:00
|
|
|
|
sig = sig->next;
|
2002-12-04 16:28:34 +00:00
|
|
|
|
idx--;
|
|
|
|
|
}
|
2003-04-30 03:02:50 +00:00
|
|
|
|
return sig;
|
2002-12-04 16:28:34 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const char *
|
2003-05-18 21:08:43 +00:00
|
|
|
|
gpgme_key_sig_get_string_attr (gpgme_key_t key, int uid_idx,
|
|
|
|
|
_gpgme_attr_t what,
|
2002-12-04 16:28:34 +00:00
|
|
|
|
const void *reserved, int idx)
|
|
|
|
|
{
|
2003-05-18 20:45:24 +00:00
|
|
|
|
gpgme_key_sig_t certsig = get_keysig (key, uid_idx, idx);
|
2002-12-04 16:28:34 +00:00
|
|
|
|
|
|
|
|
|
if (!certsig || reserved)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
switch (what)
|
|
|
|
|
{
|
|
|
|
|
case GPGME_ATTR_KEYID:
|
|
|
|
|
return certsig->keyid;
|
|
|
|
|
|
|
|
|
|
case GPGME_ATTR_ALGO:
|
2003-04-30 03:02:50 +00:00
|
|
|
|
return gpgme_pubkey_algo_name (certsig->pubkey_algo);
|
2002-12-04 16:28:34 +00:00
|
|
|
|
|
2003-04-30 03:02:50 +00:00
|
|
|
|
case GPGME_ATTR_USERID:
|
|
|
|
|
return certsig->uid;
|
2002-12-04 16:28:34 +00:00
|
|
|
|
|
|
|
|
|
case GPGME_ATTR_NAME:
|
2003-04-30 03:02:50 +00:00
|
|
|
|
return certsig->name;
|
2002-12-04 16:28:34 +00:00
|
|
|
|
|
|
|
|
|
case GPGME_ATTR_EMAIL:
|
2003-04-30 03:02:50 +00:00
|
|
|
|
return certsig->email;
|
2002-12-04 16:28:34 +00:00
|
|
|
|
|
|
|
|
|
case GPGME_ATTR_COMMENT:
|
2003-04-30 03:02:50 +00:00
|
|
|
|
return certsig->comment;
|
2002-12-04 16:28:34 +00:00
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
unsigned long
|
2003-05-18 20:45:24 +00:00
|
|
|
|
gpgme_key_sig_get_ulong_attr (gpgme_key_t key, int uid_idx, _gpgme_attr_t what,
|
2002-12-04 16:28:34 +00:00
|
|
|
|
const void *reserved, int idx)
|
|
|
|
|
{
|
2003-05-18 20:45:24 +00:00
|
|
|
|
gpgme_key_sig_t certsig = get_keysig (key, uid_idx, idx);
|
2002-12-04 16:28:34 +00:00
|
|
|
|
|
|
|
|
|
if (!certsig || reserved)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
switch (what)
|
|
|
|
|
{
|
|
|
|
|
case GPGME_ATTR_ALGO:
|
2003-04-30 03:02:50 +00:00
|
|
|
|
return (unsigned long) certsig->pubkey_algo;
|
2002-12-04 16:28:34 +00:00
|
|
|
|
|
|
|
|
|
case GPGME_ATTR_CREATED:
|
|
|
|
|
return certsig->timestamp < 0 ? 0L : (unsigned long) certsig->timestamp;
|
|
|
|
|
|
|
|
|
|
case GPGME_ATTR_EXPIRE:
|
2003-04-30 03:02:50 +00:00
|
|
|
|
return certsig->expires < 0 ? 0L : (unsigned long) certsig->expires;
|
2002-12-04 16:28:34 +00:00
|
|
|
|
|
|
|
|
|
case GPGME_ATTR_KEY_REVOKED:
|
2003-04-30 03:02:50 +00:00
|
|
|
|
return certsig->revoked;
|
2002-12-04 16:28:34 +00:00
|
|
|
|
|
|
|
|
|
case GPGME_ATTR_KEY_INVALID:
|
2003-04-30 03:02:50 +00:00
|
|
|
|
return certsig->invalid;
|
2002-12-04 16:28:34 +00:00
|
|
|
|
|
|
|
|
|
case GPGME_ATTR_KEY_EXPIRED:
|
2003-04-30 03:02:50 +00:00
|
|
|
|
return certsig->expired;
|
2002-12-04 16:28:34 +00:00
|
|
|
|
|
|
|
|
|
case GPGME_ATTR_SIG_CLASS:
|
2003-12-25 14:38:40 +00:00
|
|
|
|
return certsig->sig_class;
|
2002-12-04 16:28:34 +00:00
|
|
|
|
|
|
|
|
|
case GPGME_ATTR_SIG_STATUS:
|
2003-04-30 03:02:50 +00:00
|
|
|
|
return certsig->status;
|
2002-12-04 16:28:34 +00:00
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|