See ChangeLog: Mon Mar 8 20:47:17 CET 1999 Werner Koch

This commit is contained in:
Werner Koch 1999-03-08 19:50:18 +00:00
parent 6d5eecb706
commit b31145f3e2
39 changed files with 2458 additions and 2355 deletions

37
BUGS
View File

@ -18,12 +18,6 @@ and after about half a day in the rsync snapshots.
and pgp263in has problems if the clearsign has been created by
pgp263ia.
[***] #2 1999-02-21
Problem while importing or deleting public keys in 0.9.3 - 0.9.2
worked fine. Error message:
gpg:[stdin]: key A6A59DB9: secret key not found: public key not found
FIX: 1999-02-22 wk
[ *] #3
--list-packets should continue even w/o a passphrase (or in batch
mode). Maybe we have to move it to a separate program??
@ -50,35 +44,6 @@ and after about half a day in the rsync snapshots.
Buserror on IRIX 6.4: Crash while doing a keygen. I think while creating
the prime. Other buserrors are reported when doing a "gpg README"
on sparc-solaris2.6.
--> I hope I've fixed this: Please, can check someone it.
--> I hope I've fixed this: Please, can someone check this.
I can't reproduce it on the alpha I have access to.
[ *] #7 1999-02-22 <dwpalmer@dwpalm.jf.intel.com> 0.9.3
Conventional encrytion incompatibilty:
$ gpg -c --cipher-algo cast5 --compress-algo 1 --no-comment secrets.txt
Creates a file that gpg can decrypt, but PGP 5.5 has problems with it.
PGP decrypts 6416k out of 6424k, then complains with "PGP Warning",
"The keyring contains a bad (corrupted) PGP packet". The resulting
file is missing information from the front.
[26.02.99: temporary fix in encrypt_simple()]
[ *] #8 1999-02-25 <kazu@iijlab.net> 0.9.3
%gpg --encrypt -r kazu@iijlab.net --batch foo
gpg: Warning: using insecure memory!
gpg: 11C23F61: no info to calculate a trust probability
This creates a symmetrically encrypted message WITHOUT a session key
encrypted with public cryptographic(i.e. foo.gpg). This is probably
FIX: 199-02-26 wk
[ **] #9 1999-02-25
Misalignment in md5.c#md5_write.
FIX: 1999-02-26 wk
[ **] #10 1999-03-01
Armor detection code is broken. Direct import of keyrings is not possible.
FIX: 1999-03-02 wk
[***] #11 1999-02-25
"cipher algo 10 not found".
FIX: 1999-02-25 wk

View File

@ -1,3 +1,10 @@
Mon Mar 8 20:47:17 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* configure.in (DLSYM_NEEDS_UNDERSCORE): Replaced.
* acinclude.in (AM_SYS_SYMBOL_UNDERSCORE): New.
* VERSION: Now 0.9.4
Sun Feb 28 19:11:00 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* configure.in (dld): Test disabled.

4
NEWS
View File

@ -1,9 +1,13 @@
Noteworthy changes in version 0.9.4
-----------------------------------
* New configure option --enable-static-rnd=[egd|linux|unix|none]
to select a random gathering module for static linking.
* The original text is now verbatim copied to a cleartext signed message.
* Bugfixes but there are still a couple of bugs.
Noteworthy changes in version 0.9.3
-----------------------------------

36
OBUGS
View File

@ -4,4 +4,40 @@
(format: severity: [ *] to [***], no, first reported, by, version)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[***] #2 1999-02-21
Problem while importing or deleting public keys in 0.9.3 - 0.9.2
worked fine. Error message:
gpg:[stdin]: key A6A59DB9: secret key not found: public key not found
FIX: 1999-02-22 wk
[ *] #7 1999-02-22 <dwpalmer@dwpalm.jf.intel.com> 0.9.3
Conventional encrytion incompatibilty:
$ gpg -c --cipher-algo cast5 --compress-algo 1 --no-comment secrets.txt
Creates a file that gpg can decrypt, but PGP 5.5 has problems with it.
PGP decrypts 6416k out of 6424k, then complains with "PGP Warning",
"The keyring contains a bad (corrupted) PGP packet". The resulting
file is missing information from the front.
FIX: 1999-02-26 temporary fix in encrypt_simple()
[ *] #8 1999-02-25 <kazu@iijlab.net> 0.9.3
%gpg --encrypt -r kazu@iijlab.net --batch foo
gpg: Warning: using insecure memory!
gpg: 11C23F61: no info to calculate a trust probability
This creates a symmetrically encrypted message WITHOUT a session key
encrypted with public cryptographic(i.e. foo.gpg). This is probably
FIX: 199-02-26 wk
[ **] #9 1999-02-25
Misalignment in md5.c#md5_write.
FIX: 1999-02-26 wk
[ **] #10 1999-03-01
Armor detection code is broken. Direct import of keyrings is not possible.
FIX: 1999-03-02 wk
[***] #11 1999-02-25
"cipher algo 10 not found".
FIX: 1999-02-25 wk

3
README
View File

@ -1,3 +1,6 @@
Please note that this is only a bug fix release and some things
do not yet work - see TODO for parts which are problematic
-----BEGIN PGP SIGNED MESSAGE-----
GnuPG - The GNU Privacy Guard

3
TODO
View File

