2002-12-04 Marcus Brinkmann <marcus@g10code.de>
* gpgme.h: Add prototype for gpgme_get_key. * key.c (gpgme_get_key): New function. * verify.c (gpgme_get_sig_key): Rewrite using gpgme_get_key. * gpgme.h: Add prototypes for new interfaces gpgme_key_sig_get_string_attr and gpgme_key_get_ulong_attr. (enum GpgmeAttr): New attribute GPGME_ATTR_SIG_CLASS. * gpgme.c (gpgme_set_keylist_mode): Allow GPGME_KEYLIST_MODE_SIGS. * key.h (struct certsig_s): New members ALGO, NAME_PART, EMAIL_PART, COMMENT_PART, NAME, SIG_STAT and SIG_CLASS. * conversion.c (_gpgme_decode_c_string): Add new parameter LEN. Use that to determine if allocation is desired or not. * util.h: Adjust prototype of _gpgme_decode_c_string. * keylist.c (keylist_colon_handler): Adjust caller of _gpgme_decode_c_string. * key.h (struct gpgme_key_s): New member last_uid. * key.c (_gpgme_key_append_name): Rewritten using _gpgme_decode_c_string and the last_uid pointer. (my_isdigit): Macro removed. (ALLOC_CHUNK): Likewise. * keylist.c (set_userid_flags): Use last_uid member of KEY. * context.h (struct user_id_s): New member last_certsig. * key.h: Add prototype for _gpgme_key_add_certsig. * key.c (_gpgme_key_add_certsig): New function. (set_user_id_part): Move function before _gpgme_key_add_certsig. (parse_user_id): Change first argument to SRC, add new arguments NAME, EMAIL and COMMENT. Change code to use these arguments instead going through UID. Move function before _gpgme_add_certsig. (parse_x509_user_id): Likewise. (_gpgme_key_append_name): Adjust arguments to parse_x509_user_id and parse_user_id invocation. (one_certsig_as_xml): New function. (one_uid_as_xml): Print signatures. * context.h (struct gpgme_context_s): New member TMP_UID. * keylist.c (keylist_colon_handler): Rewritten, implement "sig" record entries. * key.c (get_certsig): New function. (gpgme_key_sig_get_string_attr): Likewise. (gpgme_key_sig_get_ulong_attr): Likewise. * keylist.c: Include <ctype.h>. (my_isdigit): Macro removed. (set_mainkey_trust_info): Use isdigit, not my_isdigit. (set_userid_flags): Likewise. (set_subkey_trust_info): Likewise. (set_ownertrust): Likewise. (finish_key): Move function up a bit and remove prototype. * rungpg.c (gpg_keylist_ext): Correct precedence of signature listing mode. (gpg_keylist_ext): Implement signature listing mode.
This commit is contained in:
parent
7394638cdb
commit
1b495c5140
11
NEWS
11
NEWS
@ -1,6 +1,12 @@
|
|||||||
Noteworthy changes in version 0.4.0 (unreleased)
|
Noteworthy changes in version 0.4.0 (unreleased)
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
|
|
||||||
|
* Supports signatures of user IDs in keys via the new
|
||||||
|
GPGME_KEYLIST_MODE_SIGS keylist mode and the
|
||||||
|
gpgme_key_sig_get_string_attr and gpgme_key_sig_get_ulong_attr
|
||||||
|
interfaces. The XML info about a key also includes the signatures
|
||||||
|
if available.
|
||||||
|
|
||||||
* New data object interface, which is more flexible and transparent.
|
* New data object interface, which is more flexible and transparent.
|
||||||
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
@ -23,6 +29,11 @@ gpgme_op_verify CHANGED: Take different data objects for
|
|||||||
gpgme_op_verify_start CHANGED: See gpgme_op_verify.
|
gpgme_op_verify_start CHANGED: See gpgme_op_verify.
|
||||||
gpgme_check_engine REMOVED: Deprecated since 0.3.0.
|
gpgme_check_engine REMOVED: Deprecated since 0.3.0.
|
||||||
gpgme_op_genkey CHANGED: New parameter FPR.
|
gpgme_op_genkey CHANGED: New parameter FPR.
|
||||||
|
GPGME_KEYLIST_MODE_SIGS NEW
|
||||||
|
gpgme_key_sig_get_string_attr NEW
|
||||||
|
gpgme_key_sig_get_ulong_attr NEW
|
||||||
|
gpgme_get_key NEW
|
||||||
|
GPGME_ATTR_SIG_CLASS NEW
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Noteworthy changes in version 0.3.13 (2002-11-20)
|
Noteworthy changes in version 0.3.13 (2002-11-20)
|
||||||
|
@ -1,3 +1,62 @@
|
|||||||
|
2002-12-04 Marcus Brinkmann <marcus@g10code.de>
|
||||||
|
|
||||||
|
* gpgme.h: Add prototype for gpgme_get_key.
|
||||||
|
* key.c (gpgme_get_key): New function.
|
||||||
|
* verify.c (gpgme_get_sig_key): Rewrite using gpgme_get_key.
|
||||||
|
|
||||||
|
* gpgme.h: Add prototypes for new interfaces
|
||||||
|
gpgme_key_sig_get_string_attr and gpgme_key_get_ulong_attr.
|
||||||
|
(enum GpgmeAttr): New attribute GPGME_ATTR_SIG_CLASS.
|
||||||
|
* gpgme.c (gpgme_set_keylist_mode): Allow GPGME_KEYLIST_MODE_SIGS.
|
||||||
|
* key.h (struct certsig_s): New members ALGO, NAME_PART,
|
||||||
|
EMAIL_PART, COMMENT_PART, NAME, SIG_STAT and SIG_CLASS.
|
||||||
|
|
||||||
|
* conversion.c (_gpgme_decode_c_string): Add new parameter LEN.
|
||||||
|
Use that to determine if allocation is desired or not.
|
||||||
|
* util.h: Adjust prototype of _gpgme_decode_c_string.
|
||||||
|
* keylist.c (keylist_colon_handler): Adjust caller of
|
||||||
|
_gpgme_decode_c_string.
|
||||||
|
|
||||||
|
* key.h (struct gpgme_key_s): New member last_uid.
|
||||||
|
* key.c (_gpgme_key_append_name): Rewritten using
|
||||||
|
_gpgme_decode_c_string and the last_uid pointer.
|
||||||
|
(my_isdigit): Macro removed.
|
||||||
|
(ALLOC_CHUNK): Likewise.
|
||||||
|
* keylist.c (set_userid_flags): Use last_uid member of KEY.
|
||||||
|
|
||||||
|
* context.h (struct user_id_s): New member last_certsig.
|
||||||
|
* key.h: Add prototype for _gpgme_key_add_certsig.
|
||||||
|
* key.c (_gpgme_key_add_certsig): New function.
|
||||||
|
(set_user_id_part): Move function before _gpgme_key_add_certsig.
|
||||||
|
(parse_user_id): Change first argument to SRC, add new arguments
|
||||||
|
NAME, EMAIL and COMMENT. Change code to use these arguments
|
||||||
|
instead going through UID. Move function before
|
||||||
|
_gpgme_add_certsig.
|
||||||
|
(parse_x509_user_id): Likewise.
|
||||||
|
(_gpgme_key_append_name): Adjust arguments to parse_x509_user_id
|
||||||
|
and parse_user_id invocation.
|
||||||
|
(one_certsig_as_xml): New function.
|
||||||
|
(one_uid_as_xml): Print signatures.
|
||||||
|
* context.h (struct gpgme_context_s): New member TMP_UID.
|
||||||
|
* keylist.c (keylist_colon_handler): Rewritten, implement "sig"
|
||||||
|
record entries.
|
||||||
|
|
||||||
|
* key.c (get_certsig): New function.
|
||||||
|
(gpgme_key_sig_get_string_attr): Likewise.
|
||||||
|
(gpgme_key_sig_get_ulong_attr): Likewise.
|
||||||
|
|
||||||
|
* keylist.c: Include <ctype.h>.
|
||||||
|
(my_isdigit): Macro removed.
|
||||||
|
(set_mainkey_trust_info): Use isdigit, not my_isdigit.
|
||||||
|
(set_userid_flags): Likewise.
|
||||||
|
(set_subkey_trust_info): Likewise.
|
||||||
|
(set_ownertrust): Likewise.
|
||||||
|
(finish_key): Move function up a bit and remove prototype.
|
||||||
|
|
||||||
|
* rungpg.c (gpg_keylist_ext): Correct precedence of signature
|
||||||
|
listing mode.
|
||||||
|
(gpg_keylist_ext): Implement signature listing mode.
|
||||||
|
|
||||||
2002-11-25 Marcus Brinkmann <marcus@g10code.de>
|
2002-11-25 Marcus Brinkmann <marcus@g10code.de>
|
||||||
|
|
||||||
* rungpg.c (_gpgme_gpg_spawn): Do not set parent fds to -1.
|
* rungpg.c (_gpgme_gpg_spawn): Do not set parent fds to -1.
|
||||||
|
@ -1,23 +1,22 @@
|
|||||||
/* context.h
|
/* context.h
|
||||||
* Copyright (C) 2000 Werner Koch (dd9jn)
|
Copyright (C) 2000 Werner Koch (dd9jn)
|
||||||
* Copyright (C) 2001, 2002 g10 Code GmbH
|
Copyright (C) 2001, 2002 g10 Code GmbH
|
||||||
*
|
|
||||||
* This file is part of GPGME.
|
This file is part of GPGME.
|
||||||
*
|
|
||||||
* GPGME is free software; you can redistribute it and/or modify
|
GPGME is free software; you can redistribute it and/or modify it
|
||||||
* it under the terms of the GNU General Public License as published by
|
under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
* (at your option) any later version.
|
(at your option) any later version.
|
||||||
*
|
|
||||||
* GPGME is distributed in the hope that it will be useful,
|
GPGME is distributed in the hope that it will be useful, but
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* GNU General Public License for more details.
|
General Public License for more details.
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
along with GPGME; if not, write to the Free Software Foundation,
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef CONTEXT_H
|
#ifndef CONTEXT_H
|
||||||
#define CONTEXT_H
|
#define CONTEXT_H
|
||||||
@ -93,6 +92,7 @@ struct gpgme_context_s
|
|||||||
|
|
||||||
/* Used by keylist.c. */
|
/* Used by keylist.c. */
|
||||||
GpgmeKey tmp_key;
|
GpgmeKey tmp_key;
|
||||||
|
struct user_id_s *tmp_uid;
|
||||||
/* Something new is available. */
|
/* Something new is available. */
|
||||||
volatile int key_cond;
|
volatile int key_cond;
|
||||||
struct key_queue_item_s *key_queue;
|
struct key_queue_item_s *key_queue;
|
||||||
@ -124,6 +124,7 @@ struct user_id_s
|
|||||||
unsigned int invalid : 1;
|
unsigned int invalid : 1;
|
||||||
GpgmeValidity validity;
|
GpgmeValidity validity;
|
||||||
struct certsig_s *certsigs;
|
struct certsig_s *certsigs;
|
||||||
|
struct certsig_s *last_certsig;
|
||||||
const char *name_part; /* All 3 point into strings behind name */
|
const char *name_part; /* All 3 point into strings behind name */
|
||||||
const char *email_part; /* or to read-only strings. */
|
const char *email_part; /* or to read-only strings. */
|
||||||
const char *comment_part;
|
const char *comment_part;
|
||||||
|
@ -57,18 +57,29 @@ _gpgme_hextobyte (const byte *str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Decode the C formatted string SRC and store the result in the
|
||||||
|
buffer *DESTP which is LEN bytes long. If LEN is zero, then a
|
||||||
|
large enough buffer is allocated with malloc and *DESTP is set to
|
||||||
|
the result. Currently, LEN is only used to specify if allocation
|
||||||
|
is desired or not, the caller is expected to make sure that *DESTP
|
||||||
|
is large enough if LEN is not zero. */
|
||||||
GpgmeError
|
GpgmeError
|
||||||
_gpgme_decode_c_string (const char *src, char **destp)
|
_gpgme_decode_c_string (const char *src, char **destp, int len)
|
||||||
{
|
{
|
||||||
char *dest;
|
char *dest;
|
||||||
|
|
||||||
/* We can malloc a buffer of the same length, because the converted
|
if (len)
|
||||||
string will never be larger. */
|
dest = *destp;
|
||||||
dest = malloc (strlen (src) + 1);
|
else
|
||||||
if (!dest)
|
{
|
||||||
return mk_error (Out_Of_Core);
|
/* We can malloc a buffer of the same length, because the converted
|
||||||
|
string will never be larger. */
|
||||||
|
dest = malloc (strlen (src) + 1);
|
||||||
|
if (!dest)
|
||||||
|
return mk_error (Out_Of_Core);
|
||||||
|
|
||||||
*destp = dest;
|
*destp = dest;
|
||||||
|
}
|
||||||
|
|
||||||
while (*src)
|
while (*src)
|
||||||
{
|
{
|
||||||
|
@ -1,25 +1,26 @@
|
|||||||
/* gpgme.c - GnuPG Made Easy
|
/* gpgme.c - GnuPG Made Easy
|
||||||
* Copyright (C) 2000 Werner Koch (dd9jn)
|
Copyright (C) 2000 Werner Koch (dd9jn)
|
||||||
* Copyright (C) 2001, 2002 g10 Code GmbH
|
Copyright (C) 2001, 2002 g10 Code GmbH
|
||||||
*
|
|
||||||
* This file is part of GPGME.
|
|
||||||
*
|
|
||||||
* GPGME is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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 General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
This file is part of GPGME.
|
||||||
|
|
||||||
|
GPGME is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
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
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GPGME; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
|
#if HAVE_CONFIG_H
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
#endif
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -348,8 +349,9 @@ gpgme_set_keylist_mode (GpgmeCtx ctx, int mode)
|
|||||||
return mk_error (Invalid_Value);
|
return mk_error (Invalid_Value);
|
||||||
|
|
||||||
if (!((mode & GPGME_KEYLIST_MODE_LOCAL)
|
if (!((mode & GPGME_KEYLIST_MODE_LOCAL)
|
||||||
|| (mode & GPGME_KEYLIST_MODE_EXTERN)))
|
|| (mode & GPGME_KEYLIST_MODE_EXTERN)
|
||||||
return mk_error (Invalid_Value);
|
|| (mode & GPGME_KEYLIST_MODE_SIGS)))
|
||||||
|
return mk_error (Invalid_Value);
|
||||||
|
|
||||||
ctx->keylist_mode = mode;
|
ctx->keylist_mode = mode;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -196,7 +196,8 @@ typedef enum
|
|||||||
GPGME_ATTR_CHAINID = 28,
|
GPGME_ATTR_CHAINID = 28,
|
||||||
GPGME_ATTR_SIG_STATUS = 29,
|
GPGME_ATTR_SIG_STATUS = 29,
|
||||||
GPGME_ATTR_ERRTOK = 30,
|
GPGME_ATTR_ERRTOK = 30,
|
||||||
GPGME_ATTR_SIG_SUMMARY = 31
|
GPGME_ATTR_SIG_SUMMARY = 31,
|
||||||
|
GPGME_ATTR_SIG_CLASS = 32
|
||||||
}
|
}
|
||||||
GpgmeAttr;
|
GpgmeAttr;
|
||||||
|
|
||||||
@ -611,6 +612,13 @@ GpgmeError gpgme_data_rewind (GpgmeData dh);
|
|||||||
|
|
||||||
/* Key and trust functions. */
|
/* Key and trust functions. */
|
||||||
|
|
||||||
|
/* Get the key with the fingerprint FPR from the key cache or from the
|
||||||
|
crypto backend. If FORCE_UPDATE is true, force a refresh of the
|
||||||
|
key from the crypto backend and replace the key in the cache, if
|
||||||
|
any. If SECRET is true, get the secret key. */
|
||||||
|
GpgmeError gpgme_get_key (GpgmeCtx ctx, const char *fpr, GpgmeKey *r_key,
|
||||||
|
int secret, int force_update);
|
||||||
|
|
||||||
/* Acquire a reference to KEY. */
|
/* Acquire a reference to KEY. */
|
||||||
void gpgme_key_ref (GpgmeKey key);
|
void gpgme_key_ref (GpgmeKey key);
|
||||||
|
|
||||||
@ -635,6 +643,21 @@ const char *gpgme_key_get_string_attr (GpgmeKey key, GpgmeAttr what,
|
|||||||
unsigned long gpgme_key_get_ulong_attr (GpgmeKey key, GpgmeAttr what,
|
unsigned long gpgme_key_get_ulong_attr (GpgmeKey key, GpgmeAttr what,
|
||||||
const void *reserved, int idx);
|
const void *reserved, int idx);
|
||||||
|
|
||||||
|
/* Return the value of the attribute WHAT of a signature on user ID
|
||||||
|
UID_IDX in KEY, which has to be representable by a string. IDX
|
||||||
|
specifies the signature. */
|
||||||
|
const char *gpgme_key_sig_get_string_attr (GpgmeKey key, int uid_idx,
|
||||||
|
GpgmeAttr what,
|
||||||
|
const void *reserved, int idx);
|
||||||
|
|
||||||
|
/* Return the value of the attribute WHAT of a signature on user ID
|
||||||
|
UID_IDX in KEY, which has to be representable by an unsigned
|
||||||
|
integer string. IDX specifies the signature. */
|
||||||
|
unsigned long gpgme_key_sig_get_ulong_attr (GpgmeKey key, int uid_idx,
|
||||||
|
GpgmeAttr what,
|
||||||
|
const void *reserved, int idx);
|
||||||
|
|
||||||
|
|
||||||
/* Release the trust item ITEM. */
|
/* Release the trust item ITEM. */
|
||||||
void gpgme_trust_item_release (GpgmeTrustItem item);
|
void gpgme_trust_item_release (GpgmeTrustItem item);
|
||||||
|
|
||||||
|
676
gpgme/key.c
676
gpgme/key.c
@ -1,25 +1,26 @@
|
|||||||
/* key.c - Key and keyList objects
|
/* key.c - Key objects.
|
||||||
* Copyright (C) 2000 Werner Koch (dd9jn)
|
Copyright (C) 2000 Werner Koch (dd9jn)
|
||||||
* Copyright (C) 2001, 2002 g10 Code GmbH
|
Copyright (C) 2001, 2002 g10 Code GmbH
|
||||||
*
|
|
||||||
* This file is part of GPGME.
|
|
||||||
*
|
|
||||||
* GPGME is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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 General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
This file is part of GPGME.
|
||||||
|
|
||||||
|
GPGME is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
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
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with GPGME; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
|
#if HAVE_CONFIG_H
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
#endif
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -31,13 +32,11 @@
|
|||||||
#include "key.h"
|
#include "key.h"
|
||||||
#include "sema.h"
|
#include "sema.h"
|
||||||
|
|
||||||
#define ALLOC_CHUNK 1024
|
|
||||||
#define my_isdigit(a) ((a) >='0' && (a) <= '9')
|
|
||||||
|
|
||||||
#if SIZEOF_UNSIGNED_INT < 4
|
#if SIZEOF_UNSIGNED_INT < 4
|
||||||
#error unsigned int too short to be used as a hash value
|
#error unsigned int too short to be used as a hash value
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
struct key_cache_item_s
|
struct key_cache_item_s
|
||||||
{
|
{
|
||||||
struct key_cache_item_s *next;
|
struct key_cache_item_s *next;
|
||||||
@ -82,6 +81,7 @@ hash_key (const char *fpr, unsigned int *rhash)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_gpgme_key_cache_init (void)
|
_gpgme_key_cache_init (void)
|
||||||
{
|
{
|
||||||
@ -251,7 +251,7 @@ _gpgme_key_cache_get (const char *fpr)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
pkalgo_to_string (int algo)
|
pkalgo_to_string (int algo)
|
||||||
{
|
{
|
||||||
@ -288,12 +288,14 @@ key_new (GpgmeKey *r_key, int secret)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
GpgmeError
|
GpgmeError
|
||||||
_gpgme_key_new (GpgmeKey *r_key)
|
_gpgme_key_new (GpgmeKey *r_key)
|
||||||
{
|
{
|
||||||
return key_new (r_key, 0);
|
return key_new (r_key, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
GpgmeError
|
GpgmeError
|
||||||
_gpgme_key_new_secret (GpgmeKey *r_key)
|
_gpgme_key_new_secret (GpgmeKey *r_key)
|
||||||
{
|
{
|
||||||
@ -317,7 +319,7 @@ gpgme_key_ref (GpgmeKey key)
|
|||||||
UNLOCK (key_ref_lock);
|
UNLOCK (key_ref_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static struct subkey_s *
|
static struct subkey_s *
|
||||||
add_subkey (GpgmeKey key, int secret)
|
add_subkey (GpgmeKey key, int secret)
|
||||||
{
|
{
|
||||||
@ -327,7 +329,7 @@ add_subkey (GpgmeKey key, int secret)
|
|||||||
if (!k)
|
if (!k)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if(!(kk = key->keys.next))
|
if (!(kk = key->keys.next))
|
||||||
key->keys.next = k;
|
key->keys.next = k;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -354,7 +356,173 @@ _gpgme_key_add_secret_subkey (GpgmeKey key)
|
|||||||
return add_subkey (key, 1);
|
return add_subkey (key, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
parse_user_id (const char *src, const char **name, const char **email,
|
||||||
|
const char **comment, char *tail)
|
||||||
|
{
|
||||||
|
const char *start = NULL;
|
||||||
|
int in_name = 0;
|
||||||
|
int in_email = 0;
|
||||||
|
int in_comment = 0;
|
||||||
|
|
||||||
|
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
|
||||||
|
parse_x509_user_id (const char *src, const char **name, const char **email,
|
||||||
|
const char **comment, char *tail)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct certsig_s *
|
||||||
|
_gpgme_key_add_certsig (GpgmeKey key, char *src)
|
||||||
|
{
|
||||||
|
int src_len = src ? strlen (src) : 0;
|
||||||
|
struct user_id_s *uid;
|
||||||
|
struct certsig_s *certsig;
|
||||||
|
|
||||||
|
assert (key); /* XXX */
|
||||||
|
|
||||||
|
uid = key->last_uid;
|
||||||
|
assert (uid); /* XXX */
|
||||||
|
|
||||||
|
/* 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. */
|
||||||
|
certsig = calloc (1, sizeof (*certsig) + 2 * src_len + 3);
|
||||||
|
if (!certsig)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (src)
|
||||||
|
{
|
||||||
|
char *dst = certsig->name;
|
||||||
|
_gpgme_decode_c_string (src, &dst, src_len + 1);
|
||||||
|
dst += src_len + 1;
|
||||||
|
if (key->x509)
|
||||||
|
parse_x509_user_id (src, &certsig->name_part, &certsig->email_part,
|
||||||
|
&certsig->comment_part, dst);
|
||||||
|
else
|
||||||
|
parse_user_id (src, &certsig->name_part, &certsig->email_part,
|
||||||
|
&certsig->comment_part, dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!uid->certsigs)
|
||||||
|
uid->certsigs = certsig;
|
||||||
|
if (uid->last_certsig)
|
||||||
|
uid->last_certsig->next = certsig;
|
||||||
|
uid->last_certsig = certsig;
|
||||||
|
|
||||||
|
return certsig;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gpgme_key_release:
|
* gpgme_key_release:
|
||||||
* @key: Key Object or NULL
|
* @key: Key Object or NULL
|
||||||
@ -406,6 +574,7 @@ gpgme_key_release (GpgmeKey key)
|
|||||||
free (key);
|
free (key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gpgme_key_unref:
|
* gpgme_key_unref:
|
||||||
* @key: Key Object
|
* @key: Key Object
|
||||||
@ -418,237 +587,41 @@ gpgme_key_unref (GpgmeKey key)
|
|||||||
gpgme_key_release (key);
|
gpgme_key_release (key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static char *
|
/* Take a name from the --with-colon listing, remove certain escape
|
||||||
set_user_id_part (char *tail, const char *buf, size_t len)
|
sequences sequences and put it into the list of UIDs. */
|
||||||
{
|
|
||||||
while (len && (buf[len-1] == ' ' || buf[len-1] == '\t'))
|
|
||||||
len--;
|
|
||||||
for (; len; len--)
|
|
||||||
*tail++ = *buf++;
|
|
||||||
*tail++ = 0;
|
|
||||||
return tail;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
parse_user_id (struct user_id_s *uid, char *tail)
|
|
||||||
{
|
|
||||||
const char *s, *start=NULL;
|
|
||||||
int in_name = 0;
|
|
||||||
int in_email = 0;
|
|
||||||
int in_comment = 0;
|
|
||||||
|
|
||||||
for (s = uid->name; *s; s++)
|
|
||||||
{
|
|
||||||
if (in_email)
|
|
||||||
{
|
|
||||||
if (*s == '<')
|
|
||||||
/* Not legal but anyway. */
|
|
||||||
in_email++;
|
|
||||||
else if (*s == '>')
|
|
||||||
{
|
|
||||||
if (!--in_email)
|
|
||||||
{
|
|
||||||
if (!uid->email_part)
|
|
||||||
{
|
|
||||||
uid->email_part = tail;
|
|
||||||
tail = set_user_id_part ( tail, start, s-start );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (in_comment)
|
|
||||||
{
|
|
||||||
if (*s == '(')
|
|
||||||
in_comment++;
|
|
||||||
else if (*s== ')')
|
|
||||||
{
|
|
||||||
if (!--in_comment)
|
|
||||||
{
|
|
||||||
if (!uid->comment_part)
|
|
||||||
{
|
|
||||||
uid->comment_part = tail;
|
|
||||||
tail = set_user_id_part ( tail, start, s-start );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (*s == '<')
|
|
||||||
{
|
|
||||||
if (in_name)
|
|
||||||
{
|
|
||||||
if (!uid->name_part)
|
|
||||||
{
|
|
||||||
uid->name_part = tail;
|
|
||||||
tail = set_user_id_part (tail, start, s-start);
|
|
||||||
}
|
|
||||||
in_name = 0;
|
|
||||||
}
|
|
||||||
in_email = 1;
|
|
||||||
start = s+1;
|
|
||||||
}
|
|
||||||
else if (*s == '(')
|
|
||||||
{
|
|
||||||
if (in_name)
|
|
||||||
{
|
|
||||||
if (!uid->name_part)
|
|
||||||
{
|
|
||||||
uid->name_part = tail;
|
|
||||||
tail = set_user_id_part (tail, start, s-start );
|
|
||||||
}
|
|
||||||
in_name = 0;
|
|
||||||
}
|
|
||||||
in_comment = 1;
|
|
||||||
start = s+1;
|
|
||||||
}
|
|
||||||
else if (!in_name && *s != ' ' && *s != '\t')
|
|
||||||
{
|
|
||||||
in_name = 1;
|
|
||||||
start = s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (in_name)
|
|
||||||
{
|
|
||||||
if (!uid->name_part)
|
|
||||||
{
|
|
||||||
uid->name_part = tail;
|
|
||||||
tail = set_user_id_part (tail, start, s-start);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Let unused parts point to an EOS. */
|
|
||||||
tail--;
|
|
||||||
if (!uid->name_part)
|
|
||||||
uid->name_part = tail;
|
|
||||||
if (!uid->email_part)
|
|
||||||
uid->email_part = tail;
|
|
||||||
if (!uid->comment_part)
|
|
||||||
uid->comment_part = tail;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
parse_x509_user_id (struct user_id_s *uid, char *tail)
|
|
||||||
{
|
|
||||||
const char *s;
|
|
||||||
|
|
||||||
s=uid->name;
|
|
||||||
if (*s == '<' && s[strlen (s) - 1] == '>')
|
|
||||||
uid->email_part = s;
|
|
||||||
|
|
||||||
/* Let unused parts point to an EOS. */
|
|
||||||
tail--;
|
|
||||||
if (!uid->name_part)
|
|
||||||
uid->name_part = tail;
|
|
||||||
if (!uid->email_part)
|
|
||||||
uid->email_part = tail;
|
|
||||||
if (!uid->comment_part)
|
|
||||||
uid->comment_part = tail;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Take a name from the --with-colon listing, remove certain escape sequences
|
|
||||||
* sequences and put it into the list of UIDs
|
|
||||||
*/
|
|
||||||
GpgmeError
|
GpgmeError
|
||||||
_gpgme_key_append_name (GpgmeKey key, const char *s)
|
_gpgme_key_append_name (GpgmeKey key, const char *src)
|
||||||
{
|
{
|
||||||
struct user_id_s *uid;
|
struct user_id_s *uid;
|
||||||
char *d;
|
char *dst;
|
||||||
|
int src_len = strlen (src);
|
||||||
|
|
||||||
assert (key);
|
assert (key);
|
||||||
/* We can malloc a buffer of the same length, because the converted
|
/* We can malloc a buffer of the same length, because the converted
|
||||||
string will never be larger. Actually we allocate it twice the
|
string will never be larger. Actually we allocate it twice the
|
||||||
size, so that we are able to store the parsed stuff there too. */
|
size, so that we are able to store the parsed stuff there too. */
|
||||||
uid = malloc (sizeof *uid + 2*strlen (s)+3);
|
uid = malloc (sizeof (*uid) + 2 * src_len + 3);
|
||||||
if (!uid)
|
if (!uid)
|
||||||
return mk_error (Out_Of_Core);
|
return mk_error (Out_Of_Core);
|
||||||
memset (uid, 0, sizeof *uid);
|
memset (uid, 0, sizeof *uid);
|
||||||
d = uid->name;
|
|
||||||
|
|
||||||
while (*s)
|
dst = uid->name;
|
||||||
{
|
_gpgme_decode_c_string (src, &dst, src_len + 1);
|
||||||
if (*s != '\\')
|
|
||||||
*d++ = *s++;
|
dst += src_len + 1;
|
||||||
else if (s[1] == '\\')
|
|
||||||
{
|
|
||||||
s++;
|
|
||||||
*d++ = *s++;
|
|
||||||
}
|
|
||||||
else if (s[1] == 'n')
|
|
||||||
{
|
|
||||||
s += 2;
|
|
||||||
*d++ = '\n';
|
|
||||||
}
|
|
||||||
else if (s[1] == 'r')
|
|
||||||
{
|
|
||||||
s += 2;
|
|
||||||
*d++ = '\r';
|
|
||||||
}
|
|
||||||
else if (s[1] == 'v')
|
|
||||||
{
|
|
||||||
s += 2;
|
|
||||||
*d++ = '\v';
|
|
||||||
}
|
|
||||||
else if (s[1] == 'b')
|
|
||||||
{
|
|
||||||
s += 2;
|
|
||||||
*d++ = '\b';
|
|
||||||
}
|
|
||||||
else if (s[1] == '0')
|
|
||||||
{
|
|
||||||
/* Hmmm: no way to express this */
|
|
||||||
s += 2;
|
|
||||||
*d++ = '\\';
|
|
||||||
*d++ = '\0';
|
|
||||||
}
|
|
||||||
else if (s[1] == 'x' && isxdigit (s[2]) && isxdigit (s[3]))
|
|
||||||
{
|
|
||||||
int val = _gpgme_hextobyte (&s[2]);
|
|
||||||
if (val == -1)
|
|
||||||
{
|
|
||||||
/* Should not happen. */
|
|
||||||
*d++ = *s++;
|
|
||||||
*d++ = *s++;
|
|
||||||
*d++ = *s++;
|
|
||||||
*d++ = *s++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!val)
|
|
||||||
{
|
|
||||||
*d++ = '\\';
|
|
||||||
*d++ = '\0';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
*(byte*)d++ = val;
|
|
||||||
s += 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* should not happen */
|
|
||||||
s++;
|
|
||||||
*d++ = '\\';
|
|
||||||
*d++ = *s++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*d++ = 0;
|
|
||||||
if (key->x509)
|
if (key->x509)
|
||||||
parse_x509_user_id (uid, d);
|
parse_x509_user_id (src, &uid->name_part, &uid->email_part,
|
||||||
|
&uid->comment_part, dst);
|
||||||
else
|
else
|
||||||
parse_user_id (uid, d);
|
parse_user_id (src, &uid->name_part, &uid->email_part,
|
||||||
|
&uid->comment_part, dst);
|
||||||
|
|
||||||
if (key->uids)
|
if (!key->uids)
|
||||||
{
|
|
||||||
struct user_id_s *u = key->uids;
|
|
||||||
while (u->next)
|
|
||||||
u = u->next;
|
|
||||||
u->next = uid;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
key->uids = uid;
|
key->uids = uid;
|
||||||
|
if (key->last_uid)
|
||||||
|
key->last_uid->next = uid;
|
||||||
|
key->last_uid = uid;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -662,6 +635,7 @@ add_otag (GpgmeData d, const char *tag)
|
|||||||
_gpgme_data_append_string (d, ">");
|
_gpgme_data_append_string (d, ">");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
add_ctag (GpgmeData d, const char *tag)
|
add_ctag (GpgmeData d, const char *tag)
|
||||||
{
|
{
|
||||||
@ -670,6 +644,7 @@ add_ctag (GpgmeData d, const char *tag)
|
|||||||
_gpgme_data_append_string (d, ">\n");
|
_gpgme_data_append_string (d, ">\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
add_tag_and_string (GpgmeData d, const char *tag, const char *string)
|
add_tag_and_string (GpgmeData d, const char *tag, const char *string)
|
||||||
{
|
{
|
||||||
@ -678,6 +653,7 @@ add_tag_and_string (GpgmeData d, const char *tag, const char *string)
|
|||||||
add_ctag (d, tag);
|
add_ctag (d, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
add_tag_and_uint (GpgmeData d, const char *tag, unsigned int val)
|
add_tag_and_uint (GpgmeData d, const char *tag, unsigned int val)
|
||||||
{
|
{
|
||||||
@ -686,6 +662,7 @@ add_tag_and_uint (GpgmeData d, const char *tag, unsigned int val)
|
|||||||
add_tag_and_string (d, tag, buf);
|
add_tag_and_string (d, tag, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
add_tag_and_time (GpgmeData d, const char *tag, time_t val)
|
add_tag_and_time (GpgmeData d, const char *tag, time_t val)
|
||||||
{
|
{
|
||||||
@ -697,22 +674,55 @@ add_tag_and_time (GpgmeData d, const char *tag, time_t val)
|
|||||||
add_tag_and_string (d, tag, buf);
|
add_tag_and_string (d, tag, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
one_uid_as_xml (GpgmeData d, struct user_id_s *u)
|
one_certsig_as_xml (GpgmeData data, struct certsig_s *certsig)
|
||||||
{
|
{
|
||||||
_gpgme_data_append_string (d, " <userid>\n");
|
_gpgme_data_append_string (data, " <signature>\n");
|
||||||
if (u->invalid)
|
if (certsig->flags.invalid)
|
||||||
_gpgme_data_append_string (d, " <invalid/>\n");
|
_gpgme_data_append_string (data, " <invalid/>\n");
|
||||||
if (u->revoked)
|
if (certsig->flags.revoked)
|
||||||
_gpgme_data_append_string (d, " <revoked/>\n");
|
_gpgme_data_append_string (data, " <revoked/>\n");
|
||||||
add_tag_and_string (d, "raw", u->name);
|
if (certsig->flags.expired)
|
||||||
if (*u->name_part)
|
_gpgme_data_append_string (data, " <expired/>\n");
|
||||||
add_tag_and_string (d, "name", u->name_part);
|
add_tag_and_string (data, "keyid", certsig->keyid);
|
||||||
if (*u->email_part)
|
add_tag_and_uint (data, "algo", certsig->algo);
|
||||||
add_tag_and_string (d, "email", u->email_part);
|
add_tag_and_time (data, "created", certsig->timestamp);
|
||||||
if (*u->comment_part)
|
add_tag_and_time (data, "expire", certsig->expires_at);
|
||||||
add_tag_and_string (d, "comment", u->comment_part);
|
if (*certsig->name)
|
||||||
_gpgme_data_append_string (d, " </userid>\n");
|
add_tag_and_string (data, "raw", certsig->name);
|
||||||
|
if (*certsig->name_part)
|
||||||
|
add_tag_and_string (data, "name", certsig->name_part);
|
||||||
|
if (*certsig->email_part)
|
||||||
|
add_tag_and_string (data, "email", certsig->email_part);
|
||||||
|
if (*certsig->comment_part)
|
||||||
|
add_tag_and_string (data, "comment", certsig->comment_part);
|
||||||
|
_gpgme_data_append_string (data, " </signature>\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
one_uid_as_xml (GpgmeData data, struct user_id_s *uid)
|
||||||
|
{
|
||||||
|
struct certsig_s *certsig;
|
||||||
|
|
||||||
|
_gpgme_data_append_string (data, " <userid>\n");
|
||||||
|
if (uid->invalid)
|
||||||
|
_gpgme_data_append_string (data, " <invalid/>\n");
|
||||||
|
if (uid->revoked)
|
||||||
|
_gpgme_data_append_string (data, " <revoked/>\n");
|
||||||
|
add_tag_and_string (data, "raw", uid->name);
|
||||||
|
if (*uid->name_part)
|
||||||
|
add_tag_and_string (data, "name", uid->name_part);
|
||||||
|
if (*uid->email_part)
|
||||||
|
add_tag_and_string (data, "email", uid->email_part);
|
||||||
|
if (*uid->comment_part)
|
||||||
|
add_tag_and_string (data, "comment", uid->comment_part);
|
||||||
|
|
||||||
|
/* Now the signatures. */
|
||||||
|
for (certsig = uid->certsigs; certsig; certsig = certsig->next)
|
||||||
|
one_certsig_as_xml (data, certsig);
|
||||||
|
_gpgme_data_append_string (data, " </userid>\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -817,8 +827,8 @@ capabilities_to_string (struct subkey_s *k)
|
|||||||
"esc"
|
"esc"
|
||||||
};
|
};
|
||||||
return strings[(!!k->flags.can_encrypt << 2)
|
return strings[(!!k->flags.can_encrypt << 2)
|
||||||
| (!!k->flags.can_sign << 1)
|
| (!!k->flags.can_sign << 1)
|
||||||
| (!!k->flags.can_certify )];
|
| (!!k->flags.can_certify)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -972,6 +982,7 @@ gpgme_key_get_string_attr (GpgmeKey key, GpgmeAttr what,
|
|||||||
case GPGME_ATTR_SIG_STATUS:
|
case GPGME_ATTR_SIG_STATUS:
|
||||||
case GPGME_ATTR_SIG_SUMMARY:
|
case GPGME_ATTR_SIG_SUMMARY:
|
||||||
case GPGME_ATTR_ERRTOK:
|
case GPGME_ATTR_ERRTOK:
|
||||||
|
case GPGME_ATTR_SIG_CLASS:
|
||||||
/* Not of any use here. */
|
/* Not of any use here. */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1102,3 +1113,154 @@ gpgme_key_get_ulong_attr (GpgmeKey key, GpgmeAttr what,
|
|||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct certsig_s *
|
||||||
|
get_certsig (GpgmeKey key, int uid_idx, int idx)
|
||||||
|
{
|
||||||
|
struct user_id_s *uid;
|
||||||
|
struct certsig_s *certsig;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
certsig = uid->certsigs;
|
||||||
|
while (certsig && idx > 0)
|
||||||
|
{
|
||||||
|
certsig = certsig->next;
|
||||||
|
idx--;
|
||||||
|
}
|
||||||
|
return certsig;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char *
|
||||||
|
gpgme_key_sig_get_string_attr (GpgmeKey key, int uid_idx, GpgmeAttr what,
|
||||||
|
const void *reserved, int idx)
|
||||||
|
{
|
||||||
|
struct certsig_s *certsig = get_certsig (key, uid_idx, idx);
|
||||||
|
|
||||||
|
if (!certsig || reserved)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
switch (what)
|
||||||
|
{
|
||||||
|
case GPGME_ATTR_KEYID:
|
||||||
|
return certsig->keyid;
|
||||||
|
|
||||||
|
case GPGME_ATTR_ALGO:
|
||||||
|
return pkalgo_to_string (certsig->algo);
|
||||||
|
|
||||||
|
case GPGME_ATTR_USERID:
|
||||||
|
return certsig->name;
|
||||||
|
|
||||||
|
case GPGME_ATTR_NAME:
|
||||||
|
return certsig->name_part;
|
||||||
|
|
||||||
|
case GPGME_ATTR_EMAIL:
|
||||||
|
return certsig->email_part;
|
||||||
|
|
||||||
|
case GPGME_ATTR_COMMENT:
|
||||||
|
return certsig->comment_part;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned long
|
||||||
|
gpgme_key_sig_get_ulong_attr (GpgmeKey key, int uid_idx, GpgmeAttr what,
|
||||||
|
const void *reserved, int idx)
|
||||||
|
{
|
||||||
|
struct certsig_s *certsig = get_certsig (key, uid_idx, idx);
|
||||||
|
|
||||||
|
if (!certsig || reserved)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
switch (what)
|
||||||
|
{
|
||||||
|
case GPGME_ATTR_ALGO:
|
||||||
|
return (unsigned long) certsig->algo;
|
||||||
|
|
||||||
|
case GPGME_ATTR_CREATED:
|
||||||
|
return certsig->timestamp < 0 ? 0L : (unsigned long) certsig->timestamp;
|
||||||
|
|
||||||
|
case GPGME_ATTR_EXPIRE:
|
||||||
|
return certsig->expires_at < 0 ? 0L : (unsigned long) certsig->expires_at;
|
||||||
|
|
||||||
|
case GPGME_ATTR_KEY_REVOKED:
|
||||||
|
return certsig->flags.revoked;
|
||||||
|
|
||||||
|
case GPGME_ATTR_KEY_INVALID:
|
||||||
|
return certsig->flags.invalid;
|
||||||
|
|
||||||
|
case GPGME_ATTR_KEY_EXPIRED:
|
||||||
|
return certsig->flags.expired;
|
||||||
|
|
||||||
|
case GPGME_ATTR_SIG_CLASS:
|
||||||
|
return certsig->sig_class;
|
||||||
|
|
||||||
|
case GPGME_ATTR_SIG_STATUS:
|
||||||
|
return certsig->sig_stat;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Get the key with the fingerprint FPR from the key cache or from the
|
||||||
|
crypto backend. If FORCE_UPDATE is true, force a refresh of the
|
||||||
|
key from the crypto backend and replace the key in the cache, if
|
||||||
|
any. If SECRET is true, get the secret key. */
|
||||||
|
GpgmeError
|
||||||
|
gpgme_get_key (GpgmeCtx ctx, const char *fpr, GpgmeKey *r_key,
|
||||||
|
int secret, int force_update)
|
||||||
|
{
|
||||||
|
GpgmeCtx listctx;
|
||||||
|
GpgmeError err;
|
||||||
|
|
||||||
|
if (!ctx || !r_key)
|
||||||
|
return mk_error (Invalid_Value);
|
||||||
|
if (ctx->pending)
|
||||||
|
return mk_error (Busy);
|
||||||
|
|
||||||
|
if (strlen (fpr) < 16) /* We have at least a key ID. */
|
||||||
|
return mk_error (Invalid_Key);
|
||||||
|
|
||||||
|
if (!force_update)
|
||||||
|
{
|
||||||
|
*r_key = _gpgme_key_cache_get (fpr);
|
||||||
|
if (*r_key)
|
||||||
|
{
|
||||||
|
/* If the primary UID (if available) has no signatures, and
|
||||||
|
we are in the signature listing keylist mode, then try to
|
||||||
|
update the key below before returning. */
|
||||||
|
if (!((ctx->keylist_mode & GPGME_KEYLIST_MODE_SIGS)
|
||||||
|
&& (*r_key)->uids && !(*r_key)->uids->certsigs))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fixme: This can be optimized by keeping an internal context
|
||||||
|
used for such key listings. */
|
||||||
|
err = gpgme_new (&listctx);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
gpgme_set_protocol (listctx, gpgme_get_protocol (ctx));
|
||||||
|
gpgme_set_keylist_mode (listctx, ctx->keylist_mode);
|
||||||
|
err = gpgme_op_keylist_start (listctx, fpr, secret);
|
||||||
|
if (!err)
|
||||||
|
err = gpgme_op_keylist_next (listctx, r_key);
|
||||||
|
gpgme_release (listctx);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
139
gpgme/key.h
139
gpgme/key.h
@ -1,23 +1,22 @@
|
|||||||
/* key.h
|
/* key.h - Key handling interface.
|
||||||
* Copyright (C) 2000 Werner Koch (dd9jn)
|
Copyright (C) 2000 Werner Koch (dd9jn)
|
||||||
* Copyright (C) 2001 g10 Code GmbH
|
Copyright (C) 2001, 2002 g10 Code GmbH
|
||||||
*
|
|
||||||
* This file is part of GPGME.
|
This file is part of GPGME.
|
||||||
*
|
|
||||||
* GPGME is free software; you can redistribute it and/or modify
|
GPGME is free software; you can redistribute it and/or modify it
|
||||||
* it under the terms of the GNU General Public License as published by
|
under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
* (at your option) any later version.
|
(at your option) any later version.
|
||||||
*
|
|
||||||
* GPGME is distributed in the hope that it will be useful,
|
GPGME is distributed in the hope that it will be useful, but
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
* GNU General Public License for more details.
|
General Public License for more details.
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
along with GPGME; if not, write to the Free Software Foundation,
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef KEY_H
|
#ifndef KEY_H
|
||||||
#define KEY_H
|
#define KEY_H
|
||||||
@ -26,68 +25,86 @@
|
|||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
|
|
||||||
struct certsig_s {
|
|
||||||
|
struct certsig_s
|
||||||
|
{
|
||||||
struct certsig_s *next;
|
struct certsig_s *next;
|
||||||
struct {
|
struct
|
||||||
unsigned int revoked:1 ;
|
{
|
||||||
unsigned int expired:1 ;
|
unsigned int revoked : 1;
|
||||||
unsigned int invalid:1 ;
|
unsigned int expired : 1;
|
||||||
|
unsigned int invalid : 1;
|
||||||
|
unsigned int exportable : 1;
|
||||||
} flags;
|
} flags;
|
||||||
char keyid[16+1];
|
unsigned int algo;
|
||||||
time_t timestamp; /* -1 for invalid, 0 for not available */
|
char keyid[16 + 1];
|
||||||
time_t expires_at; /* 0 for does not expires */
|
time_t timestamp; /* -1 for invalid, 0 for not available. */
|
||||||
|
time_t expires_at; /* 0 for no expiration. */
|
||||||
|
GpgmeSigStat sig_stat;
|
||||||
|
unsigned int sig_class;
|
||||||
|
const char *name_part; /* All 3 point into strings behind name */
|
||||||
|
const char *email_part; /* or to read-only strings. */
|
||||||
|
const char *comment_part;
|
||||||
|
char name[1];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct subkey_s {
|
|
||||||
|
struct subkey_s
|
||||||
|
{
|
||||||
struct subkey_s *next;
|
struct subkey_s *next;
|
||||||
unsigned int secret:1;
|
unsigned int secret:1;
|
||||||
struct {
|
struct
|
||||||
unsigned int revoked:1 ;
|
{
|
||||||
unsigned int expired:1 ;
|
unsigned int revoked : 1;
|
||||||
unsigned int disabled:1 ;
|
unsigned int expired : 1;
|
||||||
unsigned int invalid:1 ;
|
unsigned int disabled : 1;
|
||||||
unsigned int can_encrypt:1;
|
unsigned int invalid : 1;
|
||||||
unsigned int can_sign:1;
|
unsigned int can_encrypt : 1;
|
||||||
unsigned int can_certify:1;
|
unsigned int can_sign : 1;
|
||||||
|
unsigned int can_certify : 1;
|
||||||
} flags;
|
} flags;
|
||||||
unsigned int key_algo;
|
unsigned int key_algo;
|
||||||
unsigned int key_len;
|
unsigned int key_len;
|
||||||
char keyid[16+1];
|
char keyid[16 + 1];
|
||||||
char *fingerprint; /* malloced hex digits */
|
char *fingerprint; /* Malloced hex digits. */
|
||||||
time_t timestamp; /* -1 for invalid, 0 for not available */
|
time_t timestamp; /* -1 for invalid, 0 for not available. */
|
||||||
time_t expires_at; /* 0 for does not expires */
|
time_t expires_at; /* 0 for does not expires. */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct gpgme_key_s {
|
|
||||||
struct {
|
struct gpgme_key_s
|
||||||
unsigned int revoked:1 ;
|
{
|
||||||
unsigned int expired:1 ;
|
struct
|
||||||
unsigned int disabled:1 ;
|
{
|
||||||
unsigned int invalid:1 ;
|
unsigned int revoked : 1;
|
||||||
unsigned int can_encrypt:1;
|
unsigned int expired : 1;
|
||||||
unsigned int can_sign:1;
|
unsigned int disabled : 1;
|
||||||
unsigned int can_certify:1;
|
unsigned int invalid : 1;
|
||||||
|
unsigned int can_encrypt : 1;
|
||||||
|
unsigned int can_sign : 1;
|
||||||
|
unsigned int can_certify : 1;
|
||||||
} gloflags;
|
} gloflags;
|
||||||
unsigned int ref_count;
|
unsigned int ref_count;
|
||||||
unsigned int secret:1;
|
unsigned int secret : 1;
|
||||||
unsigned int x509:1;
|
unsigned int x509 : 1;
|
||||||
char *issuer_serial; /* malloced string used only with X.509 */
|
char *issuer_serial; /* Malloced string used only with X.509. */
|
||||||
char *issuer_name; /* ditto */
|
char *issuer_name; /* Ditto. */
|
||||||
char *chain_id; /* ditto */
|
char *chain_id; /* Ditto. */
|
||||||
GpgmeValidity otrust; /* only used with OpenPGP */
|
GpgmeValidity otrust; /* Only used with OpenPGP. */
|
||||||
struct subkey_s keys;
|
struct subkey_s keys;
|
||||||
struct user_id_s *uids;
|
struct user_id_s *uids;
|
||||||
|
struct user_id_s *last_uid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void _gpgme_key_cache_init (void);
|
void _gpgme_key_cache_init (void);
|
||||||
void _gpgme_key_cache_add (GpgmeKey key);
|
void _gpgme_key_cache_add (GpgmeKey key);
|
||||||
GpgmeKey _gpgme_key_cache_get (const char *fpr);
|
GpgmeKey _gpgme_key_cache_get (const char *fpr);
|
||||||
|
|
||||||
|
|
||||||
|
struct certsig_s *_gpgme_key_add_certsig (GpgmeKey key, char *src);
|
||||||
struct subkey_s *_gpgme_key_add_subkey (GpgmeKey key);
|
struct subkey_s *_gpgme_key_add_subkey (GpgmeKey key);
|
||||||
struct subkey_s *_gpgme_key_add_secret_subkey (GpgmeKey key);
|
struct subkey_s *_gpgme_key_add_secret_subkey (GpgmeKey key);
|
||||||
GpgmeError _gpgme_key_append_name ( GpgmeKey key, const char *s );
|
GpgmeError _gpgme_key_append_name (GpgmeKey key, const char *str);
|
||||||
|
|
||||||
|
#endif /* KEY_H */
|
||||||
|
|
||||||
#endif /* KEY_H */
|
|
||||||
|
898
gpgme/keylist.c
898
gpgme/keylist.c
File diff suppressed because it is too large
Load Diff
@ -1486,10 +1486,9 @@ gpg_keylist (void *engine, const char *pattern, int secret_only,
|
|||||||
if (!err)
|
if (!err)
|
||||||
err = add_arg (gpg, "--with-fingerprint");
|
err = add_arg (gpg, "--with-fingerprint");
|
||||||
if (!err)
|
if (!err)
|
||||||
err = add_arg (gpg, (keylist_mode & GPGME_KEYLIST_MODE_SIGS) ?
|
err = add_arg (gpg, secret_only ? "--list-secret-keys"
|
||||||
"--check-sigs" :
|
: ((keylist_mode & GPGME_KEYLIST_MODE_SIGS)
|
||||||
secret_only ? "--list-secret-keys"
|
? "--check-sigs" : "--list-keys"));
|
||||||
: "--list-keys");
|
|
||||||
|
|
||||||
/* Tell the gpg object about the data. */
|
/* Tell the gpg object about the data. */
|
||||||
if (!err)
|
if (!err)
|
||||||
@ -1519,7 +1518,9 @@ gpg_keylist_ext (void *engine, const char *pattern[], int secret_only,
|
|||||||
if (!err)
|
if (!err)
|
||||||
err = add_arg (gpg, "--with-fingerprint");
|
err = add_arg (gpg, "--with-fingerprint");
|
||||||
if (!err)
|
if (!err)
|
||||||
err = add_arg (gpg, secret_only ? "--list-secret-keys" : "--list-keys");
|
err = add_arg (gpg, secret_only ? "--list-secret-keys"
|
||||||
|
: ((keylist_mode & GPGME_KEYLIST_MODE_SIGS)
|
||||||
|
? "--check-sigs" : "--list-keys"));
|
||||||
|
|
||||||
/* Tell the gpg object about the data. */
|
/* Tell the gpg object about the data. */
|
||||||
if (!err)
|
if (!err)
|
||||||
|
@ -85,7 +85,13 @@ FILE *fopencookie (void *cookie, const char *opentype,
|
|||||||
|
|
||||||
|
|
||||||
/*-- conversion.c --*/
|
/*-- conversion.c --*/
|
||||||
GpgmeError _gpgme_decode_c_string (const char *src, char **destp);
|
/* Decode the C formatted string SRC and store the result in the
|
||||||
|
buffer *DESTP which is LEN bytes long. If LEN is zero, then a
|
||||||
|
large enough buffer is allocated with malloc and *DESTP is set to
|
||||||
|
the result. Currently, LEN is only used to specify if allocation
|
||||||
|
is desired or not, the caller is expected to make sure that *DESTP
|
||||||
|
is large enough if LEN is not zero. */
|
||||||
|
GpgmeError _gpgme_decode_c_string (const char *src, char **destp, int len);
|
||||||
int _gpgme_hextobyte (const byte *str);
|
int _gpgme_hextobyte (const byte *str);
|
||||||
|
|
||||||
#endif /* UTIL_H */
|
#endif /* UTIL_H */
|
||||||
|
@ -643,42 +643,20 @@ gpgme_get_sig_ulong_attr (GpgmeCtx c, int idx, GpgmeAttr what, int reserved)
|
|||||||
* indicate that there are no more signatures.
|
* indicate that there are no more signatures.
|
||||||
**/
|
**/
|
||||||
GpgmeError
|
GpgmeError
|
||||||
gpgme_get_sig_key (GpgmeCtx c, int idx, GpgmeKey *r_key)
|
gpgme_get_sig_key (GpgmeCtx ctx, int idx, GpgmeKey *r_key)
|
||||||
{
|
{
|
||||||
VerifyResult result;
|
VerifyResult result;
|
||||||
GpgmeError err = 0;
|
|
||||||
|
|
||||||
if (!c || !r_key)
|
if (!ctx || !r_key)
|
||||||
return mk_error (Invalid_Value);
|
return mk_error (Invalid_Value);
|
||||||
if (c->pending || !c->result.verify)
|
if (ctx->pending || !ctx->result.verify)
|
||||||
return mk_error (Busy);
|
return mk_error (Busy);
|
||||||
|
|
||||||
for (result = c->result.verify;
|
for (result = ctx->result.verify;
|
||||||
result && idx > 0; result = result->next, idx--)
|
result && idx > 0; result = result->next, idx--)
|
||||||
;
|
;
|
||||||
if (!result)
|
if (!result)
|
||||||
return mk_error (EOF);
|
return mk_error (EOF);
|
||||||
|
|
||||||
if (strlen(result->fpr) < 16) /* We have at least a key ID. */
|
return gpgme_get_key (ctx, result->fpr, r_key, 0, 0);
|
||||||
return mk_error (Invalid_Key);
|
|
||||||
|
|
||||||
*r_key = _gpgme_key_cache_get (result->fpr);
|
|
||||||
if (!*r_key)
|
|
||||||
{
|
|
||||||
GpgmeCtx listctx;
|
|
||||||
|
|
||||||
/* Fixme: This can be optimized by keeping an internal context
|
|
||||||
used for such key listings. */
|
|
||||||
err = gpgme_new (&listctx);
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
gpgme_set_protocol (listctx, gpgme_get_protocol (c));
|
|
||||||
gpgme_set_keylist_mode (listctx, c->keylist_mode);
|
|
||||||
err = gpgme_op_keylist_start (listctx, result->fpr, 0);
|
|
||||||
if (!err)
|
|
||||||
err = gpgme_op_keylist_next (listctx, r_key);
|
|
||||||
gpgme_release (listctx);
|
|
||||||
}
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user