mirror of
git://git.gnupg.org/gnupg.git
synced 2025-05-19 09:02:22 +02:00
Trust stuff works partly.
This commit is contained in:
parent
ea4b6f9db7
commit
d71f8bce7e
86
README
86
README
@ -57,15 +57,10 @@
|
|||||||
|
|
||||||
4) You end up with a binary "g10" in /usr/local/bin
|
4) You end up with a binary "g10" in /usr/local/bin
|
||||||
|
|
||||||
|
5) create a directory ".g10" under your hoem directory ("mkdir ~/.g10")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Resources
|
|
||||||
---------
|
|
||||||
G10 needs a directory "~/.g10" to store the default keyrings
|
|
||||||
and other files.
|
|
||||||
|
|
||||||
|
|
||||||
Key Generation
|
Key Generation
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
@ -75,8 +70,9 @@
|
|||||||
good random numbers for prime number generation, it uses a /dev/random
|
good random numbers for prime number generation, it uses a /dev/random
|
||||||
which will emit only bytes if the kernel can gather enough entropy.
|
which will emit only bytes if the kernel can gather enough entropy.
|
||||||
If you see no progress, you should start some other activities such
|
If you see no progress, you should start some other activities such
|
||||||
as mouse moves or a "find /". Because we have no hardware device
|
as mouse moves, "find /" or using the keyboard (on another window).
|
||||||
to generate random we have to use this method.
|
Because we have no hardware device to generate random we have to use
|
||||||
|
this method.
|
||||||
|
|
||||||
Key generation shows progress by printing different characters to
|
Key generation shows progress by printing different characters to
|
||||||
stderr:
|
stderr:
|
||||||
@ -109,17 +105,18 @@
|
|||||||
|
|
||||||
g10 --sign-key Donald
|
g10 --sign-key Donald
|
||||||
|
|
||||||
To sign the key of of "Donald" with your default userid
|
This let you sign the key of "Donald" with your default userid.
|
||||||
|
|
||||||
g10 --sign-key -u Karl -u Joe Donald
|
g10 --sign-key -u Karl -u Joe Donald
|
||||||
|
|
||||||
To sign the key of of "Donald" with the userids of "Karl" and "Joe".
|
This let you sign the key of of "Donald" with the userids of "Karl"
|
||||||
|
and "Joe".
|
||||||
All existing signatures are checked, if some are invalid, a menu is
|
All existing signatures are checked, if some are invalid, a menu is
|
||||||
offered to delete some of them, and the you are asked for every user
|
offered to delete some of them, and the you are asked for every user
|
||||||
wether you want to sign this key.
|
wether you want to sign this key.
|
||||||
|
|
||||||
You may remove a signature at any time by usiing the option "--edit-sig",
|
You may remove a signature at any time using the option "--edit-sig",
|
||||||
which also asks for the sigs to remove.
|
which asks for the sigs to remove.
|
||||||
|
|
||||||
|
|
||||||
Sign
|
Sign
|
||||||
@ -166,17 +163,6 @@
|
|||||||
Ditto, but sign the file with the user id "Suttner"
|
Ditto, but sign the file with the user id "Suttner"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Examine a data or key file
|
|
||||||
--------------------------
|
|
||||||
|
|
||||||
g10 --list-packets datafile
|
|
||||||
|
|
||||||
Use this to list the contents of a data file. If the file is encrypted
|
|
||||||
you are asked for the passphrase, so that G10 is able to look at the
|
|
||||||
inner structure of a encrypted packet.
|
|
||||||
|
|
||||||
|
|
||||||
Batch mode
|
Batch mode
|
||||||
----------
|
----------
|
||||||
If you use the option "--batch", G10 runs in non-interactive mode and
|
If you use the option "--batch", G10 runs in non-interactive mode and
|
||||||
@ -185,7 +171,7 @@
|
|||||||
you can use the option "--passhrase-fd n", which works like PGPs
|
you can use the option "--passhrase-fd n", which works like PGPs
|
||||||
PGPPASSFD.
|
PGPPASSFD.
|
||||||
|
|
||||||
Batch mode also causes PGP to terminate as soon as a BAD signature is
|
Batch mode also causes G10 to terminate as soon as a BAD signature is
|
||||||
detected.
|
detected.
|
||||||
|
|
||||||
|
|
||||||
@ -196,6 +182,56 @@
|
|||||||
stderr to get detailed informations about the errors.
|
stderr to get detailed informations about the errors.
|
||||||
|
|
||||||
|
|
||||||
|
Esoteric commands
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
g10 --list-packets datafile
|
||||||
|
|
||||||
|
Use this to list the contents of a data file. If the file is encrypted
|
||||||
|
you are asked for the passphrase, so that G10 is able to look at the
|
||||||
|
inner structure of a encrypted packet.
|
||||||
|
|
||||||
|
--quick-random
|
||||||
|
|
||||||
|
Do not use the stroing random generator but a faster one. This can be
|
||||||
|
used to generate keys for tests; those are marked as insecure.
|
||||||
|
|
||||||
|
--list-trustdb
|
||||||
|
|
||||||
|
List the contents of the trustdb in a human readable format
|
||||||
|
|
||||||
|
--list-trustdb <usernames>
|
||||||
|
|
||||||
|
List the tree of certificates for the given usernames
|
||||||
|
|
||||||
|
--list-trust-path depth username
|
||||||
|
|
||||||
|
List the possible trust paths for the given username, up to the specified
|
||||||
|
depth. If depth is negative, duplicate introducers are not listed,
|
||||||
|
because those would increase the trust probabilty only minimal.
|
||||||
|
(you must use the special option "--" to stop option parsing when
|
||||||
|
using a negative number)
|
||||||
|
|
||||||
|
--print-mds filenames
|
||||||
|
|
||||||
|
List all available message digest values for the fiven filenames
|
||||||
|
|
||||||
|
--gen-prime n
|
||||||
|
|
||||||
|
Generate and print a simple prime number of size n
|
||||||
|
|
||||||
|
--gen-prime n q
|
||||||
|
|
||||||
|
Generate a prime number suitable for ElGamal signatures of size n with
|
||||||
|
a q as largest primefactor of n-1.
|
||||||
|
|
||||||
|
--gen-prime n q 1
|
||||||
|
|
||||||
|
Ditto, but calculate a generator too.
|
||||||
|
|
||||||
|
|
||||||
|
For more options/commands see the file g10/OPTIONS.
|
||||||
|
|
||||||
|
|
||||||
Debug Flags
|
Debug Flags
|
||||||
-----------
|
-----------
|
||||||
@ -213,7 +249,7 @@
|
|||||||
32 memory allocation stuff
|
32 memory allocation stuff
|
||||||
64 caching
|
64 caching
|
||||||
128 show memory statistics at exit
|
128 show memory statistics at exit
|
||||||
|
256 trust verification stuff
|
||||||
|
|
||||||
|
|
||||||
Other Notes
|
Other Notes
|
||||||
|
16
acconfig.h
16
acconfig.h
@ -50,4 +50,20 @@
|
|||||||
@BOTTOM@
|
@BOTTOM@
|
||||||
|
|
||||||
|
|
||||||
|
/* The AC_CHECK_SIZEOF() fails for some machines.
|
||||||
|
* we provide some fallback values here */
|
||||||
|
#if !SIZEOF_UNSIGNED_SHORT
|
||||||
|
#undef SIZEOF_UNSIGNED_SHORT
|
||||||
|
#define SIZEOF_UNSIGNED_SHORT 2
|
||||||
|
#endif
|
||||||
|
#if !SIZEOF_UNSIGNED_INT
|
||||||
|
#undef SIZEOF_UNSIGNED_INT
|
||||||
|
#define SIZEOF_UNSIGNED_INT 4
|
||||||
|
#endif
|
||||||
|
#if !SIZEOF_UNSIGNED_LONG
|
||||||
|
#undef SIZEOF_UNSIGNED_LONG
|
||||||
|
#define SIZEOF_UNSIGNED_LONG 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif /*G10_CONFIG_H*/
|
#endif /*G10_CONFIG_H*/
|
||||||
|
@ -167,6 +167,10 @@ the OS a chance to collect more entropy! (Need %d more bytes)\n", length );
|
|||||||
#else /* not HAVE_DEV_RANDOM */
|
#else /* not HAVE_DEV_RANDOM */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef RAND_MAX /* for SunOS */
|
||||||
|
#define RAND_MAX 32767
|
||||||
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fill_buffer( byte *buffer, size_t length, int level )
|
fill_buffer( byte *buffer, size_t length, int level )
|
||||||
{
|
{
|
||||||
@ -178,11 +182,20 @@ fill_buffer( byte *buffer, size_t length, int level )
|
|||||||
"it compile - it is in no way a strong RNG!\n\n"
|
"it compile - it is in no way a strong RNG!\n\n"
|
||||||
"DON'T USE ANY DATA GENERATED BY THIS PROGRAM!!\n\n");
|
"DON'T USE ANY DATA GENERATED BY THIS PROGRAM!!\n\n");
|
||||||
initialized=1;
|
initialized=1;
|
||||||
|
#ifdef HAVE_RAND
|
||||||
srand(make_timestamp()*getpid());
|
srand(make_timestamp()*getpid());
|
||||||
|
#else
|
||||||
|
srandom(make_timestamp()*getpid());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_RAND
|
||||||
while( length-- )
|
while( length-- )
|
||||||
*buffer++ = ((unsigned)(1 + (int) (256.0*rand()/(RAND_MAX+1.0)))-1);
|
*buffer++ = ((unsigned)(1 + (int) (256.0*rand()/(RAND_MAX+1.0)))-1);
|
||||||
|
#else
|
||||||
|
while( length-- )
|
||||||
|
*buffer++ = ((unsigned)(1 + (int) (256.0*random()/(RAND_MAX+1.0)))-1);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
22
config.h.in
22
config.h.in
@ -72,6 +72,9 @@
|
|||||||
/* The number of bytes in a unsigned short. */
|
/* The number of bytes in a unsigned short. */
|
||||||
#undef SIZEOF_UNSIGNED_SHORT
|
#undef SIZEOF_UNSIGNED_SHORT
|
||||||
|
|
||||||
|
/* Define if you have the rand function. */
|
||||||
|
#undef HAVE_RAND
|
||||||
|
|
||||||
/* Define if you have the stpcpy function. */
|
/* Define if you have the stpcpy function. */
|
||||||
#undef HAVE_STPCPY
|
#undef HAVE_STPCPY
|
||||||
|
|
||||||
@ -81,6 +84,9 @@
|
|||||||
/* Define if you have the strlwr function. */
|
/* Define if you have the strlwr function. */
|
||||||
#undef HAVE_STRLWR
|
#undef HAVE_STRLWR
|
||||||
|
|
||||||
|
/* Define if you have the strtoul function. */
|
||||||
|
#undef HAVE_STRTOUL
|
||||||
|
|
||||||
/* Define if you have the tcgetattr function. */
|
/* Define if you have the tcgetattr function. */
|
||||||
#undef HAVE_TCGETATTR
|
#undef HAVE_TCGETATTR
|
||||||
|
|
||||||
@ -91,4 +97,20 @@
|
|||||||
#undef HAVE_ZLIB_H
|
#undef HAVE_ZLIB_H
|
||||||
|
|
||||||
|
|
||||||
|
/* The AC_CHECK_SIZEOF() fails for some machines.
|
||||||
|
* we provide some fallback values here */
|
||||||
|
#if !SIZEOF_UNSIGNED_SHORT
|
||||||
|
#undef SIZEOF_UNSIGNED_SHORT
|
||||||
|
#define SIZEOF_UNSIGNED_SHORT 2
|
||||||
|
#endif
|
||||||
|
#if !SIZEOF_UNSIGNED_INT
|
||||||
|
#undef SIZEOF_UNSIGNED_INT
|
||||||
|
#define SIZEOF_UNSIGNED_INT 4
|
||||||
|
#endif
|
||||||
|
#if !SIZEOF_UNSIGNED_LONG
|
||||||
|
#undef SIZEOF_UNSIGNED_LONG
|
||||||
|
#define SIZEOF_UNSIGNED_LONG 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif /*G10_CONFIG_H*/
|
#endif /*G10_CONFIG_H*/
|
||||||
|
29
configure.in
29
configure.in
@ -8,7 +8,7 @@ AC_CONFIG_AUX_DIR(scripts)
|
|||||||
AC_CONFIG_HEADER(config.h)
|
AC_CONFIG_HEADER(config.h)
|
||||||
|
|
||||||
|
|
||||||
VERSION=`cat ./VERSION`
|
VERSION=`cat $srcdir/VERSION`
|
||||||
PACKAGE=g10
|
PACKAGE=g10
|
||||||
AC_SUBST(VERSION)
|
AC_SUBST(VERSION)
|
||||||
AC_SUBST(PACKAGE)
|
AC_SUBST(PACKAGE)
|
||||||
@ -90,10 +90,6 @@ dnl Checks for libraries.
|
|||||||
dnl Checks for header files.
|
dnl Checks for header files.
|
||||||
AC_HEADER_STDC
|
AC_HEADER_STDC
|
||||||
AC_CHECK_HEADERS(unistd.h)
|
AC_CHECK_HEADERS(unistd.h)
|
||||||
AC_CHECK_HEADERS(zlib.h,
|
|
||||||
[LIBS="$LIBS -lz"],
|
|
||||||
AC_MSG_WARN([zlib missing - creating without ZLIB support!])
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||||
@ -150,12 +146,20 @@ AC_CHECK_SIZEOF(unsigned short, 2)
|
|||||||
AC_CHECK_SIZEOF(unsigned int, 4)
|
AC_CHECK_SIZEOF(unsigned int, 4)
|
||||||
AC_CHECK_SIZEOF(unsigned long, 4)
|
AC_CHECK_SIZEOF(unsigned long, 4)
|
||||||
|
|
||||||
|
if test "$ac_cv_sizeof_unsigned_short" = "0" \
|
||||||
|
|| test "$ac_cv_sizeof_unsigned_int" = "0" \
|
||||||
|
|| test "$ac_cv_sizeof_unsigned_long" = "0"; then
|
||||||
|
AC_MSG_WARN([Hmmm, something is wrong with the sizes - using defaults]);
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
dnl Checks for library functions.
|
dnl Checks for library functions.
|
||||||
AC_FUNC_VPRINTF
|
AC_FUNC_VPRINTF
|
||||||
AC_CHECK_FUNCS(strerror stpcpy strlwr tcgetattr)
|
AC_CHECK_FUNCS(strerror stpcpy strlwr tcgetattr rand strtoul)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
dnl check wether we have a random device
|
dnl check wether we have a random device
|
||||||
AC_CACHE_CHECK(for random device, ac_cv_have_dev_random,
|
AC_CACHE_CHECK(for random device, ac_cv_have_dev_random,
|
||||||
@ -175,8 +179,8 @@ if test "$ac_cv_mpi_config_done" = yes; then
|
|||||||
AC_MSG_RESULT(done)
|
AC_MSG_RESULT(done)
|
||||||
else
|
else
|
||||||
ac_cv_mpi_config_done=""
|
ac_cv_mpi_config_done=""
|
||||||
if test -f ./mpi/config.links ; then
|
if test -f $srcdir/mpi/config.links ; then
|
||||||
. ./mpi/config.links
|
. $srcdir/mpi/config.links
|
||||||
ac_cv_mpi_extra_asm_modules="$mpi_extra_modules"
|
ac_cv_mpi_extra_asm_modules="$mpi_extra_modules"
|
||||||
AC_LINK_FILES( ${mpi_ln_src}, ${mpi_ln_dst} )
|
AC_LINK_FILES( ${mpi_ln_src}, ${mpi_ln_dst} )
|
||||||
ac_cv_mpi_config_done="yes"
|
ac_cv_mpi_config_done="yes"
|
||||||
@ -198,11 +202,18 @@ fi
|
|||||||
AC_SUBST(MPI_EXTRA_ASM_OBJS)
|
AC_SUBST(MPI_EXTRA_ASM_OBJS)
|
||||||
|
|
||||||
|
|
||||||
|
dnl Do we have zlib? Must do it here because Solaris failed
|
||||||
|
dnl when compiling a conftest (due to the "-lz" from LIBS).
|
||||||
|
AC_CHECK_HEADERS(zlib.h,
|
||||||
|
[LIBS="$LIBS -lz"],
|
||||||
|
AC_MSG_WARN([zlib missing - creating without ZLIB support!])
|
||||||
|
)
|
||||||
|
|
||||||
dnl checking whether we have other cipher source files
|
dnl checking whether we have other cipher source files
|
||||||
CIPHER_EXTRA_OBJS=""
|
CIPHER_EXTRA_OBJS=""
|
||||||
CIPHER_EXTRA_DIST=""
|
CIPHER_EXTRA_DIST=""
|
||||||
AC_CACHE_CHECK(for extra cipher modules, ac_cv_have_rsa_cipher,
|
AC_CACHE_CHECK(for extra cipher modules, ac_cv_have_rsa_cipher,
|
||||||
[if test -f cipher/rsa.c && test -f cipher/rsa.h; then
|
[if test -f $srcdir/cipher/rsa.c && test -f $srcdir/cipher/rsa.h; then
|
||||||
ac_cv_have_rsa_cipher=yes; else ac_cv_have_rsa_cipher=no; fi])
|
ac_cv_have_rsa_cipher=yes; else ac_cv_have_rsa_cipher=no; fi])
|
||||||
if test $ac_cv_have_rsa_cipher = yes; then
|
if test $ac_cv_have_rsa_cipher = yes; then
|
||||||
AC_DEFINE(HAVE_RSA_CIPHER)
|
AC_DEFINE(HAVE_RSA_CIPHER)
|
||||||
|
@ -147,9 +147,11 @@ calc_packet_length( PACKET *pkt )
|
|||||||
static int
|
static int
|
||||||
do_comment( IOBUF out, int ctb, PKT_comment *rem )
|
do_comment( IOBUF out, int ctb, PKT_comment *rem )
|
||||||
{
|
{
|
||||||
|
if( !opt.no_comment ) {
|
||||||
write_header(out, ctb, rem->len);
|
write_header(out, ctb, rem->len);
|
||||||
if( iobuf_write( out, rem->data, rem->len ) )
|
if( iobuf_write( out, rem->data, rem->len ) )
|
||||||
return G10ERR_WRITE_FILE;
|
return G10ERR_WRITE_FILE;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,9 +57,10 @@ write_comment( IOBUF out, const char *s )
|
|||||||
KBNODE
|
KBNODE
|
||||||
make_comment_node( const char *s )
|
make_comment_node( const char *s )
|
||||||
{
|
{
|
||||||
PACKET *pkt = m_alloc_clear( sizeof *pkt );
|
PACKET *pkt;
|
||||||
size_t n = strlen(s);
|
size_t n = strlen(s);
|
||||||
|
|
||||||
|
pkt = m_alloc_clear( sizeof *pkt );
|
||||||
pkt->pkttype = PKT_COMMENT;
|
pkt->pkttype = PKT_COMMENT;
|
||||||
pkt->pkt.comment = m_alloc( sizeof *pkt->pkt.comment + n - 1 );
|
pkt->pkt.comment = m_alloc( sizeof *pkt->pkt.comment + n - 1 );
|
||||||
pkt->pkt.comment->len = n;
|
pkt->pkt.comment->len = n;
|
||||||
|
@ -190,6 +190,7 @@ main( int argc, char **argv )
|
|||||||
{ 531, "list-trustdb",0 , "\r"},
|
{ 531, "list-trustdb",0 , "\r"},
|
||||||
{ 532, "quick-random", 0, "\r"},
|
{ 532, "quick-random", 0, "\r"},
|
||||||
{ 533, "list-trust-path",0, "\r"},
|
{ 533, "list-trust-path",0, "\r"},
|
||||||
|
{ 534, "no-comment", 0, "do not write comment packets"},
|
||||||
|
|
||||||
{0} };
|
{0} };
|
||||||
ARGPARSE_ARGS pargs;
|
ARGPARSE_ARGS pargs;
|
||||||
@ -336,6 +337,7 @@ main( int argc, char **argv )
|
|||||||
case 531: set_cmd( &cmd, aListTrustDB); break;
|
case 531: set_cmd( &cmd, aListTrustDB); break;
|
||||||
case 532: quick_random_gen(1); break;
|
case 532: quick_random_gen(1); break;
|
||||||
case 533: set_cmd( &cmd, aListTrustPath); break;
|
case 533: set_cmd( &cmd, aListTrustPath); break;
|
||||||
|
case 534: opt.no_comment=1; break;
|
||||||
default : errors++; pargs.err = configfp? 1:2; break;
|
default : errors++; pargs.err = configfp? 1:2; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ struct {
|
|||||||
int def_cipher_algo;
|
int def_cipher_algo;
|
||||||
int def_pubkey_algo;
|
int def_pubkey_algo;
|
||||||
int def_digest_algo;
|
int def_digest_algo;
|
||||||
int reserved9;
|
int no_comment;
|
||||||
int reserved10;
|
int reserved10;
|
||||||
int reserved11;
|
int reserved11;
|
||||||
int reserved12;
|
int reserved12;
|
||||||
|
@ -34,16 +34,35 @@
|
|||||||
#include "trustdb.h"
|
#include "trustdb.h"
|
||||||
#include "ttyio.h"
|
#include "ttyio.h"
|
||||||
|
|
||||||
|
/****************
|
||||||
|
* Returns true if a ownertrust has changed.
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
query_ownertrust( PKT_public_cert *pkc )
|
query_ownertrust( ulong lid )
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
|
int rc;
|
||||||
size_t n;
|
size_t n;
|
||||||
u32 keyid[2];
|
u32 keyid[2];
|
||||||
|
PKT_public_cert *pkc ;
|
||||||
|
int changed=0;
|
||||||
|
|
||||||
keyid_from_pkc( pkc, keyid );
|
rc = keyid_from_trustdb( lid, keyid );
|
||||||
tty_printf("No ownertrust specified for:\n"
|
if( rc ) {
|
||||||
"%4u%c/%08lX %s \"",
|
log_error("ooops: can't get keyid for lid %lu\n", lid);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pkc = m_alloc_clear( sizeof *pkc );
|
||||||
|
rc = get_pubkey( pkc, keyid );
|
||||||
|
if( rc ) {
|
||||||
|
log_error("keyid %08lX: pubkey not found: %s\n",
|
||||||
|
(ulong)keyid[1], g10_errstr(rc) );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
tty_printf("No ownertrust defined for %lu:\n"
|
||||||
|
"%4u%c/%08lX %s \"", lid,
|
||||||
nbits_from_pkc( pkc ), pubkey_letter( pkc->pubkey_algo ),
|
nbits_from_pkc( pkc ), pubkey_letter( pkc->pubkey_algo ),
|
||||||
(ulong)keyid[1], datestr_from_pkc( pkc ) );
|
(ulong)keyid[1], datestr_from_pkc( pkc ) );
|
||||||
p = get_user_id( keyid, &n );
|
p = get_user_id( keyid, &n );
|
||||||
@ -72,7 +91,16 @@ query_ownertrust( PKT_public_cert *pkc )
|
|||||||
"to do with the (implicitly created) web-of-certificates.\n");
|
"to do with the (implicitly created) web-of-certificates.\n");
|
||||||
}
|
}
|
||||||
else if( !p[1] && (*p >= '1' && *p <= '4') ) {
|
else if( !p[1] && (*p >= '1' && *p <= '4') ) {
|
||||||
/* okay */
|
unsigned trust;
|
||||||
|
switch( *p ) {
|
||||||
|
case '1': trust = TRUST_UNDEFINED; break;
|
||||||
|
case '2': trust = TRUST_NEVER ; break;
|
||||||
|
case '3': trust = TRUST_MARGINAL ; break;
|
||||||
|
case '4': trust = TRUST_FULLY ; break;
|
||||||
|
default: BUG();
|
||||||
|
}
|
||||||
|
if( !update_ownertrust( lid, trust ) )
|
||||||
|
changed++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if( *p == 's' || *p == 'S' ) {
|
else if( *p == 's' || *p == 'S' ) {
|
||||||
@ -81,10 +109,53 @@ query_ownertrust( PKT_public_cert *pkc )
|
|||||||
m_free(p); p = NULL;
|
m_free(p); p = NULL;
|
||||||
}
|
}
|
||||||
m_free(p);
|
m_free(p);
|
||||||
return 0;
|
m_free(pkc);
|
||||||
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************
|
||||||
|
* Try to add some more owner trusts (interactive)
|
||||||
|
* Returns: -1 if no ownertrust were added.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
add_ownertrust( PKT_public_cert *pkc )
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
void *context = NULL;
|
||||||
|
ulong lid;
|
||||||
|
unsigned trust;
|
||||||
|
int any=0;
|
||||||
|
|
||||||
|
tty_printf(
|
||||||
|
"Could not find a valid trust path to the key. Lets see, wether we\n"
|
||||||
|
"can assign some missing owner trust values.\n\n");
|
||||||
|
|
||||||
|
rc = query_trust_record( pkc );
|
||||||
|
if( rc ) {
|
||||||
|
log_error("Ooops: not in trustdb\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
lid = pkc->local_id;
|
||||||
|
while( !(rc=enum_trust_web( &context, &lid )) ) {
|
||||||
|
rc = get_ownertrust( lid, &trust );
|
||||||
|
if( rc )
|
||||||
|
log_fatal("Ooops: couldn't get ownertrust for %lu\n", lid);
|
||||||
|
if( trust == TRUST_UNDEFINED || trust == TRUST_EXPIRED ||
|
||||||
|
trust == TRUST_UNKNOWN ) {
|
||||||
|
if( query_ownertrust( lid ) )
|
||||||
|
any=1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( rc == -1 )
|
||||||
|
rc = 0;
|
||||||
|
enum_trust_web( &context, NULL ); /* close */
|
||||||
|
|
||||||
|
|
||||||
|
return rc? rc : any? 0:-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************
|
/****************
|
||||||
* Check wether we can trust this pkc which has a trustlevel of TRUSTLEVEL
|
* Check wether we can trust this pkc which has a trustlevel of TRUSTLEVEL
|
||||||
@ -119,7 +190,15 @@ do_we_trust( PKT_public_cert *pkc, int trustlevel )
|
|||||||
if( opt.batch || opt.answer_no )
|
if( opt.batch || opt.answer_no )
|
||||||
log_info("no info to calculate a trust probability\n");
|
log_info("no info to calculate a trust probability\n");
|
||||||
else {
|
else {
|
||||||
query_ownertrust( pkc );
|
rc = add_ownertrust( pkc );
|
||||||
|
if( !rc ) {
|
||||||
|
rc = check_trust( pkc, &trustlevel );
|
||||||
|
if( rc )
|
||||||
|
log_fatal("trust check after add_ownertrust failed: %s\n",
|
||||||
|
g10_errstr(rc) );
|
||||||
|
/* FIXME: this is recursive; we better should unroll it */
|
||||||
|
return do_we_trust( pkc, trustlevel );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0; /* no */
|
return 0; /* no */
|
||||||
|
|
||||||
@ -137,7 +216,7 @@ do_we_trust( PKT_public_cert *pkc, int trustlevel )
|
|||||||
return 1; /* yes */
|
return 1; /* yes */
|
||||||
|
|
||||||
case TRUST_ULTIMATE:
|
case TRUST_ULTIMATE:
|
||||||
log_info("Our own key is always good.\n");
|
log_info("Our own keys is always good.\n");
|
||||||
return 1; /* yes */
|
return 1; /* yes */
|
||||||
|
|
||||||
default: BUG();
|
default: BUG();
|
||||||
|
375
g10/trustdb.c
375
g10/trustdb.c
@ -110,15 +110,28 @@ struct local_id_info {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct trust_info TRUST_INFO;
|
||||||
|
struct trust_info {
|
||||||
|
ulong lid;
|
||||||
|
unsigned trust;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
typedef struct trust_seg_list *TRUST_SEG_LIST;
|
typedef struct trust_seg_list *TRUST_SEG_LIST;
|
||||||
struct trust_seg_list {
|
struct trust_seg_list {
|
||||||
TRUST_SEG_LIST next;
|
TRUST_SEG_LIST next;
|
||||||
int nseg; /* number of segmens */
|
int nseg; /* number of segmens */
|
||||||
int dup;
|
int dup;
|
||||||
ulong seg[1]; /* segment list */
|
TRUST_INFO seg[1]; /* segment list */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
TRUST_SEG_LIST tsl;
|
||||||
|
int index;
|
||||||
|
} ENUM_TRUST_WEB_CONTEXT;
|
||||||
|
|
||||||
|
|
||||||
static void create_db( const char *fname );
|
static void create_db( const char *fname );
|
||||||
static void open_db(void);
|
static void open_db(void);
|
||||||
static int read_record( ulong recnum, TRUSTREC *rec );
|
static int read_record( ulong recnum, TRUSTREC *rec );
|
||||||
@ -134,11 +147,12 @@ static int qry_lid_table_flag( LOCAL_ID_INFO *tbl, ulong lid, unsigned *flag );
|
|||||||
static void upd_lid_table_flag( LOCAL_ID_INFO *tbl, ulong lid, unsigned flag );
|
static void upd_lid_table_flag( LOCAL_ID_INFO *tbl, ulong lid, unsigned flag );
|
||||||
|
|
||||||
static void print_user_id( const char *text, u32 *keyid );
|
static void print_user_id( const char *text, u32 *keyid );
|
||||||
static int do_list_path( ulong *stack, int depth, int max_depth,
|
static int do_list_path( TRUST_INFO *stack, int depth, int max_depth,
|
||||||
LOCAL_ID_INFO *lids, TRUST_SEG_LIST *tslist );
|
LOCAL_ID_INFO *lids, TRUST_SEG_LIST *tslist );
|
||||||
|
|
||||||
static int list_sigs( ulong pubkey_id );
|
static int list_sigs( ulong pubkey_id );
|
||||||
static int do_check( ulong pubkeyid, int *trustlevel );
|
static int propagate_trust( TRUST_SEG_LIST tslist );
|
||||||
|
static int do_check( ulong pubkeyid, unsigned *trustlevel );
|
||||||
|
|
||||||
|
|
||||||
static char *db_name;
|
static char *db_name;
|
||||||
@ -147,6 +161,9 @@ static int db_fd = -1;
|
|||||||
* which are the ones from our secrings */
|
* which are the ones from our secrings */
|
||||||
static LOCAL_ID_INFO *ultikey_table;
|
static LOCAL_ID_INFO *ultikey_table;
|
||||||
|
|
||||||
|
static ulong last_trust_web_key;
|
||||||
|
static TRUST_SEG_LIST last_trust_web_tslist;
|
||||||
|
|
||||||
#define buftoulong( p ) ((*(byte*)(p) << 24) | (*((byte*)(p)+1)<< 16) | \
|
#define buftoulong( p ) ((*(byte*)(p) << 24) | (*((byte*)(p)+1)<< 16) | \
|
||||||
(*((byte*)(p)+2) << 8) | (*((byte*)(p)+3)))
|
(*((byte*)(p)+2) << 8) | (*((byte*)(p)+3)))
|
||||||
#define buftoushort( p ) ((*((byte*)(p)) << 8) | (*((byte*)(p)+1)))
|
#define buftoushort( p ) ((*((byte*)(p)) << 8) | (*((byte*)(p)+1)))
|
||||||
@ -642,13 +659,15 @@ void
|
|||||||
list_trust_path( int max_depth, const char *username )
|
list_trust_path( int max_depth, const char *username )
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
int wipe=0;
|
||||||
int i;
|
int i;
|
||||||
TRUSTREC rec;
|
TRUSTREC rec;
|
||||||
PKT_public_cert *pkc = m_alloc_clear( sizeof *pkc );
|
PKT_public_cert *pkc = m_alloc_clear( sizeof *pkc );
|
||||||
|
|
||||||
if( max_depth < 0 )
|
if( max_depth < 0 ) {
|
||||||
max_depth = MAX_LIST_SIGS_DEPTH+1;
|
wipe = 1;
|
||||||
|
max_depth = -max_depth;
|
||||||
|
}
|
||||||
|
|
||||||
if( (rc = get_pubkey_byname( pkc, username )) )
|
if( (rc = get_pubkey_byname( pkc, username )) )
|
||||||
log_error("user '%s' not found: %s\n", username, g10_errstr(rc) );
|
log_error("user '%s' not found: %s\n", username, g10_errstr(rc) );
|
||||||
@ -658,37 +677,53 @@ list_trust_path( int max_depth, const char *username )
|
|||||||
else if( rc == -1 )
|
else if( rc == -1 )
|
||||||
log_error("user '%s' not in trustdb\n", username);
|
log_error("user '%s' not in trustdb\n", username);
|
||||||
else {
|
else {
|
||||||
LOCAL_ID_INFO *lids;
|
|
||||||
LOCAL_ID_INFO *work;
|
|
||||||
ulong stack[MAX_LIST_SIGS_DEPTH];
|
|
||||||
TRUST_SEG_LIST tsl, tslist = NULL;
|
TRUST_SEG_LIST tsl, tslist = NULL;
|
||||||
|
|
||||||
lids = new_lid_table();
|
if( !qry_lid_table_flag( ultikey_table, pkc->local_id, NULL ) ) {
|
||||||
stack[0] = pkc->local_id;
|
tslist = m_alloc( sizeof *tslist );
|
||||||
|
tslist->nseg = 1;
|
||||||
|
tslist->dup = 0;
|
||||||
|
tslist->seg[0].lid = pkc->local_id;
|
||||||
|
tslist->seg[0].trust = 0;
|
||||||
|
tslist->next = NULL;
|
||||||
|
rc = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LOCAL_ID_INFO *lids = new_lid_table();
|
||||||
|
TRUST_INFO stack[MAX_LIST_SIGS_DEPTH];
|
||||||
|
|
||||||
|
stack[0].lid = pkc->local_id;
|
||||||
|
stack[0].trust = 0;
|
||||||
rc = do_list_path( stack, 1, max_depth, lids, &tslist );
|
rc = do_list_path( stack, 1, max_depth, lids, &tslist );
|
||||||
/* wipe out duplicates */
|
if( wipe ) { /* wipe out duplicates */
|
||||||
|
LOCAL_ID_INFO *work;
|
||||||
|
|
||||||
work = new_lid_table();
|
work = new_lid_table();
|
||||||
for( tsl=tslist; tsl; tsl = tsl->next ) {
|
for( tsl=tslist; tsl; tsl = tsl->next ) {
|
||||||
for(i=1; i < tsl->nseg-1; i++ ) {
|
for(i=1; i < tsl->nseg-1; i++ ) {
|
||||||
if( ins_lid_table_item( work, tsl->seg[i], 0 ) ) {
|
if( ins_lid_table_item( work, tsl->seg[i].lid, 0 ) ) {
|
||||||
tsl->dup = 1; /* mark as duplicate */
|
tsl->dup = 1; /* mark as duplicate */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
release_lid_table(work);
|
release_lid_table(work);
|
||||||
|
}
|
||||||
release_lid_table(lids);
|
release_lid_table(lids);
|
||||||
|
}
|
||||||
if( rc )
|
if( rc )
|
||||||
log_error("user '%s' list problem: %s\n", username, g10_errstr(rc));
|
log_error("user '%s' list problem: %s\n", username, g10_errstr(rc));
|
||||||
|
rc = propagate_trust( tslist );
|
||||||
|
if( rc )
|
||||||
|
log_error("user '%s' trust problem: %s\n", username, g10_errstr(rc));
|
||||||
for(tsl = tslist; tsl; tsl = tsl->next ) {
|
for(tsl = tslist; tsl; tsl = tsl->next ) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if( tsl->dup )
|
if( tsl->dup )
|
||||||
continue;
|
continue;
|
||||||
printf("tslist segs:" );
|
printf("trust path:" );
|
||||||
for(i=0; i < tsl->nseg; i++ )
|
for(i=0; i < tsl->nseg; i++ )
|
||||||
printf(" %lu", tsl->seg[i]);
|
printf(" %lu/%02x", tsl->seg[i].lid, tsl->seg[i].trust );
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -855,8 +890,7 @@ keyid_from_local_id( ulong lid, u32 *keyid )
|
|||||||
|
|
||||||
|
|
||||||
/****************
|
/****************
|
||||||
* Verify, that all our public keys are in the trustDB and marked as
|
* Verify, that all our public keys are in the trustDB.
|
||||||
* ultimately trusted.
|
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
verify_own_certs()
|
verify_own_certs()
|
||||||
@ -866,7 +900,6 @@ verify_own_certs()
|
|||||||
PKT_secret_cert *skc = m_alloc_clear( sizeof *skc );
|
PKT_secret_cert *skc = m_alloc_clear( sizeof *skc );
|
||||||
PKT_public_cert *pkc = m_alloc_clear( sizeof *pkc );
|
PKT_public_cert *pkc = m_alloc_clear( sizeof *pkc );
|
||||||
u32 keyid[2];
|
u32 keyid[2];
|
||||||
int trust;
|
|
||||||
|
|
||||||
while( !(rc=enum_secret_keys( &enum_context, skc) ) ) {
|
while( !(rc=enum_secret_keys( &enum_context, skc) ) ) {
|
||||||
/* fixed: to be sure that it is a secret key of our own,
|
/* fixed: to be sure that it is a secret key of our own,
|
||||||
@ -895,23 +928,21 @@ verify_own_certs()
|
|||||||
rc = G10ERR_GENERAL;
|
rc = G10ERR_GENERAL;
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
/* look into the trustdb */
|
|
||||||
rc = check_trust( pkc, &trust );
|
/* make sure that the pubkey is in the trustdb */
|
||||||
|
rc = query_trust_record( pkc );
|
||||||
|
if( rc == -1 ) { /* put it into the trustdb */
|
||||||
|
rc = insert_trust_record( pkc );
|
||||||
if( rc ) {
|
if( rc ) {
|
||||||
log_info("keyid %08lX: problem in trustdb: %s\n", (ulong)keyid[1],
|
log_error("keyid %08lX: can't put it into the trustdb\n",
|
||||||
g10_errstr(rc) );
|
(ulong)keyid[1] );
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
if( trust == TRUST_UNKNOWN ) {
|
|
||||||
rc = insert_trust_record( pkc );
|
|
||||||
if( rc )
|
|
||||||
log_error("keyid %08lX: insert failed: %s\n",
|
|
||||||
(ulong)keyid[1], g10_errstr(rc) );
|
|
||||||
else
|
|
||||||
log_info("keyid %08lX: inserted\n", (ulong)keyid[1] );
|
|
||||||
}
|
}
|
||||||
else {
|
else if( rc ) {
|
||||||
/* FIXME: we should chek the other values */
|
log_error("keyid %08lX: query record failed\n", (ulong)keyid[1] );
|
||||||
|
goto leave;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( DBG_TRUST )
|
if( DBG_TRUST )
|
||||||
@ -921,6 +952,7 @@ verify_own_certs()
|
|||||||
log_error("keyid %08lX: already in ultikey_table\n",
|
log_error("keyid %08lX: already in ultikey_table\n",
|
||||||
(ulong)keyid[1]);
|
(ulong)keyid[1]);
|
||||||
|
|
||||||
|
|
||||||
release_secret_cert_parts( skc );
|
release_secret_cert_parts( skc );
|
||||||
release_public_cert_parts( pkc );
|
release_public_cert_parts( pkc );
|
||||||
}
|
}
|
||||||
@ -1042,7 +1074,7 @@ list_sigs( ulong pubkey_id )
|
|||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
do_list_path( ulong *stack, int depth, int max_depth,
|
do_list_path( TRUST_INFO *stack, int depth, int max_depth,
|
||||||
LOCAL_ID_INFO *lids, TRUST_SEG_LIST *tslist )
|
LOCAL_ID_INFO *lids, TRUST_SEG_LIST *tslist )
|
||||||
{
|
{
|
||||||
SIGREC_CONTEXT sx;
|
SIGREC_CONTEXT sx;
|
||||||
@ -1057,12 +1089,13 @@ do_list_path( ulong *stack, int depth, int max_depth,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
memset( &sx, 0, sizeof sx );
|
memset( &sx, 0, sizeof sx );
|
||||||
sx.pubkey_id = stack[depth-1];
|
sx.pubkey_id = stack[depth-1].lid;
|
||||||
while( !(rc = walk_sigrecs( &sx )) ) {
|
while( !(rc = walk_sigrecs( &sx )) ) {
|
||||||
TRUST_SEG_LIST tsl, t2, tl;
|
TRUST_SEG_LIST tsl, t2, tl;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
stack[depth] = sx.sig_id;
|
stack[depth].lid = sx.sig_id;
|
||||||
|
stack[depth].trust = 0;
|
||||||
if( qry_lid_table_flag( lids, sx.sig_id, &last_depth) ) {
|
if( qry_lid_table_flag( lids, sx.sig_id, &last_depth) ) {
|
||||||
/*printf("%2lu/%d: marked\n", sx.sig_id, depth );*/
|
/*printf("%2lu/%d: marked\n", sx.sig_id, depth );*/
|
||||||
ins_lid_table_item( lids, sx.sig_id, depth);
|
ins_lid_table_item( lids, sx.sig_id, depth);
|
||||||
@ -1078,7 +1111,7 @@ do_list_path( ulong *stack, int depth, int max_depth,
|
|||||||
/*printf("%2lu/%d: already visited\n", sx.sig_id, depth)*/;
|
/*printf("%2lu/%d: already visited\n", sx.sig_id, depth)*/;
|
||||||
else if( !qry_lid_table_flag( ultikey_table, sx.sig_id, NULL ) ) {
|
else if( !qry_lid_table_flag( ultikey_table, sx.sig_id, NULL ) ) {
|
||||||
/* found end of path; store it, ordered by path length */
|
/* found end of path; store it, ordered by path length */
|
||||||
tsl = m_alloc( sizeof *tsl + depth*sizeof(ulong) );
|
tsl = m_alloc( sizeof *tsl + depth*sizeof(TRUST_INFO) );
|
||||||
tsl->nseg = depth+1;
|
tsl->nseg = depth+1;
|
||||||
tsl->dup = 0;
|
tsl->dup = 0;
|
||||||
for(i=0; i <= depth; i++ )
|
for(i=0; i <= depth; i++ )
|
||||||
@ -1268,19 +1301,110 @@ build_sigrecs( ulong pubkeyid )
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/****************
|
||||||
|
* Make a list of trust paths
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
make_tsl( ulong pubkey_id, TRUST_SEG_LIST *ret_tslist )
|
||||||
|
{
|
||||||
|
int i, rc;
|
||||||
|
LOCAL_ID_INFO *lids = new_lid_table();
|
||||||
|
TRUST_INFO stack[MAX_LIST_SIGS_DEPTH];
|
||||||
|
TRUST_SEG_LIST tsl, tslist;
|
||||||
|
int max_depth = 4;
|
||||||
|
|
||||||
|
tslist = *ret_tslist = NULL;
|
||||||
|
|
||||||
|
if( !qry_lid_table_flag( ultikey_table, pubkey_id, NULL ) ) {
|
||||||
|
tslist = m_alloc( sizeof *tslist );
|
||||||
|
tslist->nseg = 1;
|
||||||
|
tslist->dup = 0;
|
||||||
|
tslist->seg[0].lid = pubkey_id;
|
||||||
|
tslist->seg[0].trust = 0;
|
||||||
|
tslist->next = NULL;
|
||||||
|
rc = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
stack[0].lid = pubkey_id;
|
||||||
|
stack[0].trust = 0;
|
||||||
|
rc = do_list_path( stack, 1, max_depth, lids, &tslist );
|
||||||
|
}
|
||||||
|
if( !rc ) { /* wipe out duplicates */
|
||||||
|
LOCAL_ID_INFO *work = new_lid_table();
|
||||||
|
for( tsl=tslist; tsl; tsl = tsl->next ) {
|
||||||
|
for(i=1; i < tsl->nseg-1; i++ ) {
|
||||||
|
if( ins_lid_table_item( work, tsl->seg[i].lid, 0 ) ) {
|
||||||
|
tsl->dup = 1; /* mark as duplicate */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
release_lid_table(work);
|
||||||
|
*ret_tslist = tslist;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
; /* FIXME: release tslist */
|
||||||
|
release_lid_table(lids);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************
|
/****************
|
||||||
|
* Given a trust segment list tslist, walk over all paths and fill in
|
||||||
|
* the trust information for each segment. What this function does is
|
||||||
|
* to assign a trustvalue to the first segment (which is the requested key)
|
||||||
|
* of each path.
|
||||||
*
|
*
|
||||||
|
* FIXME: We have to do more thinks here. e.g. we should never increase
|
||||||
|
* the trust value.
|
||||||
|
*
|
||||||
|
* Do not do it for duplicates.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
do_check( ulong pubkeyid, int *trustlevel )
|
propagate_trust( TRUST_SEG_LIST tslist )
|
||||||
{
|
{
|
||||||
int rc=0;
|
int i, rc;
|
||||||
|
unsigned trust;
|
||||||
|
TRUST_SEG_LIST tsl;
|
||||||
|
|
||||||
|
for(tsl = tslist; tsl; tsl = tsl->next ) {
|
||||||
|
if( tsl->dup )
|
||||||
|
continue;
|
||||||
|
assert( tsl->nseg );
|
||||||
|
/* the last segment is always a ultimately trusted one, so we can
|
||||||
|
* assign a fully trust to the next one */
|
||||||
|
i = tsl->nseg-1;
|
||||||
|
tsl->seg[i].trust = TRUST_ULTIMATE;
|
||||||
|
trust = TRUST_FULLY;
|
||||||
|
for(i-- ; i >= 0; i-- ) {
|
||||||
|
tsl->seg[i].trust = trust;
|
||||||
|
if( i > 0 ) {
|
||||||
|
/* get the trust of this pubkey */
|
||||||
|
rc = get_ownertrust( tsl->seg[i].lid, &trust );
|
||||||
|
if( rc )
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************
|
||||||
|
* we have the pubkey record but nothing more is known
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
do_check( ulong pubkeyid, unsigned *trustlevel )
|
||||||
|
{
|
||||||
|
int i, rc=0;
|
||||||
ulong rnum;
|
ulong rnum;
|
||||||
TRUSTREC rec;
|
TRUSTREC rec;
|
||||||
|
TRUST_SEG_LIST tsl, tsl2, tslist;
|
||||||
|
int marginal, fully;
|
||||||
|
int fully_needed = 4;
|
||||||
|
int marginal_needed = 6;
|
||||||
|
|
||||||
|
*trustlevel = TRUST_UNDEFINED;
|
||||||
|
|
||||||
/* verify the cache */
|
/* verify the cache */
|
||||||
|
|
||||||
@ -1294,11 +1418,64 @@ do_check( ulong pubkeyid, int *trustlevel )
|
|||||||
if( rc )
|
if( rc )
|
||||||
return rc; /* error while looking for sigrec or building sigrecs */
|
return rc; /* error while looking for sigrec or building sigrecs */
|
||||||
|
|
||||||
|
/* fixme: take it from the cache if it is valid */
|
||||||
|
|
||||||
|
/* Make a list of all possible trust-paths */
|
||||||
|
rc = make_tsl( pubkeyid, &tslist );
|
||||||
|
if( rc )
|
||||||
|
return rc;
|
||||||
|
rc = propagate_trust( tslist );
|
||||||
|
if( rc )
|
||||||
|
return rc;
|
||||||
|
for(tsl = tslist; tsl; tsl = tsl->next ) {
|
||||||
|
if( tsl->dup )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
log_debug("tslist segs:" );
|
||||||
|
for(i=0; i < tsl->nseg; i++ )
|
||||||
|
fprintf(stderr, " %lu/%02x", tsl->seg[i].lid, tsl->seg[i].trust );
|
||||||
|
putc('\n',stderr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* and look wether there is a trusted path.
|
||||||
|
* We only have to look at the first segment, because
|
||||||
|
* propagate_trust has investigated all other segments */
|
||||||
|
marginal = fully = 0;
|
||||||
|
for(tsl = tslist; tsl; tsl = tsl->next ) {
|
||||||
|
if( tsl->dup )
|
||||||
|
continue;
|
||||||
|
if( tsl->seg[0].trust == TRUST_ULTIMATE ) {
|
||||||
|
*trustlevel = TRUST_ULTIMATE; /* our own key */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if( tsl->seg[0].trust == TRUST_FULLY ) {
|
||||||
|
marginal++;
|
||||||
|
fully++;
|
||||||
|
}
|
||||||
|
else if( tsl->seg[0].trust == TRUST_MARGINAL )
|
||||||
|
marginal++;
|
||||||
|
|
||||||
|
if( fully >= fully_needed ) {
|
||||||
|
*trustlevel = TRUST_FULLY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( !tsl && marginal >= marginal_needed )
|
||||||
|
*trustlevel = TRUST_MARGINAL;
|
||||||
|
|
||||||
|
/* cache the tslist */
|
||||||
|
if( last_trust_web_key ) {
|
||||||
|
for( tsl = last_trust_web_tslist; tsl; tsl = tsl2 ) {
|
||||||
|
tsl2 = tsl->next;
|
||||||
|
m_free(tsl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
last_trust_web_key = pubkeyid;
|
||||||
|
last_trust_web_tslist = tslist;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*********************************************************
|
/*********************************************************
|
||||||
**************** API Interface ************************
|
**************** API Interface ************************
|
||||||
*********************************************************/
|
*********************************************************/
|
||||||
@ -1375,10 +1552,10 @@ init_trustdb( int level )
|
|||||||
* is not necessary to check this if we use a local pubring. Hmmmm.
|
* is not necessary to check this if we use a local pubring. Hmmmm.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
check_trust( PKT_public_cert *pkc, int *r_trustlevel )
|
check_trust( PKT_public_cert *pkc, unsigned *r_trustlevel )
|
||||||
{
|
{
|
||||||
TRUSTREC rec;
|
TRUSTREC rec;
|
||||||
int trustlevel = TRUST_UNKNOWN;
|
unsigned trustlevel = TRUST_UNKNOWN;
|
||||||
int rc=0;
|
int rc=0;
|
||||||
|
|
||||||
if( DBG_TRUST )
|
if( DBG_TRUST )
|
||||||
@ -1409,10 +1586,6 @@ check_trust( PKT_public_cert *pkc, int *r_trustlevel )
|
|||||||
log_error("check_trust: do_check failed: %s\n", g10_errstr(rc));
|
log_error("check_trust: do_check failed: %s\n", g10_errstr(rc));
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
if( !rec.r.pubkey.ownertrust )
|
|
||||||
trustlevel = TRUST_UNDEFINED;
|
|
||||||
else
|
|
||||||
trustlevel = TRUST_EXPIRED;
|
|
||||||
|
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
@ -1423,29 +1596,109 @@ check_trust( PKT_public_cert *pkc, int *r_trustlevel )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/****************
|
||||||
|
* Enumerate all keys, which are needed to build all trust paths for
|
||||||
|
* the given key. This function dies not return the key itself or
|
||||||
|
* the ultimate key.
|
||||||
|
*
|
||||||
|
* 1) create a void pointer and initialize it to NULL
|
||||||
|
* 2) pass this void pointer by reference to this function.
|
||||||
|
* Set lid to the key you want to enumerate and pass it by reference.
|
||||||
|
* 3) call this function as long as it does not return -1
|
||||||
|
* to indicate EOF. LID does contain the next key used to build the web
|
||||||
|
* 4) Always call this function a last time with LID set to NULL,
|
||||||
|
* so that it can free it's context.
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
get_ownertrust( PKT_public_cert *pkc, int *r_otrust )
|
enum_trust_web( void **context, ulong *lid )
|
||||||
|
{
|
||||||
|
ENUM_TRUST_WEB_CONTEXT *c = *context;
|
||||||
|
|
||||||
|
if( !c ) { /* make a new context */
|
||||||
|
c = m_alloc_clear( sizeof *c );
|
||||||
|
*context = c;
|
||||||
|
if( *lid != last_trust_web_key )
|
||||||
|
log_bug("enum_trust_web: nyi\n");
|
||||||
|
c->tsl = last_trust_web_tslist;
|
||||||
|
c->index = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !lid ) { /* free the context */
|
||||||
|
m_free( c );
|
||||||
|
*context = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
while( c->tsl ) {
|
||||||
|
if( !c->tsl->dup && c->index < c->tsl->nseg-1 ) {
|
||||||
|
*lid = c->tsl->seg[c->index].lid;
|
||||||
|
c->index++;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
c->index = 1;
|
||||||
|
c->tsl = c->tsl->next;
|
||||||
|
}
|
||||||
|
return -1; /* eof */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************
|
||||||
|
* Return the assigned ownertrust value for the given LID
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
get_ownertrust( ulong lid, unsigned *r_otrust )
|
||||||
{
|
{
|
||||||
TRUSTREC rec;
|
TRUSTREC rec;
|
||||||
int rc;
|
|
||||||
|
|
||||||
/* get the pubkey record */
|
if( read_record( lid, &rec ) ) {
|
||||||
|
log_error("get_ownertrust: read record failed\n");
|
||||||
|
return G10ERR_TRUSTDB;
|
||||||
|
}
|
||||||
|
if( r_otrust )
|
||||||
|
*r_otrust = rec.r.pubkey.ownertrust;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
keyid_from_trustdb( ulong lid, u32 *keyid )
|
||||||
|
{
|
||||||
|
TRUSTREC rec;
|
||||||
|
|
||||||
|
if( read_record( lid, &rec ) ) {
|
||||||
|
log_error("keyid_from_trustdb: read record failed\n");
|
||||||
|
return G10ERR_TRUSTDB;
|
||||||
|
}
|
||||||
|
if( keyid ) {
|
||||||
|
keyid[0] = rec.r.pubkey.keyid[0];
|
||||||
|
keyid[1] = rec.r.pubkey.keyid[1];
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
query_trust_record( PKT_public_cert *pkc )
|
||||||
|
{
|
||||||
|
TRUSTREC rec;
|
||||||
|
int rc=0;
|
||||||
|
|
||||||
if( pkc->local_id ) {
|
if( pkc->local_id ) {
|
||||||
if( read_record( pkc->local_id, &rec ) ) {
|
if( read_record( pkc->local_id, &rec ) ) {
|
||||||
log_error("get_ownertrust: read record failed\n");
|
log_error("query_trust_record: read record failed\n");
|
||||||
return G10ERR_TRUSTDB;
|
return G10ERR_TRUSTDB;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else { /* no local_id: scan the trustdb */
|
else { /* no local_id: scan the trustdb */
|
||||||
if( (rc=scan_record_by_pkc( pkc, &rec, 2 )) && rc != -1 ) {
|
if( (rc=scan_record_by_pkc( pkc, &rec, 2 )) && rc != -1 ) {
|
||||||
log_error("get_ownertrust: scan_record_by_pkc(2) failed: %s\n",
|
log_error("query_trust_record: scan_record_by_pkc(2) failed: %s\n",
|
||||||
g10_errstr(rc));
|
g10_errstr(rc));
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
else if( rc == -1 )
|
else if( rc == -1 )
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
*r_otrust = rec.r.pubkey.ownertrust;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1494,23 +1747,23 @@ insert_trust_record( PKT_public_cert *pkc )
|
|||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
update_trust_record( PKT_public_cert *pkc, int new_trust )
|
update_ownertrust( ulong lid, unsigned new_trust )
|
||||||
{
|
{
|
||||||
TRUSTREC rec;
|
TRUSTREC rec;
|
||||||
ulong recnum;
|
|
||||||
|
|
||||||
|
if( read_record( lid, &rec ) ) {
|
||||||
assert( pkc->local_id );
|
log_error("update_ownertrust: read failed\n");
|
||||||
|
|
||||||
if( read_record( pkc->local_id, &rec ) ) {
|
|
||||||
log_error("update_trust_record: read failed\n");
|
|
||||||
return G10ERR_TRUSTDB;
|
return G10ERR_TRUSTDB;
|
||||||
}
|
}
|
||||||
/* check keyid, fingerprint etc ? */
|
/* check keyid, fingerprint etc ? */
|
||||||
|
if( rec.rectype != 2 ) {
|
||||||
|
log_error("update_ownertrust: invalid record type\n");
|
||||||
|
return G10ERR_TRUSTDB;
|
||||||
|
}
|
||||||
|
|
||||||
rec.r.pubkey.ownertrust = 0;
|
rec.r.pubkey.ownertrust = new_trust;
|
||||||
if( write_record( recnum, &rec ) ) {
|
if( write_record( lid, &rec ) ) {
|
||||||
log_error("insert_trust_record: write failed\n");
|
log_error("update_ownertrust: write failed\n");
|
||||||
return G10ERR_TRUSTDB;
|
return G10ERR_TRUSTDB;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,9 +36,13 @@
|
|||||||
void list_trustdb(const char *username);
|
void list_trustdb(const char *username);
|
||||||
void list_trust_path( int max_depth, const char *username );
|
void list_trust_path( int max_depth, const char *username );
|
||||||
int init_trustdb( int level );
|
int init_trustdb( int level );
|
||||||
int check_trust( PKT_public_cert *pkc, int *r_trustlevel );
|
int check_trust( PKT_public_cert *pkc, unsigned *r_trustlevel );
|
||||||
int get_ownertrust( PKT_public_cert *pkc, int *r_otrust );
|
int enum_trust_web( void **context, ulong *lid );
|
||||||
|
int get_ownertrust( ulong lid, unsigned *r_otrust );
|
||||||
|
int keyid_from_trustdb( ulong lid, u32 *keyid );
|
||||||
|
int query_trust_record( PKT_public_cert *pkc );
|
||||||
int insert_trust_record( PKT_public_cert *pkc );
|
int insert_trust_record( PKT_public_cert *pkc );
|
||||||
|
int update_ownertrust( ulong lid, unsigned new_trust );
|
||||||
int verify_private_data(void);
|
int verify_private_data(void);
|
||||||
int sign_private_data(void);
|
int sign_private_data(void);
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ struct iobuf_struct {
|
|||||||
IOBUF chain; /* next iobuf used for i/o if any (passed to filter) */
|
IOBUF chain; /* next iobuf used for i/o if any (passed to filter) */
|
||||||
int no, subno;
|
int no, subno;
|
||||||
const char *desc;
|
const char *desc;
|
||||||
void *opaque; /* can be used to old any information */
|
void *opaque; /* can be used to hold any information */
|
||||||
/* this value is copied to all instances */
|
/* this value is copied to all instances */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -121,7 +121,9 @@ char *stpcpy(char *a,const char *b);
|
|||||||
#ifndef HAVE_STRLWR
|
#ifndef HAVE_STRLWR
|
||||||
char *strlwr(char *a);
|
char *strlwr(char *a);
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef HAVE_STRTOUL
|
||||||
|
#define strtoul(a,b,c) ((unsigned long)strtol((a),(b),(c)))
|
||||||
|
#endif
|
||||||
|
|
||||||
/******** some macros ************/
|
/******** some macros ************/
|
||||||
#ifndef STR
|
#ifndef STR
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
/* longlong.h -- definitions for mixed size 32/64 bit arithmetic.
|
/* longlong.h -- definitions for mixed size 32/64 bit arithmetic.
|
||||||
|
Note: I added some stuff for use with g10
|
||||||
|
|
||||||
Copyright (C) 1991, 1992, 1993, 1994, 1996 Free Software Foundation, Inc.
|
Copyright (C) 1991, 1992, 1993, 1994, 1996 Free Software Foundation, Inc.
|
||||||
|
|
||||||
@ -1440,6 +1441,7 @@ extern
|
|||||||
const
|
const
|
||||||
#endif
|
#endif
|
||||||
unsigned char __clz_tab[];
|
unsigned char __clz_tab[];
|
||||||
|
#define MPI_INTERNAL_NEED_CLZ_TAB 1
|
||||||
#define count_leading_zeros(count, x) \
|
#define count_leading_zeros(count, x) \
|
||||||
do { \
|
do { \
|
||||||
UWtype __xr = (x); \
|
UWtype __xr = (x); \
|
||||||
|
@ -26,6 +26,28 @@
|
|||||||
#include "longlong.h"
|
#include "longlong.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef MPI_INTERNAL_NEED_CLZ_TAB
|
||||||
|
unsigned char
|
||||||
|
__clz_tab[] =
|
||||||
|
{
|
||||||
|
0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
|
||||||
|
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
|
||||||
|
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
||||||
|
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
||||||
|
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
|
||||||
|
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
|
||||||
|
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
|
||||||
|
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/****************
|
/****************
|
||||||
* Return the number of bits in A.
|
* Return the number of bits in A.
|
||||||
*/
|
*/
|
||||||
|
@ -286,7 +286,7 @@ optfile_parse( FILE *fp, const char *filename, unsigned *lineno,
|
|||||||
else if( state == 3 ) { /* skip leading spaces of the argument */
|
else if( state == 3 ) { /* skip leading spaces of the argument */
|
||||||
if( !isspace(c) ) {
|
if( !isspace(c) ) {
|
||||||
i = 0;
|
i = 0;
|
||||||
keyword[i] = c;
|
keyword[i++] = c;
|
||||||
state = 4;
|
state = 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user