@ -1,4 +1,6 @@
* Finish the EGD module.
* Implement 256 bit key Twofish.
* Check revocation and expire stuff. [I'm currently working on this.]
@ -20,6 +22,7 @@
Nice to have
------------
* Do a real fix for bug #7 or document that it is a PGP 5 error.
* clearsig: Keep lineendings while writing the output of a clearsig
* preferences of hash algorithms are not yet used.
* new menu to delete signatures and list signature in menu

View File

@ -1 +1 @@
0.9.3a
0.9.4

View File

@ -74,7 +74,6 @@
#undef USE_DYNAMIC_LINKING
#undef HAVE_DL_DLOPEN
#undef HAVE_DLD_DLD_LINK
#undef DLSYM_NEEDS_UNDERSCORE
#undef USE_SHM_COPROCESSING

View File

@ -342,5 +342,222 @@ define(GNUPG_CHECK_MLOCK,
fi
])
#####################################################################
# AM_SYS_SYMBOL_UNDERSCORE, AM_SYS_NM_PARSE:
# This has been taken from glib 1.2.0 acinclude.m4 which states that
# it is copyrighted by the FSF
################################################################### ##
dnl AM_SYS_SYMBOL_UNDERSCORE - does the compiler prefix global symbols
dnl with an underscore?
AC_DEFUN(AM_SYS_SYMBOL_UNDERSCORE,
[AC_REQUIRE([AM_PROG_NM])dnl
AC_REQUIRE([AM_SYS_NM_PARSE])dnl
AC_MSG_CHECKING([for _ prefix in compiled symbols])
AC_CACHE_VAL(ac_cv_sys_symbol_underscore,
[ac_cv_sys_symbol_underscore=no
cat > conftest.$ac_ext <<EOF
void nm_test_func(){}
int main(){nm_test_func;return 0;}
EOF
if AC_TRY_EVAL(ac_compile); then
# Now try to grab the symbols.
ac_nlist=conftest.nm
if AC_TRY_EVAL(NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist) && test -s "$ac_nlist"; then
# See whether the symbols have a leading underscore.
if egrep '^_nm_test_func' "$ac_nlist" >/dev/null; then
ac_cv_sys_symbol_underscore=yes
else
if egrep '^nm_test_func ' "$ac_nlist" >/dev/null; then
:
else
echo "configure: cannot find nm_test_func in $ac_nlist" >&AC_FD_CC
fi
fi
else
echo "configure: cannot run $ac_cv_sys_global_symbol_pipe" >&AC_FD_CC
fi
else
echo "configure: failed program was:" >&AC_FD_CC
cat conftest.c >&AC_FD_CC
fi
rm -rf conftest*
])
AC_MSG_RESULT($ac_cv_sys_symbol_underscore)
if test x$ac_cv_sys_symbol_underscore = xyes; then
AC_DEFINE(WITH_SYMBOL_UNDERSCORE,1,
[define if compiled symbols have a leading underscore])
fi
])
dnl AM_SYS_NM_PARSE - Check for command to grab the raw symbol name followed
dnl by C symbol name from nm.
AC_DEFUN(AM_SYS_NM_PARSE,
[AC_REQUIRE([AC_CANONICAL_HOST])dnl
AC_REQUIRE([AM_PROG_NM])dnl
# Check for command to grab the raw symbol name followed by C symbol from nm.
AC_MSG_CHECKING([command to parse $NM output])
AC_CACHE_VAL(ac_cv_sys_global_symbol_pipe,
[# These are sane defaults that work on at least a few old systems.
# {They come from Ultrix. What could be older than Ultrix?!! ;)}
changequote(,)dnl
# Character class describing NM global symbol codes.
ac_symcode='[BCDEGRSTU]'
# Regexp to match symbols that can be accessed directly from C.
ac_sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
# Transform the above into a raw symbol and a C symbol.
ac_symxfrm='\1 \1'
# Define system-specific variables.
case "$host_os" in
aix*)
ac_symcode='[BCDTU]'
;;
sunos* | cygwin32* | mingw32*)
ac_sympat='_\([_A-Za-z][_A-Za-z0-9]*\)'
ac_symxfrm='_\1 \1'
;;
irix*)
# Cannot use undefined symbols on IRIX because inlined functions mess us up.
ac_symcode='[BCDEGRST]'
;;
solaris*)
ac_symcode='[BDTU]'
;;
esac
# If we're using GNU nm, then use its standard symbol codes.
if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then
ac_symcode='[ABCDGISTUW]'
fi
case "$host_os" in
cygwin32* | mingw32*)
# We do not want undefined symbols on cygwin32. The user must
# arrange to define them via -l arguments.
ac_symcode='[ABCDGISTW]'
;;
esac
changequote([,])dnl
# Write the raw and C identifiers.
ac_cv_sys_global_symbol_pipe="sed -n -e 's/^.* $ac_symcode $ac_sympat$/$ac_symxfrm/p'"
# Check to see that the pipe works correctly.
ac_pipe_works=no
cat > conftest.$ac_ext <<EOF
#ifdef __cplusplus
extern "C" {
#endif
char nm_test_var;
void nm_test_func(){}
#ifdef __cplusplus
}
#endif
int main(){nm_test_var='a';nm_test_func;return 0;}
EOF
if AC_TRY_EVAL(ac_compile); then
# Now try to grab the symbols.
ac_nlist=conftest.nm
if AC_TRY_EVAL(NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist) && test -s "$ac_nlist"; then
# Try sorting and uniquifying the output.
if sort "$ac_nlist" | uniq > "$ac_nlist"T; then
mv -f "$ac_nlist"T "$ac_nlist"
ac_wcout=`wc "$ac_nlist" 2>/dev/null`
changequote(,)dnl
ac_count=`echo "X$ac_wcout" | sed -e 's,^X,,' -e 's/^[ ]*\([0-9][0-9]*\).*$/\1/'`
changequote([,])dnl
(test "$ac_count" -ge 0) 2>/dev/null || ac_count=-1
else
rm -f "$ac_nlist"T
ac_count=-1
fi
# Make sure that we snagged all the symbols we need.
if egrep ' nm_test_var$' "$ac_nlist" >/dev/null; then
if egrep ' nm_test_func$' "$ac_nlist" >/dev/null; then
cat <<EOF > conftest.c
#ifdef __cplusplus
extern "C" {
#endif
EOF
# Now generate the symbol file.
sed 's/^.* \(.*\)$/extern char \1;/' < "$ac_nlist" >> conftest.c
cat <<EOF >> conftest.c
#if defined (__STDC__) && __STDC__
# define __ptr_t void *
#else
# define __ptr_t char *
#endif
/* The number of symbols in dld_preloaded_symbols, -1 if unsorted. */
int dld_preloaded_symbol_count = $ac_count;
/* The mapping between symbol names and symbols. */
struct {
char *name;
__ptr_t address;
}
changequote(,)dnl
dld_preloaded_symbols[] =
changequote([,])dnl
{
EOF
sed 's/^\(.*\) \(.*\)$/ {"\1", (__ptr_t) \&\2},/' < "$ac_nlist" >> conftest.c
cat <<\EOF >> conftest.c
{0, (__ptr_t) 0}
};
#ifdef __cplusplus
}
#endif
EOF
# Now try linking the two files.
mv conftest.$ac_objext conftestm.$ac_objext
ac_save_LIBS="$LIBS"
ac_save_CFLAGS="$CFLAGS"
LIBS="conftestm.$ac_objext"
CFLAGS="$CFLAGS$no_builtin_flag"
if AC_TRY_EVAL(ac_link) && test -s conftest; then
ac_pipe_works=yes
else
echo "configure: failed program was:" >&AC_FD_CC
cat conftest.c >&AC_FD_CC
fi
LIBS="$ac_save_LIBS"
CFLAGS="$ac_save_CFLAGS"
else
echo "cannot find nm_test_func in $ac_nlist" >&AC_FD_CC
fi
else
echo "cannot find nm_test_var in $ac_nlist" >&AC_FD_CC
fi
else
echo "cannot run $ac_cv_sys_global_symbol_pipe" >&AC_FD_CC
fi
else
echo "$progname: failed program was:" >&AC_FD_CC
cat conftest.c >&AC_FD_CC
fi
rm -rf conftest*
# Do not use the global_symbol_pipe unless it works.
test "$ac_pipe_works" = yes || ac_cv_sys_global_symbol_pipe=
])
ac_result=yes
if test -z "$ac_cv_sys_global_symbol_pipe"; then
ac_result=no
fi
AC_MSG_RESULT($ac_result)
])
dnl end of AM_SYS_NM_PARSE
dnl *-*wedit:notab*-* Please keep this as the last line.

View File

@ -1,3 +1,7 @@
Mon Mar 8 20:47:17 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* pubdemo.asc, secdemo.asc: New.
Fri Feb 19 15:49:15 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* genkey1024.test: Be really quiet.

View File

@ -14,7 +14,7 @@ TESTS = version.test mds.test \
TEST_FILES = pubring.asc secring.asc plain-1o.asc plain-2o.asc plain-3o.asc \
plain-1.asc plain-2.asc plain-3.asc plain-1-pgp.asc \
pubring.pkr.asc secring.skr.asc
pubring.pkr.asc secring.skr.asc secdemo.asc pubdemo.asc
DATA_FILES = data-500 data-9000 data-32000 data-80000 plain-large

View File

@ -78,7 +78,6 @@ cat <<EOF >./options
no-greeting
no-secmem-warning
load-extension ../cipher/tiger
load-extension ../cipher/rndlinux
batch
EOF

View File

@ -1,4 +1,4 @@
26 demo keys:
26 demo keys (passphrase is "abc"):
sec 1024D/68697734 1999-03-08 Alpha Test (demo key) <alpha@example.net>
uid Alice (demo key)

View File

@ -1,3 +1,7 @@
Mon Mar 8 20:47:17 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* dynload.c (DLSYM_NEEDS_UNDERSCORE): Renamed.
Fri Feb 26 17:55:41 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* md.c: Nearly a total rewrote.

View File

@ -32,7 +32,7 @@
#include "cipher.h"
#include "dynload.h"
#ifdef DLSYM_NEEDS_UNDERSCORE
#ifdef WITH_SYMBOL_UNDERSCORE
#define SYMBOL_VERSION "_gnupgext_version"
#define SYMBOL_ENUM "_gnupgext_enum_func"
#else

View File

@ -171,7 +171,7 @@ case "${target}" in
esac
AC_SUBST(MPI_OPT_FLAGS)
AM_SYS_SYMBOL_UNDERSCORE
GNUPG_CHECK_PIC
GNUPG_CHECK_RDYNAMIC
if test "$NO_PIC" = yes; then
@ -241,9 +241,6 @@ if test "$try_dynload" = yes ; then
AC_DEFINE(USE_DYNAMIC_LINKING)
AC_DEFINE(HAVE_DL_DLOPEN)
DYNLINK_LDFLAGS="$CFLAGS_RDYNAMIC"
dnl fixme: this is probably false but it should
dnl work for freebsd
AC_DEFINE(DLSYM_NEEDS_UNDERSCORE)
use_gnupg_extensions=yes
dnl else
dnl
@ -429,12 +426,10 @@ echo '}' >>cipher/construct.c
dnl
dnl Figure how to link the cipher modules
dnl
dnl (form now these are only dynamic)
AC_SUBST(STATIC_CIPHER_OBJS)
AC_SUBST(DYNAMIC_CIPHER_MODS)
dnl setup assembler stuff
AC_MSG_CHECKING(for mpi assembler functions)
if test -f $srcdir/mpi/config.links ; then

7
debian/changelog vendored
View File

@ -1,3 +1,10 @@
gnupg (0.9.4) unstable; urgency=low
* New version.
* debian/control: s/GNUPG/GnuPG/
-- Werner Koch <wk@isil.d.suttle.de> Mon, 8 Mar 1999 19:58:28 +0100
gnupg (0.9.2-1) unstable; urgency=low
* New version.

12
debian/control vendored
View File

@ -8,16 +8,16 @@ Package: gnupg
Architecture: any
Depends: ${shlibs:Depends}
Description: GNU privacy guard - a free PGP replacement.
GNUPG is the GNU encryption and signing tool. As you can see from the
version number, the program may have some bugs and some features may not
GnuPG is the GNU encryption and signing tool. As you can see from the
version number, the program may have some bugs and some features may not
work at all.
.
Due to the fact that GNUPG does not use use any patented algorithm,
Due to the fact that GnuPG does not use use any patented algorithm,
it cannot be compatible to old PGP versions, because those use
IDEA (which is worldwide patented) and RSA (which is patented in
the United States until Sep 20, 2000).
the United States until Sep 20, 2000).
.
GNUPG is in almost all aspects compatible with other OpenPGP
implementations. The default algorithms are DSA and ELGamal.
GnuPG is in almost all aspects compatible with other OpenPGP
implementations. The default algorithms are DSA and ELGamal.
Symmetric algorithms are: Blowfish and CAST5, Digest algorithms are
MD5, RIPEMD160, SHA1 and TIGER/192.

