mirror of
git://git.gnupg.org/gnupg.git
synced 2025-04-17 15:44:34 +02:00
Revamped the keyring code
This commit is contained in:
parent
3f465d5d7a
commit
ed17c7afd0
@ -1,3 +1,7 @@
|
|||||||
|
2001-09-03 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
|
* configure.ac: Removed GDBM tests.
|
||||||
|
|
||||||
2001-08-23 Werner Koch <wk@gnupg.org>
|
2001-08-23 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
* configure.in (AC_FUNC_FSEEKO): Add.
|
* configure.in (AC_FUNC_FSEEKO): Add.
|
||||||
|
5
INSTALL
5
INSTALL
@ -102,6 +102,11 @@ Specific problems on some machines
|
|||||||
not build. In this case try to run configure using:
|
not build. In this case try to run configure using:
|
||||||
CFLAGS="-g -O2 -mcpu=powerpc" ./configure
|
CFLAGS="-g -O2 -mcpu=powerpc" ./configure
|
||||||
|
|
||||||
|
* Compaq C V6.2 for alpha:
|
||||||
|
|
||||||
|
You may want to use the option "-msg-disable ptrmismatch1"
|
||||||
|
to get rid of the sign/unsigned char mismatch warnings.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
The Random Device
|
The Random Device
|
||||||
|
4
NEWS
4
NEWS
@ -33,6 +33,10 @@
|
|||||||
UID, encoded using %XX escaping (but with spaces left as spaces,
|
UID, encoded using %XX escaping (but with spaces left as spaces,
|
||||||
so that it should not break too much)
|
so that it should not break too much)
|
||||||
|
|
||||||
|
* Support for GDBM based keyrings has been removed.
|
||||||
|
|
||||||
|
* The entire keyring management has been revamped.
|
||||||
|
|
||||||
|
|
||||||
Noteworthy changes in version 1.0.6 (2001-05-29)
|
Noteworthy changes in version 1.0.6 (2001-05-29)
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
|
4
TODO
4
TODO
@ -73,11 +73,11 @@
|
|||||||
* Concatenated encryption messages don't work corectly - only the
|
* Concatenated encryption messages don't work corectly - only the
|
||||||
first one is processed.
|
first one is processed.
|
||||||
|
|
||||||
* Add status message for reasons why a key was not selected.
|
|
||||||
|
|
||||||
* Add option to put the list of recipients (from the encryption
|
* Add option to put the list of recipients (from the encryption
|
||||||
layer) into the signatures notation data.
|
layer) into the signatures notation data.
|
||||||
|
|
||||||
|
* Allow to update key signatyres, add status that a key is already signed.
|
||||||
|
|
||||||
Scheduled for 1.1
|
Scheduled for 1.1
|
||||||
-----------------
|
-----------------
|
||||||
* export by user-IDs does only export the first matching name which leads
|
* export by user-IDs does only export the first matching name which leads
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
2001-09-06 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
|
* genkey1024.test: Simplified by using a parameter file.
|
||||||
|
|
||||||
2001-05-30 Werner Koch <wk@gnupg.org>
|
2001-05-30 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
* multisig.test (IFS): Reset IFS just before the test.
|
* multisig.test (IFS): Reset IFS just before the test.
|
||||||
|
@ -2,99 +2,25 @@
|
|||||||
|
|
||||||
. $srcdir/defs.inc || exit 3
|
. $srcdir/defs.inc || exit 3
|
||||||
|
|
||||||
|
../g10/gpg --quiet --batch --quick-random --homedir . --gen-key <<EOF
|
||||||
if (expect -v) < /dev/null > /dev/null 2>&1 ; then
|
Key-Type: DSA
|
||||||
:
|
Key-Length: 1024
|
||||||
else
|
Subkey-Type: ELG-E
|
||||||
echo "\"expect\" needed but not found - test skipped"
|
Subkey-Length: 1024
|
||||||
exit 0
|
Name-Real: Harry H.
|
||||||
fi
|
Name-Comment: test key
|
||||||
|
Name-Email: hh@@ddorf.de
|
||||||
LANG=
|
Expire-Date: 1
|
||||||
LANGUAGE=
|
Passphrase: abc
|
||||||
|
%commit
|
||||||
expect - <<EOF >/dev/null
|
Key-Type: RSA
|
||||||
#set timeout -1
|
Key-Length: 1024
|
||||||
set timeout 8
|
Key-Usage: sign,encrypt
|
||||||
match_max 100000
|
Name-Real: Harry A.
|
||||||
spawn ../g10/gpg --no-batch --quick-random --homedir . --gen-key
|
Name-Comment: RSA test key
|
||||||
expect {
|
Name-Email: hh@@ddorf.de
|
||||||
-exact "Please select what kind of key you want:\r
|
Expire-Date: 2
|
||||||
(1) DSA and ElGamal (default)\r
|
Passphrase: abc
|
||||||
(2) DSA (sign only)\r
|
%commit
|
||||||
(4) ElGamal (sign and encrypt)\r
|
|
||||||
Your selection? " { send -- "1\r" }
|
|
||||||
timeout { exit 1 } }
|
|
||||||
expect {
|
|
||||||
-exact "1\r
|
|
||||||
\r \rDSA keypair will have 1024 bits.\r
|
|
||||||
About to generate a new ELG-E keypair.\r
|
|
||||||
minimum keysize is 768 bits\r
|
|
||||||
default keysize is 1024 bits\r
|
|
||||||
highest suggested keysize is 2048 bits\r
|
|
||||||
What keysize do you want? (1024) " { send -- "\r" }
|
|
||||||
timeout { exit 1 } }
|
|
||||||
expect {
|
|
||||||
-exact "\r
|
|
||||||
\r \rRequested keysize is 1024 bits\r
|
|
||||||
Please specify how long the key should be valid.\r
|
|
||||||
0 = key does not expire\r
|
|
||||||
<n> = key expires in n days\r
|
|
||||||
<n>w = key expires in n weeks\r
|
|
||||||
<n>m = key expires in n months\r
|
|
||||||
<n>y = key expires in n years\r
|
|
||||||
Key is valid for? (0) " { send -- "1\r" }
|
|
||||||
timeout { exit 1 } }
|
|
||||||
expect {
|
|
||||||
-exact "1\r
|
|
||||||
\r \rKey expires at " { }
|
|
||||||
timeout { exit 1 } }
|
|
||||||
expect {
|
|
||||||
-re "(.*)\r
|
|
||||||
" {}
|
|
||||||
timeout { exit 1 } }
|
|
||||||
expect {
|
|
||||||
-exact "Is this correct (y/n)? " { send -- "y\r" }
|
|
||||||
timeout { exit 1 } }
|
|
||||||
expect {
|
|
||||||
-exact "y\r
|
|
||||||
\r \r\r
|
|
||||||
You need a User-ID to identify your key; the software constructs the user id\r
|
|
||||||
from Real Name, Comment and Email Address in this form:\r
|
|
||||||
\"Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>\"\r
|
|
||||||
\r
|
|
||||||
Real name: " { send -- "Harry H.\r" }
|
|
||||||
timeout { exit 1 } }
|
|
||||||
expect {
|
|
||||||
-exact "Harry H.\r
|
|
||||||
\r \rEmail address: " { send -- "hh@ddorf.de\r" }
|
|
||||||
timeout { exit 1 } }
|
|
||||||
expect {
|
|
||||||
-exact "hh@ddorf.de\r
|
|
||||||
\r \rComment: " { send -- "a test\r" }
|
|
||||||
timeout { exit 1 } }
|
|
||||||
expect {
|
|
||||||
-exact "a test\r
|
|
||||||
\r \rYou selected this USER-ID:\r
|
|
||||||
\"Harry H. (a test) <hh@ddorf.de> (INSECURE!)\"\r
|
|
||||||
\r
|
|
||||||
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? " { send -- "o\r" }
|
|
||||||
timeout { exit 1 } }
|
|
||||||
expect {
|
|
||||||
-exact "o\r
|
|
||||||
\r \rYou need a Passphrase to protect your secret key.\r
|
|
||||||
\r
|
|
||||||
Enter passphrase: " { sleep 1; send -- "abc\r" }
|
|
||||||
timeout { exit 1 } }
|
|
||||||
expect {
|
|
||||||
-ex "\r \rRepeat passphrase: " { sleep 1; send -- "abc\r" }
|
|
||||||
timeout { exit 1 } }
|
|
||||||
set timeout 600
|
|
||||||
expect {
|
|
||||||
-re "^.*\r\npublic and secret key" { exit 0 }
|
|
||||||
eof { exit 1 }
|
|
||||||
}
|
|
||||||
exit 1
|
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
#*-*wedit:notab*-*
|
|
||||||
|
39
configure.ac
39
configure.ac
@ -183,7 +183,6 @@ MPI_OPT_FLAGS=""
|
|||||||
|
|
||||||
|
|
||||||
try_gettext=yes
|
try_gettext=yes
|
||||||
try_gdbm=yes
|
|
||||||
case "${target}" in
|
case "${target}" in
|
||||||
*-*-mingw32*)
|
*-*-mingw32*)
|
||||||
# special stuff for Windoze NT
|
# special stuff for Windoze NT
|
||||||
@ -201,7 +200,6 @@ case "${target}" in
|
|||||||
MingW32 systems and these systems lack Posix functions,
|
MingW32 systems and these systems lack Posix functions,
|
||||||
we use a simplified version of gettext])
|
we use a simplified version of gettext])
|
||||||
try_gettext="no"
|
try_gettext="no"
|
||||||
try_gdbm="no"
|
|
||||||
;;
|
;;
|
||||||
i?86-emx-os2 | i?86-*-os2*emx )
|
i?86-emx-os2 | i?86-*-os2*emx )
|
||||||
# OS/2 with the EMX environment
|
# OS/2 with the EMX environment
|
||||||
@ -209,7 +207,6 @@ case "${target}" in
|
|||||||
AC_DEFINE(HAVE_DRIVE_LETTERS)
|
AC_DEFINE(HAVE_DRIVE_LETTERS)
|
||||||
AC_DEFINE(HAVE_DOSISH_SYSTEM)
|
AC_DEFINE(HAVE_DOSISH_SYSTEM)
|
||||||
try_gettext="no"
|
try_gettext="no"
|
||||||
try_gdbm="no"
|
|
||||||
;;
|
;;
|
||||||
|
|
||||||
i?86-*-msdosdjgpp*)
|
i?86-*-msdosdjgpp*)
|
||||||
@ -218,7 +215,6 @@ case "${target}" in
|
|||||||
AC_DEFINE(HAVE_DRIVE_LETTERS)
|
AC_DEFINE(HAVE_DRIVE_LETTERS)
|
||||||
AC_DEFINE(HAVE_DOSISH_SYSTEM)
|
AC_DEFINE(HAVE_DOSISH_SYSTEM)
|
||||||
try_gettext="no"
|
try_gettext="no"
|
||||||
try_gdbm="no"
|
|
||||||
;;
|
;;
|
||||||
|
|
||||||
*-*-freebsd*)
|
*-*-freebsd*)
|
||||||
@ -363,41 +359,6 @@ AC_SUBST(USE_INCLUDED_LIBINTL)
|
|||||||
AC_SUBST(BUILD_INCLUDED_LIBINTL)
|
AC_SUBST(BUILD_INCLUDED_LIBINTL)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
dnl
|
|
||||||
dnl There are lot of misconfigured systems. We include
|
|
||||||
dnl gdbm support only if the lib and the header is installed.
|
|
||||||
dnl
|
|
||||||
if test "$try_gdbm" = yes; then
|
|
||||||
AC_CHECK_HEADERS(gdbm.h)
|
|
||||||
if test "$ac_cv_header_gdbm_h" = yes ; then
|
|
||||||
AC_CHECK_LIB(gdbm,gdbm_firstkey)
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
dnl This old test is here just for reference tin case it fails:
|
|
||||||
dnl
|
|
||||||
dnl Solaris needs -lsocket and -lnsl. Unisys system includes
|
|
||||||
dnl gethostbyname in libsocket but needs libnsl for socket.
|
|
||||||
dnl The test does not workfor all system, so some are hardcoded here.
|
|
||||||
dnl case "${target}" in
|
|
||||||
dnl i386-univel-sysv4*)
|
|
||||||
dnl LIBS="$LIBS -lsocket -lnsl"
|
|
||||||
dnl ;;
|
|
||||||
dnl *)
|
|
||||||
dnl AC_CHECK_LIB(nsl, gethostbyname)
|
|
||||||
dnl AC_CHECK_LIB(socket, socket, ac_need_libsocket=1, ac_try_nsl=1)
|
|
||||||
dnl if test x$ac_need_libsocket = x1; then
|
|
||||||
dnl LIBS="$LIBS -lsocket"
|
|
||||||
dnl fi
|
|
||||||
dnl if test x$ac_try_nsl = x1; then
|
|
||||||
dnl AC_CHECK_LIB(nsl, gethostbyname, ac_need_libnsl=1)
|
|
||||||
dnl if test x$ac_need_libnsl = x1
|
|
||||||
dnl then
|
|
||||||
dnl LIBS="$LIBS -lnsl"
|
|
||||||
dnl fi
|
|
||||||
dnl fi
|
|
||||||
dnl ;;
|
|
||||||
dnl esac
|
|
||||||
|
|
||||||
AC_CHECK_FUNC(gethostbyname, , AC_CHECK_LIB(nsl, gethostbyname))
|
AC_CHECK_FUNC(gethostbyname, , AC_CHECK_LIB(nsl, gethostbyname))
|
||||||
AC_CHECK_FUNC(setsockopt, , AC_CHECK_LIB(socket, setsockopt))
|
AC_CHECK_FUNC(setsockopt, , AC_CHECK_LIB(socket, setsockopt))
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
2001-09-03 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
|
* gpg.sgml, gpgv.sgml: Removed GDBM stuff.
|
||||||
|
|
||||||
2001-08-29 Werner Koch <wk@gnupg.org>
|
2001-08-29 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
* faq.raw: Described how to delete a secret key w/o a public key
|
* faq.raw: Described how to delete a secret key w/o a public key
|
||||||
|
@ -283,6 +283,10 @@ more arguments in future versions.
|
|||||||
END_STREAM
|
END_STREAM
|
||||||
Issued by pipemode.
|
Issued by pipemode.
|
||||||
|
|
||||||
|
INV_RECP <reason> <requested_recipient>
|
||||||
|
Issued for each unusable recipient. The only reason code
|
||||||
|
currently defined is 0 for "No specific reason given".
|
||||||
|
|
||||||
|
|
||||||
Key generation
|
Key generation
|
||||||
==============
|
==============
|
||||||
|
@ -839,8 +839,6 @@ does not contain a slash, it is assumed to be in the
|
|||||||
home-directory ("~/.gnupg" if --homedir is not used).
|
home-directory ("~/.gnupg" if --homedir is not used).
|
||||||
The filename may be prefixed with a scheme:</para>
|
The filename may be prefixed with a scheme:</para>
|
||||||
<para>"gnupg-ring:" is the default one.</para>
|
<para>"gnupg-ring:" is the default one.</para>
|
||||||
<para>"gnupg-gdbm:" may be used for a GDBM ring. Note that GDBM
|
|
||||||
is experimental and likely to be removed in future versions.</para>
|
|
||||||
<para>It might make sense to use it together with --no-default-keyring.
|
<para>It might make sense to use it together with --no-default-keyring.
|
||||||
</para></listitem></varlistentry>
|
</para></listitem></varlistentry>
|
||||||
|
|
||||||
|
@ -119,8 +119,6 @@ does not contain a slash, it is assumed to be in the
|
|||||||
home-directory ("~/.gnupg" if --homedir is not used).
|
home-directory ("~/.gnupg" if --homedir is not used).
|
||||||
The filename may be prefixed with a scheme:</para>
|
The filename may be prefixed with a scheme:</para>
|
||||||
<para>"gnupg-ring:" is the default one.</para>
|
<para>"gnupg-ring:" is the default one.</para>
|
||||||
<para>"gnupg-gdbm:" may be used for a GDBM ring. Note that GDBM
|
|
||||||
is experimental and likely to be removed in future versions.</para>
|
|
||||||
<para>It might make sense to use it together with --no-default-keyring.
|
<para>It might make sense to use it together with --no-default-keyring.
|
||||||
</para></listitem></varlistentry>
|
</para></listitem></varlistentry>
|
||||||
|
|
||||||
|
@ -1,3 +1,57 @@
|
|||||||
|
2001-09-06 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
|
* getkey.c (fixup_uidnode): Features flag is now a bit vector.
|
||||||
|
* keygen.c (add_feature_mdc): Ditto.
|
||||||
|
|
||||||
|
Revamped the entire key I/O code to be prepared for other ways of
|
||||||
|
key storages and to get rid of the existing shit. GDBM support has
|
||||||
|
gone.
|
||||||
|
* keydb.c: New
|
||||||
|
* keyring.c, keyring.h: New.
|
||||||
|
* ringedit.c: Removed. Moved some stuff to keyring.c
|
||||||
|
* getkey.c: Changed everything related to the key retrieving
|
||||||
|
functions which are now using the keydb_ functions.
|
||||||
|
(prepare_search, word_match_chars, word_match)
|
||||||
|
(prepare_word_match, compare_name): Moved to keyring.c
|
||||||
|
(get_pubkey_byname): Removed ctx arg and add ret_kdbhd
|
||||||
|
arg. Changed all callers.
|
||||||
|
(key_byname): Use get_pubkey_end to release the context and take
|
||||||
|
new ret_kbdhd arg. Changed all callers.
|
||||||
|
(classify_user_id2): Fill the 16 byte fingerprint up with 4 null
|
||||||
|
bytes not with zero bytes of value 4, tsss.
|
||||||
|
* import.c (import_one): Updated to use the new keydb interface.
|
||||||
|
(import_secret_one): Ditto.
|
||||||
|
(import_revoke_cert): Ditto.
|
||||||
|
* delkey.c (do_delete_key): Ditto.
|
||||||
|
* keyedit.c (keyedit_menu): Ditto.
|
||||||
|
(get_keyblock_byname): Removed.
|
||||||
|
* revoke.c (gen_revoke): Ditto.
|
||||||
|
* export.c (do_export_stream): Ditto.
|
||||||
|
* trustdb.c (update_trustdb): Ditto.
|
||||||
|
* g10.c, gpgv.c (main): Renamed add_keyblock_resource to
|
||||||
|
keydb_add_resource.
|
||||||
|
* Makefile.am: Added and removed files.
|
||||||
|
|
||||||
|
* keydb.h: Moved KBNODE typedef and MAX_FINGERPRINT_LEN to
|
||||||
|
* global.h: this new header.
|
||||||
|
|
||||||
|
2001-09-03 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
|
* passphrase.c (agent_get_passphrase): Changed nread to size_t.
|
||||||
|
(passphrase_clear_cache): Ditto.
|
||||||
|
|
||||||
|
* keyid.c (mk_datestr): Avoid trigraphs.
|
||||||
|
(fingerprint_from_pk): Cache the keyid in the pk.
|
||||||
|
|
||||||
|
* options.h: Add opt.with_fingerprint so that we know whether the
|
||||||
|
corresponding options was used.
|
||||||
|
* g10.c (main): Set it here.
|
||||||
|
* pkclist.c (check_signatures_trust): Always print fingerprint
|
||||||
|
when this option is used. Mixed a minor memory leak.
|
||||||
|
|
||||||
|
* status.c, status.h: New status INV_RECP.
|
||||||
|
* pkclist.c (build_pk_list): Issue this status.
|
||||||
|
|
||||||
2001-08-31 Werner Koch <wk@gnupg.org>
|
2001-08-31 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
* parse-packet.c (parse_key,parse_pubkeyenc)
|
* parse-packet.c (parse_key,parse_pubkeyenc)
|
||||||
|
@ -28,14 +28,15 @@ needed_libs = ../cipher/libcipher.a ../mpi/libmpi.a ../util/libutil.a
|
|||||||
bin_PROGRAMS = gpg gpgv
|
bin_PROGRAMS = gpg gpgv
|
||||||
|
|
||||||
common_source = \
|
common_source = \
|
||||||
|
global.h \
|
||||||
build-packet.c \
|
build-packet.c \
|
||||||
compress.c \
|
compress.c \
|
||||||
filter.h \
|
filter.h \
|
||||||
free-packet.c \
|
free-packet.c \
|
||||||
getkey.c \
|
getkey.c \
|
||||||
ringedit.c \
|
keydb.c keydb.h \
|
||||||
|
keyring.c keyring.h \
|
||||||
seskey.c \
|
seskey.c \
|
||||||
keydb.h \
|
|
||||||
kbnode.c \
|
kbnode.c \
|
||||||
main.h \
|
main.h \
|
||||||
mainproc.c \
|
mainproc.c \
|
||||||
|
43
g10/delkey.c
43
g10/delkey.c
@ -52,37 +52,35 @@ do_delete_key( const char *username, int secret, int *r_sec_avail )
|
|||||||
int rc = 0;
|
int rc = 0;
|
||||||
KBNODE keyblock = NULL;
|
KBNODE keyblock = NULL;
|
||||||
KBNODE node;
|
KBNODE node;
|
||||||
KBPOS kbpos;
|
KEYDB_HANDLE hd = keydb_new (secret);
|
||||||
PKT_public_key *pk = NULL;
|
PKT_public_key *pk = NULL;
|
||||||
PKT_secret_key *sk = NULL;
|
PKT_secret_key *sk = NULL;
|
||||||
u32 keyid[2];
|
u32 keyid[2];
|
||||||
int okay=0;
|
int okay=0;
|
||||||
int yes;
|
int yes;
|
||||||
|
KEYDB_SEARCH_DESC desc;
|
||||||
|
|
||||||
*r_sec_avail = 0;
|
*r_sec_avail = 0;
|
||||||
/* search the userid */
|
|
||||||
if (secret
|
|
||||||
&& classify_user_id (username, keyid, NULL, NULL, NULL) == 11) {
|
|
||||||
/* if the user supplied a long keyID we use the direct search
|
|
||||||
methods which allows us to delete a key if the
|
|
||||||
corresponding secret key is missing */
|
|
||||||
rc = find_secret_keyblock_direct (&kbpos, keyid);
|
|
||||||
}
|
|
||||||
else if (secret)
|
|
||||||
rc = find_secret_keyblock_byname (&kbpos, username);
|
|
||||||
else
|
|
||||||
rc = find_keyblock_byname (&kbpos, username);
|
|
||||||
|
|
||||||
if( rc ) {
|
/* search the userid */
|
||||||
log_error(_("%s: user not found\n"), username );
|
memset (&desc, 0, sizeof desc);
|
||||||
|
desc.mode = classify_user_id (username,
|
||||||
|
desc.u.kid,
|
||||||
|
desc.u.fpr,
|
||||||
|
&desc.u.name,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
rc = desc.mode? keydb_search (hd, &desc, 1):G10ERR_INV_USER_ID;
|
||||||
|
if (rc) {
|
||||||
|
log_error (_("key `%s' not found: %s\n"), username, g10_errstr (rc));
|
||||||
write_status_text( STATUS_DELETE_PROBLEM, "1" );
|
write_status_text( STATUS_DELETE_PROBLEM, "1" );
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read the keyblock */
|
/* read the keyblock */
|
||||||
rc = read_keyblock( &kbpos, &keyblock );
|
rc = keydb_get_keyblock (hd, &keyblock );
|
||||||
if( rc ) {
|
if (rc) {
|
||||||
log_error("%s: read problem: %s\n", username, g10_errstr(rc) );
|
log_error (_("error reading keyblock: %s\n"), g10_errstr(rc) );
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,15 +157,16 @@ do_delete_key( const char *username, int secret, int *r_sec_avail )
|
|||||||
|
|
||||||
|
|
||||||
if( okay ) {
|
if( okay ) {
|
||||||
rc = delete_keyblock( &kbpos );
|
rc = keydb_delete_keyblock (hd);
|
||||||
if( rc ) {
|
if (rc) {
|
||||||
log_error("delete_keyblock failed: %s\n", g10_errstr(rc) );
|
log_error (_("deleting keyblock failed: %s\n"), g10_errstr(rc) );
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
release_kbnode( keyblock );
|
keydb_release (hd);
|
||||||
|
release_kbnode (keyblock);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
43
g10/export.c
43
g10/export.c
@ -112,58 +112,56 @@ do_export_stream( IOBUF out, STRLIST users, int secret, int onlyrfc, int *any )
|
|||||||
PACKET pkt;
|
PACKET pkt;
|
||||||
KBNODE keyblock = NULL;
|
KBNODE keyblock = NULL;
|
||||||
KBNODE kbctx, node;
|
KBNODE kbctx, node;
|
||||||
KBPOS kbpos;
|
KEYDB_HANDLE kdbhd;
|
||||||
STRLIST sl;
|
STRLIST sl;
|
||||||
int all = !users;
|
int all = !users;
|
||||||
|
int all_first = 1;
|
||||||
|
|
||||||
*any = 0;
|
*any = 0;
|
||||||
memset( &zfx, 0, sizeof zfx);
|
memset( &zfx, 0, sizeof zfx);
|
||||||
init_packet( &pkt );
|
init_packet( &pkt );
|
||||||
|
|
||||||
|
kdbhd = keydb_new (secret);
|
||||||
|
|
||||||
if( opt.compress_keys && opt.compress )
|
if( opt.compress_keys && opt.compress )
|
||||||
iobuf_push_filter( out, compress_filter, &zfx );
|
iobuf_push_filter( out, compress_filter, &zfx );
|
||||||
|
|
||||||
if( all ) {
|
|
||||||
rc = enum_keyblocks( secret?5:0, &kbpos, &keyblock );
|
|
||||||
if( rc ) {
|
|
||||||
if( rc != -1 )
|
|
||||||
log_error("enum_keyblocks(open) failed: %s\n", g10_errstr(rc) );
|
|
||||||
goto leave;
|
|
||||||
}
|
|
||||||
all = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* use the correct sequence. strlist_last,prev do work correctly with
|
/* use the correct sequence. strlist_last,prev do work correctly with
|
||||||
* NULL pointers :-) */
|
* NULL pointers :-) */
|
||||||
for( sl=strlist_last(users); sl || all ; sl=strlist_prev( users, sl )) {
|
for( sl=strlist_last(users); sl || all ; sl=strlist_prev( users, sl )) {
|
||||||
if( all ) { /* get the next user */
|
if( all ) { /* get the next user */
|
||||||
rc = enum_keyblocks( 1, &kbpos, &keyblock );
|
rc = all_first ? keydb_search_first (kdbhd)
|
||||||
|
: keydb_search_next (kdbhd);
|
||||||
|
all_first = 0;
|
||||||
if( rc == -1 ) /* EOF */
|
if( rc == -1 ) /* EOF */
|
||||||
break;
|
break;
|
||||||
if( rc ) {
|
if( rc ) {
|
||||||
log_error("enum_keyblocks(read) failed: %s\n", g10_errstr(rc));
|
log_error ("error searching key: %s\n", g10_errstr(rc));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* search the userid */
|
KEYDB_SEARCH_DESC desc;
|
||||||
rc = secret? find_secret_keyblock_byname( &kbpos, sl->d )
|
|
||||||
: find_keyblock_byname( &kbpos, sl->d );
|
memset (&desc, 0, sizeof desc);
|
||||||
|
desc.mode = classify_user_id (sl->d, desc.u.kid, desc.u.fpr,
|
||||||
|
&desc.u.name, NULL);
|
||||||
|
rc = desc.mode? keydb_search (kdbhd, &desc, 1):G10ERR_INV_USER_ID;
|
||||||
if( rc ) {
|
if( rc ) {
|
||||||
log_error(_("%s: user not found: %s\n"), sl->d, g10_errstr(rc));
|
log_error (_("key `%s' not found: %s\n"),
|
||||||
|
sl->d, g10_errstr (rc));
|
||||||
rc = 0;
|
rc = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* read the keyblock */
|
|
||||||
rc = read_keyblock( &kbpos, &keyblock );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* read the keyblock */
|
||||||
|
rc = keydb_get_keyblock (kdbhd, &keyblock );
|
||||||
if( rc ) {
|
if( rc ) {
|
||||||
log_error(_("certificate read problem: %s\n"), g10_errstr(rc));
|
log_error (_("error reading keyblock: %s\n"), g10_errstr(rc) );
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* do not export keys which are incompatible with rfc2440 */
|
/* do not export keys which are incompatible with rfc2440 */
|
||||||
if( onlyrfc && (node = find_kbnode( keyblock, PKT_PUBLIC_KEY )) ) {
|
if( onlyrfc && (node = find_kbnode( keyblock, PKT_PUBLIC_KEY )) ) {
|
||||||
PKT_public_key *pk = node->pkt->pkt.public_key;
|
PKT_public_key *pk = node->pkt->pkt.public_key;
|
||||||
@ -229,8 +227,7 @@ do_export_stream( IOBUF out, STRLIST users, int secret, int onlyrfc, int *any )
|
|||||||
rc = 0;
|
rc = 0;
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
if( all == 2 )
|
keydb_release (kdbhd);
|
||||||
enum_keyblocks( 2, &kbpos, &keyblock ); /* close */
|
|
||||||
release_kbnode( keyblock );
|
release_kbnode( keyblock );
|
||||||
if( !*any )
|
if( !*any )
|
||||||
log_info(_("WARNING: nothing exported\n"));
|
log_info(_("WARNING: nothing exported\n"));
|
||||||
|
11
g10/g10.c
11
g10/g10.c
@ -886,6 +886,7 @@ main( int argc, char **argv )
|
|||||||
break;
|
break;
|
||||||
#endif /* __riscos__ */
|
#endif /* __riscos__ */
|
||||||
case oWithFingerprint:
|
case oWithFingerprint:
|
||||||
|
opt.with_fingerprint = 1;
|
||||||
with_fpr=1; /*fall thru*/
|
with_fpr=1; /*fall thru*/
|
||||||
case oFingerprint: opt.fingerprint++; break;
|
case oFingerprint: opt.fingerprint++; break;
|
||||||
case oSecretKeyring: append_to_strlist( &sec_nrings, pargs.r.ret_str); break;
|
case oSecretKeyring: append_to_strlist( &sec_nrings, pargs.r.ret_str); break;
|
||||||
@ -1225,13 +1226,13 @@ main( int argc, char **argv )
|
|||||||
&& !(cmd == aKMode && argc == 2 ) ) {
|
&& !(cmd == aKMode && argc == 2 ) ) {
|
||||||
|
|
||||||
if( !sec_nrings || default_keyring ) /* add default secret rings */
|
if( !sec_nrings || default_keyring ) /* add default secret rings */
|
||||||
add_keyblock_resource("secring" EXTSEP_S "gpg", 0, 1);
|
keydb_add_resource ("secring" EXTSEP_S "gpg", 0, 1);
|
||||||
for(sl = sec_nrings; sl; sl = sl->next )
|
for(sl = sec_nrings; sl; sl = sl->next )
|
||||||
add_keyblock_resource( sl->d, 0, 1 );
|
keydb_add_resource ( sl->d, 0, 1 );
|
||||||
if( !nrings || default_keyring ) /* add default ring */
|
if( !nrings || default_keyring ) /* add default ring */
|
||||||
add_keyblock_resource("pubring" EXTSEP_S "gpg", 0, 0);
|
keydb_add_resource ("pubring" EXTSEP_S "gpg", 0, 0);
|
||||||
for(sl = nrings; sl; sl = sl->next )
|
for(sl = nrings; sl; sl = sl->next )
|
||||||
add_keyblock_resource( sl->d, 0, 0 );
|
keydb_add_resource ( sl->d, 0, 0 );
|
||||||
}
|
}
|
||||||
FREE_STRLIST(nrings);
|
FREE_STRLIST(nrings);
|
||||||
FREE_STRLIST(sec_nrings);
|
FREE_STRLIST(sec_nrings);
|
||||||
@ -1445,7 +1446,7 @@ main( int argc, char **argv )
|
|||||||
else {
|
else {
|
||||||
/* add keyring (default keyrings are not registered in this
|
/* add keyring (default keyrings are not registered in this
|
||||||
* special case */
|
* special case */
|
||||||
add_keyblock_resource( argv[1], 0, 0 );
|
keydb_add_resource( argv[1], 0, 0 );
|
||||||
sl = NULL;
|
sl = NULL;
|
||||||
if (**argv)
|
if (**argv)
|
||||||
add_to_strlist2( &sl, *argv, utf8_strings );
|
add_to_strlist2( &sl, *argv, utf8_strings );
|
||||||
|
623
g10/getkey.c
623
g10/getkey.c
@ -34,7 +34,6 @@
|
|||||||
#include "trustdb.h"
|
#include "trustdb.h"
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
|
|
||||||
|
|
||||||
#define MAX_UNK_CACHE_ENTRIES 1000 /* we use a linked list - so I guess
|
#define MAX_UNK_CACHE_ENTRIES 1000 /* we use a linked list - so I guess
|
||||||
* this is a reasonable limit */
|
* this is a reasonable limit */
|
||||||
#define MAX_PK_CACHE_ENTRIES 200
|
#define MAX_PK_CACHE_ENTRIES 200
|
||||||
@ -45,60 +44,6 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* A map of the all characters valid used for word_match()
|
|
||||||
* Valid characters are in in this table converted to uppercase.
|
|
||||||
* because the upper 128 bytes have special meaning, we assume
|
|
||||||
* that they are all valid.
|
|
||||||
* Note: We must use numerical values here in case that this program
|
|
||||||
* will be converted to those little blue HAL9000s with their strange
|
|
||||||
* EBCDIC character set (user ids are UTF-8).
|
|
||||||
* wk 2000-04-13: Hmmm, does this really make sense, given the fact that
|
|
||||||
* we can run gpg now on a S/390 running GNU/Linux, where the code
|
|
||||||
* translation is done by the device drivers?
|
|
||||||
*/
|
|
||||||
static const byte word_match_chars[256] = {
|
|
||||||
/* 00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
/* 08 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
/* 10 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
/* 18 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
/* 20 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
/* 28 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
/* 30 */ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
|
||||||
/* 38 */ 0x38, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
/* 40 */ 0x00, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
|
|
||||||
/* 48 */ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
|
|
||||||
/* 50 */ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
|
|
||||||
/* 58 */ 0x58, 0x59, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
/* 60 */ 0x00, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
|
|
||||||
/* 68 */ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
|
|
||||||
/* 70 */ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
|
|
||||||
/* 78 */ 0x58, 0x59, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
/* 80 */ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
|
|
||||||
/* 88 */ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
|
|
||||||
/* 90 */ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
|
|
||||||
/* 98 */ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
|
|
||||||
/* a0 */ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
|
|
||||||
/* a8 */ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
|
|
||||||
/* b0 */ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
|
|
||||||
/* b8 */ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
|
|
||||||
/* c0 */ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
|
|
||||||
/* c8 */ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
|
|
||||||
/* d0 */ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
|
|
||||||
/* d8 */ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
|
|
||||||
/* e0 */ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
|
|
||||||
/* e8 */ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
|
|
||||||
/* f0 */ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
|
|
||||||
/* f8 */ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int mode;
|
|
||||||
u32 keyid[2];
|
|
||||||
byte fprint[20];
|
|
||||||
char *namebuf;
|
|
||||||
const char *name;
|
|
||||||
} getkey_item_t;
|
|
||||||
|
|
||||||
struct getkey_ctx_s {
|
struct getkey_ctx_s {
|
||||||
int exact;
|
int exact;
|
||||||
KBNODE keyblock;
|
KBNODE keyblock;
|
||||||
@ -107,10 +52,10 @@ struct getkey_ctx_s {
|
|||||||
int last_rc;
|
int last_rc;
|
||||||
int req_usage;
|
int req_usage;
|
||||||
int req_algo;
|
int req_algo;
|
||||||
ulong count;
|
KEYDB_HANDLE kr_handle;
|
||||||
int not_allocated;
|
int not_allocated;
|
||||||
int nitems;
|
int nitems;
|
||||||
getkey_item_t items[1];
|
KEYDB_SEARCH_DESC items[1];
|
||||||
};
|
};
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@ -157,11 +102,8 @@ typedef struct user_id_db {
|
|||||||
static user_id_db_t user_id_db;
|
static user_id_db_t user_id_db;
|
||||||
static int uid_cache_entries; /* number of entries in uid cache */
|
static int uid_cache_entries; /* number of entries in uid cache */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static char* prepare_word_match( const byte *name );
|
|
||||||
static int lookup( GETKEY_CTX ctx, KBNODE *ret_kb, int secmode );
|
|
||||||
static void merge_selfsigs( KBNODE keyblock );
|
static void merge_selfsigs( KBNODE keyblock );
|
||||||
|
static int lookup( GETKEY_CTX ctx, KBNODE *ret_keyblock, int secmode );
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@ -426,10 +368,11 @@ get_pubkey( PKT_public_key *pk, u32 *keyid )
|
|||||||
memset( &ctx, 0, sizeof ctx );
|
memset( &ctx, 0, sizeof ctx );
|
||||||
ctx.exact = 1; /* use the key ID exactly as given */
|
ctx.exact = 1; /* use the key ID exactly as given */
|
||||||
ctx.not_allocated = 1;
|
ctx.not_allocated = 1;
|
||||||
|
ctx.kr_handle = keydb_new (0);
|
||||||
ctx.nitems = 1;
|
ctx.nitems = 1;
|
||||||
ctx.items[0].mode = 11;
|
ctx.items[0].mode = KEYDB_SEARCH_MODE_LONG_KID;
|
||||||
ctx.items[0].keyid[0] = keyid[0];
|
ctx.items[0].u.kid[0] = keyid[0];
|
||||||
ctx.items[0].keyid[1] = keyid[1];
|
ctx.items[0].u.kid[1] = keyid[1];
|
||||||
ctx.req_algo = pk->req_algo;
|
ctx.req_algo = pk->req_algo;
|
||||||
ctx.req_usage = pk->req_usage;
|
ctx.req_usage = pk->req_usage;
|
||||||
rc = lookup( &ctx, &kb, 0 );
|
rc = lookup( &ctx, &kb, 0 );
|
||||||
@ -480,12 +423,13 @@ get_pubkeyblock( u32 *keyid )
|
|||||||
KBNODE keyblock = NULL;
|
KBNODE keyblock = NULL;
|
||||||
|
|
||||||
memset( &ctx, 0, sizeof ctx );
|
memset( &ctx, 0, sizeof ctx );
|
||||||
/* co need to set exact here because we want the entire block */
|
/* no need to set exact here because we want the entire block */
|
||||||
ctx.not_allocated = 1;
|
ctx.not_allocated = 1;
|
||||||
|
ctx.kr_handle = keydb_new (0);
|
||||||
ctx.nitems = 1;
|
ctx.nitems = 1;
|
||||||
ctx.items[0].mode = 11;
|
ctx.items[0].mode = KEYDB_SEARCH_MODE_LONG_KID;
|
||||||
ctx.items[0].keyid[0] = keyid[0];
|
ctx.items[0].u.kid[0] = keyid[0];
|
||||||
ctx.items[0].keyid[1] = keyid[1];
|
ctx.items[0].u.kid[1] = keyid[1];
|
||||||
rc = lookup( &ctx, &keyblock, 0 );
|
rc = lookup( &ctx, &keyblock, 0 );
|
||||||
get_pubkey_end( &ctx );
|
get_pubkey_end( &ctx );
|
||||||
|
|
||||||
@ -508,10 +452,11 @@ get_seckey( PKT_secret_key *sk, u32 *keyid )
|
|||||||
memset( &ctx, 0, sizeof ctx );
|
memset( &ctx, 0, sizeof ctx );
|
||||||
ctx.exact = 1; /* use the key ID exactly as given */
|
ctx.exact = 1; /* use the key ID exactly as given */
|
||||||
ctx.not_allocated = 1;
|
ctx.not_allocated = 1;
|
||||||
|
ctx.kr_handle = keydb_new (1);
|
||||||
ctx.nitems = 1;
|
ctx.nitems = 1;
|
||||||
ctx.items[0].mode = 11;
|
ctx.items[0].mode = KEYDB_SEARCH_MODE_LONG_KID;
|
||||||
ctx.items[0].keyid[0] = keyid[0];
|
ctx.items[0].u.kid[0] = keyid[0];
|
||||||
ctx.items[0].keyid[1] = keyid[1];
|
ctx.items[0].u.kid[1] = keyid[1];
|
||||||
ctx.req_algo = sk->req_algo;
|
ctx.req_algo = sk->req_algo;
|
||||||
ctx.req_usage = sk->req_usage;
|
ctx.req_usage = sk->req_usage;
|
||||||
rc = lookup( &ctx, &kb, 1 );
|
rc = lookup( &ctx, &kb, 1 );
|
||||||
@ -542,8 +487,13 @@ get_seckey( PKT_secret_key *sk, u32 *keyid )
|
|||||||
int
|
int
|
||||||
seckey_available( u32 *keyid )
|
seckey_available( u32 *keyid )
|
||||||
{
|
{
|
||||||
KBPOS dummy_kbpos;
|
int rc;
|
||||||
return find_secret_keyblock_direct (&dummy_kbpos, keyid)? G10ERR_NO_SECKEY:0;
|
KEYDB_HANDLE hd = keydb_new (1);
|
||||||
|
rc = keydb_search_kid (hd, keyid);
|
||||||
|
if ( rc == -1 )
|
||||||
|
rc = G10ERR_NO_SECKEY;
|
||||||
|
keydb_release (hd);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -638,36 +588,36 @@ classify_user_id2( const char *name, u32 *keyid, byte *fprint,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case '.': /* an email address, compare from end */
|
case '.': /* an email address, compare from end */
|
||||||
mode = 5;
|
mode = KEYDB_SEARCH_MODE_MAILEND;
|
||||||
s++;
|
s++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '<': /* an email address */
|
case '<': /* an email address */
|
||||||
mode = 3;
|
mode = KEYDB_SEARCH_MODE_MAIL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '@': /* part of an email address */
|
case '@': /* part of an email address */
|
||||||
mode = 4;
|
mode = KEYDB_SEARCH_MODE_MAILSUB;
|
||||||
s++;
|
s++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '=': /* exact compare */
|
case '=': /* exact compare */
|
||||||
mode = 1;
|
mode = KEYDB_SEARCH_MODE_EXACT;
|
||||||
s++;
|
s++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '*': /* case insensitive substring search */
|
case '*': /* case insensitive substring search */
|
||||||
mode = 2;
|
mode = KEYDB_SEARCH_MODE_SUBSTR;
|
||||||
s++;
|
s++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '+': /* compare individual words */
|
case '+': /* compare individual words */
|
||||||
mode = 6;
|
mode = KEYDB_SEARCH_MODE_WORDS;
|
||||||
s++;
|
s++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '#': /* local user id */
|
case '#': /* local user id */
|
||||||
mode = 12;
|
mode = KEYDB_SEARCH_MODE_TDBIDX;
|
||||||
s++;
|
s++;
|
||||||
if (keyid) {
|
if (keyid) {
|
||||||
if (keyid_from_lid(strtoul(s, NULL, 10), keyid))
|
if (keyid_from_lid(strtoul(s, NULL, 10), keyid))
|
||||||
@ -696,7 +646,7 @@ classify_user_id2( const char *name, u32 *keyid, byte *fprint,
|
|||||||
fprint[i]= 0;
|
fprint[i]= 0;
|
||||||
}
|
}
|
||||||
s = se + 1;
|
s = se + 1;
|
||||||
mode = 21;
|
mode = KEYDB_SEARCH_MODE_FPR;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -732,7 +682,7 @@ classify_user_id2( const char *name, u32 *keyid, byte *fprint,
|
|||||||
keyid[0] = 0;
|
keyid[0] = 0;
|
||||||
keyid[1] = strtoul( s, NULL, 16 );
|
keyid[1] = strtoul( s, NULL, 16 );
|
||||||
}
|
}
|
||||||
mode = 10;
|
mode = KEYDB_SEARCH_MODE_SHORT_KID;
|
||||||
}
|
}
|
||||||
else if (hexlength == 16
|
else if (hexlength == 16
|
||||||
|| (!hexprefix && hexlength == 17 && *s == '0')) {
|
|| (!hexprefix && hexlength == 17 && *s == '0')) {
|
||||||
@ -743,7 +693,7 @@ classify_user_id2( const char *name, u32 *keyid, byte *fprint,
|
|||||||
mem2str(buf, s, 9 );
|
mem2str(buf, s, 9 );
|
||||||
keyid[0] = strtoul( buf, NULL, 16 );
|
keyid[0] = strtoul( buf, NULL, 16 );
|
||||||
keyid[1] = strtoul( s+8, NULL, 16 );
|
keyid[1] = strtoul( s+8, NULL, 16 );
|
||||||
mode = 11;
|
mode = KEYDB_SEARCH_MODE_LONG_KID;
|
||||||
}
|
}
|
||||||
else if (hexlength == 32 || (!hexprefix && hexlength == 33
|
else if (hexlength == 32 || (!hexprefix && hexlength == 33
|
||||||
&& *s == '0')) {
|
&& *s == '0')) {
|
||||||
@ -752,7 +702,7 @@ classify_user_id2( const char *name, u32 *keyid, byte *fprint,
|
|||||||
if (hexlength == 33)
|
if (hexlength == 33)
|
||||||
s++;
|
s++;
|
||||||
if (fprint) {
|
if (fprint) {
|
||||||
memset(fprint+16, 4, 0);
|
memset(fprint+16, 0, 4);
|
||||||
for (i=0; i < 16; i++, s+=2) {
|
for (i=0; i < 16; i++, s+=2) {
|
||||||
int c = hextobyte(s);
|
int c = hextobyte(s);
|
||||||
if (c == -1)
|
if (c == -1)
|
||||||
@ -760,7 +710,7 @@ classify_user_id2( const char *name, u32 *keyid, byte *fprint,
|
|||||||
fprint[i] = c;
|
fprint[i] = c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mode = 16;
|
mode = KEYDB_SEARCH_MODE_FPR16;
|
||||||
}
|
}
|
||||||
else if (hexlength == 40 || (!hexprefix && hexlength == 41
|
else if (hexlength == 40 || (!hexprefix && hexlength == 41
|
||||||
&& *s == '0')) {
|
&& *s == '0')) {
|
||||||
@ -776,14 +726,14 @@ classify_user_id2( const char *name, u32 *keyid, byte *fprint,
|
|||||||
fprint[i] = c;
|
fprint[i] = c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mode = 20;
|
mode = KEYDB_SEARCH_MODE_FPR20;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (hexprefix) /* This was a hex number with a prefix */
|
if (hexprefix) /* This was a hex number with a prefix */
|
||||||
return 0; /* and a wrong length */
|
return 0; /* and a wrong length */
|
||||||
|
|
||||||
*force_exact = 0;
|
*force_exact = 0;
|
||||||
mode = 2; /* Default is case insensitive substring search */
|
mode = KEYDB_SEARCH_MODE_SUBSTR; /* default mode */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -815,7 +765,7 @@ classify_user_id( const char *name, u32 *keyid, byte *fprint,
|
|||||||
static int
|
static int
|
||||||
key_byname( GETKEY_CTX *retctx, STRLIST namelist,
|
key_byname( GETKEY_CTX *retctx, STRLIST namelist,
|
||||||
PKT_public_key *pk, PKT_secret_key *sk, int secmode,
|
PKT_public_key *pk, PKT_secret_key *sk, int secmode,
|
||||||
KBNODE *ret_kb )
|
KBNODE *ret_kb, KEYDB_HANDLE *ret_kdbhd )
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
int n;
|
int n;
|
||||||
@ -824,22 +774,25 @@ key_byname( GETKEY_CTX *retctx, STRLIST namelist,
|
|||||||
KBNODE help_kb = NULL;
|
KBNODE help_kb = NULL;
|
||||||
int exact;
|
int exact;
|
||||||
|
|
||||||
if( retctx ) /* reset the returned context in case of error */
|
if( retctx ) {/* reset the returned context in case of error */
|
||||||
|
assert (!ret_kdbhd); /* not allowed because the handle is
|
||||||
|
stored in the context */
|
||||||
*retctx = NULL;
|
*retctx = NULL;
|
||||||
|
}
|
||||||
|
if (ret_kdbhd)
|
||||||
|
*ret_kdbhd = NULL;
|
||||||
|
|
||||||
/* build the search context */
|
/* build the search context */
|
||||||
/* Performance hint: Use a static buffer if there is only one name */
|
|
||||||
/* and we don't have mode 6 */
|
|
||||||
for(n=0, r=namelist; r; r = r->next )
|
for(n=0, r=namelist; r; r = r->next )
|
||||||
n++;
|
n++;
|
||||||
ctx = m_alloc_clear( sizeof *ctx + (n-1)*sizeof ctx->items );
|
ctx = m_alloc_clear (sizeof *ctx + (n-1)*sizeof ctx->items );
|
||||||
ctx->nitems = n;
|
ctx->nitems = n;
|
||||||
|
|
||||||
for(n=0, r=namelist; r; r = r->next, n++ ) {
|
for(n=0, r=namelist; r; r = r->next, n++ ) {
|
||||||
int mode = classify_user_id2 ( r->d,
|
int mode = classify_user_id2 ( r->d,
|
||||||
ctx->items[n].keyid,
|
ctx->items[n].u.kid,
|
||||||
ctx->items[n].fprint,
|
ctx->items[n].u.fpr,
|
||||||
&ctx->items[n].name,
|
&ctx->items[n].u.name,
|
||||||
NULL, &exact );
|
NULL, &exact );
|
||||||
|
|
||||||
if ( exact )
|
if ( exact )
|
||||||
@ -849,14 +802,9 @@ key_byname( GETKEY_CTX *retctx, STRLIST namelist,
|
|||||||
m_free( ctx );
|
m_free( ctx );
|
||||||
return G10ERR_INV_USER_ID;
|
return G10ERR_INV_USER_ID;
|
||||||
}
|
}
|
||||||
if( ctx->items[n].mode == 6 ) {
|
|
||||||
ctx->items[n].namebuf = prepare_word_match(ctx->items[n].name);
|
|
||||||
ctx->items[n].name = ctx->items[n].namebuf;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ctx->kr_handle = keydb_new (secmode);
|
||||||
|
|
||||||
if ( !ret_kb )
|
if ( !ret_kb )
|
||||||
ret_kb = &help_kb;
|
ret_kb = &help_kb;
|
||||||
|
|
||||||
@ -883,29 +831,34 @@ key_byname( GETKEY_CTX *retctx, STRLIST namelist,
|
|||||||
|
|
||||||
release_kbnode ( help_kb );
|
release_kbnode ( help_kb );
|
||||||
|
|
||||||
if( retctx ) /* caller wants the context */
|
if (retctx) /* caller wants the context */
|
||||||
*retctx = ctx;
|
*retctx = ctx;
|
||||||
else {
|
else {
|
||||||
/* Hmmm, why not get_pubkey-end here?? */
|
if (ret_kdbhd) {
|
||||||
enum_keyblocks( 2, &ctx->kbpos, NULL );
|
*ret_kdbhd = ctx->kr_handle;
|
||||||
memset (&ctx->kbpos, 0, sizeof ctx->kbpos);
|
ctx->kr_handle = NULL;
|
||||||
for(n=0; n < ctx->nitems; n++ )
|
}
|
||||||
m_free( ctx->items[n].namebuf );
|
get_pubkey_end (ctx);
|
||||||
m_free( ctx );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find a public key from NAME and returh the keyblock or the key.
|
||||||
|
* If ret_kdb is not NULL, the KEYDB handle used to locate this keyblock is
|
||||||
|
* returned and the caller is responsible for closing it.
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
get_pubkey_byname( GETKEY_CTX *retctx, PKT_public_key *pk,
|
get_pubkey_byname (PKT_public_key *pk,
|
||||||
const char *name, KBNODE *ret_keyblock )
|
const char *name, KBNODE *ret_keyblock,
|
||||||
|
KEYDB_HANDLE *ret_kdbhd )
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
STRLIST namelist = NULL;
|
STRLIST namelist = NULL;
|
||||||
|
|
||||||
add_to_strlist( &namelist, name );
|
add_to_strlist( &namelist, name );
|
||||||
rc = key_byname( retctx, namelist, pk, NULL, 0, ret_keyblock );
|
rc = key_byname( NULL, namelist, pk, NULL, 0, ret_keyblock, ret_kdbhd);
|
||||||
free_strlist( namelist );
|
free_strlist( namelist );
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -914,7 +867,7 @@ int
|
|||||||
get_pubkey_bynames( GETKEY_CTX *retctx, PKT_public_key *pk,
|
get_pubkey_bynames( GETKEY_CTX *retctx, PKT_public_key *pk,
|
||||||
STRLIST names, KBNODE *ret_keyblock )
|
STRLIST names, KBNODE *ret_keyblock )
|
||||||
{
|
{
|
||||||
return key_byname( retctx, names, pk, NULL, 0, ret_keyblock );
|
return key_byname( retctx, names, pk, NULL, 0, ret_keyblock, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -934,12 +887,8 @@ void
|
|||||||
get_pubkey_end( GETKEY_CTX ctx )
|
get_pubkey_end( GETKEY_CTX ctx )
|
||||||
{
|
{
|
||||||
if( ctx ) {
|
if( ctx ) {
|
||||||
int n;
|
|
||||||
|
|
||||||
enum_keyblocks( 2, &ctx->kbpos, NULL );
|
|
||||||
memset (&ctx->kbpos, 0, sizeof ctx->kbpos);
|
memset (&ctx->kbpos, 0, sizeof ctx->kbpos);
|
||||||
for(n=0; n < ctx->nitems; n++ )
|
keydb_release (ctx->kr_handle);
|
||||||
m_free( ctx->items[n].namebuf );
|
|
||||||
if( !ctx->not_allocated )
|
if( !ctx->not_allocated )
|
||||||
m_free( ctx );
|
m_free( ctx );
|
||||||
}
|
}
|
||||||
@ -967,9 +916,10 @@ get_pubkey_byfprint( PKT_public_key *pk,
|
|||||||
memset( &ctx, 0, sizeof ctx );
|
memset( &ctx, 0, sizeof ctx );
|
||||||
ctx.exact = 1 ;
|
ctx.exact = 1 ;
|
||||||
ctx.not_allocated = 1;
|
ctx.not_allocated = 1;
|
||||||
|
ctx.kr_handle = keydb_new (0);
|
||||||
ctx.nitems = 1;
|
ctx.nitems = 1;
|
||||||
ctx.items[0].mode = fprint_len;
|
ctx.items[0].mode = fprint_len;
|
||||||
memcpy( ctx.items[0].fprint, fprint, fprint_len );
|
memcpy( ctx.items[0].u.fpr, fprint, fprint_len );
|
||||||
rc = lookup( &ctx, &kb, 0 );
|
rc = lookup( &ctx, &kb, 0 );
|
||||||
if (!rc && pk )
|
if (!rc && pk )
|
||||||
pk_from_block ( &ctx, pk, kb );
|
pk_from_block ( &ctx, pk, kb );
|
||||||
@ -996,9 +946,11 @@ get_keyblock_byfprint( KBNODE *ret_keyblock, const byte *fprint,
|
|||||||
|
|
||||||
memset( &ctx, 0, sizeof ctx );
|
memset( &ctx, 0, sizeof ctx );
|
||||||
ctx.not_allocated = 1;
|
ctx.not_allocated = 1;
|
||||||
|
ctx.kr_handle = keydb_new (0);
|
||||||
ctx.nitems = 1;
|
ctx.nitems = 1;
|
||||||
ctx.items[0].mode = fprint_len;
|
ctx.items[0].mode = fprint_len==16? KEYDB_SEARCH_MODE_FPR16
|
||||||
memcpy( ctx.items[0].fprint, fprint, fprint_len );
|
: KEYDB_SEARCH_MODE_FPR20;
|
||||||
|
memcpy( ctx.items[0].u.fpr, fprint, fprint_len );
|
||||||
rc = lookup( &ctx, ret_keyblock, 0 );
|
rc = lookup( &ctx, ret_keyblock, 0 );
|
||||||
get_pubkey_end( &ctx );
|
get_pubkey_end( &ctx );
|
||||||
}
|
}
|
||||||
@ -1025,10 +977,11 @@ get_keyblock_bylid( KBNODE *ret_keyblock, ulong lid )
|
|||||||
memset( &ctx, 0, sizeof ctx );
|
memset( &ctx, 0, sizeof ctx );
|
||||||
ctx.exact = 1;
|
ctx.exact = 1;
|
||||||
ctx.not_allocated = 1;
|
ctx.not_allocated = 1;
|
||||||
|
ctx.kr_handle = keydb_new (0);
|
||||||
ctx.nitems = 1;
|
ctx.nitems = 1;
|
||||||
ctx.items[0].mode = 12;
|
ctx.items[0].mode = KEYDB_SEARCH_MODE_LONG_KID;
|
||||||
ctx.items[0].keyid[0] = kid[0];
|
ctx.items[0].u.kid[0] = kid[0];
|
||||||
ctx.items[0].keyid[1] = kid[1];
|
ctx.items[0].u.kid[1] = kid[1];
|
||||||
rc = lookup( &ctx, ret_keyblock, 0 );
|
rc = lookup( &ctx, ret_keyblock, 0 );
|
||||||
get_pubkey_end( &ctx );
|
get_pubkey_end( &ctx );
|
||||||
|
|
||||||
@ -1053,7 +1006,7 @@ get_seckey_byname2( GETKEY_CTX *retctx,
|
|||||||
|
|
||||||
if( !name && opt.def_secret_key && *opt.def_secret_key ) {
|
if( !name && opt.def_secret_key && *opt.def_secret_key ) {
|
||||||
add_to_strlist( &namelist, opt.def_secret_key );
|
add_to_strlist( &namelist, opt.def_secret_key );
|
||||||
rc = key_byname( retctx, namelist, NULL, sk, 1, retblock );
|
rc = key_byname( retctx, namelist, NULL, sk, 1, retblock, NULL );
|
||||||
}
|
}
|
||||||
else if( !name ) { /* use the first one as default key */
|
else if( !name ) { /* use the first one as default key */
|
||||||
struct getkey_ctx_s ctx;
|
struct getkey_ctx_s ctx;
|
||||||
@ -1063,8 +1016,9 @@ get_seckey_byname2( GETKEY_CTX *retctx,
|
|||||||
assert (!retblock);
|
assert (!retblock);
|
||||||
memset( &ctx, 0, sizeof ctx );
|
memset( &ctx, 0, sizeof ctx );
|
||||||
ctx.not_allocated = 1;
|
ctx.not_allocated = 1;
|
||||||
|
ctx.kr_handle = keydb_new (1);
|
||||||
ctx.nitems = 1;
|
ctx.nitems = 1;
|
||||||
ctx.items[0].mode = 15;
|
ctx.items[0].mode = KEYDB_SEARCH_MODE_FIRST;
|
||||||
rc = lookup( &ctx, &kb, 1 );
|
rc = lookup( &ctx, &kb, 1 );
|
||||||
if (!rc && sk )
|
if (!rc && sk )
|
||||||
sk_from_block ( &ctx, sk, kb );
|
sk_from_block ( &ctx, sk, kb );
|
||||||
@ -1073,7 +1027,7 @@ get_seckey_byname2( GETKEY_CTX *retctx,
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
add_to_strlist( &namelist, name );
|
add_to_strlist( &namelist, name );
|
||||||
rc = key_byname( retctx, namelist, NULL, sk, 1, retblock );
|
rc = key_byname( retctx, namelist, NULL, sk, 1, retblock, NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
free_strlist( namelist );
|
free_strlist( namelist );
|
||||||
@ -1095,7 +1049,7 @@ int
|
|||||||
get_seckey_bynames( GETKEY_CTX *retctx, PKT_secret_key *sk,
|
get_seckey_bynames( GETKEY_CTX *retctx, PKT_secret_key *sk,
|
||||||
STRLIST names, KBNODE *ret_keyblock )
|
STRLIST names, KBNODE *ret_keyblock )
|
||||||
{
|
{
|
||||||
return key_byname( retctx, names, NULL, sk, 1, ret_keyblock );
|
return key_byname( retctx, names, NULL, sk, 1, ret_keyblock, NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1119,150 +1073,6 @@ get_seckey_end( GETKEY_CTX ctx )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************
|
|
||||||
************** compare functions **********************
|
|
||||||
*******************************************************/
|
|
||||||
|
|
||||||
/****************
|
|
||||||
* Do a word match (original user id starts with a '+').
|
|
||||||
* The pattern is already tokenized to a more suitable format:
|
|
||||||
* There are only the real words in it delimited by one space
|
|
||||||
* and all converted to uppercase.
|
|
||||||
*
|
|
||||||
* Returns: 0 if all words match.
|
|
||||||
*
|
|
||||||
* Note: This algorithm is a straightforward one and not very
|
|
||||||
* fast. It works for UTF-8 strings. The uidlen should
|
|
||||||
* be removed but due to the fact that old versions of
|
|
||||||
* pgp don't use UTF-8 we still use the length; this should
|
|
||||||
* be fixed in parse-packet (and replace \0 by some special
|
|
||||||
* UTF-8 encoding)
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
word_match( const byte *uid, size_t uidlen, const byte *pattern )
|
|
||||||
{
|
|
||||||
size_t wlen, n;
|
|
||||||
const byte *p;
|
|
||||||
const byte *s;
|
|
||||||
|
|
||||||
for( s=pattern; *s; ) {
|
|
||||||
do {
|
|
||||||
/* skip leading delimiters */
|
|
||||||
while( uidlen && !word_match_chars[*uid] )
|
|
||||||
uid++, uidlen--;
|
|
||||||
/* get length of the word */
|
|
||||||
n = uidlen; p = uid;
|
|
||||||
while( n && word_match_chars[*p] )
|
|
||||||
p++, n--;
|
|
||||||
wlen = p - uid;
|
|
||||||
/* and compare against the current word from pattern */
|
|
||||||
for(n=0, p=uid; n < wlen && s[n] != ' ' && s[n] ; n++, p++ ) {
|
|
||||||
if( word_match_chars[*p] != s[n] )
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if( n == wlen && (s[n] == ' ' || !s[n]) )
|
|
||||||
break; /* found */
|
|
||||||
uid += wlen;
|
|
||||||
uidlen -= wlen;
|
|
||||||
} while( uidlen );
|
|
||||||
if( !uidlen )
|
|
||||||
return -1; /* not found */
|
|
||||||
|
|
||||||
/* advance to next word in pattern */
|
|
||||||
for(; *s != ' ' && *s ; s++ )
|
|
||||||
;
|
|
||||||
if( *s )
|
|
||||||
s++ ;
|
|
||||||
}
|
|
||||||
return 0; /* found */
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************
|
|
||||||
* prepare word word_match; that is parse the name and
|
|
||||||
* build the pattern.
|
|
||||||
* caller has to free the returned pattern
|
|
||||||
*/
|
|
||||||
static char*
|
|
||||||
prepare_word_match( const byte *name )
|
|
||||||
{
|
|
||||||
byte *pattern, *p;
|
|
||||||
int c;
|
|
||||||
|
|
||||||
/* the original length is always enough for the pattern */
|
|
||||||
p = pattern = m_alloc(strlen(name)+1);
|
|
||||||
do {
|
|
||||||
/* skip leading delimiters */
|
|
||||||
while( *name && !word_match_chars[*name] )
|
|
||||||
name++;
|
|
||||||
/* copy as long as we don't have a delimiter and convert
|
|
||||||
* to uppercase.
|
|
||||||
* fixme: how can we handle utf8 uppercasing */
|
|
||||||
for( ; *name && (c=word_match_chars[*name]); name++ )
|
|
||||||
*p++ = c;
|
|
||||||
*p++ = ' '; /* append pattern delimiter */
|
|
||||||
} while( *name );
|
|
||||||
p[-1] = 0; /* replace last pattern delimiter by EOS */
|
|
||||||
|
|
||||||
return pattern;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
compare_name( const char *uid, size_t uidlen, const char *name, int mode )
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
const char *s, *se;
|
|
||||||
|
|
||||||
if( mode == 1 ) { /* exact match */
|
|
||||||
for(i=0; name[i] && uidlen; i++, uidlen-- )
|
|
||||||
if( uid[i] != name[i] )
|
|
||||||
break;
|
|
||||||
if( !uidlen && !name[i] )
|
|
||||||
return 0; /* found */
|
|
||||||
}
|
|
||||||
else if( mode == 2 ) { /* case insensitive substring */
|
|
||||||
if( ascii_memistr( uid, uidlen, name ) )
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else if( mode >= 3 && mode <= 5 ) { /* look at the email address */
|
|
||||||
for( i=0, s= uid; i < uidlen && *s != '<'; s++, i++ )
|
|
||||||
;
|
|
||||||
if( i < uidlen ) {
|
|
||||||
/* skip opening delim and one char and look for the closing one*/
|
|
||||||
s++; i++;
|
|
||||||
for( se=s+1, i++; i < uidlen && *se != '>'; se++, i++ )
|
|
||||||
;
|
|
||||||
if( i < uidlen ) {
|
|
||||||
i = se - s;
|
|
||||||
if( mode == 3 ) { /* exact email address */
|
|
||||||
if( strlen(name)-2 == i
|
|
||||||
&& !ascii_memcasecmp( s, name+1, i) )
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else if( mode == 4 ) { /* email substring */
|
|
||||||
if( ascii_memistr( s, i, name ) )
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else { /* email from end */
|
|
||||||
/* nyi */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if( mode == 6 )
|
|
||||||
return word_match( uid, uidlen, name );
|
|
||||||
else
|
|
||||||
BUG();
|
|
||||||
|
|
||||||
return -1; /* not found */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/************************************************
|
/************************************************
|
||||||
************* Merging stuff ********************
|
************* Merging stuff ********************
|
||||||
@ -1446,14 +1256,8 @@ fixup_uidnode ( KBNODE uidnode, KBNODE signode, u32 keycreated )
|
|||||||
/* see whether we have the MDC feature */
|
/* see whether we have the MDC feature */
|
||||||
uid->mdc_feature = 0;
|
uid->mdc_feature = 0;
|
||||||
p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_FEATURES, &n);
|
p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_FEATURES, &n);
|
||||||
if (!p)
|
if (p && n && (p[0] & 0x01))
|
||||||
n=0;
|
|
||||||
for (; n; n--, p++) {
|
|
||||||
if (*p == 1) {
|
|
||||||
uid->mdc_feature = 1;
|
uid->mdc_feature = 1;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1936,8 +1740,9 @@ merge_public_with_secret ( KBNODE pubblock, KBNODE secblock )
|
|||||||
|
|
||||||
/* This function checks that for every public subkey a corresponding
|
/* This function checks that for every public subkey a corresponding
|
||||||
* secret subkey is avalable and deletes the public subkey otherwise.
|
* secret subkey is avalable and deletes the public subkey otherwise.
|
||||||
* We need this function becuase we can'tdelete it later when we
|
* We need this function because we can't delete it later when we
|
||||||
* actually merge the secret parts into the pubring.
|
* actually merge the secret parts into the pubring.
|
||||||
|
& The function also plays some games with the node flags.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
premerge_public_with_secret ( KBNODE pubblock, KBNODE secblock )
|
premerge_public_with_secret ( KBNODE pubblock, KBNODE secblock )
|
||||||
@ -1948,6 +1753,7 @@ premerge_public_with_secret ( KBNODE pubblock, KBNODE secblock )
|
|||||||
assert ( secblock->pkt->pkttype == PKT_SECRET_KEY );
|
assert ( secblock->pkt->pkttype == PKT_SECRET_KEY );
|
||||||
|
|
||||||
for (pub=pubblock,last=NULL; pub; last = pub, pub = pub->next ) {
|
for (pub=pubblock,last=NULL; pub; last = pub, pub = pub->next ) {
|
||||||
|
pub->flag &= ~3; /* reset bits 0 and 1 */
|
||||||
if ( pub->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
|
if ( pub->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
|
||||||
KBNODE sec;
|
KBNODE sec;
|
||||||
PKT_public_key *pk = pub->pkt->pkt.public_key;
|
PKT_public_key *pk = pub->pkt->pkt.public_key;
|
||||||
@ -1962,6 +1768,8 @@ premerge_public_with_secret ( KBNODE pubblock, KBNODE secblock )
|
|||||||
Fix the pubkey usage */
|
Fix the pubkey usage */
|
||||||
pk->pubkey_usage &= ~PUBKEY_USAGE_SIG;
|
pk->pubkey_usage &= ~PUBKEY_USAGE_SIG;
|
||||||
}
|
}
|
||||||
|
/* transfer flag bits 0 and 1 to the pubblock */
|
||||||
|
pub->flag |= (sec->flag &3);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1994,80 +1802,6 @@ premerge_public_with_secret ( KBNODE pubblock, KBNODE secblock )
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/************************************************
|
|
||||||
************* Find stuff ***********************
|
|
||||||
************************************************/
|
|
||||||
|
|
||||||
static PKT_user_id *
|
|
||||||
find_by_name( KBNODE keyblock, const char *name, int mode )
|
|
||||||
{
|
|
||||||
KBNODE k;
|
|
||||||
|
|
||||||
for(k=keyblock; k; k = k->next ) {
|
|
||||||
if( k->pkt->pkttype == PKT_USER_ID
|
|
||||||
&& !compare_name( k->pkt->pkt.user_id->name,
|
|
||||||
k->pkt->pkt.user_id->len, name, mode)) {
|
|
||||||
return k->pkt->pkt.user_id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static KBNODE
|
|
||||||
find_by_keyid( KBNODE keyblock, u32 *keyid, int mode )
|
|
||||||
{
|
|
||||||
KBNODE k;
|
|
||||||
|
|
||||||
for(k=keyblock; k; k = k->next ) {
|
|
||||||
if( k->pkt->pkttype == PKT_PUBLIC_KEY
|
|
||||||
|| k->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
|
|
||||||
u32 aki[2];
|
|
||||||
keyid_from_pk( k->pkt->pkt.public_key, aki );
|
|
||||||
if( aki[1] == keyid[1] && ( mode == 10 || aki[0] == keyid[0] ) ) {
|
|
||||||
return k; /* found */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static KBNODE
|
|
||||||
find_by_fpr( KBNODE keyblock, const char *name, int mode )
|
|
||||||
{
|
|
||||||
KBNODE k;
|
|
||||||
|
|
||||||
for(k=keyblock; k; k = k->next ) {
|
|
||||||
if( k->pkt->pkttype == PKT_PUBLIC_KEY
|
|
||||||
|| k->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
|
|
||||||
byte afp[MAX_FINGERPRINT_LEN];
|
|
||||||
size_t an;
|
|
||||||
|
|
||||||
fingerprint_from_pk(k->pkt->pkt.public_key, afp, &an );
|
|
||||||
if ( mode == 21 ) {
|
|
||||||
/* Unified fingerprint. The fingerprint is always 20 bytes*/
|
|
||||||
while ( an < 20 )
|
|
||||||
afp[an++] = 0;
|
|
||||||
if ( !memcmp( afp, name, 20 ) )
|
|
||||||
return k;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if( an == mode && !memcmp( afp, name, an) ) {
|
|
||||||
return k;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* See see whether the key fits
|
/* See see whether the key fits
|
||||||
* our requirements and in case we do not
|
* our requirements and in case we do not
|
||||||
* request the primary key, we should select
|
* request the primary key, we should select
|
||||||
@ -2098,24 +1832,40 @@ find_by_fpr( KBNODE keyblock, const char *name, int mode )
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static int
|
static int
|
||||||
finish_lookup( GETKEY_CTX ctx, KBNODE foundk, PKT_user_id *foundu )
|
finish_lookup (GETKEY_CTX ctx)
|
||||||
{
|
{
|
||||||
KBNODE keyblock = ctx->keyblock;
|
KBNODE keyblock = ctx->keyblock;
|
||||||
KBNODE k;
|
KBNODE k;
|
||||||
|
KBNODE foundk = NULL;
|
||||||
|
PKT_user_id *foundu = NULL;
|
||||||
#define USAGE_MASK (PUBKEY_USAGE_SIG|PUBKEY_USAGE_ENC)
|
#define USAGE_MASK (PUBKEY_USAGE_SIG|PUBKEY_USAGE_ENC)
|
||||||
unsigned int req_usage = ( ctx->req_usage & USAGE_MASK );
|
unsigned int req_usage = ( ctx->req_usage & USAGE_MASK );
|
||||||
u32 latest_date;
|
u32 latest_date;
|
||||||
KBNODE latest_key;
|
KBNODE latest_key;
|
||||||
u32 curtime = make_timestamp ();
|
u32 curtime = make_timestamp ();
|
||||||
|
|
||||||
assert( !foundk || foundk->pkt->pkttype == PKT_PUBLIC_KEY
|
|
||||||
|| foundk->pkt->pkttype == PKT_PUBLIC_SUBKEY );
|
|
||||||
assert( keyblock->pkt->pkttype == PKT_PUBLIC_KEY );
|
assert( keyblock->pkt->pkttype == PKT_PUBLIC_KEY );
|
||||||
|
|
||||||
ctx->found_key = NULL;
|
ctx->found_key = NULL;
|
||||||
|
|
||||||
if (!ctx->exact)
|
if (ctx->exact) {
|
||||||
foundk = NULL;
|
for (k=keyblock; k; k = k->next) {
|
||||||
|
if ( (k->flag & 1) ) {
|
||||||
|
assert ( k->pkt->pkttype == PKT_PUBLIC_KEY
|
||||||
|
|| k->pkt->pkttype == PKT_PUBLIC_SUBKEY );
|
||||||
|
foundk = k;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (k=keyblock; k; k = k->next) {
|
||||||
|
if ( (k->flag & 2) ) {
|
||||||
|
assert (k->pkt->pkttype == PKT_USER_ID);
|
||||||
|
foundu = k->pkt->pkt.user_id;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ( DBG_CACHE )
|
if ( DBG_CACHE )
|
||||||
log_debug( "finish_lookup: checking key %08lX (%s)(req_usage=%x)\n",
|
log_debug( "finish_lookup: checking key %08lX (%s)(req_usage=%x)\n",
|
||||||
@ -2260,18 +2010,17 @@ static int
|
|||||||
lookup( GETKEY_CTX ctx, KBNODE *ret_keyblock, int secmode )
|
lookup( GETKEY_CTX ctx, KBNODE *ret_keyblock, int secmode )
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
int oldmode = set_packet_list_mode(0);
|
|
||||||
KBNODE secblock = NULL; /* helper */
|
KBNODE secblock = NULL; /* helper */
|
||||||
int no_suitable_key = 0;
|
int no_suitable_key = 0;
|
||||||
|
|
||||||
if( !ctx->count ) /* first time */
|
|
||||||
rc = enum_keyblocks( secmode? 5:0, &ctx->kbpos, NULL );
|
|
||||||
else
|
|
||||||
rc = 0;
|
rc = 0;
|
||||||
if( !rc ) {
|
while (!(rc = keydb_search (ctx->kr_handle, ctx->items, ctx->nitems))) {
|
||||||
while( !(rc = enum_keyblocks( 1, &ctx->kbpos, &ctx->keyblock )) ) {
|
rc = keydb_get_keyblock (ctx->kr_handle, &ctx->keyblock);
|
||||||
int n;
|
if (rc) {
|
||||||
getkey_item_t *item;
|
log_error ("keydb_get_keyblock failed: %s\n", g10_errstr(rc));
|
||||||
|
rc = 0;
|
||||||
|
goto skip;
|
||||||
|
}
|
||||||
|
|
||||||
if ( secmode ) {
|
if ( secmode ) {
|
||||||
/* find the correspondig public key and use this
|
/* find the correspondig public key and use this
|
||||||
@ -2279,10 +2028,11 @@ lookup( GETKEY_CTX ctx, KBNODE *ret_keyblock, int secmode )
|
|||||||
u32 aki[2];
|
u32 aki[2];
|
||||||
KBNODE k = ctx->keyblock;
|
KBNODE k = ctx->keyblock;
|
||||||
|
|
||||||
if ( k->pkt->pkttype != PKT_SECRET_KEY )
|
if (k->pkt->pkttype != PKT_SECRET_KEY)
|
||||||
BUG();
|
BUG();
|
||||||
keyid_from_sk( k->pkt->pkt.secret_key, aki );
|
|
||||||
k = get_pubkeyblock( aki );
|
keyid_from_sk (k->pkt->pkt.secret_key, aki);
|
||||||
|
k = get_pubkeyblock (aki);
|
||||||
if( !k ) {
|
if( !k ) {
|
||||||
if (!opt.quiet)
|
if (!opt.quiet)
|
||||||
log_info(_("key %08lX: secret key without public key "
|
log_info(_("key %08lX: secret key without public key "
|
||||||
@ -2291,42 +2041,15 @@ lookup( GETKEY_CTX ctx, KBNODE *ret_keyblock, int secmode )
|
|||||||
}
|
}
|
||||||
secblock = ctx->keyblock;
|
secblock = ctx->keyblock;
|
||||||
ctx->keyblock = k;
|
ctx->keyblock = k;
|
||||||
|
|
||||||
premerge_public_with_secret ( ctx->keyblock, secblock );
|
premerge_public_with_secret ( ctx->keyblock, secblock );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* warning: node flag bits 0 and 1 should be preserved by
|
||||||
/* loop over all the user ids we want to look for */
|
* merge_selfsigs. For secret keys, premerge did tranfer the
|
||||||
item = ctx->items;
|
* keys to the keyblock */
|
||||||
for(n=0; n < ctx->nitems; n++, item++ ) {
|
|
||||||
KBNODE k = NULL;
|
|
||||||
int found = 0;
|
|
||||||
PKT_user_id *found_uid = NULL;
|
|
||||||
|
|
||||||
if( item->mode < 10 ) {
|
|
||||||
found_uid = find_by_name( ctx->keyblock,
|
|
||||||
item->name, item->mode );
|
|
||||||
found = !!found_uid;
|
|
||||||
}
|
|
||||||
else if( item->mode >= 10 && item->mode <= 12 ) {
|
|
||||||
k = find_by_keyid( ctx->keyblock,
|
|
||||||
item->keyid, item->mode );
|
|
||||||
found = !!k;
|
|
||||||
}
|
|
||||||
else if( item->mode == 15 ) {
|
|
||||||
found = 1;
|
|
||||||
}
|
|
||||||
else if( item->mode == 16 || item->mode == 20
|
|
||||||
|| item->mode == 21 ) {
|
|
||||||
k = find_by_fpr( ctx->keyblock,
|
|
||||||
item->fprint, item->mode );
|
|
||||||
found = !!k;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
BUG();
|
|
||||||
if( found ) {
|
|
||||||
/* this keyblock looks fine - do further investigation */
|
|
||||||
merge_selfsigs ( ctx->keyblock );
|
merge_selfsigs ( ctx->keyblock );
|
||||||
if ( finish_lookup( ctx, k, found_uid ) ) {
|
if ( finish_lookup (ctx) ) {
|
||||||
no_suitable_key = 0;
|
no_suitable_key = 0;
|
||||||
if ( secmode ) {
|
if ( secmode ) {
|
||||||
merge_public_with_secret ( ctx->keyblock,
|
merge_public_with_secret ( ctx->keyblock,
|
||||||
@ -2338,10 +2061,9 @@ lookup( GETKEY_CTX ctx, KBNODE *ret_keyblock, int secmode )
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
no_suitable_key = 1;
|
no_suitable_key = 1;
|
||||||
}
|
|
||||||
}
|
|
||||||
skip:
|
skip:
|
||||||
/* release resources and try the next keyblock */
|
/* release resources and continue search */
|
||||||
if ( secmode ) {
|
if ( secmode ) {
|
||||||
release_kbnode( secblock );
|
release_kbnode( secblock );
|
||||||
secblock = NULL;
|
secblock = NULL;
|
||||||
@ -2349,11 +2071,10 @@ lookup( GETKEY_CTX ctx, KBNODE *ret_keyblock, int secmode )
|
|||||||
release_kbnode( ctx->keyblock );
|
release_kbnode( ctx->keyblock );
|
||||||
ctx->keyblock = NULL;
|
ctx->keyblock = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
found:
|
found:
|
||||||
;
|
|
||||||
}
|
|
||||||
if( rc && rc != -1 )
|
if( rc && rc != -1 )
|
||||||
log_error("enum_keyblocks failed: %s\n", g10_errstr(rc));
|
log_error("enum_keyblocks_read failed: %s\n", g10_errstr(rc));
|
||||||
|
|
||||||
if( !rc ) {
|
if( !rc ) {
|
||||||
*ret_keyblock = ctx->keyblock; /* return the keyblock */
|
*ret_keyblock = ctx->keyblock; /* return the keyblock */
|
||||||
@ -2370,29 +2091,8 @@ lookup( GETKEY_CTX ctx, KBNODE *ret_keyblock, int secmode )
|
|||||||
}
|
}
|
||||||
release_kbnode( ctx->keyblock );
|
release_kbnode( ctx->keyblock );
|
||||||
ctx->keyblock = NULL;
|
ctx->keyblock = NULL;
|
||||||
set_packet_list_mode(oldmode);
|
|
||||||
#if 0
|
|
||||||
if( opt.debug & DBG_MEMSTAT_VALUE ) {
|
|
||||||
static int initialized;
|
|
||||||
|
|
||||||
if( !initialized ) {
|
|
||||||
initialized = 1;
|
|
||||||
atexit( print_stats );
|
|
||||||
}
|
|
||||||
|
|
||||||
assert( ctx->mode < DIM(lkup_stats) );
|
|
||||||
lkup_stats[ctx->mode].any = 1;
|
|
||||||
if( !rc )
|
|
||||||
lkup_stats[ctx->mode].okay_count++;
|
|
||||||
else if ( rc == G10ERR_NO_PUBKEY || rc == G10ERR_NO_SECKEY )
|
|
||||||
lkup_stats[ctx->mode].nokey_count++;
|
|
||||||
else
|
|
||||||
lkup_stats[ctx->mode].error_count++;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ctx->last_rc = rc;
|
ctx->last_rc = rc;
|
||||||
ctx->count++;
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2414,33 +2114,32 @@ lookup( GETKEY_CTX ctx, KBNODE *ret_keyblock, int secmode )
|
|||||||
* to indicate EOF.
|
* to indicate EOF.
|
||||||
* 4) Always call this function a last time with SK set to NULL,
|
* 4) Always call this function a last time with SK set to NULL,
|
||||||
* so that can free it's context.
|
* so that can free it's context.
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
enum_secret_keys( void **context, PKT_secret_key *sk, int with_subkeys )
|
enum_secret_keys( void **context, PKT_secret_key *sk, int with_subkeys )
|
||||||
{
|
{
|
||||||
int rc=0;
|
int rc=0;
|
||||||
PACKET pkt;
|
|
||||||
int save_mode;
|
|
||||||
struct {
|
struct {
|
||||||
int eof;
|
int eof;
|
||||||
int sequence;
|
int first;
|
||||||
const char *name;
|
KEYDB_HANDLE hd;
|
||||||
IOBUF iobuf;
|
KBNODE keyblock;
|
||||||
|
KBNODE node;
|
||||||
} *c = *context;
|
} *c = *context;
|
||||||
|
|
||||||
|
|
||||||
if( !c ) { /* make a new context */
|
if( !c ) { /* make a new context */
|
||||||
c = m_alloc_clear( sizeof *c );
|
c = m_alloc_clear( sizeof *c );
|
||||||
*context = c;
|
*context = c;
|
||||||
c->sequence = 0;
|
c->hd = keydb_new (1);
|
||||||
c->name = enum_keyblock_resources( &c->sequence, 1 );
|
c->first = 1;
|
||||||
|
c->keyblock = NULL;
|
||||||
|
c->node = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !sk ) { /* free the context */
|
if( !sk ) { /* free the context */
|
||||||
if( c->iobuf )
|
keydb_release (c->hd);
|
||||||
iobuf_close(c->iobuf);
|
release_kbnode (c->keyblock);
|
||||||
m_free( c );
|
m_free( c );
|
||||||
*context = NULL;
|
*context = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
@ -2449,33 +2148,33 @@ enum_secret_keys( void **context, PKT_secret_key *sk, int with_subkeys )
|
|||||||
if( c->eof )
|
if( c->eof )
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* FIXME: This assumes a plain keyring file */
|
do {
|
||||||
for( ; c->name; c->name = enum_keyblock_resources( &c->sequence, 1 ) ) {
|
/* get the next secret key from the current keyblock */
|
||||||
if( !c->iobuf ) {
|
for (; c->node; c->node = c->node->next) {
|
||||||
if( !(c->iobuf = iobuf_open( c->name ) ) ) {
|
if (c->node->pkt->pkttype == PKT_SECRET_KEY
|
||||||
log_error("enum_secret_keys: can't open `%s'\n", c->name );
|
|| (with_subkeys
|
||||||
continue; /* try next file */
|
&& c->node->pkt->pkttype == PKT_SECRET_SUBKEY) ) {
|
||||||
}
|
copy_secret_key (sk, c->node->pkt->pkt.secret_key );
|
||||||
}
|
c->node = c->node->next;
|
||||||
|
|
||||||
save_mode = set_packet_list_mode(0);
|
|
||||||
init_packet(&pkt);
|
|
||||||
while( (rc=parse_packet(c->iobuf, &pkt)) != -1 ) {
|
|
||||||
if( rc )
|
|
||||||
; /* e.g. unknown packet */
|
|
||||||
else if( pkt.pkttype == PKT_SECRET_KEY
|
|
||||||
|| ( with_subkeys && pkt.pkttype == PKT_SECRET_SUBKEY ) ) {
|
|
||||||
copy_secret_key( sk, pkt.pkt.secret_key );
|
|
||||||
set_packet_list_mode(save_mode);
|
|
||||||
return 0; /* found */
|
return 0; /* found */
|
||||||
}
|
}
|
||||||
free_packet(&pkt);
|
|
||||||
}
|
|
||||||
set_packet_list_mode(save_mode);
|
|
||||||
iobuf_close(c->iobuf); c->iobuf = NULL;
|
|
||||||
}
|
}
|
||||||
|
release_kbnode (c->keyblock);
|
||||||
|
c->keyblock = c->node = NULL;
|
||||||
|
|
||||||
|
rc = c->first? keydb_search_first (c->hd) : keydb_search_next (c->hd);
|
||||||
|
c->first = 0;
|
||||||
|
if (rc) {
|
||||||
|
keydb_release (c->hd); c->hd = NULL;
|
||||||
c->eof = 1;
|
c->eof = 1;
|
||||||
return -1;
|
return -1; /* eof */
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = keydb_get_keyblock (c->hd, &c->keyblock);
|
||||||
|
c->node = c->keyblock;
|
||||||
|
} while (!rc);
|
||||||
|
|
||||||
|
return rc; /* error */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
29
g10/global.h
Normal file
29
g10/global.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/* global.h - Local typedefs and constants
|
||||||
|
* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of GnuPG.
|
||||||
|
*
|
||||||
|
* GnuPG 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.
|
||||||
|
*
|
||||||
|
* GnuPG 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GPG_GLOBAL_H
|
||||||
|
#define GPG_GLOBAL_H
|
||||||
|
|
||||||
|
#define MAX_FINGERPRINT_LEN 20
|
||||||
|
|
||||||
|
typedef struct kbnode_struct *KBNODE;
|
||||||
|
typedef struct keydb_search_desc KEYDB_SEARCH_DESC;
|
||||||
|
|
||||||
|
#endif /*GPG_GLOBAL_H*/
|
@ -189,9 +189,9 @@ main( int argc, char **argv )
|
|||||||
set_packet_list_mode(1);
|
set_packet_list_mode(1);
|
||||||
|
|
||||||
if( !nrings ) /* no keyring given: use default one */
|
if( !nrings ) /* no keyring given: use default one */
|
||||||
add_keyblock_resource("trustedkeys" EXTSEP_S "gpg", 0, 0);
|
keydb_add_resource ("trustedkeys" EXTSEP_S "gpg", 0, 0);
|
||||||
for(sl = nrings; sl; sl = sl->next )
|
for(sl = nrings; sl; sl = sl->next )
|
||||||
add_keyblock_resource( sl->d, 0, 0 );
|
keydb_add_resource (sl->d, 0, 0 );
|
||||||
|
|
||||||
FREE_STRLIST(nrings);
|
FREE_STRLIST(nrings);
|
||||||
|
|
||||||
|
120
g10/import.c
120
g10/import.c
@ -379,7 +379,6 @@ import_one( const char *fname, KBNODE keyblock, int fast )
|
|||||||
PKT_public_key *pk_orig;
|
PKT_public_key *pk_orig;
|
||||||
KBNODE node, uidnode;
|
KBNODE node, uidnode;
|
||||||
KBNODE keyblock_orig = NULL;
|
KBNODE keyblock_orig = NULL;
|
||||||
KBPOS kbpos;
|
|
||||||
u32 keyid[2];
|
u32 keyid[2];
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
int new_key = 0;
|
int new_key = 0;
|
||||||
@ -443,21 +442,20 @@ import_one( const char *fname, KBNODE keyblock, int fast )
|
|||||||
stats.skipped_new_keys++;
|
stats.skipped_new_keys++;
|
||||||
}
|
}
|
||||||
else if( rc ) { /* insert this key */
|
else if( rc ) { /* insert this key */
|
||||||
/* get default resource */
|
KEYDB_HANDLE hd = keydb_new (0);
|
||||||
if( get_keyblock_handle( NULL, 0, &kbpos ) ) {
|
|
||||||
log_error(_("no default public keyring\n"));
|
rc = keydb_locate_writable (hd, NULL);
|
||||||
|
if (rc) {
|
||||||
|
log_error (_("no writable keyring found: %s\n"), g10_errstr (rc));
|
||||||
return G10ERR_GENERAL;
|
return G10ERR_GENERAL;
|
||||||
}
|
}
|
||||||
if( opt.verbose > 1 )
|
if( opt.verbose > 1 )
|
||||||
log_info( _("writing to `%s'\n"),
|
log_info (_("writing to `%s'\n"), keydb_get_resource_name (hd) );
|
||||||
keyblock_resource_name(&kbpos) );
|
rc = keydb_insert_keyblock (hd, keyblock );
|
||||||
if( (rc=lock_keyblock( &kbpos )) )
|
if (rc)
|
||||||
log_error(_("can't lock keyring `%s': %s\n"),
|
log_error (_("error writing keyring `%s': %s\n"),
|
||||||
keyblock_resource_name(&kbpos), g10_errstr(rc) );
|
keydb_get_resource_name (hd), g10_errstr(rc));
|
||||||
else if( (rc=insert_keyblock( &kbpos, keyblock )) )
|
keydb_release (hd);
|
||||||
log_error( _("error writing keyring `%s': %s\n"),
|
|
||||||
keyblock_resource_name(&kbpos), g10_errstr(rc) );
|
|
||||||
unlock_keyblock( &kbpos );
|
|
||||||
/* we are ready */
|
/* we are ready */
|
||||||
if( !opt.quiet )
|
if( !opt.quiet )
|
||||||
log_info( _("key %08lX: public key imported\n"), (ulong)keyid[1]);
|
log_info( _("key %08lX: public key imported\n"), (ulong)keyid[1]);
|
||||||
@ -472,8 +470,10 @@ import_one( const char *fname, KBNODE keyblock, int fast )
|
|||||||
new_key = 1;
|
new_key = 1;
|
||||||
}
|
}
|
||||||
else { /* merge */
|
else { /* merge */
|
||||||
|
KEYDB_HANDLE hd;
|
||||||
int n_uids, n_sigs, n_subk;
|
int n_uids, n_sigs, n_subk;
|
||||||
|
|
||||||
|
|
||||||
/* Compare the original against the new key; just to be sure nothing
|
/* Compare the original against the new key; just to be sure nothing
|
||||||
* weird is going on */
|
* weird is going on */
|
||||||
if( cmp_public_keys( pk_orig, pk ) ) {
|
if( cmp_public_keys( pk_orig, pk ) ) {
|
||||||
@ -484,16 +484,27 @@ import_one( const char *fname, KBNODE keyblock, int fast )
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* now read the original keyblock */
|
/* now read the original keyblock */
|
||||||
rc = find_keyblock_bypk( &kbpos, pk_orig );
|
hd = keydb_new (0);
|
||||||
|
{
|
||||||
|
byte afp[MAX_FINGERPRINT_LEN];
|
||||||
|
size_t an;
|
||||||
|
|
||||||
|
fingerprint_from_pk (pk_orig, afp, &an);
|
||||||
|
while (an < MAX_FINGERPRINT_LEN)
|
||||||
|
afp[an++] = 0;
|
||||||
|
rc = keydb_search_fpr (hd, afp);
|
||||||
|
}
|
||||||
if( rc ) {
|
if( rc ) {
|
||||||
log_error( _("key %08lX: can't locate original keyblock: %s\n"),
|
log_error (_("key %08lX: can't locate original keyblock: %s\n"),
|
||||||
(ulong)keyid[1], g10_errstr(rc));
|
(ulong)keyid[1], g10_errstr(rc));
|
||||||
|
keydb_release (hd);
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
rc = read_keyblock( &kbpos, &keyblock_orig );
|
rc = keydb_get_keyblock (hd, &keyblock_orig );
|
||||||
if( rc ) {
|
if (rc) {
|
||||||
log_error( _("key %08lX: can't read original keyblock: %s\n"),
|
log_error (_("key %08lX: can't read original keyblock: %s\n"),
|
||||||
(ulong)keyid[1], g10_errstr(rc));
|
(ulong)keyid[1], g10_errstr(rc));
|
||||||
|
keydb_release (hd);
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -504,18 +515,18 @@ import_one( const char *fname, KBNODE keyblock, int fast )
|
|||||||
n_uids = n_sigs = n_subk = 0;
|
n_uids = n_sigs = n_subk = 0;
|
||||||
rc = merge_blocks( fname, keyblock_orig, keyblock,
|
rc = merge_blocks( fname, keyblock_orig, keyblock,
|
||||||
keyid, &n_uids, &n_sigs, &n_subk );
|
keyid, &n_uids, &n_sigs, &n_subk );
|
||||||
if( rc )
|
if( rc ) {
|
||||||
|
keydb_release (hd);
|
||||||
goto leave;
|
goto leave;
|
||||||
|
}
|
||||||
if( n_uids || n_sigs || n_subk ) {
|
if( n_uids || n_sigs || n_subk ) {
|
||||||
mod_key = 1;
|
mod_key = 1;
|
||||||
/* keyblock_orig has been updated; write */
|
/* keyblock_orig has been updated; write */
|
||||||
if( (rc=lock_keyblock( &kbpos )) )
|
rc = keydb_update_keyblock (hd, keyblock_orig);
|
||||||
log_error( _("can't lock keyring `%s': %s\n"),
|
if (rc)
|
||||||
keyblock_resource_name(&kbpos), g10_errstr(rc) );
|
log_error (_("error writing keyring `%s': %s\n"),
|
||||||
else if( (rc=update_keyblock( &kbpos, keyblock_orig )) )
|
keydb_get_resource_name (hd), g10_errstr(rc) );
|
||||||
log_error( _("error writing keyring `%s': %s\n"),
|
keydb_release (hd); hd = NULL;
|
||||||
keyblock_resource_name(&kbpos), g10_errstr(rc) );
|
|
||||||
unlock_keyblock( &kbpos );
|
|
||||||
/* we are ready */
|
/* we are ready */
|
||||||
if( !opt.quiet ) {
|
if( !opt.quiet ) {
|
||||||
if( n_uids == 1 )
|
if( n_uids == 1 )
|
||||||
@ -582,7 +593,6 @@ import_secret_one( const char *fname, KBNODE keyblock, int allow )
|
|||||||
{
|
{
|
||||||
PKT_secret_key *sk;
|
PKT_secret_key *sk;
|
||||||
KBNODE node, uidnode;
|
KBNODE node, uidnode;
|
||||||
KBPOS kbpos;
|
|
||||||
u32 keyid[2];
|
u32 keyid[2];
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
@ -623,18 +633,20 @@ import_secret_one( const char *fname, KBNODE keyblock, int allow )
|
|||||||
/* do we have this key already in one of our secrings ? */
|
/* do we have this key already in one of our secrings ? */
|
||||||
rc = seckey_available( keyid );
|
rc = seckey_available( keyid );
|
||||||
if( rc == G10ERR_NO_SECKEY && !opt.merge_only ) { /* simply insert this key */
|
if( rc == G10ERR_NO_SECKEY && !opt.merge_only ) { /* simply insert this key */
|
||||||
|
KEYDB_HANDLE hd = keydb_new (1);
|
||||||
|
|
||||||
/* get default resource */
|
/* get default resource */
|
||||||
if( get_keyblock_handle( NULL, 1, &kbpos ) ) {
|
rc = keydb_locate_writable (hd, NULL);
|
||||||
log_error("no default secret keyring\n");
|
if (rc) {
|
||||||
|
log_error (_("no default secret keyring: %s\n"), g10_errstr (rc));
|
||||||
|
keydb_release (hd);
|
||||||
return G10ERR_GENERAL;
|
return G10ERR_GENERAL;
|
||||||
}
|
}
|
||||||
if( (rc=lock_keyblock( &kbpos )) )
|
rc = keydb_insert_keyblock (hd, keyblock );
|
||||||
log_error( _("can't lock keyring `%s': %s\n"),
|
if (rc)
|
||||||
keyblock_resource_name(&kbpos), g10_errstr(rc) );
|
log_error (_("error writing keyring `%s': %s\n"),
|
||||||
else if( (rc=insert_keyblock( &kbpos, keyblock )) )
|
keydb_get_resource_name (hd), g10_errstr(rc) );
|
||||||
log_error( _("error writing keyring `%s': %s\n"),
|
keydb_release (hd);
|
||||||
keyblock_resource_name(&kbpos), g10_errstr(rc) );
|
|
||||||
unlock_keyblock( &kbpos );
|
|
||||||
/* we are ready */
|
/* we are ready */
|
||||||
if( !opt.quiet )
|
if( !opt.quiet )
|
||||||
log_info( _("key %08lX: secret key imported\n"), (ulong)keyid[1]);
|
log_info( _("key %08lX: secret key imported\n"), (ulong)keyid[1]);
|
||||||
@ -661,7 +673,7 @@ import_revoke_cert( const char *fname, KBNODE node )
|
|||||||
{
|
{
|
||||||
PKT_public_key *pk=NULL;
|
PKT_public_key *pk=NULL;
|
||||||
KBNODE onode, keyblock = NULL;
|
KBNODE onode, keyblock = NULL;
|
||||||
KBPOS kbpos;
|
KEYDB_HANDLE hd = NULL;
|
||||||
u32 keyid[2];
|
u32 keyid[2];
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
@ -687,15 +699,24 @@ import_revoke_cert( const char *fname, KBNODE node )
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* read the original keyblock */
|
/* read the original keyblock */
|
||||||
rc = find_keyblock_bypk( &kbpos, pk );
|
hd = keydb_new (0);
|
||||||
if( rc ) {
|
{
|
||||||
log_error( _("key %08lX: can't locate original keyblock: %s\n"),
|
byte afp[MAX_FINGERPRINT_LEN];
|
||||||
|
size_t an;
|
||||||
|
|
||||||
|
fingerprint_from_pk (pk, afp, &an);
|
||||||
|
while (an < MAX_FINGERPRINT_LEN)
|
||||||
|
afp[an++] = 0;
|
||||||
|
rc = keydb_search_fpr (hd, afp);
|
||||||
|
}
|
||||||
|
if (rc) {
|
||||||
|
log_error (_("key %08lX: can't locate original keyblock: %s\n"),
|
||||||
(ulong)keyid[1], g10_errstr(rc));
|
(ulong)keyid[1], g10_errstr(rc));
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
rc = read_keyblock( &kbpos, &keyblock );
|
rc = keydb_get_keyblock (hd, &keyblock );
|
||||||
if( rc ) {
|
if (rc) {
|
||||||
log_error( _("key %08lX: can't read original keyblock: %s\n"),
|
log_error (_("key %08lX: can't read original keyblock: %s\n"),
|
||||||
(ulong)keyid[1], g10_errstr(rc));
|
(ulong)keyid[1], g10_errstr(rc));
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
@ -729,13 +750,11 @@ import_revoke_cert( const char *fname, KBNODE node )
|
|||||||
insert_kbnode( keyblock, clone_kbnode(node), 0 );
|
insert_kbnode( keyblock, clone_kbnode(node), 0 );
|
||||||
|
|
||||||
/* and write the keyblock back */
|
/* and write the keyblock back */
|
||||||
if( (rc=lock_keyblock( &kbpos )) )
|
rc = keydb_update_keyblock (hd, keyblock );
|
||||||
log_error( _("can't lock keyring `%s': %s\n"),
|
if (rc)
|
||||||
keyblock_resource_name(&kbpos), g10_errstr(rc) );
|
log_error (_("error writing keyring `%s': %s\n"),
|
||||||
else if( (rc=update_keyblock( &kbpos, keyblock )) )
|
keydb_get_resource_name (hd), g10_errstr(rc) );
|
||||||
log_error( _("error writing keyring `%s': %s\n"),
|
keydb_release (hd); hd = NULL;
|
||||||
keyblock_resource_name(&kbpos), g10_errstr(rc) );
|
|
||||||
unlock_keyblock( &kbpos );
|
|
||||||
/* we are ready */
|
/* we are ready */
|
||||||
if( !opt.quiet )
|
if( !opt.quiet )
|
||||||
log_info( _("key %08lX: revocation certificate imported\n"),
|
log_info( _("key %08lX: revocation certificate imported\n"),
|
||||||
@ -752,6 +771,7 @@ import_revoke_cert( const char *fname, KBNODE node )
|
|||||||
}
|
}
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
|
keydb_release (hd);
|
||||||
release_kbnode( keyblock );
|
release_kbnode( keyblock );
|
||||||
free_public_key( pk );
|
free_public_key( pk );
|
||||||
return rc;
|
return rc;
|
||||||
|
623
g10/keydb.c
Normal file
623
g10/keydb.c
Normal file
@ -0,0 +1,623 @@
|
|||||||
|
/* keydb.c - key database dispatcher
|
||||||
|
* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of GnuPG.
|
||||||
|
*
|
||||||
|
* GnuPG 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.
|
||||||
|
*
|
||||||
|
* GnuPG 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "util.h"
|
||||||
|
#include "options.h"
|
||||||
|
#include "main.h" /*try_make_homedir ()*/
|
||||||
|
#include "packet.h"
|
||||||
|
#include "keyring.h"
|
||||||
|
#include "keydb.h"
|
||||||
|
#include "i18n.h"
|
||||||
|
|
||||||
|
static int active_handles;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
KEYDB_RESOURCE_TYPE_NONE = 0,
|
||||||
|
KEYDB_RESOURCE_TYPE_KEYRING
|
||||||
|
} KeydbResourceType;
|
||||||
|
#define MAX_KEYDB_RESOURCES 1
|
||||||
|
|
||||||
|
struct resource_item {
|
||||||
|
KeydbResourceType type;
|
||||||
|
union {
|
||||||
|
KEYRING_HANDLE kr;
|
||||||
|
} u;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct keydb_handle {
|
||||||
|
int locked;
|
||||||
|
int found;
|
||||||
|
int current;
|
||||||
|
struct resource_item active[MAX_KEYDB_RESOURCES];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static int lock_all (KEYDB_HANDLE hd);
|
||||||
|
static void unlock_all (KEYDB_HANDLE hd);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Register a resource (which currently may only be a keyring file).
|
||||||
|
* The first keyring which is added by this function is
|
||||||
|
* created if it does not exist.
|
||||||
|
* Note: this function may be called before secure memory is
|
||||||
|
* available.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
keydb_add_resource (const char *url, int force, int secret)
|
||||||
|
{
|
||||||
|
static int any_secret, any_public;
|
||||||
|
const char *resname = url;
|
||||||
|
IOBUF iobuf = NULL;
|
||||||
|
char *filename = NULL;
|
||||||
|
int rc = 0;
|
||||||
|
KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE;
|
||||||
|
const char *created_fname = NULL;
|
||||||
|
|
||||||
|
/* Do we have an URL?
|
||||||
|
* gnupg-ring:filename := this is a plain keyring
|
||||||
|
* filename := See what is is, but create as plain keyring.
|
||||||
|
*/
|
||||||
|
if (strlen (resname) > 11) {
|
||||||
|
if (!strncmp( resname, "gnupg-ring:", 11) ) {
|
||||||
|
rt = KEYDB_RESOURCE_TYPE_KEYRING;
|
||||||
|
resname += 11;
|
||||||
|
}
|
||||||
|
#if !defined(HAVE_DRIVE_LETTERS) && !defined(__riscos__)
|
||||||
|
else if (strchr (resname, ':')) {
|
||||||
|
log_error ("invalid key resource URL `%s'\n", url );
|
||||||
|
rc = G10ERR_GENERAL;
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
#endif /* !HAVE_DRIVE_LETTERS && !__riscos__ */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*resname != DIRSEP_C ) { /* do tilde expansion etc */
|
||||||
|
if (strchr(resname, DIRSEP_C) )
|
||||||
|
filename = make_filename (resname, NULL);
|
||||||
|
else
|
||||||
|
filename = make_filename (opt.homedir, resname, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
filename = m_strdup (resname);
|
||||||
|
|
||||||
|
if (!force)
|
||||||
|
force = secret? !any_secret : !any_public;
|
||||||
|
|
||||||
|
/* see whether we can determine the filetype */
|
||||||
|
if (rt == KEYDB_RESOURCE_TYPE_NONE) {
|
||||||
|
FILE *fp = fopen( filename, "rb" );
|
||||||
|
|
||||||
|
if (fp) {
|
||||||
|
u32 magic;
|
||||||
|
|
||||||
|
if (fread( &magic, 4, 1, fp) == 1 ) {
|
||||||
|
if (magic == 0x13579ace || magic == 0xce9a5713)
|
||||||
|
; /* GDBM magic - no more support */
|
||||||
|
else
|
||||||
|
rt = KEYDB_RESOURCE_TYPE_KEYRING;
|
||||||
|
}
|
||||||
|
else /* maybe empty: assume ring */
|
||||||
|
rt = KEYDB_RESOURCE_TYPE_KEYRING;
|
||||||
|
fclose( fp );
|
||||||
|
}
|
||||||
|
else /* no file yet: create ring */
|
||||||
|
rt = KEYDB_RESOURCE_TYPE_KEYRING;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (rt) {
|
||||||
|
case KEYDB_RESOURCE_TYPE_NONE:
|
||||||
|
log_error ("unknown type of key resource `%s'\n", url );
|
||||||
|
rc = G10ERR_GENERAL;
|
||||||
|
goto leave;
|
||||||
|
|
||||||
|
case KEYDB_RESOURCE_TYPE_KEYRING:
|
||||||
|
iobuf = iobuf_open (filename);
|
||||||
|
if (!iobuf && !force) {
|
||||||
|
rc = G10ERR_OPEN_FILE;
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!iobuf) {
|
||||||
|
char *last_slash_in_filename;
|
||||||
|
|
||||||
|
last_slash_in_filename = strrchr (filename, DIRSEP_C);
|
||||||
|
*last_slash_in_filename = 0;
|
||||||
|
|
||||||
|
if (access(filename, F_OK)) {
|
||||||
|
/* on the first time we try to create the default homedir and
|
||||||
|
* in this case the process will be terminated, so that on the
|
||||||
|
* next invocation it can read the options file in on startup
|
||||||
|
*/
|
||||||
|
try_make_homedir (filename);
|
||||||
|
rc = G10ERR_OPEN_FILE;
|
||||||
|
*last_slash_in_filename = DIRSEP_C;
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
*last_slash_in_filename = DIRSEP_C;
|
||||||
|
|
||||||
|
iobuf = iobuf_create (filename);
|
||||||
|
if (!iobuf) {
|
||||||
|
log_error ( _("error creating keyring `%s': %s\n"),
|
||||||
|
filename, strerror(errno));
|
||||||
|
rc = G10ERR_OPEN_FILE;
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
#ifndef HAVE_DOSISH_SYSTEM
|
||||||
|
if (secret && !opt.preserve_permissions) {
|
||||||
|
if (chmod (filename, S_IRUSR | S_IWUSR) ) {
|
||||||
|
log_error (_("changing permission of "
|
||||||
|
" `%s' failed: %s\n"),
|
||||||
|
filename, strerror(errno) );
|
||||||
|
rc = G10ERR_WRITE_FILE;
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (!opt.quiet)
|
||||||
|
log_info (_("keyring `%s' created\n"), filename);
|
||||||
|
created_fname = filename;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
iobuf_close (iobuf);
|
||||||
|
iobuf = NULL;
|
||||||
|
if (created_fname) /* must invalidate that ugly cache */
|
||||||
|
iobuf_ioctl (NULL, 2, 0, (char*)created_fname);
|
||||||
|
keyring_register_filename (filename, secret);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
log_error ("resource type of `%s' not supported\n", url);
|
||||||
|
rc = G10ERR_GENERAL;
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fixme: check directory permissions and print a warning */
|
||||||
|
|
||||||
|
leave:
|
||||||
|
if (rc)
|
||||||
|
log_error ("keyblock resource `%s': %s\n", filename, g10_errstr(rc));
|
||||||
|
else if (secret)
|
||||||
|
any_secret = 1;
|
||||||
|
else
|
||||||
|
any_public = 1;
|
||||||
|
m_free (filename);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
KEYDB_HANDLE
|
||||||
|
keydb_new (int secret)
|
||||||
|
{
|
||||||
|
KEYDB_HANDLE hd;
|
||||||
|
int i=0;
|
||||||
|
|
||||||
|
hd = m_alloc_clear (sizeof *hd);
|
||||||
|
hd->found = -1;
|
||||||
|
|
||||||
|
hd->active[i].type = KEYDB_RESOURCE_TYPE_KEYRING;
|
||||||
|
hd->active[i].u.kr = keyring_new (secret);
|
||||||
|
if (!hd->active[i].u.kr) {
|
||||||
|
m_free (hd);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
|
||||||
|
|
||||||
|
assert (i <= MAX_KEYDB_RESOURCES);
|
||||||
|
active_handles++;
|
||||||
|
return hd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
keydb_release (KEYDB_HANDLE hd)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!hd)
|
||||||
|
return;
|
||||||
|
assert (active_handles > 0);
|
||||||
|
active_handles--;
|
||||||
|
|
||||||
|
unlock_all (hd);
|
||||||
|
for (i=0; i < MAX_KEYDB_RESOURCES; i++) {
|
||||||
|
switch (hd->active[i].type) {
|
||||||
|
case KEYDB_RESOURCE_TYPE_NONE:
|
||||||
|
break;
|
||||||
|
case KEYDB_RESOURCE_TYPE_KEYRING:
|
||||||
|
keyring_release (hd->active[i].u.kr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_free (hd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the name of the current resource. This is function first
|
||||||
|
* looks for the last found found, then for the current search
|
||||||
|
* position, and last returns the first available resource. The
|
||||||
|
* returned string is only valid as long as the handle exists. This
|
||||||
|
* function does only return NULL if no handle is specified, in all
|
||||||
|
* other error cases an empty string is returned.
|
||||||
|
*/
|
||||||
|
const char *
|
||||||
|
keydb_get_resource_name (KEYDB_HANDLE hd)
|
||||||
|
{
|
||||||
|
int idx;
|
||||||
|
const char *s = NULL;
|
||||||
|
|
||||||
|
if (!hd)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if ( hd->found >= 0 && hd->found < MAX_KEYDB_RESOURCES)
|
||||||
|
idx = hd->found;
|
||||||
|
else if ( hd->current >= 0 && hd->current < MAX_KEYDB_RESOURCES)
|
||||||
|
idx = hd->current;
|
||||||
|
else
|
||||||
|
idx = 0;
|
||||||
|
|
||||||
|
switch (hd->active[idx].type) {
|
||||||
|
case KEYDB_RESOURCE_TYPE_NONE:
|
||||||
|
s = NULL;
|
||||||
|
break;
|
||||||
|
case KEYDB_RESOURCE_TYPE_KEYRING:
|
||||||
|
s = keyring_get_resource_name (hd->active[idx].u.kr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return s? s: "";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
lock_all (KEYDB_HANDLE hd)
|
||||||
|
{
|
||||||
|
int i, rc = 0;
|
||||||
|
|
||||||
|
for (i=0; !rc && i < MAX_KEYDB_RESOURCES; i++) {
|
||||||
|
switch (hd->active[i].type) {
|
||||||
|
case KEYDB_RESOURCE_TYPE_NONE:
|
||||||
|
break;
|
||||||
|
case KEYDB_RESOURCE_TYPE_KEYRING:
|
||||||
|
rc = keyring_lock (hd->active[i].u.kr, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rc) {
|
||||||
|
/* revert the alreadt set locks */
|
||||||
|
for (i--; i >= 0; i--) {
|
||||||
|
switch (hd->active[i].type) {
|
||||||
|
case KEYDB_RESOURCE_TYPE_NONE:
|
||||||
|
break;
|
||||||
|
case KEYDB_RESOURCE_TYPE_KEYRING:
|
||||||
|
keyring_lock (hd->active[i].u.kr, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
hd->locked = 1;
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
unlock_all (KEYDB_HANDLE hd)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!hd->locked)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i=MAX_KEYDB_RESOURCES-1; i >= 0; i--) {
|
||||||
|
switch (hd->active[i].type) {
|
||||||
|
case KEYDB_RESOURCE_TYPE_NONE:
|
||||||
|
break;
|
||||||
|
case KEYDB_RESOURCE_TYPE_KEYRING:
|
||||||
|
keyring_lock (hd->active[i].u.kr, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hd->locked = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the last found keyring. Caller must free it.
|
||||||
|
* The returned keyblock has the kbode flag bit 0 set for the node with
|
||||||
|
* the public key used to locate the keyblock or flag bit 1 set for
|
||||||
|
* the user ID node.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if (!hd)
|
||||||
|
return G10ERR_INV_ARG;
|
||||||
|
|
||||||
|
if ( hd->found < 0 || hd->found >= MAX_KEYDB_RESOURCES)
|
||||||
|
return -1; /* nothing found */
|
||||||
|
|
||||||
|
switch (hd->active[hd->found].type) {
|
||||||
|
case KEYDB_RESOURCE_TYPE_NONE:
|
||||||
|
rc = G10ERR_GENERAL; /* oops */
|
||||||
|
break;
|
||||||
|
case KEYDB_RESOURCE_TYPE_KEYRING:
|
||||||
|
rc = keyring_get_keyblock (hd->active[hd->found].u.kr, ret_kb);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* update the current keyblock with KB
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
keydb_update_keyblock (KEYDB_HANDLE hd, KBNODE kb)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if (!hd)
|
||||||
|
return G10ERR_INV_ARG;
|
||||||
|
|
||||||
|
if ( hd->found < 0 || hd->found >= MAX_KEYDB_RESOURCES)
|
||||||
|
return -1; /* nothing found */
|
||||||
|
|
||||||
|
if( opt.dry_run )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
rc = lock_all (hd);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
switch (hd->active[hd->found].type) {
|
||||||
|
case KEYDB_RESOURCE_TYPE_NONE:
|
||||||
|
rc = G10ERR_GENERAL; /* oops */
|
||||||
|
break;
|
||||||
|
case KEYDB_RESOURCE_TYPE_KEYRING:
|
||||||
|
rc = keyring_update_keyblock (hd->active[hd->found].u.kr, kb);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
unlock_all (hd);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Insert a new KB into one of the resources.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
keydb_insert_keyblock (KEYDB_HANDLE hd, KBNODE kb)
|
||||||
|
{
|
||||||
|
int rc = -1;
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
if (!hd)
|
||||||
|
return G10ERR_INV_ARG;
|
||||||
|
|
||||||
|
if( opt.dry_run )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if ( hd->found >= 0 && hd->found < MAX_KEYDB_RESOURCES)
|
||||||
|
idx = hd->found;
|
||||||
|
else if ( hd->current >= 0 && hd->current < MAX_KEYDB_RESOURCES)
|
||||||
|
idx = hd->current;
|
||||||
|
else
|
||||||
|
return G10ERR_GENERAL;
|
||||||
|
|
||||||
|
rc = lock_all (hd);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
switch (hd->active[idx].type) {
|
||||||
|
case KEYDB_RESOURCE_TYPE_NONE:
|
||||||
|
rc = G10ERR_GENERAL; /* oops */
|
||||||
|
break;
|
||||||
|
case KEYDB_RESOURCE_TYPE_KEYRING:
|
||||||
|
rc = keyring_insert_keyblock (hd->active[idx].u.kr, kb);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
unlock_all (hd);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The current keyblock will be deleted.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
keydb_delete_keyblock (KEYDB_HANDLE hd)
|
||||||
|
{
|
||||||
|
int rc = -1;
|
||||||
|
|
||||||
|
if (!hd)
|
||||||
|
return G10ERR_INV_ARG;
|
||||||
|
|
||||||
|
if ( hd->found < 0 || hd->found >= MAX_KEYDB_RESOURCES)
|
||||||
|
return -1; /* nothing found */
|
||||||
|
|
||||||
|
if( opt.dry_run )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
rc = lock_all (hd);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
switch (hd->active[hd->found].type) {
|
||||||
|
case KEYDB_RESOURCE_TYPE_NONE:
|
||||||
|
rc = G10ERR_GENERAL; /* oops */
|
||||||
|
break;
|
||||||
|
case KEYDB_RESOURCE_TYPE_KEYRING:
|
||||||
|
rc = keyring_delete_keyblock (hd->active[hd->found].u.kr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
unlock_all (hd);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Locate the default writable key resource, so that the next
|
||||||
|
* operation (which is only releavnt for inserts) will be onde on this
|
||||||
|
* resource.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (!hd)
|
||||||
|
return G10ERR_INV_ARG;
|
||||||
|
|
||||||
|
rc = keydb_search_reset (hd);
|
||||||
|
if (!rc) {
|
||||||
|
/* fixme: set forward to a writable one */
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Start the next search on this handle right at the beginning
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
keydb_search_reset (KEYDB_HANDLE hd)
|
||||||
|
{
|
||||||
|
int i, rc = 0;
|
||||||
|
|
||||||
|
if (!hd)
|
||||||
|
return G10ERR_INV_ARG;
|
||||||
|
|
||||||
|
hd->current = 0;
|
||||||
|
hd->found = -1;
|
||||||
|
/* and reset all resources */
|
||||||
|
for (i=0; !rc && i < MAX_KEYDB_RESOURCES; i++) {
|
||||||
|
switch (hd->active[i].type) {
|
||||||
|
case KEYDB_RESOURCE_TYPE_NONE:
|
||||||
|
break;
|
||||||
|
case KEYDB_RESOURCE_TYPE_KEYRING:
|
||||||
|
rc = keyring_search_reset (hd->active[i].u.kr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Search through all keydb resources, starting at the current position,
|
||||||
|
* for a keyblock which contains one of the keys described in the DESC array.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc)
|
||||||
|
{
|
||||||
|
int rc = -1;
|
||||||
|
|
||||||
|
if (!hd)
|
||||||
|
return G10ERR_INV_ARG;
|
||||||
|
|
||||||
|
while (rc == -1 && hd->current >= 0 && hd->current < MAX_KEYDB_RESOURCES) {
|
||||||
|
switch (hd->active[hd->current].type) {
|
||||||
|
case KEYDB_RESOURCE_TYPE_NONE:
|
||||||
|
rc = -1; /* no resource = eof */
|
||||||
|
break;
|
||||||
|
case KEYDB_RESOURCE_TYPE_KEYRING:
|
||||||
|
rc = keyring_search (hd->active[hd->current].u.kr, desc, ndesc);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (rc == -1) /* EOF -> switch to next resource */
|
||||||
|
hd->current++;
|
||||||
|
else if (!rc)
|
||||||
|
hd->found = hd->current;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
keydb_search_first (KEYDB_HANDLE hd)
|
||||||
|
{
|
||||||
|
KEYDB_SEARCH_DESC desc;
|
||||||
|
|
||||||
|
memset (&desc, 0, sizeof desc);
|
||||||
|
desc.mode = KEYDB_SEARCH_MODE_FIRST;
|
||||||
|
return keydb_search (hd, &desc, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
keydb_search_next (KEYDB_HANDLE hd)
|
||||||
|
{
|
||||||
|
KEYDB_SEARCH_DESC desc;
|
||||||
|
|
||||||
|
memset (&desc, 0, sizeof desc);
|
||||||
|
desc.mode = KEYDB_SEARCH_MODE_NEXT;
|
||||||
|
return keydb_search (hd, &desc, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
keydb_search_kid (KEYDB_HANDLE hd, u32 *kid)
|
||||||
|
{
|
||||||
|
KEYDB_SEARCH_DESC desc;
|
||||||
|
|
||||||
|
memset (&desc, 0, sizeof desc);
|
||||||
|
desc.mode = KEYDB_SEARCH_MODE_LONG_KID;
|
||||||
|
desc.u.kid[0] = kid[0];
|
||||||
|
desc.u.kid[1] = kid[1];
|
||||||
|
return keydb_search (hd, &desc, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr)
|
||||||
|
{
|
||||||
|
KEYDB_SEARCH_DESC desc;
|
||||||
|
|
||||||
|
memset (&desc, 0, sizeof desc);
|
||||||
|
desc.mode = KEYDB_SEARCH_MODE_FPR;
|
||||||
|
memcpy (desc.u.fpr, fpr, MAX_FINGERPRINT_LEN);
|
||||||
|
return keydb_search (hd, &desc, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
85
g10/keydb.h
85
g10/keydb.h
@ -21,15 +21,11 @@
|
|||||||
#ifndef G10_KEYDB_H
|
#ifndef G10_KEYDB_H
|
||||||
#define G10_KEYDB_H
|
#define G10_KEYDB_H
|
||||||
|
|
||||||
#ifdef HAVE_LIBGDBM
|
|
||||||
#include <gdbm.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
#include "global.h"
|
||||||
#include "packet.h"
|
#include "packet.h"
|
||||||
#include "cipher.h"
|
#include "cipher.h"
|
||||||
|
|
||||||
#define MAX_FINGERPRINT_LEN 20
|
|
||||||
|
|
||||||
#define IS_KEY_SIG(s) ((s)->sig_class == 0x1f)
|
#define IS_KEY_SIG(s) ((s)->sig_class == 0x1f)
|
||||||
#define IS_UID_SIG(s) (((s)->sig_class & ~3) == 0x10)
|
#define IS_UID_SIG(s) (((s)->sig_class & ~3) == 0x10)
|
||||||
@ -50,7 +46,6 @@ typedef struct getkey_ctx_s *GETKEY_CTX;
|
|||||||
* This structure is also used to bind arbitrary packets together.
|
* This structure is also used to bind arbitrary packets together.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct kbnode_struct *KBNODE;
|
|
||||||
struct kbnode_struct {
|
struct kbnode_struct {
|
||||||
KBNODE next;
|
KBNODE next;
|
||||||
PACKET *pkt;
|
PACKET *pkt;
|
||||||
@ -65,8 +60,7 @@ struct kbnode_struct {
|
|||||||
|
|
||||||
enum resource_type {
|
enum resource_type {
|
||||||
rt_UNKNOWN = 0,
|
rt_UNKNOWN = 0,
|
||||||
rt_RING = 1,
|
rt_RING = 1
|
||||||
rt_GDBM = 2
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -81,10 +75,6 @@ struct keyblock_pos_struct {
|
|||||||
unsigned count; /* length of the keyblock in packets */
|
unsigned count; /* length of the keyblock in packets */
|
||||||
IOBUF fp; /* used by enum_keyblocks */
|
IOBUF fp; /* used by enum_keyblocks */
|
||||||
int secret; /* working on a secret keyring */
|
int secret; /* working on a secret keyring */
|
||||||
#ifdef HAVE_LIBGDBM
|
|
||||||
GDBM_FILE dbf;
|
|
||||||
byte keybuf[21];
|
|
||||||
#endif
|
|
||||||
PACKET *pkt; /* ditto */
|
PACKET *pkt; /* ditto */
|
||||||
int valid;
|
int valid;
|
||||||
};
|
};
|
||||||
@ -118,6 +108,52 @@ struct pubkey_find_info {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct keydb_handle *KEYDB_HANDLE;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
KEYDB_SEARCH_MODE_NONE,
|
||||||
|
KEYDB_SEARCH_MODE_EXACT,
|
||||||
|
KEYDB_SEARCH_MODE_SUBSTR,
|
||||||
|
KEYDB_SEARCH_MODE_MAIL,
|
||||||
|
KEYDB_SEARCH_MODE_MAILSUB,
|
||||||
|
KEYDB_SEARCH_MODE_MAILEND,
|
||||||
|
KEYDB_SEARCH_MODE_WORDS,
|
||||||
|
KEYDB_SEARCH_MODE_SHORT_KID,
|
||||||
|
KEYDB_SEARCH_MODE_LONG_KID,
|
||||||
|
KEYDB_SEARCH_MODE_TDBIDX,
|
||||||
|
KEYDB_SEARCH_MODE_FPR16,
|
||||||
|
KEYDB_SEARCH_MODE_FPR20,
|
||||||
|
KEYDB_SEARCH_MODE_FPR,
|
||||||
|
KEYDB_SEARCH_MODE_FIRST,
|
||||||
|
KEYDB_SEARCH_MODE_NEXT
|
||||||
|
} KeydbSearchMode;
|
||||||
|
|
||||||
|
struct keydb_search_desc {
|
||||||
|
KeydbSearchMode mode;
|
||||||
|
union {
|
||||||
|
const char *name;
|
||||||
|
char fpr[MAX_FINGERPRINT_LEN];
|
||||||
|
u32 kid[2];
|
||||||
|
} u;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*-- keydb.c --*/
|
||||||
|
int keydb_add_resource (const char *url, int force, int secret);
|
||||||
|
KEYDB_HANDLE keydb_new (int secret);
|
||||||
|
void keydb_release (KEYDB_HANDLE hd);
|
||||||
|
const char *keydb_get_resource_name (KEYDB_HANDLE hd);
|
||||||
|
int keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb);
|
||||||
|
int keydb_update_keyblock (KEYDB_HANDLE hd, KBNODE kb);
|
||||||
|
int keydb_insert_keyblock (KEYDB_HANDLE hd, KBNODE kb);
|
||||||
|
int keydb_delete_keyblock (KEYDB_HANDLE hd);
|
||||||
|
int keydb_locate_writable (KEYDB_HANDLE hd, const char *reserved);
|
||||||
|
int keydb_search_reset (KEYDB_HANDLE hd);
|
||||||
|
int keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc);
|
||||||
|
int keydb_search_first (KEYDB_HANDLE hd);
|
||||||
|
int keydb_search_next (KEYDB_HANDLE hd);
|
||||||
|
int keydb_search_kid (KEYDB_HANDLE hd, u32 *kid);
|
||||||
|
int keydb_search_fpr (KEYDB_HANDLE hd, const byte *fpr);
|
||||||
|
|
||||||
|
|
||||||
/*-- pkclist.c --*/
|
/*-- pkclist.c --*/
|
||||||
int check_signatures_trust( PKT_signature *sig );
|
int check_signatures_trust( PKT_signature *sig );
|
||||||
@ -147,8 +183,8 @@ void cache_public_key( PKT_public_key *pk );
|
|||||||
void getkey_disable_caches(void);
|
void getkey_disable_caches(void);
|
||||||
int get_pubkey( PKT_public_key *pk, u32 *keyid );
|
int get_pubkey( PKT_public_key *pk, u32 *keyid );
|
||||||
KBNODE get_pubkeyblock( u32 *keyid );
|
KBNODE get_pubkeyblock( u32 *keyid );
|
||||||
int get_pubkey_byname( GETKEY_CTX *rx, PKT_public_key *pk,
|
int get_pubkey_byname( PKT_public_key *pk, const char *name,
|
||||||
const char *name, KBNODE *ret_keyblock );
|
KBNODE *ret_keyblock, KEYDB_HANDLE *ret_kdbhd);
|
||||||
int get_pubkey_bynames( GETKEY_CTX *rx, PKT_public_key *pk,
|
int get_pubkey_bynames( GETKEY_CTX *rx, PKT_public_key *pk,
|
||||||
STRLIST names, KBNODE *ret_keyblock );
|
STRLIST names, KBNODE *ret_keyblock );
|
||||||
int get_pubkey_next( GETKEY_CTX ctx, PKT_public_key *pk, KBNODE *ret_keyblock );
|
int get_pubkey_next( GETKEY_CTX ctx, PKT_public_key *pk, KBNODE *ret_keyblock );
|
||||||
@ -213,25 +249,4 @@ void clear_kbnode_flags( KBNODE n );
|
|||||||
int commit_kbnode( KBNODE *root );
|
int commit_kbnode( KBNODE *root );
|
||||||
void dump_kbnode( KBNODE node );
|
void dump_kbnode( KBNODE node );
|
||||||
|
|
||||||
/*-- ringedit.c --*/
|
|
||||||
const char *enum_keyblock_resources( int *sequence, int secret );
|
|
||||||
int add_keyblock_resource( const char *resname, int force, int secret );
|
|
||||||
const char *keyblock_resource_name( KBPOS *kbpos );
|
|
||||||
int get_keyblock_handle( const char *filename, int secret, KBPOS *kbpos );
|
|
||||||
char *get_writable_keyblock_file( int secret );
|
|
||||||
int find_keyblock( PUBKEY_FIND_INFO info, KBPOS *kbpos );
|
|
||||||
int find_keyblock_byname( KBPOS *kbpos, const char *username );
|
|
||||||
int find_keyblock_bypk( KBPOS *kbpos, PKT_public_key *pk );
|
|
||||||
int find_secret_keyblock_bypk( KBPOS *kbpos, PKT_public_key *pk );
|
|
||||||
int find_secret_keyblock_byname( KBPOS *kbpos, const char *username );
|
|
||||||
int find_secret_keyblock_direct (KBPOS *kbpos, u32 *keyid);
|
|
||||||
int lock_keyblock( KBPOS *kbpos );
|
|
||||||
void unlock_keyblock( KBPOS *kbpos );
|
|
||||||
int read_keyblock( KBPOS *kbpos, KBNODE *ret_root );
|
|
||||||
int enum_keyblocks( int mode, KBPOS *kbpos, KBNODE *ret_root );
|
|
||||||
int insert_keyblock( KBPOS *kbpos, KBNODE root );
|
|
||||||
int delete_keyblock( KBPOS *kbpos );
|
|
||||||
int update_keyblock( KBPOS *kbpos, KBNODE root );
|
|
||||||
|
|
||||||
|
|
||||||
#endif /*G10_KEYDB_H*/
|
#endif /*G10_KEYDB_H*/
|
||||||
|
@ -84,30 +84,6 @@ struct sign_attrib {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
get_keyblock_byname( KBNODE *keyblock, KBPOS *kbpos, const char *username )
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
*keyblock = NULL;
|
|
||||||
/* search the userid */
|
|
||||||
rc = find_keyblock_byname( kbpos, username );
|
|
||||||
if( rc ) {
|
|
||||||
log_error(_("%s: user not found\n"), username );
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* read the keyblock */
|
|
||||||
rc = read_keyblock( kbpos, keyblock );
|
|
||||||
if( rc )
|
|
||||||
log_error("%s: keyblock read problem: %s\n", username, g10_errstr(rc));
|
|
||||||
else
|
|
||||||
merge_keys_and_selfsig( *keyblock );
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/****************
|
/****************
|
||||||
* Print information about a signature, check it and return true
|
* Print information about a signature, check it and return true
|
||||||
* if the signature is okay. NODE must be a signature packet.
|
* if the signature is okay. NODE must be a signature packet.
|
||||||
@ -626,9 +602,9 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands,
|
|||||||
enum cmdids cmd = 0;
|
enum cmdids cmd = 0;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
KBNODE keyblock = NULL;
|
KBNODE keyblock = NULL;
|
||||||
KBPOS keyblockpos;
|
KEYDB_HANDLE kdbhd = NULL;
|
||||||
KBNODE sec_keyblock = NULL;
|
KBNODE sec_keyblock = NULL;
|
||||||
KBPOS sec_keyblockpos;
|
KEYDB_HANDLE sec_kdbhd = NULL;
|
||||||
KBNODE cur_keyblock;
|
KBNODE cur_keyblock;
|
||||||
char *answer = NULL;
|
char *answer = NULL;
|
||||||
int redisplay = 1;
|
int redisplay = 1;
|
||||||
@ -651,7 +627,7 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* get the public key */
|
/* get the public key */
|
||||||
rc = get_keyblock_byname( &keyblock, &keyblockpos, username );
|
rc = get_pubkey_byname (NULL, username, &keyblock, &kdbhd);
|
||||||
if( rc )
|
if( rc )
|
||||||
goto leave;
|
goto leave;
|
||||||
if( fix_keyblock( keyblock ) )
|
if( fix_keyblock( keyblock ) )
|
||||||
@ -662,20 +638,36 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands,
|
|||||||
if( !sign_mode ) {/* see whether we have a matching secret key */
|
if( !sign_mode ) {/* see whether we have a matching secret key */
|
||||||
PKT_public_key *pk = keyblock->pkt->pkt.public_key;
|
PKT_public_key *pk = keyblock->pkt->pkt.public_key;
|
||||||
|
|
||||||
rc = find_secret_keyblock_bypk( &sec_keyblockpos, pk );
|
sec_kdbhd = keydb_new (1);
|
||||||
if( !rc ) {
|
{
|
||||||
rc = read_keyblock( &sec_keyblockpos, &sec_keyblock );
|
byte afp[MAX_FINGERPRINT_LEN];
|
||||||
if( rc ) {
|
size_t an;
|
||||||
log_error("%s: secret keyblock read problem: %s\n",
|
|
||||||
username, g10_errstr(rc));
|
fingerprint_from_pk (pk, afp, &an);
|
||||||
goto leave;
|
while (an < MAX_FINGERPRINT_LEN)
|
||||||
|
afp[an++] = 0;
|
||||||
|
rc = keydb_search_fpr (sec_kdbhd, afp);
|
||||||
}
|
}
|
||||||
|
if (!rc) {
|
||||||
|
rc = keydb_get_keyblock (sec_kdbhd, &sec_keyblock);
|
||||||
|
if (rc) {
|
||||||
|
log_error (_("error reading secret keyblock `%s': %s\n"),
|
||||||
|
username, g10_errstr(rc));
|
||||||
|
}
|
||||||
|
else {
|
||||||
merge_keys_and_selfsig( sec_keyblock );
|
merge_keys_and_selfsig( sec_keyblock );
|
||||||
if( fix_keyblock( sec_keyblock ) )
|
if( fix_keyblock( sec_keyblock ) )
|
||||||
sec_modified++;
|
sec_modified++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rc) {
|
||||||
|
sec_keyblock = NULL;
|
||||||
|
keydb_release (sec_kdbhd); sec_kdbhd = NULL;
|
||||||
|
rc = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if( sec_keyblock ) {
|
if( sec_keyblock ) {
|
||||||
tty_printf(_("Secret key is available.\n"));
|
tty_printf(_("Secret key is available.\n"));
|
||||||
}
|
}
|
||||||
@ -1012,16 +1004,16 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands,
|
|||||||
do_cmd_save:
|
do_cmd_save:
|
||||||
if( modified || sec_modified ) {
|
if( modified || sec_modified ) {
|
||||||
if( modified ) {
|
if( modified ) {
|
||||||
rc = update_keyblock( &keyblockpos, keyblock );
|
rc = keydb_update_keyblock (kdbhd, keyblock);
|
||||||
if( rc ) {
|
if( rc ) {
|
||||||
log_error(_("update failed: %s\n"), g10_errstr(rc) );
|
log_error(_("update failed: %s\n"), g10_errstr(rc) );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( sec_modified ) {
|
if( sec_modified ) {
|
||||||
rc = update_keyblock( &sec_keyblockpos, sec_keyblock );
|
rc = keydb_update_keyblock (sec_kdbhd, sec_keyblock );
|
||||||
if( rc ) {
|
if( rc ) {
|
||||||
log_error(_("update secret failed: %s\n"),
|
log_error( _("update secret failed: %s\n"),
|
||||||
g10_errstr(rc) );
|
g10_errstr(rc) );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1029,6 +1021,7 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
tty_printf(_("Key not changed so no update needed.\n"));
|
tty_printf(_("Key not changed so no update needed.\n"));
|
||||||
|
|
||||||
/* TODO: we should keep track whether we have changed
|
/* TODO: we should keep track whether we have changed
|
||||||
* something relevant to the trustdb */
|
* something relevant to the trustdb */
|
||||||
if( !modified && sign_mode )
|
if( !modified && sign_mode )
|
||||||
@ -1051,6 +1044,7 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands,
|
|||||||
leave:
|
leave:
|
||||||
release_kbnode( keyblock );
|
release_kbnode( keyblock );
|
||||||
release_kbnode( sec_keyblock );
|
release_kbnode( sec_keyblock );
|
||||||
|
keydb_release (kdbhd);
|
||||||
m_free(answer);
|
m_free(answer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
120
g10/keygen.c
120
g10/keygen.c
@ -284,22 +284,22 @@ static void
|
|||||||
add_feature_mdc (PKT_signature *sig)
|
add_feature_mdc (PKT_signature *sig)
|
||||||
{
|
{
|
||||||
const byte *s;
|
const byte *s;
|
||||||
size_t i, n;
|
size_t n;
|
||||||
char *buf;
|
char *buf;
|
||||||
|
|
||||||
s = parse_sig_subpkt (sig->hashed, SIGSUBPKT_FEATURES, &n );
|
s = parse_sig_subpkt (sig->hashed, SIGSUBPKT_FEATURES, &n );
|
||||||
if (!s)
|
if (s && n && (s[0] & 0x01))
|
||||||
n = 0;
|
|
||||||
|
|
||||||
for (i=0; i < n; i++ ) {
|
|
||||||
if (s[i] == 1)
|
|
||||||
return; /* already set */
|
return; /* already set */
|
||||||
|
if (!s || !n) { /* create a new one */
|
||||||
|
n = 1;
|
||||||
|
buf = m_alloc (n);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
buf = m_alloc (n+1);
|
buf = m_alloc (n);
|
||||||
buf[0] = 1; /* MDC feature */
|
memcpy (buf, s, n);
|
||||||
memcpy (buf+1, s, n);
|
}
|
||||||
build_sig_subpkt (sig, SIGSUBPKT_FEATURES, buf, n+1);
|
buf[0] |= 0x01; /* MDC feature */
|
||||||
|
build_sig_subpkt (sig, SIGSUBPKT_FEATURES, buf, n);
|
||||||
m_free (buf);
|
m_free (buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1769,8 +1769,6 @@ static void
|
|||||||
do_generate_keypair( struct para_data_s *para,
|
do_generate_keypair( struct para_data_s *para,
|
||||||
struct output_control_s *outctrl )
|
struct output_control_s *outctrl )
|
||||||
{
|
{
|
||||||
char *pub_fname = NULL;
|
|
||||||
char *sec_fname = NULL;
|
|
||||||
KBNODE pub_root = NULL;
|
KBNODE pub_root = NULL;
|
||||||
KBNODE sec_root = NULL;
|
KBNODE sec_root = NULL;
|
||||||
PKT_secret_key *sk = NULL;
|
PKT_secret_key *sk = NULL;
|
||||||
@ -1823,20 +1821,14 @@ do_generate_keypair( struct para_data_s *para,
|
|||||||
&outctrl->sec.afx );
|
&outctrl->sec.afx );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub_fname = outctrl->pub.fname; /* only for info output */
|
|
||||||
sec_fname = outctrl->sec.fname; /* only for info output */
|
|
||||||
assert( outctrl->pub.stream );
|
assert( outctrl->pub.stream );
|
||||||
assert( outctrl->sec.stream );
|
assert( outctrl->sec.stream );
|
||||||
|
if( opt.verbose ) {
|
||||||
|
log_info(_("writing public key to `%s'\n"), outctrl->pub.fname );
|
||||||
|
log_info(_("writing secret key to `%s'\n"), outctrl->sec.fname );
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
pub_fname = get_writable_keyblock_file( 0 );
|
|
||||||
sec_fname = get_writable_keyblock_file( 1 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( opt.verbose ) {
|
|
||||||
log_info(_("writing public key to `%s'\n"), pub_fname );
|
|
||||||
log_info(_("writing secret key to `%s'\n"), sec_fname );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* we create the packets as a tree of kbnodes. Because the structure
|
/* we create the packets as a tree of kbnodes. Because the structure
|
||||||
* we create is known in advance we simply generate a linked list
|
* we create is known in advance we simply generate a linked list
|
||||||
@ -1895,46 +1887,47 @@ do_generate_keypair( struct para_data_s *para,
|
|||||||
|
|
||||||
}
|
}
|
||||||
else if( !rc ) { /* write to the standard keyrings */
|
else if( !rc ) { /* write to the standard keyrings */
|
||||||
KBPOS pub_kbpos;
|
KEYDB_HANDLE pub_hd = keydb_new (0);
|
||||||
KBPOS sec_kbpos;
|
KEYDB_HANDLE sec_hd = keydb_new (1);
|
||||||
int rc1 = -1;
|
|
||||||
int rc2 = -1;
|
|
||||||
|
|
||||||
/* we can now write the certificates */
|
/* FIXME: we may have to create the keyring first */
|
||||||
if( get_keyblock_handle( pub_fname, 0, &pub_kbpos ) ) {
|
rc = keydb_locate_writable (pub_hd, NULL);
|
||||||
if( add_keyblock_resource( pub_fname, 1, 0 ) ) {
|
if (rc)
|
||||||
log_error("can add keyblock file `%s'\n", pub_fname );
|
log_error (_("no writable public keyring found: %s\n"),
|
||||||
rc = G10ERR_CREATE_FILE;
|
g10_errstr (rc));
|
||||||
}
|
|
||||||
else if( get_keyblock_handle( pub_fname, 0, &pub_kbpos ) ) {
|
if (!rc) {
|
||||||
log_error("can get keyblock handle for `%s'\n", pub_fname );
|
rc = keydb_locate_writable (sec_hd, NULL);
|
||||||
rc = G10ERR_CREATE_FILE;
|
if (rc)
|
||||||
}
|
log_error (_("no writable secret keyring found: %s\n"),
|
||||||
}
|
g10_errstr (rc));
|
||||||
if( rc )
|
|
||||||
;
|
|
||||||
else if( get_keyblock_handle( sec_fname, 1, &sec_kbpos ) ) {
|
|
||||||
if( add_keyblock_resource( sec_fname, 1, 1 ) ) {
|
|
||||||
log_error("can add keyblock file `%s'\n", sec_fname );
|
|
||||||
rc = G10ERR_CREATE_FILE;
|
|
||||||
}
|
|
||||||
else if( get_keyblock_handle( sec_fname, 1, &sec_kbpos ) ) {
|
|
||||||
log_error("can get keyblock handle for `%s'\n", sec_fname );
|
|
||||||
rc = G10ERR_CREATE_FILE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( rc )
|
if (!rc && opt.verbose) {
|
||||||
;
|
log_info(_("writing public key to `%s'\n"),
|
||||||
else if( (rc=rc1=lock_keyblock( &pub_kbpos )) )
|
keydb_get_resource_name (pub_hd));
|
||||||
log_error("can't lock public keyring: %s\n", g10_errstr(rc) );
|
log_info(_("writing secret key to `%s'\n"),
|
||||||
else if( (rc=rc2=lock_keyblock( &sec_kbpos )) )
|
keydb_get_resource_name (sec_hd));
|
||||||
log_error("can't lock secret keyring: %s\n", g10_errstr(rc) );
|
}
|
||||||
else if( (rc=insert_keyblock( &pub_kbpos, pub_root )) )
|
|
||||||
log_error("can't write public key: %s\n", g10_errstr(rc) );
|
if (!rc) {
|
||||||
else if( (rc=insert_keyblock( &sec_kbpos, sec_root )) )
|
rc = keydb_insert_keyblock (pub_hd, pub_root);
|
||||||
log_error("can't write secret key: %s\n", g10_errstr(rc) );
|
if (rc)
|
||||||
else {
|
log_error (_("error writing public keyring `%s': %s\n"),
|
||||||
|
keydb_get_resource_name (pub_hd), g10_errstr(rc));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rc) {
|
||||||
|
rc = keydb_insert_keyblock (sec_hd, sec_root);
|
||||||
|
if (rc)
|
||||||
|
log_error (_("error writing secret keyring `%s': %s\n"),
|
||||||
|
keydb_get_resource_name (pub_hd), g10_errstr(rc));
|
||||||
|
}
|
||||||
|
|
||||||
|
keydb_release (pub_hd);
|
||||||
|
keydb_release (sec_hd);
|
||||||
|
|
||||||
|
if (!rc) {
|
||||||
int no_enc_rsa =
|
int no_enc_rsa =
|
||||||
get_parameter_algo(para, pKEYTYPE) == PUBKEY_ALGO_RSA
|
get_parameter_algo(para, pKEYTYPE) == PUBKEY_ALGO_RSA
|
||||||
&& get_parameter_uint( para, pKEYUSAGE )
|
&& get_parameter_uint( para, pKEYUSAGE )
|
||||||
@ -1953,11 +1946,6 @@ do_generate_keypair( struct para_data_s *para,
|
|||||||
"secondary key for this purpose.\n") );
|
"secondary key for this purpose.\n") );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !rc1 )
|
|
||||||
unlock_keyblock( &pub_kbpos );
|
|
||||||
if( !rc2 )
|
|
||||||
unlock_keyblock( &sec_kbpos );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( rc ) {
|
if( rc ) {
|
||||||
@ -1973,10 +1961,6 @@ do_generate_keypair( struct para_data_s *para,
|
|||||||
release_kbnode( sec_root );
|
release_kbnode( sec_root );
|
||||||
if( sk ) /* the unprotected secret key */
|
if( sk ) /* the unprotected secret key */
|
||||||
free_secret_key(sk);
|
free_secret_key(sk);
|
||||||
if( !outctrl->use_files ) {
|
|
||||||
m_free(pub_fname);
|
|
||||||
m_free(sec_fname);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -277,7 +277,7 @@ mk_datestr (char *buffer, time_t atime)
|
|||||||
struct tm *tp;
|
struct tm *tp;
|
||||||
|
|
||||||
if ( atime < 0 ) /* 32 bit time_t and after 2038-01-19 */
|
if ( atime < 0 ) /* 32 bit time_t and after 2038-01-19 */
|
||||||
strcpy (buffer, "????-??-??"); /* mark this as invalid */
|
strcpy (buffer, "????" "-??" "-??"); /* mark this as invalid */
|
||||||
else {
|
else {
|
||||||
tp = gmtime (&atime);
|
tp = gmtime (&atime);
|
||||||
sprintf (buffer,"%04d-%02d-%02d",
|
sprintf (buffer,"%04d-%02d-%02d",
|
||||||
@ -401,9 +401,9 @@ byte *
|
|||||||
fingerprint_from_pk( PKT_public_key *pk, byte *array, size_t *ret_len )
|
fingerprint_from_pk( PKT_public_key *pk, byte *array, size_t *ret_len )
|
||||||
{
|
{
|
||||||
byte *p, *buf;
|
byte *p, *buf;
|
||||||
const char *dp;
|
const byte *dp;
|
||||||
size_t len;
|
size_t len;
|
||||||
unsigned n;
|
unsigned int n;
|
||||||
|
|
||||||
if( pk->version < 4 && is_RSA(pk->pubkey_algo) ) {
|
if( pk->version < 4 && is_RSA(pk->pubkey_algo) ) {
|
||||||
/* RSA in version 3 packets is special */
|
/* RSA in version 3 packets is special */
|
||||||
@ -434,6 +434,8 @@ fingerprint_from_pk( PKT_public_key *pk, byte *array, size_t *ret_len )
|
|||||||
if( !array )
|
if( !array )
|
||||||
array = m_alloc( len );
|
array = m_alloc( len );
|
||||||
memcpy(array, dp, len );
|
memcpy(array, dp, len );
|
||||||
|
pk->keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
|
||||||
|
pk->keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
|
||||||
md_close(md);
|
md_close(md);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,41 +67,50 @@ secret_key_list( STRLIST list )
|
|||||||
static void
|
static void
|
||||||
list_all( int secret )
|
list_all( int secret )
|
||||||
{
|
{
|
||||||
KBPOS kbpos;
|
KEYDB_HANDLE hd;
|
||||||
KBNODE keyblock = NULL;
|
KBNODE keyblock = NULL;
|
||||||
int rc=0;
|
int rc=0;
|
||||||
int lastresno;
|
const char *lastresname, *resname;
|
||||||
|
|
||||||
rc = enum_keyblocks( secret? 5:0, &kbpos, &keyblock );
|
hd = keydb_new (secret);
|
||||||
|
if (!hd)
|
||||||
|
rc = G10ERR_GENERAL;
|
||||||
|
else
|
||||||
|
rc = keydb_search_first (hd);
|
||||||
if( rc ) {
|
if( rc ) {
|
||||||
if( rc != -1 )
|
if( rc != -1 )
|
||||||
log_error("enum_keyblocks(open) failed: %s\n", g10_errstr(rc) );
|
log_error("keydb_search_first failed: %s\n", g10_errstr(rc) );
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
lastresno = -1;
|
lastresname = NULL;
|
||||||
while( !(rc = enum_keyblocks( 1, &kbpos, &keyblock )) ) {
|
do {
|
||||||
if( lastresno != kbpos.resno ) {
|
rc = keydb_get_keyblock (hd, &keyblock);
|
||||||
const char *s = keyblock_resource_name( &kbpos );
|
if (rc) {
|
||||||
|
log_error ("keydb_get_keyblock failed: %s\n", g10_errstr(rc));
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
resname = keydb_get_resource_name (hd);
|
||||||
|
if (lastresname != resname ) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
lastresno = kbpos.resno;
|
printf("%s\n", resname );
|
||||||
printf("%s\n", s );
|
for(i=strlen(resname); i; i-- )
|
||||||
for(i=strlen(s); i; i-- )
|
|
||||||
putchar('-');
|
putchar('-');
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
|
lastresname = resname;
|
||||||
}
|
}
|
||||||
merge_keys_and_selfsig( keyblock );
|
merge_keys_and_selfsig( keyblock );
|
||||||
list_keyblock( keyblock, secret );
|
list_keyblock( keyblock, secret );
|
||||||
release_kbnode( keyblock ); keyblock = NULL;
|
release_kbnode( keyblock );
|
||||||
}
|
keyblock = NULL;
|
||||||
|
} while (!(rc = keydb_search_next (hd)));
|
||||||
if( rc && rc != -1 )
|
if( rc && rc != -1 )
|
||||||
log_error("enum_keyblocks(read) failed: %s\n", g10_errstr(rc));
|
log_error ("keydb_search_next failed: %s\n", g10_errstr(rc));
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
enum_keyblocks( 2, &kbpos, &keyblock ); /* close */
|
release_kbnode (keyblock);
|
||||||
release_kbnode( keyblock );
|
keydb_release (hd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
1061
g10/keyring.c
Normal file
1061
g10/keyring.c
Normal file
File diff suppressed because it is too large
Load Diff
44
g10/keyring.h
Normal file
44
g10/keyring.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/* keyring.h - Keyring operations
|
||||||
|
* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of GnuPG.
|
||||||
|
*
|
||||||
|
* GnuPG 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.
|
||||||
|
*
|
||||||
|
* GnuPG 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GPG_KEYRING_H
|
||||||
|
#define GPG_KEYRING_H 1
|
||||||
|
|
||||||
|
#include "global.h"
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct keyring_handle *KEYRING_HANDLE;
|
||||||
|
|
||||||
|
void keyring_register_filename (const char *fname, int secret);
|
||||||
|
|
||||||
|
|
||||||
|
KEYRING_HANDLE keyring_new (int secret);
|
||||||
|
void keyring_release (KEYRING_HANDLE hd);
|
||||||
|
const char *keyring_get_resource_name (KEYRING_HANDLE hd);
|
||||||
|
int keyring_lock (KEYRING_HANDLE hd, int yes);
|
||||||
|
int keyring_get_keyblock (KEYRING_HANDLE hd, KBNODE *ret_kb);
|
||||||
|
int keyring_update_keyblock (KEYRING_HANDLE hd, KBNODE kb);
|
||||||
|
int keyring_insert_keyblock (KEYRING_HANDLE hd, KBNODE kb);
|
||||||
|
int keyring_delete_keyblock (KEYRING_HANDLE hd);
|
||||||
|
int keyring_search_reset (KEYRING_HANDLE hd);
|
||||||
|
int keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc, size_t ndesc);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /*GPG_KEYRING_H*/
|
BIN
g10/keyring.o
Normal file
BIN
g10/keyring.o
Normal file
Binary file not shown.
@ -755,7 +755,7 @@ print_notation_data( PKT_signature *sig )
|
|||||||
write_status_buffer ( STATUS_POLICY_URL, p, n, 0 );
|
write_status_buffer ( STATUS_POLICY_URL, p, n, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now check wheter the key of this signature has some
|
/* Now check whether the key of this signature has some
|
||||||
* notation data */
|
* notation data */
|
||||||
|
|
||||||
/* TODO */
|
/* TODO */
|
||||||
|
@ -50,6 +50,7 @@ struct {
|
|||||||
int check_sigs; /* check key signatures */
|
int check_sigs; /* check key signatures */
|
||||||
int with_colons;
|
int with_colons;
|
||||||
int with_key_data;
|
int with_key_data;
|
||||||
|
int with_fingerprint; /* opt --with-fingerprint active */
|
||||||
int fingerprint; /* list fingerprints */
|
int fingerprint; /* list fingerprints */
|
||||||
int list_sigs; /* list signatures */
|
int list_sigs; /* list signatures */
|
||||||
int no_armor;
|
int no_armor;
|
||||||
|
@ -323,7 +323,7 @@ int list_packets( IOBUF a );
|
|||||||
int set_packet_list_mode( int mode );
|
int set_packet_list_mode( int mode );
|
||||||
|
|
||||||
#if DEBUG_PARSE_PACKET
|
#if DEBUG_PARSE_PACKET
|
||||||
int dbg_search_packet( IOBUF inp, PACKET *pkt, off_t *retpos,
|
int dbg_search_packet( IOBUF inp, PACKET *pkt, off_t *retpos, int with_uid,
|
||||||
const char* file, int lineno );
|
const char* file, int lineno );
|
||||||
int dbg_parse_packet( IOBUF inp, PACKET *ret_pkt,
|
int dbg_parse_packet( IOBUF inp, PACKET *ret_pkt,
|
||||||
const char* file, int lineno );
|
const char* file, int lineno );
|
||||||
@ -333,8 +333,8 @@ int dbg_copy_some_packets( IOBUF inp, IOBUF out, off_t stopoff,
|
|||||||
const char* file, int lineno );
|
const char* file, int lineno );
|
||||||
int dbg_skip_some_packets( IOBUF inp, unsigned n,
|
int dbg_skip_some_packets( IOBUF inp, unsigned n,
|
||||||
const char* file, int lineno );
|
const char* file, int lineno );
|
||||||
#define search_packet( a,b,c ) \
|
#define search_packet( a,b,c,d ) \
|
||||||
dbg_search_packet( (a), (b), (c), __FILE__, __LINE__ )
|
dbg_search_packet( (a), (b), (c), (d), __FILE__, __LINE__ )
|
||||||
#define parse_packet( a, b ) \
|
#define parse_packet( a, b ) \
|
||||||
dbg_parse_packet( (a), (b), __FILE__, __LINE__ )
|
dbg_parse_packet( (a), (b), __FILE__, __LINE__ )
|
||||||
#define copy_all_packets( a,b ) \
|
#define copy_all_packets( a,b ) \
|
||||||
@ -344,7 +344,7 @@ int dbg_skip_some_packets( IOBUF inp, unsigned n,
|
|||||||
#define skip_some_packets( a,b ) \
|
#define skip_some_packets( a,b ) \
|
||||||
dbg_skip_some_packets((a),(b), __FILE__, __LINE__ )
|
dbg_skip_some_packets((a),(b), __FILE__, __LINE__ )
|
||||||
#else
|
#else
|
||||||
int search_packet( IOBUF inp, PACKET *pkt, off_t *retpos );
|
int search_packet( IOBUF inp, PACKET *pkt, off_t *retpos, int with_uid );
|
||||||
int parse_packet( IOBUF inp, PACKET *ret_pkt);
|
int parse_packet( IOBUF inp, PACKET *ret_pkt);
|
||||||
int copy_all_packets( IOBUF inp, IOBUF out );
|
int copy_all_packets( IOBUF inp, IOBUF out );
|
||||||
int copy_some_packets( IOBUF inp, IOBUF out, off_t stopoff );
|
int copy_some_packets( IOBUF inp, IOBUF out, off_t stopoff );
|
||||||
|
@ -158,24 +158,24 @@ parse_packet( IOBUF inp, PACKET *pkt )
|
|||||||
*/
|
*/
|
||||||
#ifdef DEBUG_PARSE_PACKET
|
#ifdef DEBUG_PARSE_PACKET
|
||||||
int
|
int
|
||||||
dbg_search_packet( IOBUF inp, PACKET *pkt, off_t *retpos,
|
dbg_search_packet( IOBUF inp, PACKET *pkt, off_t *retpos, int with_uid,
|
||||||
const char *dbg_f, int dbg_l )
|
const char *dbg_f, int dbg_l )
|
||||||
{
|
{
|
||||||
int skip, rc;
|
int skip, rc;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
rc = parse( inp, pkt, 1, retpos, &skip, NULL, 0, "search", dbg_f, dbg_l );
|
rc = parse( inp, pkt, with_uid?2:1, retpos, &skip, NULL, 0, "search", dbg_f, dbg_l );
|
||||||
} while( skip );
|
} while( skip );
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
int
|
int
|
||||||
search_packet( IOBUF inp, PACKET *pkt, off_t *retpos )
|
search_packet( IOBUF inp, PACKET *pkt, off_t *retpos, int with_uid )
|
||||||
{
|
{
|
||||||
int skip, rc;
|
int skip, rc;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
rc = parse( inp, pkt, 1, retpos, &skip, NULL, 0 );
|
rc = parse( inp, pkt, with_uid?2:1, retpos, &skip, NULL, 0 );
|
||||||
} while( skip );
|
} while( skip );
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -296,6 +296,7 @@ parse( IOBUF inp, PACKET *pkt, int onlykeypkts, off_t *retpos,
|
|||||||
byte hdr[8];
|
byte hdr[8];
|
||||||
int hdrlen;
|
int hdrlen;
|
||||||
int new_ctb = 0;
|
int new_ctb = 0;
|
||||||
|
int with_uid = (onlykeypkts == 2);
|
||||||
|
|
||||||
*skip = 0;
|
*skip = 0;
|
||||||
assert( !pkt->pkt.generic );
|
assert( !pkt->pkt.generic );
|
||||||
@ -375,7 +376,9 @@ parse( IOBUF inp, PACKET *pkt, int onlykeypkts, off_t *retpos,
|
|||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( do_skip
|
if (with_uid && pkttype == PKT_USER_ID)
|
||||||
|
;
|
||||||
|
else if( do_skip
|
||||||
|| !pkttype
|
|| !pkttype
|
||||||
|| (onlykeypkts && pkttype != PKT_PUBLIC_SUBKEY
|
|| (onlykeypkts && pkttype != PKT_PUBLIC_SUBKEY
|
||||||
&& pkttype != PKT_PUBLIC_KEY
|
&& pkttype != PKT_PUBLIC_KEY
|
||||||
@ -866,7 +869,7 @@ dump_sig_subpkt( int hashed, int type, int critical,
|
|||||||
case SIGSUBPKT_FEATURES:
|
case SIGSUBPKT_FEATURES:
|
||||||
fputs ( "features:", stdout );
|
fputs ( "features:", stdout );
|
||||||
for( i=0; i < length; i++ )
|
for( i=0; i < length; i++ )
|
||||||
printf(" %d", buffer[i] );
|
printf(" %02x", buffer[i] );
|
||||||
break;
|
break;
|
||||||
case SIGSUBPKT_PRIV_VERIFY_CACHE:
|
case SIGSUBPKT_PRIV_VERIFY_CACHE:
|
||||||
p = "verification cache";
|
p = "verification cache";
|
||||||
|
@ -285,7 +285,7 @@ agent_get_passphrase ( u32 *keyid, int mode )
|
|||||||
char *atext;
|
char *atext;
|
||||||
char buf[50];
|
char buf[50];
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
int nread;
|
size_t nread;
|
||||||
u32 reply;
|
u32 reply;
|
||||||
char *pw = NULL;
|
char *pw = NULL;
|
||||||
PKT_public_key *pk = m_alloc_clear( sizeof *pk );
|
PKT_public_key *pk = m_alloc_clear( sizeof *pk );
|
||||||
@ -433,7 +433,7 @@ passphrase_clear_cache ( u32 *keyid, int algo )
|
|||||||
size_t n;
|
size_t n;
|
||||||
char buf[50];
|
char buf[50];
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
int nread;
|
size_t nread;
|
||||||
u32 reply;
|
u32 reply;
|
||||||
PKT_public_key *pk;
|
PKT_public_key *pk;
|
||||||
byte fpr[MAX_FINGERPRINT_LEN];
|
byte fpr[MAX_FINGERPRINT_LEN];
|
||||||
|
@ -628,7 +628,10 @@ check_signatures_trust( PKT_signature *sig )
|
|||||||
if( opt.always_trust ) {
|
if( opt.always_trust ) {
|
||||||
if( !opt.quiet )
|
if( !opt.quiet )
|
||||||
log_info(_("WARNING: Using untrusted key!\n"));
|
log_info(_("WARNING: Using untrusted key!\n"));
|
||||||
return 0;
|
if (opt.with_fingerprint)
|
||||||
|
fpr_info (pk);
|
||||||
|
rc = 0;
|
||||||
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -705,6 +708,8 @@ check_signatures_trust( PKT_signature *sig )
|
|||||||
write_status( STATUS_TRUST_NEVER );
|
write_status( STATUS_TRUST_NEVER );
|
||||||
log_info(_("WARNING: We do NOT trust this key!\n"));
|
log_info(_("WARNING: We do NOT trust this key!\n"));
|
||||||
log_info(_(" The signature is probably a FORGERY.\n"));
|
log_info(_(" The signature is probably a FORGERY.\n"));
|
||||||
|
if (opt.with_fingerprint)
|
||||||
|
fpr_info (pk);
|
||||||
rc = G10ERR_BAD_SIGN;
|
rc = G10ERR_BAD_SIGN;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -721,10 +726,14 @@ check_signatures_trust( PKT_signature *sig )
|
|||||||
|
|
||||||
case TRUST_FULLY:
|
case TRUST_FULLY:
|
||||||
write_status( STATUS_TRUST_FULLY );
|
write_status( STATUS_TRUST_FULLY );
|
||||||
|
if (opt.with_fingerprint)
|
||||||
|
fpr_info (pk);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TRUST_ULTIMATE:
|
case TRUST_ULTIMATE:
|
||||||
write_status( STATUS_TRUST_ULTIMATE );
|
write_status( STATUS_TRUST_ULTIMATE );
|
||||||
|
if (opt.with_fingerprint)
|
||||||
|
fpr_info (pk);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: BUG();
|
default: BUG();
|
||||||
@ -814,9 +823,11 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use )
|
|||||||
else if( (use & PUBKEY_USAGE_ENC) && !opt.no_encrypt_to ) {
|
else if( (use & PUBKEY_USAGE_ENC) && !opt.no_encrypt_to ) {
|
||||||
pk = m_alloc_clear( sizeof *pk );
|
pk = m_alloc_clear( sizeof *pk );
|
||||||
pk->req_usage = use;
|
pk->req_usage = use;
|
||||||
if( (rc = get_pubkey_byname( NULL, pk, rov->d, NULL )) ) {
|
if( (rc = get_pubkey_byname( pk, rov->d, NULL, NULL )) ) {
|
||||||
free_public_key( pk ); pk = NULL;
|
free_public_key( pk ); pk = NULL;
|
||||||
log_error(_("%s: skipped: %s\n"), rov->d, g10_errstr(rc) );
|
log_error(_("%s: skipped: %s\n"), rov->d, g10_errstr(rc) );
|
||||||
|
write_status_text_and_buffer (STATUS_INV_RECP, "0 ",
|
||||||
|
rov->d, strlen (rov->d), -1);
|
||||||
}
|
}
|
||||||
else if( !(rc=check_pubkey_algo2(pk->pubkey_algo, use )) ) {
|
else if( !(rc=check_pubkey_algo2(pk->pubkey_algo, use )) ) {
|
||||||
/* Skip the actual key if the key is already present
|
/* Skip the actual key if the key is already present
|
||||||
@ -838,6 +849,8 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use )
|
|||||||
else {
|
else {
|
||||||
free_public_key( pk ); pk = NULL;
|
free_public_key( pk ); pk = NULL;
|
||||||
log_error(_("%s: skipped: %s\n"), rov->d, g10_errstr(rc) );
|
log_error(_("%s: skipped: %s\n"), rov->d, g10_errstr(rc) );
|
||||||
|
write_status_text_and_buffer (STATUS_INV_RECP, "0 ",
|
||||||
|
rov->d, strlen (rov->d), -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -870,7 +883,7 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use )
|
|||||||
free_public_key( pk );
|
free_public_key( pk );
|
||||||
pk = m_alloc_clear( sizeof *pk );
|
pk = m_alloc_clear( sizeof *pk );
|
||||||
pk->req_usage = use;
|
pk->req_usage = use;
|
||||||
rc = get_pubkey_byname( NULL, pk, answer, NULL );
|
rc = get_pubkey_byname( pk, answer, NULL, NULL );
|
||||||
if( rc )
|
if( rc )
|
||||||
tty_printf(_("No such user ID.\n"));
|
tty_printf(_("No such user ID.\n"));
|
||||||
else if( !(rc=check_pubkey_algo2(pk->pubkey_algo, use)) ) {
|
else if( !(rc=check_pubkey_algo2(pk->pubkey_algo, use)) ) {
|
||||||
@ -936,7 +949,7 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use )
|
|||||||
else if( !any_recipients && (def_rec = default_recipient()) ) {
|
else if( !any_recipients && (def_rec = default_recipient()) ) {
|
||||||
pk = m_alloc_clear( sizeof *pk );
|
pk = m_alloc_clear( sizeof *pk );
|
||||||
pk->req_usage = use;
|
pk->req_usage = use;
|
||||||
rc = get_pubkey_byname( NULL, pk, def_rec, NULL );
|
rc = get_pubkey_byname( pk, def_rec, NULL, NULL );
|
||||||
if( rc )
|
if( rc )
|
||||||
log_error(_("unknown default recipient `%s'\n"), def_rec );
|
log_error(_("unknown default recipient `%s'\n"), def_rec );
|
||||||
else if( !(rc=check_pubkey_algo2(pk->pubkey_algo, use)) ) {
|
else if( !(rc=check_pubkey_algo2(pk->pubkey_algo, use)) ) {
|
||||||
@ -961,9 +974,12 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use )
|
|||||||
|
|
||||||
pk = m_alloc_clear( sizeof *pk );
|
pk = m_alloc_clear( sizeof *pk );
|
||||||
pk->req_usage = use;
|
pk->req_usage = use;
|
||||||
if( (rc = get_pubkey_byname( NULL, pk, remusr->d, NULL )) ) {
|
if( (rc = get_pubkey_byname( pk, remusr->d, NULL, NULL )) ) {
|
||||||
free_public_key( pk ); pk = NULL;
|
free_public_key( pk ); pk = NULL;
|
||||||
log_error(_("%s: skipped: %s\n"), remusr->d, g10_errstr(rc) );
|
log_error(_("%s: skipped: %s\n"), remusr->d, g10_errstr(rc) );
|
||||||
|
write_status_text_and_buffer (STATUS_INV_RECP, "0 ",
|
||||||
|
remusr->d, strlen (remusr->d),
|
||||||
|
-1);
|
||||||
}
|
}
|
||||||
else if( !(rc=check_pubkey_algo2(pk->pubkey_algo, use )) ) {
|
else if( !(rc=check_pubkey_algo2(pk->pubkey_algo, use )) ) {
|
||||||
int trustlevel;
|
int trustlevel;
|
||||||
@ -973,11 +989,19 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use )
|
|||||||
free_public_key( pk ); pk = NULL;
|
free_public_key( pk ); pk = NULL;
|
||||||
log_error(_("%s: error checking key: %s\n"),
|
log_error(_("%s: error checking key: %s\n"),
|
||||||
remusr->d, g10_errstr(rc) );
|
remusr->d, g10_errstr(rc) );
|
||||||
|
write_status_text_and_buffer (STATUS_INV_RECP, "0 ",
|
||||||
|
remusr->d,
|
||||||
|
strlen (remusr->d),
|
||||||
|
-1);
|
||||||
}
|
}
|
||||||
else if( (trustlevel & TRUST_FLAG_DISABLED) ) {
|
else if( (trustlevel & TRUST_FLAG_DISABLED) ) {
|
||||||
free_public_key(pk); pk = NULL;
|
free_public_key(pk); pk = NULL;
|
||||||
log_info(_("%s: skipped: public key is disabled\n"),
|
log_info(_("%s: skipped: public key is disabled\n"),
|
||||||
remusr->d);
|
remusr->d);
|
||||||
|
write_status_text_and_buffer (STATUS_INV_RECP, "0 ",
|
||||||
|
remusr->d,
|
||||||
|
strlen (remusr->d),
|
||||||
|
-1);
|
||||||
}
|
}
|
||||||
else if( do_we_trust_pre( pk, trustlevel ) ) {
|
else if( do_we_trust_pre( pk, trustlevel ) ) {
|
||||||
/* note: do_we_trust may have changed the trustlevel */
|
/* note: do_we_trust may have changed the trustlevel */
|
||||||
@ -1004,10 +1028,18 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use )
|
|||||||
}
|
}
|
||||||
else { /* we don't trust this pk */
|
else { /* we don't trust this pk */
|
||||||
free_public_key( pk ); pk = NULL;
|
free_public_key( pk ); pk = NULL;
|
||||||
|
write_status_text_and_buffer (STATUS_INV_RECP, "0 ",
|
||||||
|
remusr->d,
|
||||||
|
strlen (remusr->d),
|
||||||
|
-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
free_public_key( pk ); pk = NULL;
|
free_public_key( pk ); pk = NULL;
|
||||||
|
write_status_text_and_buffer (STATUS_INV_RECP, "0 ",
|
||||||
|
remusr->d,
|
||||||
|
strlen (remusr->d),
|
||||||
|
-1);
|
||||||
log_error(_("%s: skipped: %s\n"), remusr->d, g10_errstr(rc) );
|
log_error(_("%s: skipped: %s\n"), remusr->d, g10_errstr(rc) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
38
g10/revoke.c
38
g10/revoke.c
@ -87,41 +87,46 @@ gen_revoke( const char *uname )
|
|||||||
IOBUF out = NULL;
|
IOBUF out = NULL;
|
||||||
KBNODE keyblock = NULL;
|
KBNODE keyblock = NULL;
|
||||||
KBNODE node;
|
KBNODE node;
|
||||||
KBPOS kbpos;
|
KEYDB_HANDLE kdbhd;
|
||||||
struct revocation_reason_info *reason = NULL;
|
struct revocation_reason_info *reason = NULL;
|
||||||
|
KEYDB_SEARCH_DESC desc;
|
||||||
|
|
||||||
if( opt.batch ) {
|
if( opt.batch ) {
|
||||||
log_error(_("sorry, can't do this in batch mode\n"));
|
log_error(_("sorry, can't do this in batch mode\n"));
|
||||||
return G10ERR_GENERAL;
|
return G10ERR_GENERAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
memset( &afx, 0, sizeof afx);
|
memset( &afx, 0, sizeof afx);
|
||||||
memset( &zfx, 0, sizeof zfx);
|
memset( &zfx, 0, sizeof zfx);
|
||||||
init_packet( &pkt );
|
init_packet( &pkt );
|
||||||
|
|
||||||
|
/* search the userid:
|
||||||
/* search the userid */
|
* We don't want the whole getkey stuff here but the entire keyblock
|
||||||
rc = find_secret_keyblock_byname( &kbpos, uname );
|
*/
|
||||||
if( rc ) {
|
kdbhd = keydb_new (1);
|
||||||
log_error(_("secret key for user `%s' not found\n"), uname );
|
memset (&desc, 0, sizeof desc);
|
||||||
|
desc.mode = classify_user_id (uname,
|
||||||
|
desc.u.kid,
|
||||||
|
desc.u.fpr,
|
||||||
|
&desc.u.name,
|
||||||
|
NULL);
|
||||||
|
rc = desc.mode? keydb_search (kdbhd, &desc, 1) : G10ERR_INV_USER_ID;
|
||||||
|
if (rc) {
|
||||||
|
log_error (_("secret key `%s' not found: %s\n"),
|
||||||
|
uname, g10_errstr (rc));
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read the keyblock */
|
rc = keydb_get_keyblock (kdbhd, &keyblock );
|
||||||
rc = read_keyblock( &kbpos, &keyblock );
|
|
||||||
if( rc ) {
|
if( rc ) {
|
||||||
log_error(_("error reading the certificate: %s\n"), g10_errstr(rc) );
|
log_error (_("error reading keyblock: %s\n"), g10_errstr(rc) );
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the keyid from the keyblock */
|
/* get the keyid from the keyblock */
|
||||||
node = find_kbnode( keyblock, PKT_SECRET_KEY );
|
node = find_kbnode( keyblock, PKT_SECRET_KEY );
|
||||||
if( !node ) { /* maybe better to use log_bug ? */
|
if( !node )
|
||||||
log_error(_("Oops; secret key not found anymore!\n"));
|
BUG ();
|
||||||
rc = G10ERR_GENERAL;
|
|
||||||
goto leave;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* fixme: should make a function out of this stuff,
|
/* fixme: should make a function out of this stuff,
|
||||||
* it's used all over the source */
|
* it's used all over the source */
|
||||||
@ -139,6 +144,8 @@ gen_revoke( const char *uname )
|
|||||||
tty_printf("\n");
|
tty_printf("\n");
|
||||||
}
|
}
|
||||||
pk = m_alloc_clear( sizeof *pk );
|
pk = m_alloc_clear( sizeof *pk );
|
||||||
|
|
||||||
|
/* FIXME: We should get the public key direct from the secret one */
|
||||||
rc = get_pubkey( pk, sk_keyid );
|
rc = get_pubkey( pk, sk_keyid );
|
||||||
if( rc ) {
|
if( rc ) {
|
||||||
log_error(_("no corresponding public key: %s\n"), g10_errstr(rc) );
|
log_error(_("no corresponding public key: %s\n"), g10_errstr(rc) );
|
||||||
@ -224,6 +231,7 @@ gen_revoke( const char *uname )
|
|||||||
if( sig )
|
if( sig )
|
||||||
free_seckey_enc( sig );
|
free_seckey_enc( sig );
|
||||||
release_kbnode( keyblock );
|
release_kbnode( keyblock );
|
||||||
|
keydb_release (kdbhd);
|
||||||
if( rc )
|
if( rc )
|
||||||
iobuf_cancel(out);
|
iobuf_cancel(out);
|
||||||
else
|
else
|
||||||
|
1796
g10/ringedit.c
1796
g10/ringedit.c
File diff suppressed because it is too large
Load Diff
@ -140,6 +140,7 @@ get_status_string ( int no )
|
|||||||
case STATUS_KEY_CREATED : s = "KEY_CREATED"; break;
|
case STATUS_KEY_CREATED : s = "KEY_CREATED"; break;
|
||||||
case STATUS_USERID_HINT : s = "USERID_HINT"; break;
|
case STATUS_USERID_HINT : s = "USERID_HINT"; break;
|
||||||
case STATUS_UNEXPECTED : s = "UNEXPECTED"; break;
|
case STATUS_UNEXPECTED : s = "UNEXPECTED"; break;
|
||||||
|
case STATUS_INV_RECP : s = "INV_RECP"; break;
|
||||||
default: s = "?"; break;
|
default: s = "?"; break;
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
|
@ -90,6 +90,8 @@
|
|||||||
#define STATUS_KEY_CREATED 58
|
#define STATUS_KEY_CREATED 58
|
||||||
#define STATUS_USERID_HINT 59
|
#define STATUS_USERID_HINT 59
|
||||||
#define STATUS_UNEXPECTED 60
|
#define STATUS_UNEXPECTED 60
|
||||||
|
#define STATUS_INV_RECP 61
|
||||||
|
|
||||||
|
|
||||||
/*-- status.c --*/
|
/*-- status.c --*/
|
||||||
void set_status_fd ( int fd );
|
void set_status_fd ( int fd );
|
||||||
|
@ -352,7 +352,7 @@ list_trustdb( const char *username )
|
|||||||
PKT_public_key *pk = m_alloc_clear( sizeof *pk );
|
PKT_public_key *pk = m_alloc_clear( sizeof *pk );
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if( (rc = get_pubkey_byname( NULL, pk, username, NULL )) )
|
if( (rc = get_pubkey_byname( pk, username, NULL, NULL )) )
|
||||||
log_error(_("user '%s' not found: %s\n"), username, g10_errstr(rc) );
|
log_error(_("user '%s' not found: %s\n"), username, g10_errstr(rc) );
|
||||||
else if( (rc=tdbio_search_dir_bypk( pk, &rec )) && rc != -1 )
|
else if( (rc=tdbio_search_dir_bypk( pk, &rec )) && rc != -1 )
|
||||||
log_error(_("problem finding '%s' in trustdb: %s\n"),
|
log_error(_("problem finding '%s' in trustdb: %s\n"),
|
||||||
|
@ -1697,22 +1697,28 @@ void
|
|||||||
update_trustdb()
|
update_trustdb()
|
||||||
{
|
{
|
||||||
KBNODE keyblock = NULL;
|
KBNODE keyblock = NULL;
|
||||||
KBPOS kbpos;
|
KEYDB_HANDLE kdbhd;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if( opt.dry_run )
|
if( opt.dry_run )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
init_trustdb();
|
init_trustdb();
|
||||||
rc = enum_keyblocks( 0, &kbpos, &keyblock );
|
kdbhd = keydb_new (0);
|
||||||
if( !rc ) {
|
rc = keydb_search_first (kdbhd);
|
||||||
|
if (!rc) {
|
||||||
ulong count=0, err_count=0, new_count=0;
|
ulong count=0, err_count=0, new_count=0;
|
||||||
|
|
||||||
while( !(rc = enum_keyblocks( 1, &kbpos, &keyblock )) ) {
|
do {
|
||||||
/*int modified;*/
|
|
||||||
TRUSTREC drec;
|
TRUSTREC drec;
|
||||||
PKT_public_key *pk = find_kbnode( keyblock, PKT_PUBLIC_KEY )
|
PKT_public_key *pk;
|
||||||
->pkt->pkt.public_key;
|
/*int modified;*/
|
||||||
|
|
||||||
|
rc = keydb_get_keyblock (kdbhd, &keyblock );
|
||||||
|
if (rc)
|
||||||
|
break;
|
||||||
|
|
||||||
|
pk = find_kbnode (keyblock, PKT_PUBLIC_KEY)->pkt->pkt.public_key;
|
||||||
|
|
||||||
rc = get_dir_record( pk, &drec );
|
rc = get_dir_record( pk, &drec );
|
||||||
if( rc == -1 ) { /* not in trustdb: insert */
|
if( rc == -1 ) { /* not in trustdb: insert */
|
||||||
@ -1741,7 +1747,7 @@ update_trustdb()
|
|||||||
release_kbnode( keyblock ); keyblock = NULL;
|
release_kbnode( keyblock ); keyblock = NULL;
|
||||||
if( !(++count % 100) )
|
if( !(++count % 100) )
|
||||||
log_info(_("%lu keys so far processed\n"), count);
|
log_info(_("%lu keys so far processed\n"), count);
|
||||||
}
|
} while ( !(rc = keydb_search_next (kdbhd)));
|
||||||
log_info(_("%lu keys processed\n"), count);
|
log_info(_("%lu keys processed\n"), count);
|
||||||
if( err_count )
|
if( err_count )
|
||||||
log_info(_("\t%lu keys with errors\n"), err_count);
|
log_info(_("\t%lu keys with errors\n"), err_count);
|
||||||
@ -1751,7 +1757,7 @@ update_trustdb()
|
|||||||
if( rc && rc != -1 )
|
if( rc && rc != -1 )
|
||||||
log_error(_("enumerate keyblocks failed: %s\n"), g10_errstr(rc));
|
log_error(_("enumerate keyblocks failed: %s\n"), g10_errstr(rc));
|
||||||
|
|
||||||
enum_keyblocks( 2, &kbpos, &keyblock ); /* close */
|
keydb_release (kdbhd);
|
||||||
release_kbnode( keyblock );
|
release_kbnode( keyblock );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2514,7 +2520,7 @@ list_trust_path( const char *username )
|
|||||||
PKT_public_key *pk = m_alloc_clear( sizeof *pk );
|
PKT_public_key *pk = m_alloc_clear( sizeof *pk );
|
||||||
|
|
||||||
init_trustdb();
|
init_trustdb();
|
||||||
if( (rc = get_pubkey_byname(NULL, pk, username, NULL )) )
|
if( (rc = get_pubkey_byname (pk, username, NULL, NULL )) )
|
||||||
log_error(_("user '%s' not found: %s\n"), username, g10_errstr(rc) );
|
log_error(_("user '%s' not found: %s\n"), username, g10_errstr(rc) );
|
||||||
else if( (rc=tdbio_search_dir_bypk( pk, &rec )) && rc != -1 )
|
else if( (rc=tdbio_search_dir_bypk( pk, &rec )) && rc != -1 )
|
||||||
log_error(_("problem finding '%s' in trustdb: %s\n"),
|
log_error(_("problem finding '%s' in trustdb: %s\n"),
|
||||||
|
@ -120,7 +120,7 @@ if (gettext --version </dev/null 2>/dev/null | awk 'NR==1 { split($4,A,"\."); \
|
|||||||
X=10000*A[1]+100*A[2]+A[3]; echo X; if( X >= 1038 ) exit 1; exit 0}')
|
X=10000*A[1]+100*A[2]+A[3]; echo X; if( X >= 1038 ) exit 1; exit 0}')
|
||||||
then
|
then
|
||||||
echo "**Error**: You must have "\`gettext\'" installed to compile $PGM."
|
echo "**Error**: You must have "\`gettext\'" installed to compile $PGM."
|
||||||
echo ' (version 0.10.35 or newer is required; get'
|
echo ' (version 0.10.38 or newer is required; get'
|
||||||
echo ' ftp://alpha.gnu.org/gnu/gettext/gettext-0.10.38.tar.gz'
|
echo ' ftp://alpha.gnu.org/gnu/gettext/gettext-0.10.38.tar.gz'
|
||||||
echo ' or install the latest Debian package)'
|
echo ' or install the latest Debian package)'
|
||||||
DIE="yes"
|
DIE="yes"
|
||||||
|
@ -49,7 +49,6 @@ enum cmd_and_opt_values { aNull = 0,
|
|||||||
oPrefix = 'p',
|
oPrefix = 'p',
|
||||||
aTest };
|
aTest };
|
||||||
|
|
||||||
#warning Add an option to split a keyring into reasonable sized chunks.
|
|
||||||
|
|
||||||
static ARGPARSE_OPTS opts[] = {
|
static ARGPARSE_OPTS opts[] = {
|
||||||
|
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
2001-09-03 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
|
* miscutil.c (strtimestamp,asctimestamp): Avoid trigraphs.
|
||||||
|
|
||||||
2001-08-21 Stefan Bellon <sbellon@sbellon.de>
|
2001-08-21 Stefan Bellon <sbellon@sbellon.de>
|
||||||
|
|
||||||
* riscos.c [__riscos__] (close_fds): Fixed possible endless loop.
|
* riscos.c [__riscos__] (close_fds): Fixed possible endless loop.
|
||||||
|
@ -126,7 +126,7 @@ strtimestamp( u32 stamp )
|
|||||||
time_t atime = stamp;
|
time_t atime = stamp;
|
||||||
|
|
||||||
if (atime < 0) {
|
if (atime < 0) {
|
||||||
strcpy (buffer, "????-??-??");
|
strcpy (buffer, "????" "-??" "-??");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
tp = gmtime( &atime );
|
tp = gmtime( &atime );
|
||||||
@ -150,7 +150,7 @@ asctimestamp( u32 stamp )
|
|||||||
time_t atime = stamp;
|
time_t atime = stamp;
|
||||||
|
|
||||||
if (atime < 0) {
|
if (atime < 0) {
|
||||||
strcpy (buffer, "????-??-??");
|
strcpy (buffer, "????" "-??" "-??");
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user