2
debian/rules vendored
View File

@ -1,5 +1,5 @@
#!/usr/bin/make -f
# debian/rules file - for GNUPG (0.9.2)
# debian/rules file - for GNUPG (0.9.4)
# Based on sample debian/rules file - for GNU Hello (1.3).
# Copyright 1994,1995 by Ian Jackson.
# Copyright 1998 James Troup

View File

@ -64,12 +64,12 @@ more arguments in future versions.
as GOODSIG but has the fingerprint as the argument. Both
status lines ere emitted for a good signature.
SIG_ID <radix64_string>
SIG_ID <radix64_string> <sig_creation_date>
This is emitted only for signatures which
have been verified okay. The string is a signature id
and may be used in applications to detect replay attacks
of signed messages. Note that only DLP algorithms give
unique ids - others may yoild duplicated ones when they
unique ids - others may yield duplicated ones when they
have been created in the same second.
TRUST_UNDEFINED

View File

@ -1,3 +1,17 @@
Mon Mar 8 20:47:17 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* getkey.c (classify_user_id): Add new mode 12 (#<lid>).
* seckey-cert.c (check_secret_key): replaced error by info.
* trustdb.c (query_trust_info): Add another arg, changed all callers.
(check_trust): Ditto.
(do_check): Ditto.
(verify_key): Handle namehash.
* keylist.c (list_keyblock): print trust info for user ids.
* sig-check.c (signature_check): Add sig-created to status output.
Tue Mar 2 16:44:57 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* textfilter.c (copy_clearsig_text): New.

View File

@ -506,6 +506,7 @@ hextobyte( const byte *s )
* 6 = word match mode
* 10 = it is a short KEYID (don't care about keyid[0])
* 11 = it is a long KEYID
* 12 = it is a trustdb index (keyid is looked up)
* 16 = it is a 16 byte fingerprint
* 20 = it is a 20 byte fingerprint
*
@ -624,7 +625,12 @@ classify_user_id( const char *name, u32 *keyid, byte *fprint,
s++;
}
else if( *s == '#' ) { /* use local id */
return 0;
mode = 12;
s++;
if( keyid ) {
if( keyid_from_lid( strtoul( s, NULL, 10), keyid ) )
keyid[0] = keyid[1] = 0;
}
}
else if( !*s ) /* empty string */
return 0;
@ -1561,54 +1567,6 @@ finish_lookup_sk( KBNODE keyblock, PKT_secret_key *sk, KBNODE k, int primary )
}
/****** old code from lookup_read ******/
#if 0 /* can't use it anymore - invent a more general approach */
/* try the quick functions */
if( !ctx->count ) {
k = NULL;
switch( ctx->mode ) {
case 10:
case 11:
rc = locate_keyblock_by_keyid( &ctx->kbpos, ctx->keyid,
ctx->mode==10, 0 );
if( !rc )
rc = read_keyblock( &ctx->kbpos, &ctx->keyblock );
if( !rc )
k = find_by_keyid( ctx->keyblock, pk, ctx->keyid, ctx->mode );
break;
case 16:
case 20:
rc = locate_keyblock_by_fpr( &ctx->kbpos, ctx->name, ctx->mode, 0 );
if( !rc )
rc = read_keyblock( &ctx->kbpos, &ctx->keyblock );
if( !rc )
k = find_by_fpr( ctx->keyblock, pk, ctx->name, ctx->mode );
break;
default: rc = G10ERR_UNSUPPORTED;
}
if( !rc ) {
if( !k ) {
log_error("lookup: key has been located but was not found\n");
rc = G10ERR_INV_KEYRING;
}
else
finish_lookup( ctx->keyblock, pk, k, namehash, 0, ctx->primary );
}
}
else
rc = G10ERR_UNSUPPORTED;
/* if this was not possible, loop over all keyblocks
* fixme: If one of the resources in the quick functions above
* works, but the key was not found, we will not find it
* in the other resources */
if( rc == G10ERR_UNSUPPORTED ) {
}
#endif
static int
lookup_pk( GETKEY_CTX ctx, PKT_public_key *pk, KBNODE *ret_keyblock )
{
@ -1636,7 +1594,7 @@ lookup_pk( GETKEY_CTX ctx, PKT_public_key *pk, KBNODE *ret_keyblock )
k = find_by_name( ctx->keyblock, pk,
item->name, item->mode,
namehash, &use_namehash );
else if( item->mode == 10 || item->mode == 11 )
else if( item->mode >= 10 && item->mode <= 12 )
k = find_by_keyid( ctx->keyblock, pk,
item->keyid, item->mode );
else if( item->mode == 15 )
@ -1723,7 +1681,7 @@ lookup_sk( GETKEY_CTX ctx, PKT_secret_key *sk, KBNODE *ret_keyblock )
if( item->mode < 10 )
k = find_by_name_sk( ctx->keyblock, sk,
item->name, item->mode );
else if( item->mode == 10 || item->mode == 11 )
else if( item->mode >= 10 && item->mode <= 12 )
k = find_by_keyid_sk( ctx->keyblock, sk,
item->keyid, item->mode );
else if( item->mode == 15 )
@ -1765,143 +1723,6 @@ lookup_sk( GETKEY_CTX ctx, PKT_secret_key *sk, KBNODE *ret_keyblock )
}
#if 0
OLD/************
OLD * Ditto for secret keys WORK!!!!!!
OLD */
OLDstatic int
OLDlookup_sk( PKT_secret_key *sk, int mode, u32 *keyid, const char *name,
OLD int primary )
OLD{
OLD int rc;
OLD KBNODE keyblock = NULL;
OLD KBPOS kbpos;
OLD int oldmode = set_packet_list_mode(0);
OLD
OLD rc = enum_keyblocks( 5 /* open secret */, &kbpos, &keyblock );
OLD if( rc ) {
OLD if( rc == -1 )
OLD rc = G10ERR_NO_SECKEY;
OLD else if( rc )
OLD log_error("enum_keyblocks(open secret) failed: %s\n", g10_errstr(rc) );
OLD goto leave;
OLD }
OLD
OLD while( !(rc = enum_keyblocks( 1, &kbpos, &keyblock )) ) {
OLD KBNODE k, kk;
OLD if( mode < 10 ) { /* name lookup */
OLD for(k=keyblock; k; k = k->next ) {
OLD if( k->pkt->pkttype == PKT_USER_ID
OLD && !compare_name( k->pkt->pkt.user_id->name,
OLD k->pkt->pkt.user_id->len, name, mode)) {
OLD /* we found a matching name, look for the key */
OLD for(kk=keyblock; kk; kk = kk->next ) {
OLD if( ( kk->pkt->pkttype == PKT_SECRET_KEY
OLD || kk->pkt->pkttype == PKT_SECRET_SUBKEY )
OLD && ( !sk->pubkey_algo
OLD || sk->pubkey_algo
OLD == kk->pkt->pkt.secret_key->pubkey_algo)
OLD && ( !sk->pubkey_usage
OLD || !check_pubkey_algo2(
OLD kk->pkt->pkt.secret_key->pubkey_algo,
OLD sk->pubkey_usage ))
OLD )
OLD break;
OLD }
OLD if( kk ) {
OLD u32 aki[2];
OLD keyid_from_sk( kk->pkt->pkt.secret_key, aki );
OLD cache_user_id( k->pkt->pkt.user_id, aki );
OLD k = kk;
OLD break;
OLD }
OLD else
OLD log_error("No key for userid (in sk)\n");
OLD }
OLD }
OLD }
OLD else { /* keyid or fingerprint lookup */
OLD if( DBG_CACHE && (mode== 10 || mode==11) ) {
OLD log_debug("lookup_sk keyid=%08lx%08lx req_algo=%d mode=%d\n",
OLD (ulong)keyid[0], (ulong)keyid[1],
OLD sk->pubkey_algo, mode );
OLD }
OLD for(k=keyblock; k; k = k->next ) {
OLD if( k->pkt->pkttype == PKT_SECRET_KEY
OLD || k->pkt->pkttype == PKT_SECRET_SUBKEY ) {
OLD if( mode == 10 || mode == 11 ) {
OLD u32 aki[2];
OLD keyid_from_sk( k->pkt->pkt.secret_key, aki );
OLD if( DBG_CACHE ) {
OLD log_debug(" aki=%08lx%08lx algo=%d\n",
OLD (ulong)aki[0], (ulong)aki[1],
OLD k->pkt->pkt.secret_key->pubkey_algo );
OLD }
OLD if( aki[1] == keyid[1]
OLD && ( mode == 10 || aki[0] == keyid[0] )
OLD && ( !sk->pubkey_algo
OLD || sk->pubkey_algo
OLD == k->pkt->pkt.secret_key->pubkey_algo) ){
OLD /* cache the userid */
OLD for(kk=keyblock; kk; kk = kk->next )
OLD if( kk->pkt->pkttype == PKT_USER_ID )
OLD break;
OLD if( kk )
OLD cache_user_id( kk->pkt->pkt.user_id, aki );
OLD else
OLD log_error("No userid for key\n");
OLD break; /* found */
OLD }
OLD }
OLD else if( mode == 15 ) { /* get the first key */
OLD if( !sk->pubkey_algo
OLD || sk->pubkey_algo
OLD == k->pkt->pkt.secret_key->pubkey_algo )
OLD break;
OLD }
OLD else if( mode == 16 || mode == 20 ) {
OLD size_t an;
OLD byte afp[MAX_FINGERPRINT_LEN];
OLD
OLD fingerprint_from_sk(k->pkt->pkt.secret_key, afp, &an );
OLD if( an == mode && !memcmp( afp, name, an)
OLD && ( !sk->pubkey_algo
OLD || sk->pubkey_algo
OLD == k->pkt->pkt.secret_key->pubkey_algo) ) {
OLD break;
OLD }
OLD }
OLD else
OLD BUG();
OLD } /* end compare secret keys */
OLD }
OLD }
OLD if( k ) { /* found */
OLD assert( k->pkt->pkttype == PKT_SECRET_KEY
OLD || k->pkt->pkttype == PKT_SECRET_SUBKEY );
OLD assert( keyblock->pkt->pkttype == PKT_SECRET_KEY );
OLD if( primary && !sk->pubkey_usage )
OLD copy_secret_key( sk, keyblock->pkt->pkt.secret_key );
OLD else
OLD copy_secret_key( sk, k->pkt->pkt.secret_key );
OLD break; /* enumeration */
OLD }
OLD release_kbnode( keyblock );
OLD keyblock = NULL;
OLD }
OLD if( rc == -1 )
OLD rc = G10ERR_NO_SECKEY;
OLD else if( rc )
OLD log_error("enum_keyblocks(read) failed: %s\n", g10_errstr(rc));
OLD
OLD leave:
OLD enum_keyblocks( 2, &kbpos, &keyblock ); /* close */
OLD release_kbnode( keyblock );
OLD set_packet_list_mode(oldmode);
OLD return rc;
OLD}
#endif
/****************
* fixme: replace by the generic function

View File

@ -889,7 +889,7 @@ show_key_with_all_names( KBNODE keyblock, int only_marked,
if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
/* do it here, so that debug messages don't clutter the
* output */
trust = query_trust_info(pk);
trust = query_trust_info(pk, NULL);
otrust = get_ownertrust_info( pk->local_id );
}

View File

@ -196,7 +196,7 @@ list_keyblock( KBNODE keyblock, int secret )
sk = NULL;
keyid_from_pk( pk, keyid );
if( opt.with_colons ) {
trustletter = query_trust_info( pk );
trustletter = query_trust_info( pk, NULL );
printf("pub:%c:%u:%d:%08lX%08lX:%s:%s:",
trustletter,
nbits_from_pk( pk ),
@ -222,8 +222,15 @@ list_keyblock( KBNODE keyblock, int secret )
for( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx, 0)) ; ) {
if( node->pkt->pkttype == PKT_USER_ID ) {
if( any ) {
if( opt.with_colons )
printf("uid:::::::::");
if( opt.with_colons ) {
byte namehash[20];
rmd160_hash_buffer( namehash,
node->pkt->pkt.user_id->name,
node->pkt->pkt.user_id->len );
trustletter = query_trust_info( pk, namehash );
printf("uid:%c::::::::", trustletter);
}
else
printf("uid%*s", 28, "");
}

View File

@ -481,7 +481,7 @@ list_node( CTX c, KBNODE node )
keyid_from_pk( pk, keyid );
if( mainkey ) {
c->local_id = pk->local_id;
c->trustletter = query_trust_info( pk );
c->trustletter = query_trust_info( pk, NULL );
}
printf("%s:%c:%u:%d:%08lX%08lX:%s:%s:",
mainkey? "pub":"sub",

View File

@ -50,7 +50,7 @@ show_paths( ulong lid, int only_first )
last_level = 0;
while( (level=enum_cert_paths( &context, &lid, &otrust, &validity)) != -1){
char *p;
int rc;
int c, rc;
size_t n;
u32 keyid[2];
PKT_public_key *pk ;
@ -77,7 +77,7 @@ show_paths( ulong lid, int only_first )
level*2, "",
nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ),
(ulong)keyid[1], lid, datestr_from_pk( pk ) );
#if 0
c = trust_letter(otrust);
if( c )
putchar( c );
@ -90,8 +90,6 @@ show_paths( ulong lid, int only_first )
else
printf( "%02x", validity );
putchar(' ');
#endif
p = get_user_id( keyid, &n );
tty_print_string( p, n ),
@ -230,7 +228,6 @@ _("Could not find a valid trust path to the key. Let's see whether we\n"
}
lid = pk->local_id;
#if 0 /* FIXME: enable this when trustdb stuff works again */
while( enum_cert_paths( &context, &lid, &otrust, &validity ) != -1 ) {
if( lid == pk->local_id )
continue;
@ -242,6 +239,7 @@ _("Could not find a valid trust path to the key. Let's see whether we\n"
* those values from then on
*/
otrust = get_ownertrust( lid );
/* fixme: and the validity? */
}
if( otrust == TRUST_UNDEFINED ) {
any_undefined=1;
@ -257,7 +255,6 @@ _("Could not find a valid trust path to the key. Let's see whether we\n"
}
}
enum_cert_paths( &context, NULL, NULL, NULL ); /* release context */
#endif
if( !any )
tty_printf(_("No path leading to one of our keys found.\n\n") );
@ -298,12 +295,14 @@ do_we_trust( PKT_public_key *pk, int trustlevel )
g10_errstr(rc) );
return 0; /* no */
}
rc = check_trust( pk, &trustlevel );
rc = check_trust( pk, &trustlevel, NULL );
if( rc )
log_fatal("trust check after insert failed: %s\n",
g10_errstr(rc) );
if( trustlevel == TRUST_UNKNOWN || trustlevel == TRUST_EXPIRED )
BUG();
if( trustlevel == TRUST_UNKNOWN || trustlevel == TRUST_EXPIRED ) {
log_debug("do_we_trust: oops at %d\n", __LINE__ );
return 0;
}
return do_we_trust( pk, trustlevel );
case TRUST_EXPIRED:
@ -320,7 +319,7 @@ do_we_trust( PKT_public_key *pk, int trustlevel )
rc = add_ownertrust( pk, &quit );
if( !rc && !quit ) {
rc = check_trust( pk, &trustlevel );
rc = check_trust( pk, &trustlevel, NULL );
if( rc )
log_fatal("trust check after add_ownertrust failed: %s\n",
g10_errstr(rc) );
@ -431,7 +430,7 @@ check_signatures_trust( PKT_signature *sig )
}
retry:
rc = check_trust( pk, &trustlevel );
rc = check_trust( pk, &trustlevel, NULL );
if( rc ) {
log_error("check trust failed: %s\n", g10_errstr(rc));
goto leave;
@ -452,7 +451,7 @@ check_signatures_trust( PKT_signature *sig )
g10_errstr(rc) );
goto leave;
}
rc = check_trust( pk, &trustlevel );
rc = check_trust( pk, &trustlevel, NULL );
if( rc )
log_fatal("trust check after insert failed: %s\n",
g10_errstr(rc) );
@ -592,7 +591,7 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use )
else if( !(rc=check_pubkey_algo2(pk->pubkey_algo, use)) ) {
int trustlevel;
rc = check_trust( pk, &trustlevel );
rc = check_trust( pk, &trustlevel, NULL );
if( rc ) {
log_error("error checking pk of `%s': %s\n",
answer, g10_errstr(rc) );
@ -631,7 +630,7 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use )
else if( !(rc=check_pubkey_algo2(pk->pubkey_algo, use )) ) {
int trustlevel;
rc = check_trust( pk, &trustlevel );
rc = check_trust( pk, &trustlevel, NULL );
if( rc ) {
free_public_key( pk ); pk = NULL;
log_error(_("%s: error checking key: %s\n"),
@ -712,7 +711,7 @@ select_algo_from_prefs( PK_LIST pk_list, int preftype )
memset( mask, 0, 8 * sizeof *mask );
if( !pkr->pk->local_id ) { /* try to set the local id */
query_trust_info( pkr->pk );
query_trust_info( pkr->pk, NULL );
if( !pkr->pk->local_id ) {
log_debug("select_algo_from_prefs: can't get LID\n");
continue;

View File

@ -173,7 +173,7 @@ check_secret_key( PKT_secret_key *sk, int n )
for(i=0; i < n && rc == G10ERR_BAD_PASS; i++ ) {
if( i )
log_error(_("Invalid passphrase; please try again ...\n"));
log_info(_("Invalid passphrase; please try again ...\n"));
rc = do_check( sk );
if( have_static_passphrase() )
break;

View File

@ -76,7 +76,7 @@ signature_check( PKT_signature *sig, MD_HANDLE digest )
MD_HANDLE md;
u32 a = sig->timestamp;
int i, nsig = pubkey_get_nsig( sig->pubkey_algo );
byte *p;
byte *p, *buffer;
md = md_open( DIGEST_ALGO_RMD160, 0);
md_putc( digest, sig->pubkey_algo );
@ -96,7 +96,10 @@ signature_check( PKT_signature *sig, MD_HANDLE digest )
}
md_final( md );
p = make_radix64_string( md_read( md, 0 ), 20 );
write_status_text( STATUS_SIG_ID, p );
buffer = m_alloc( strlen(p) + 40 );
sprintf( buffer, "%s %s", p, strtimestamp( sig->timestamp ) );
write_status_text( STATUS_SIG_ID, buffer );
m_free(buffer);
m_free(p);
md_close(md);
}

View File

@ -1,5 +1,5 @@
/* trustdb.c
* Copyright (C) 1998 Free Software Foundation, Inc.
* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -66,25 +66,8 @@ struct local_id_table {
typedef struct local_id_table *LOCAL_ID_TABLE;
typedef struct trust_info TRUST_INFO;
struct trust_info {
ulong lid;
byte otrust; /* ownertrust (assigned trust) */
byte trust; /* calculated trust (validity) */
};
typedef struct trust_seg_list *TRUST_SEG_LIST;
struct trust_seg_list {
TRUST_SEG_LIST next;
int pathlen;
TRUST_INFO path[1];
};
struct enum_cert_paths_ctx {
int init;
TRUST_SEG_LIST tsl_head;
TRUST_SEG_LIST tsl;
int idx;
};
@ -97,6 +80,35 @@ struct recno_list_struct {
typedef struct recno_list_struct *RECNO_LIST;
typedef struct trust_node *TN;
struct trust_node {
TN back; /* parent */
TN list; /* list of other node (should all be of the same type)*/
TN next; /* used to build the list */
int is_uid; /* set if this is an uid node */
ulong lid; /* key or uid recordnumber */
union {
struct {
int ownertrust;
int validity;
/* helper */
int buckstop;
} k;
struct {
int marginal_count;
int fully_count;
int validity;
} u;
} n;
};
static TN used_tns;
static int alloced_tns;
static int max_alloced_tns;
static int walk_sigrecs( SIGREC_CONTEXT *c );
static LOCAL_ID_TABLE new_lid_table(void);
@ -105,11 +117,11 @@ static int ins_lid_table_item( LOCAL_ID_TABLE tbl, ulong lid, unsigned flag );
static int qry_lid_table_flag( LOCAL_ID_TABLE tbl, ulong lid, unsigned *flag );
static int propagate_validity( TN node );
static void print_user_id( const char *text, u32 *keyid );
static void sort_tsl_list( TRUST_SEG_LIST *trust_seg_list );
static int list_sigs( ulong pubkey_id );
static int do_check( TRUSTREC *drec, unsigned *trustlevel );
static int do_check( TRUSTREC *drec, unsigned *trustlevel, const char *nhash);
static int get_dir_record( PKT_public_key *pk, TRUSTREC *rec );
static void upd_pref_record( TRUSTREC *urec, u32 *keyid, PKT_signature *sig );
@ -450,7 +462,7 @@ walk_sigrecs( SIGREC_CONTEXT *c )
************* Trust stuff ******************
***********************************************/
static int
int
trust_letter( unsigned value )
{
switch( value ) {
@ -639,35 +651,6 @@ print_user_id( const char *text, u32 *keyid )
m_free(p);
}
#if 0
static int
print_keyid( FILE *fp, ulong lid )
{
u32 ki[2];
if( keyid_from_lid( lid, ki ) )
return fprintf(fp, "????????.%lu", lid );
else
return fprintf(fp, "%08lX.%lu", (ulong)ki[1], lid );
}
static int
print_trust( FILE *fp, unsigned trust )
{
int c;
switch( trust ) {
case TRUST_UNKNOWN: c = 'o'; break;
case TRUST_EXPIRED: c = 'e'; break;
case TRUST_UNDEFINED: c = 'q'; break;
case TRUST_NEVER: c = 'n'; break;
case TRUST_MARGINAL: c = 'm'; break;
case TRUST_FULLY: c = 'f'; break;
case TRUST_ULTIMATE: c = 'u'; break;
default: fprintf(fp, "%02x", trust ); return 2;
}
putc(c, fp);
return 1;
}
#endif
static int
print_sigflags( FILE *fp, unsigned flags )
@ -698,7 +681,7 @@ do_list_sigs( ulong root, ulong pk_lid, int depth,
sx.lid = pk_lid;
for(;;) {
rc = walk_sigrecs( &sx ); /* should we replace it and use */
if( rc ) /* use a loop like in collect_paths ??*/
if( rc )
break;
rc = keyid_from_lid( sx.sig_lid, keyid );
if( rc ) {
@ -839,199 +822,45 @@ list_records( ulong lid )
/****************
* stack is an array of (max_path+1) elements. If trust_seg_head is not
* NULL it is a pointer to a variable which will receive a linked list
* of trust paths - The caller has to free the memory.
*/
static int
collect_paths( int depth, int max_depth, int all, TRUSTREC *drec,
TRUST_INFO *stack, TRUST_SEG_LIST *trust_seg_head )
static TN
new_tn(void)
{
ulong rn, uidrn;
int marginal=0;
int fully=0;
/*LOCAL_ID_TABLE sigs_seen = NULL;*/
TN t;
if( depth >= max_depth ) /* max cert_depth reached */
return TRUST_UNDEFINED;
/* loop over all user-ids */
/*if( !all ) sigs_seen = new_lid_table();*/
for( rn = drec->r.dir.uidlist; rn; rn = uidrn ) {
TRUSTREC rec; /* used for uids and sigs */
ulong sigrn;
read_record( rn, &rec, RECTYPE_UID );
uidrn = rec.r.uid.next;
if( !(rec.r.uid.uidflags & UIDF_CHECKED) )
continue; /* user id has not been checked */
if( !(rec.r.uid.uidflags & UIDF_VALID) )
continue; /* user id is not valid */
if( (rec.r.uid.uidflags & UIDF_REVOKED) )
continue; /* user id has been revoked */
stack[depth].lid = drec->r.dir.lid;
stack[depth].otrust = drec->r.dir.ownertrust;
stack[depth].trust = 0;
{ int i;
for(i=0; i < depth; i++ )
if( stack[i].lid == drec->r.dir.lid )
return TRUST_UNDEFINED; /* closed (we already visited this lid) */
}
if( !qry_lid_table_flag( ultikey_table, drec->r.dir.lid, NULL ) ) {
/* we are at the end of a path */
TRUST_SEG_LIST tsl;
int i;
stack[depth].trust = TRUST_ULTIMATE;
stack[depth].otrust = TRUST_ULTIMATE;
if( trust_seg_head ) {
/* we can now put copy our current stack to the trust_seg_list */
tsl = m_alloc( sizeof *tsl + (depth+1)*sizeof( TRUST_INFO ) );
for(i=0; i <= depth; i++ )
tsl->path[i] = stack[i];
tsl->pathlen = i;
tsl->next = *trust_seg_head;
*trust_seg_head = tsl;
}
return TRUST_ULTIMATE;
}
/* loop over all signature records of this user id */
for( rn = rec.r.uid.siglist; rn; rn = sigrn ) {
int i;
read_record( rn, &rec, RECTYPE_SIG );
sigrn = rec.r.sig.next;
for(i=0; i < SIGS_PER_RECORD; i++ ) {
TRUSTREC tmp;
int ot, nt;
int unchecked = 0;
if( !rec.r.sig.sig[i].lid )
continue; /* skip deleted sigs */
if( !(rec.r.sig.sig[i].flag & SIGF_CHECKED) ) {
if( !all )
continue; /* skip unchecked signatures */
unchecked = 1;
}
else {
if( !(rec.r.sig.sig[i].flag & SIGF_VALID) )
continue; /* skip invalid signatures */
if( (rec.r.sig.sig[i].flag & SIGF_EXPIRED) )
continue; /* skip expired signatures */
if( (rec.r.sig.sig[i].flag & SIGF_REVOKED) )
continue; /* skip revoked signatures */
}
/* visit every signer only once (a signer may have
* signed more than one user ID)
* if( sigs_seen && ins_lid_table_item( sigs_seen,
* rec.r.sig.sig[i].lid, 0) )
* continue; we already have this one
*/
read_record( rec.r.sig.sig[i].lid, &tmp, 0 );
if( tmp.rectype != RECTYPE_DIR ) {
if( tmp.rectype != RECTYPE_SDIR )
log_info("oops: lid %lu: sig %lu has rectype %d"
" - skipped\n",
drec->r.dir.lid, tmp.recnum, tmp.rectype );
continue;
}
ot = tmp.r.dir.ownertrust & TRUST_MASK;
if( ot >= TRUST_FULLY )
ot = TRUST_FULLY; /* just in case */
nt = collect_paths( depth+1, max_depth, all, &tmp, stack,
trust_seg_head );
nt &= TRUST_MASK;
if( nt < TRUST_MARGINAL || unchecked ) {
continue;
}
if( nt == TRUST_ULTIMATE ) {
/* we have signed this key and only in this special case
* we assume that this one is fully trusted */
if( !all ) {
/*if( sigs_seen ) release_lid_table( sigs_seen );*/
return (stack[depth].trust = TRUST_FULLY);
}
}
if( nt > ot )
nt = ot;
if( nt >= TRUST_FULLY )
fully++;
if( nt >= TRUST_MARGINAL )
marginal++;
if( fully >= opt.completes_needed
|| marginal >= opt.marginals_needed ) {
if( !all ) {
/*if( sigs_seen ) release_lid_table( sigs_seen );*/
return (stack[depth].trust = TRUST_FULLY);
}
}
}
}
if( used_tns ) {
t = used_tns;
used_tns = t->next;
memset( t, 0, sizeof *t );
}
/*if( sigs_seen ) release_lid_table( sigs_seen ); */
if( all && ( fully >= opt.completes_needed
|| marginal >= opt.marginals_needed ) ) {
return (stack[depth].trust = TRUST_FULLY );
}
if( marginal ) {
return (stack[depth].trust = TRUST_MARGINAL);
}
return (stack[depth].trust=TRUST_UNDEFINED);
else
t = m_alloc_clear( sizeof *t );
if( ++alloced_tns > max_alloced_tns )
max_alloced_tns = alloced_tns;
return t;
}
typedef struct {
ulong lid;
ulong uid;
byte uid_flags;
byte uid_validity;
byte dir_flags;
byte ownertrust;
} CERT_ITEM;
/* structure to hold certification chains. Item[nitems-1] is the
* ultimateley trusted key, item[0] is the key which
* is introduced, indices [1,(nitems-2)] are all introducers.
*/
typedef struct cert_chain *CERT_CHAIN;
struct cert_chain {
CERT_CHAIN next;
int dups;
int nitems;
CERT_ITEM items[1];
};
/****************
* Copy all items to the set SET_HEAD in a way that the requirements
* of a CERT_CHAIN are met.
*/
static void
add_cert_items_to_set( CERT_CHAIN *set_head, CERT_ITEM *items, int nitems )
release_tn( TN t )
{
CERT_CHAIN ac;
int i;
if( t ) {
t->next = used_tns;
used_tns = t;
alloced_tns--;
}
}
ac = m_alloc_clear( sizeof *ac + (nitems-1)*sizeof(CERT_ITEM) );
ac->nitems = nitems;
for(i=0; i < nitems; i++ )
ac->items[i] = items[i];
ac->next = *set_head;
*set_head = ac;
static void
release_tn_tree( TN kr )
{
TN kr2;
for( ; kr; kr = kr2 ) {
release_tn_tree( kr->list );
kr2 = kr->next;
release_tn( kr );
}
}
@ -1041,57 +870,51 @@ add_cert_items_to_set( CERT_CHAIN *set_head, CERT_ITEM *items, int nitems )
* should have been allocated with size max_depth, stack[0] should
* be setup to the key we are investigating, so the minimal depth
* we should ever see in this function is 1.
* Returns: -1 max_depth reached
* 0 no paths found
* 1 ultimately trusted key found
* Returns: a new tree
* certchain_set must be a valid set or point to NULL; this function
* may modifiy it.
*/
static int
find_cert_chain( ulong lid, int depth, int max_depth,
CERT_ITEM *stack, CERT_CHAIN *cert_chain_set )
static TN
build_cert_tree( ulong lid, int depth, int max_depth, TN helproot )
{
TRUSTREC dirrec;
TRUSTREC uidrec;
ulong uidrno;
TN keynode;
if( depth >= max_depth )
return -1;
stack[depth].lid = lid;
stack[depth].uid = 0;
return NULL;
keynode = new_tn();
if( !helproot )
helproot = keynode;
keynode->lid = lid;
if( !qry_lid_table_flag( ultikey_table, lid, NULL ) ) {
/* this is an ultimately trusted key;
* which means that we have found the end of the chain:
* copy the chain to the set */
add_cert_items_to_set( cert_chain_set, stack, depth+1 );
return 1;
* We do this here prior to reading the dir record
* because we don't really need the info from that record */
keynode->n.k.ownertrust = TRUST_ULTIMATE;
keynode->n.k.buckstop = 1;
return keynode;
}
read_record( lid, &dirrec, 0 );
if( dirrec.rectype != RECTYPE_DIR ) {
if( dirrec.rectype != RECTYPE_SDIR )
log_debug("lid %lu, has rectype %d"
" - skipped\n", lid, dirrec.rectype );
return 0;
m_free(keynode);
return NULL;
}
/* Performance hint: add stuff to ignore this one when the
* assigned validity of the key is bad */
stack[depth].dir_flags = dirrec.r.dir.dirflags;
stack[depth].ownertrust = dirrec.r.dir.ownertrust;
keynode->n.k.ownertrust = dirrec.r.dir.ownertrust;
/* loop over all user ids */
for( uidrno = dirrec.r.dir.uidlist; uidrno; uidrno = uidrec.r.uid.next ) {
TRUSTREC sigrec;
ulong sigrno;
TN uidnode = NULL;
stack[depth].uid = uidrno;
read_record( uidrno, &uidrec, RECTYPE_UID );
stack[depth].uid_flags = uidrec.r.uid.uidflags;
stack[depth].uid_validity = uidrec.r.uid.validity;
if( !(uidrec.r.uid.uidflags & UIDF_CHECKED) )
continue; /* user id has not been checked */
@ -1102,7 +925,8 @@ find_cert_chain( ulong lid, int depth, int max_depth,
/* loop over all signature records */
for(sigrno=uidrec.r.uid.siglist; sigrno; sigrno = sigrec.r.sig.next ) {
int i, j;
int i;
TN tn;
read_record( sigrno, &sigrec, RECTYPE_SIG );
@ -1117,25 +941,48 @@ find_cert_chain( ulong lid, int depth, int max_depth,
continue; /* skip expired signatures */
if( (sigrec.r.sig.sig[i].flag & SIGF_REVOKED) )
continue; /* skip revoked signatures */
for(j=0; j < depth; j++ ) {
if( stack[j].lid == sigrec.r.sig.sig[i].lid )
break;
}
if( j < depth )
continue; /* avoid cycles as soon as possible */
/* check for cycles */
for( tn=keynode; tn && tn->lid != sigrec.r.sig.sig[i].lid;
tn = tn->back )
;
if( tn )
continue; /* cycle found */
if( find_cert_chain( sigrec.r.sig.sig[i].lid,
depth+1, max_depth,
stack, cert_chain_set ) > 0 ) {
tn = build_cert_tree( sigrec.r.sig.sig[i].lid,
depth+1, max_depth, helproot );
if( !tn )
continue; /* cert chain too deep or error */
if( !uidnode ) {
uidnode = new_tn();
uidnode->back = keynode;
uidnode->lid = uidrno;
uidnode->is_uid = 1;
uidnode->next = keynode->list;
keynode->list = uidnode;
}
tn->back = uidnode;
tn->next = uidnode->list;
uidnode->list = tn;
#if 0 /* optimazation - fixme: reenable this later */
if( tn->n.k.buckstop ) {
/* ultimately trusted key found:
* no need to check more signatures of this uid */
sigrec.r.sig.next = 0;
break;
}
#endif
}
} /* end loop over sig recs */
} /* end loop over user ids */
return 0;
if( !keynode->list ) {
release_tn_tree( keynode );
keynode = NULL;
}
return keynode;
}
@ -1147,14 +994,33 @@ find_cert_chain( ulong lid, int depth, int max_depth,
* checking all key signatures up to a some depth.
*/
static int
verify_key( int max_depth, TRUSTREC *drec )
verify_key( int max_depth, TRUSTREC *drec, const char *namehash )
{
TRUST_INFO *tmppath = m_alloc_clear( (max_depth+1)* sizeof *tmppath );
int tr;
TN tree;
int trust;
tr = collect_paths( 0, max_depth, 0, drec, tmppath, NULL );
m_free( tmppath );
return tr;
tree = build_cert_tree( drec->r.dir.lid, 0, opt.max_cert_depth, NULL );
if( !tree )
return TRUST_UNDEFINED;
trust = propagate_validity( tree );
if( namehash ) {
/* find the matching user id.
* FIXME: the way we handle this is too inefficient */
TN ur;
TRUSTREC rec;
trust = 0;
for( ur=tree->list; ur; ur = ur->next ) {
read_record( ur->lid, &rec, RECTYPE_UID );
if( !memcmp( namehash, rec.r.uid.namehash, 20 ) ) {
trust = ur->n.u.validity;
break;
}
}
}
release_tn_tree( tree );
return trust;
}
@ -1165,7 +1031,7 @@ verify_key( int max_depth, TRUSTREC *drec )
* but nothing more is known.
*/
static int
do_check( TRUSTREC *dr, unsigned *validity )
do_check( TRUSTREC *dr, unsigned *validity, const char *namehash )
{
if( !dr->r.dir.keylist ) {
log_error(_("Ooops, no keys\n"));
@ -1176,15 +1042,21 @@ do_check( TRUSTREC *dr, unsigned *validity )
return G10ERR_TRUSTDB;
}
if( tdbio_db_matches_options()
if( namehash ) {
/* Fixme: use the cache */
*validity = verify_key( opt.max_cert_depth, dr, namehash );
}
else if( tdbio_db_matches_options()
&& (dr->r.dir.dirflags & DIRF_VALVALID)
&& dr->r.dir.validity )
*validity = dr->r.dir.validity;
else {
*validity = verify_key( opt.max_cert_depth, dr );
*validity = verify_key( opt.max_cert_depth, dr, NULL );
if( (*validity & TRUST_MASK) >= TRUST_UNDEFINED
&& tdbio_db_matches_options() ) {
/* update the cached validity value */
/* FIXME: Move this to another place so that we can
* update the validity of the uids too */
dr->r.dir.validity = (*validity & TRUST_MASK);
dr->r.dir.dirflags |= DIRF_VALVALID;
write_record( dr );
@ -1437,9 +1309,9 @@ import_ownertrust( const char *fname )
#if 0
static void
print_path( int pathlen, TRUST_INFO *path, FILE *fp, ulong highlight )
print_path( int pathlen, TN ME .........., FILE *fp, ulong highlight )
{
int rc, c, i;
u32 keyid[2];
@ -1475,37 +1347,89 @@ print_path( int pathlen, TRUST_INFO *path, FILE *fp, ulong highlight )
putc('\n', fp );
}
}
#endif
static int
cmp_tsl_array( const void *xa, const void *xb )
propagate_validity( TN node )
{
TRUST_SEG_LIST a = *(TRUST_SEG_LIST*)xa;
TRUST_SEG_LIST b = *(TRUST_SEG_LIST*)xb;
return a->pathlen - b->pathlen;
TN kr, ur;
int max_validity = 0;
assert( !node->is_uid );
if( node->n.k.ownertrust == TRUST_ULTIMATE ) {
/* this is one of our keys */
assert( !node->list ); /* This should be a leaf */
return TRUST_ULTIMATE;
}
/* loop over all user ids */
for( ur=node->list; ur; ur = ur->next ) {
assert( ur->is_uid );
/* loop over all signators */
for(kr=ur->list; kr; kr = kr->next ) {
int val = propagate_validity( kr );
if( val == TRUST_ULTIMATE ) {
ur->n.u.fully_count = opt.completes_needed;
}
else if( val == TRUST_FULLY ) {
if( kr->n.k.ownertrust == TRUST_FULLY )
ur->n.u.fully_count++;
else if( kr->n.k.ownertrust == TRUST_MARGINAL )
ur->n.u.marginal_count++;
}
}
/* fixme: We can move this test into the loop to stop as soon as
* we have a level of FULLY and return from this function
* We dont do this now to get better debug output */
if( ur->n.u.fully_count >= opt.completes_needed
|| ur->n.u.marginal_count >= opt.marginals_needed )
ur->n.u.validity = TRUST_FULLY;
else if( ur->n.u.fully_count || ur->n.u.marginal_count )
ur->n.u.validity = TRUST_MARGINAL;
if( ur->n.u.validity >= max_validity )
max_validity = ur->n.u.validity;
}
node->n.k.validity = max_validity;
return max_validity;
}
static void
sort_tsl_list( TRUST_SEG_LIST *trust_seg_list )
print_default_uid( ulong lid )
{
TRUST_SEG_LIST *array, *tail, tsl;
size_t n;
u32 keyid[2];
for(n=0, tsl = *trust_seg_list; tsl; tsl = tsl->next )
n++;
array = m_alloc( (n+1) * sizeof *array );
for(n=0, tsl = *trust_seg_list; tsl; tsl = tsl->next )
array[n++] = tsl;
array[n] = NULL;
qsort( array, n, sizeof *array, cmp_tsl_array );
*trust_seg_list = NULL;
tail = trust_seg_list;
for(n=0; (tsl=array[n]); n++ ) {
*tail = tsl;
tail = &tsl->next;
if( !keyid_from_lid( lid, keyid ) )
print_user_id( "", keyid );
}
static void
dump_tn_tree( int indent, TN tree )
{
TN kr, ur;
for( kr=tree; kr; kr = kr->next ) {
printf("%*s", indent*4, "" );
printf("K%lu(ot=%d,val=%d) ", kr->lid,
kr->n.k.ownertrust,
kr->n.k.validity );
print_default_uid( kr->lid );
for( ur=kr->list; ur; ur = ur->next ) {
printf("%*s ", indent*4, "" );
printf("U%lu(mc=%d,fc=%d,val=%d)\n", ur->lid,
ur->n.u.marginal_count,
ur->n.u.fully_count,
ur->n.u.validity
);
dump_tn_tree( indent+1, ur->list );
}
}
m_free( array );
}
@ -1515,10 +1439,7 @@ list_trust_path( const char *username )
int rc;
ulong lid;
TRUSTREC rec;
#if 0
TRUST_INFO *tmppath;
TRUST_SEG_LIST trust_seg_list, tsl, tsl2;
#endif
TN tree;
PKT_public_key *pk = m_alloc_clear( sizeof *pk );
INIT_TRUSTDB();
@ -1540,49 +1461,12 @@ list_trust_path( const char *username )
lid = pk->local_id;
free_public_key( pk );
#if 0
/* collect the paths */
tmppath = m_alloc_clear( (opt.max_cert_depth+1)* sizeof *tmppath );
trust_seg_list = NULL;
collect_paths( 0, opt.max_cert_depth, 1, &rec, tmppath, &trust_seg_list );
m_free( tmppath );
sort_tsl_list( &trust_seg_list );
/* and now print them */
for(tsl = trust_seg_list; tsl; tsl = tsl->next ) {
print_path( tsl->pathlen, tsl->path, stdout, 0 );
if( tsl->next )
putchar('\n');
}
/* release the list */
for(tsl = trust_seg_list; tsl; tsl = tsl2 ) {
tsl2 = tsl->next;
m_free( tsl );
}
trust_seg_list = NULL;
#else /* test code */
{
CERT_ITEM *stack;
CERT_CHAIN chains, r;
int i;
chains = NULL;
stack = m_alloc_clear( (opt.max_cert_depth+1)* sizeof *stack );
find_cert_chain( lid, 0, opt.max_cert_depth, stack, &chains);
m_free( stack );
/* dump chains */
printf("lid/uid(ownertrust,validity):\n");
for(r=chains; r ; r = r->next ) {
printf("chain:" );
for(i=0; i < r->nitems; i++ )
printf(" %lu/%lu(%d,%d)", r->items[i].lid, r->items[i].uid,
r->items[i].ownertrust,
(r->items[i].uid_flags & UIDF_VALVALID )?
r->items[i].uid_validity : 0 );
putchar('\n');
}
}
#endif
tree = build_cert_tree( lid, 0, opt.max_cert_depth, NULL );
if( tree )
propagate_validity( tree );
dump_tn_tree( 0, tree );
printf("(alloced tns=%d max=%d)\n", alloced_tns, max_alloced_tns );
release_tn_tree( tree );
}
@ -1789,7 +1673,7 @@ update_trustdb( )
* is not necessary to check this if we use a local pubring. Hmmmm.
*/
int
check_trust( PKT_public_key *pk, unsigned *r_trustlevel )
check_trust( PKT_public_key *pk, unsigned *r_trustlevel, const byte *namehash )
{
TRUSTREC rec;
unsigned trustlevel = TRUST_UNKNOWN;
@ -1839,7 +1723,7 @@ check_trust( PKT_public_key *pk, unsigned *r_trustlevel )
trustlevel = TRUST_EXPIRED;
}
else {
rc = do_check( &rec, &trustlevel );
rc = do_check( &rec, &trustlevel, namehash );
if( rc ) {
log_error(_("key %08lX.%lu: trust check failed: %s\n"),
(ulong)keyid[1], pk->local_id, g10_errstr(rc));
@ -1859,13 +1743,13 @@ check_trust( PKT_public_key *pk, unsigned *r_trustlevel )
int
query_trust_info( PKT_public_key *pk )
query_trust_info( PKT_public_key *pk, const byte *namehash )
{
unsigned trustlevel;
int c;
INIT_TRUSTDB();
if( check_trust( pk, &trustlevel ) )
if( check_trust( pk, &trustlevel, namehash ) )
return '?';
if( trustlevel & TRUST_FLAG_REVOKED )
return 'r';
@ -1899,13 +1783,15 @@ int
enum_cert_paths( void **context, ulong *lid,
unsigned *ownertrust, unsigned *validity )
{
return -1;
#if 0
struct enum_cert_paths_ctx *ctx;
TRUST_SEG_LIST tsl;
fixme: ..... tsl;
INIT_TRUSTDB();
if( !lid ) { /* release the context */
if( *context ) {
TRUST_SEG_LIST tsl2;
FIXME: ........tsl2;
ctx = *context;
for(tsl = ctx->tsl_head; tsl; tsl = tsl2 ) {
@ -1918,7 +1804,7 @@ enum_cert_paths( void **context, ulong *lid,
}
if( !*context ) {
TRUST_INFO *tmppath;
FIXME .... *tmppath;
TRUSTREC rec;
if( !*lid )
@ -1927,12 +1813,14 @@ enum_cert_paths( void **context, ulong *lid,
ctx = m_alloc_clear( sizeof *ctx );
*context = ctx;
/* collect the paths */
#if 0
read_record( *lid, &rec, RECTYPE_DIR );
tmppath = m_alloc_clear( (opt.max_cert_depth+1)* sizeof *tmppath );
tsl = NULL;
collect_paths( 0, opt.max_cert_depth, 1, &rec, tmppath, &tsl );
m_free( tmppath );
sort_tsl_list( &tsl );
#endif
/* setup the context */
ctx->tsl_head = tsl;
ctx->tsl = ctx->tsl_head;
@ -1956,6 +1844,7 @@ enum_cert_paths( void **context, ulong *lid,
*lid = tsl->path[ctx->idx].lid;
ctx->idx++;
return ctx->idx-1;
#endif
}
@ -1966,8 +1855,10 @@ void
enum_cert_paths_print( void **context, FILE *fp,
int refresh, ulong selected_lid )
{
return;
#if 0
struct enum_cert_paths_ctx *ctx;
TRUST_SEG_LIST tsl;
FIXME......... tsl;
if( !*context )
return;
@ -2001,6 +1892,7 @@ enum_cert_paths_print( void **context, FILE *fp,
}
print_path( tsl->pathlen, tsl->path, fp, selected_lid );
#endif
}
@ -2035,7 +1927,7 @@ get_ownertrust_info( ulong lid )
* Return an allocated buffer with the preference values for
* the key with LID and the userid which is identified by the
* HAMEHASH or the firstone if namehash is NULL. ret_n receives
* the length of the allcoated buffer. Structure of the buffer is
* the length of the allocated buffer. Structure of the buffer is
* a repeated sequences of 2 bytes; where the first byte describes the
* type of the preference and the second one the value. The constants
* PREFTYPE_xxxx should be used to reference a type.
@ -2616,6 +2508,10 @@ upd_uid_record( KBNODE keyblock, KBNODE uidnode, u32 *keyid,
ulong recno, newrecno;
int rc;
if( DBG_TRUST )
log_debug("upd_uid_record for %08lX/%02X%02X\n",
(ulong)keyid[1], uidhash[18], uidhash[19]);
/* see whether we already have an uid record */
rmd160_hash_buffer( uidhash, uid->name, uid->len );
for( recno=drec->r.dir.uidlist; recno; recno = urec.r.uid.next ) {
@ -2785,6 +2681,11 @@ upd_pref_record( TRUSTREC *urec, u32 *keyid, PKT_signature *sig )
byte prefs_rec[200];
int n_prefs_rec = 0;
if( DBG_TRUST )
log_debug("upd_pref_record for %08lX.%lu/%02X%02X\n",
(ulong)keyid[1], lid, uidhash[18], uidhash[19] );
/* check for changed preferences */
for(k=0; ptable[k].subpkttype; k++ ) {
s = parse_sig_subpkt2( sig, ptable[k].subpkttype, &n );
@ -2884,8 +2785,8 @@ upd_cert_record( KBNODE keyblock, KBNODE signode, u32 *keyid,
* later. The problem with this is that we must somewhere store
* the information about this signature (we need a record id).
* We do this by using the record type shadow dir, which will
* be converted to a dir record as soon as a new public key is
* inserted into the trustdb.
* be converted to a dir record as soon as the missing public key
* gets inserted into the trustdb.
*/
ulong lid = drec->recnum;
PKT_signature *sig = signode->pkt->pkt.signature;
@ -2901,6 +2802,12 @@ upd_cert_record( KBNODE keyblock, KBNODE signode, u32 *keyid,
int found_delrec = 0;
int rc;
if( DBG_TRUST )
log_debug("upd_cert_record for %08lX.?/%02X%02X/%08lX\n",
(ulong)keyid[1], uidhash[18],
uidhash[19], (ulong)sig->keyid[1] );
delrec.recnum = 0;
/* get the LID of the pubkey of the signature under verification */
@ -2976,13 +2883,12 @@ upd_cert_record( KBNODE keyblock, KBNODE signode, u32 *keyid,
rec.r.sig.sig[i].flag |= SIGF_REVOKED;
}
else if( rc == G10ERR_NO_PUBKEY ) {
#if 0 /* fixme: For some reason this really happens? */
/* fixme: For some reason this really happens? */
if( (rec.r.sig.sig[i].flag & SIGF_CHECKED) )
log_info("sig %08lX.%lu/%02X%02X/%08lX: %s\n",
(ulong)keyid[1], lid, uidhash[18],
uidhash[19], (ulong)sig->keyid[1],
_("Hmmm, public key lost?") );
#endif
rec.r.sig.sig[i].flag = SIGF_NOPUBKEY;
if( revoked )
rec.r.sig.sig[i].flag |= SIGF_REVOKED;
@ -3061,7 +2967,7 @@ upd_cert_record( KBNODE keyblock, KBNODE signode, u32 *keyid,
newflag |= SIGF_REVOKED;
}
else if( rc == G10ERR_NO_PUBKEY ) {
if( opt.verbose > 1 )
if( opt.verbose > 1 || DBG_TRUST )
log_info("sig %08lX.%lu/%02X%02X/%08lX: %s\n",
(ulong)keyid[1], lid, uidhash[18],
uidhash[19], (ulong)sig->keyid[1], g10_errstr(rc) );
@ -3266,9 +3172,6 @@ insert_trust_record( PKT_public_key *pk )
INIT_TRUSTDB();
if( pk->local_id )
log_bug("pk->local_id=%lu\n", pk->local_id );
fingerprint_from_pk( pk, fingerprint, &fingerlen );
/* fixme: assert that we do not have this record.
@ -3289,6 +3192,13 @@ insert_trust_record( PKT_public_key *pk )
goto leave;
}
if( pk->local_id ) {
log_debug("insert_trust_reord with pk->local_id=%lu\n", pk->local_id );
rc = update_trust_record( keyblock, 1, NULL );
release_kbnode( keyblock );
return rc;
}
/* check that we used the primary key (we are little bit paranoid) */
{ PKT_public_key *a_pk;
u32 akid[2], bkid[2];

View File

@ -49,8 +49,8 @@ void register_trusted_key( const char *string );
void check_trustdb( const char *username );
void update_trustdb( void );
int init_trustdb( int level, const char *dbname );
int check_trust( PKT_public_key *pk, unsigned *r_trustlevel );
int query_trust_info( PKT_public_key *pk );
int check_trust( PKT_public_key *pk, unsigned *r_trustlevel, const byte* nh );
int query_trust_info( PKT_public_key *pk, const byte *nh );
int enum_cert_paths( void **context, ulong *lid,
unsigned *ownertrust, unsigned *validity );
void enum_cert_paths_print( void **context, FILE *fp,

View File

@ -1,3 +1,8 @@
Mon Mar 8 20:47:17 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* config.links: Take advantage of the with_symbol_underscore macro.
Add support for freebsd 4.
Wed Feb 24 11:07:27 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* mips3/mpih-sub1.S: Removed left over junk in last line. (Should I

View File

@ -12,12 +12,12 @@ echo '/* created by config.links - do not edit */' >./mpi/asm-syntax.h
if test "$try_asm_modules" = "yes" ; then
case "${target}" in
i[34]86*-*-freebsd*-elf | i[34]86*-*-freebsd3*)
i[34]86*-*-freebsd*-elf | i[34]86*-*-freebsd[34]*)
echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
path="i386"
;;
i[56]86*-*-freebsd*-elf | i[56]86*-*-freebsd3*)
i[56]86*-*-freebsd*-elf | i[56]86*-*-freebsd[34]*)
echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
path="i586 i386"
@ -168,22 +168,9 @@ else
fi
case "${target}" in
*-*-linuxaout* | *-*-linuxoldld* | *-*-linux-gnuoldld*)
needs_underscore="y"
;;
*-*-linux* | *-sysv* | *-solaris* | *-gnu* | *-freebsd*-elf)
needs_underscore="n"
;;
*)
needs_underscore="y"
;;
esac
# Make sysdep.h
echo '/* created by config.links - do not edit */' >./mpi/sysdep.h
if test "$needs_underscore" = "y" ; then
if test x$ac_cv_sys_symbol_underscore = xyes; then
cat <<EOF >>./mpi/sysdep.h
#if __STDC__
#define C_SYMBOL_NAME(name) _##name

513
po/de.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

501
po/fr.po

File diff suppressed because it is too large Load Diff

501
po/it.po

File diff suppressed because it is too large Load Diff

501
po/pl.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

504
po/ru.po

File diff suppressed because it is too large Load Diff