*** empty log message ***

This commit is contained in:
Werner Koch 1998-01-13 19:04:23 +00:00
parent ed36092588
commit 922e57dd57
16 changed files with 889 additions and 60 deletions

View File

@ -26,6 +26,7 @@
* key "abcdefghijklmnopqrstuvwxyz"; * key "abcdefghijklmnopqrstuvwxyz";
* plain "BLOWFISH" * plain "BLOWFISH"
* cipher 32 4E D0 FE F4 13 A2 03 * cipher 32 4E D0 FE F4 13 A2 03
*
*/ */
#include <config.h> #include <config.h>
@ -385,6 +386,9 @@ selftest()
BLOWFISH_context c; BLOWFISH_context c;
byte plain[] = "BLOWFISH"; byte plain[] = "BLOWFISH";
byte buffer[8]; byte buffer[8];
byte plain3[] = { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 };
byte key3[] = { 0x41, 0x79, 0x6E, 0xA0, 0x52, 0x61, 0x6E, 0xE4 };
byte cipher3[] = { 0xE1, 0x13, 0xF4, 0x10, 0x2C, 0xFC, 0xCE, 0x43 };
blowfish_setkey( &c, "abcdefghijklmnopqrstuvwxyz", 26 ); blowfish_setkey( &c, "abcdefghijklmnopqrstuvwxyz", 26 );
encrypt_block( &c, buffer, plain ); encrypt_block( &c, buffer, plain );
@ -393,6 +397,14 @@ selftest()
decrypt_block( &c, buffer, buffer ); decrypt_block( &c, buffer, buffer );
if( memcmp( buffer, plain, 8 ) ) if( memcmp( buffer, plain, 8 ) )
log_bug("blowfish failed\n"); log_bug("blowfish failed\n");
blowfish_setkey( &c, key3, 8 );
encrypt_block( &c, buffer, plain3 );
if( memcmp( buffer, cipher3, 8 ) )
log_error("wrong blowfish encryption (3)\n");
decrypt_block( &c, buffer, buffer );
if( memcmp( buffer, plain3, 8 ) )
log_bug("blowfish failed (3)\n");
} }

View File

@ -36,7 +36,7 @@ Record type 1:
against the pubring) against the pubring)
1 u32 Local-Id-Counter. Used to keep track of Local-IDs. 1 u32 Local-Id-Counter. Used to keep track of Local-IDs.
32 bits are enough numbers for all practial purposes; if this 32 bits are enough numbers for all practial purposes; if this
counter rolls over (due to deleted keyblock,an d new ones), counter rolls over (due to deleted keyblock and new ones),
the software should reassign new Local-Ids to the whole the software should reassign new Local-Ids to the whole
database (not expected to ever occur). database (not expected to ever occur).
1 byte marginals needed 1 byte marginals needed
@ -49,6 +49,7 @@ Record type 1:
Record type 2: Record type 2:
-------------- --------------
Informations about a public key certificate. Informations about a public key certificate.
These are static values which are never changed without user interaction.
1 byte value 2 1 byte value 2
1 byte reserved 1 byte reserved
@ -57,7 +58,7 @@ Record type 2:
and usefull if we have duplicate keyids and usefull if we have duplicate keyids
It is not defined, how an implementaion selects such It is not defined, how an implementaion selects such
a Local-Id, but it may use the local-ID counter from a Local-Id, but it may use the local-ID counter from
record type 1 record type 1, or simply use the offset of Record type 2
8 bytes keyid (of the primary key) 8 bytes keyid (of the primary key)
1 byte pubkey algorithm 1 byte pubkey algorithm
1 byte reserved 1 byte reserved
@ -67,9 +68,9 @@ Record type 2:
0 = undefined (not yet initialized) 0 = undefined (not yet initialized)
1 = unknown owner (could not initialize it) 1 = unknown owner (could not initialize it)
2 = do not trust this owner 2 = do not trust this owner
3 = usually trust this owner 4 = usually trust this owner
4 = always trust this owner 5 = always trust this owner
5 = ultimately trust this owner. This can only be set if 7 = ultimately trust this owner. This can only be set if
we have control over the secret key too. we have control over the secret key too.
Bit 3: set if key is revoked; do not use it. Bit 3: set if key is revoked; do not use it.
Bit 7-4: reserved Bit 7-4: reserved

View File

@ -159,7 +159,7 @@ encode_crypt( const char *filename, STRLIST remusr )
{ {
IOBUF inp = NULL, out = NULL; IOBUF inp = NULL, out = NULL;
PACKET pkt; PACKET pkt;
PKT_plaintext *pt; PKT_plaintext *pt = NULL;
int rc = 0; int rc = 0;
u32 filesize; u32 filesize;
cipher_filter_context_t cfx; cipher_filter_context_t cfx;
@ -244,7 +244,8 @@ encode_crypt( const char *filename, STRLIST remusr )
iobuf_cancel(out); iobuf_cancel(out);
else else
iobuf_close(out); /* fixme: check returncode */ iobuf_close(out); /* fixme: check returncode */
pt->buf = NULL; if( pt )
pt->buf = NULL;
free_packet(&pkt); free_packet(&pkt);
m_free(cfx.dek); m_free(cfx.dek);
release_pkc_list( pkc_list ); release_pkc_list( pkc_list );

View File

@ -57,18 +57,24 @@ free_seckey_enc( PKT_signature *enc )
} }
void void
free_public_cert( PKT_public_cert *cert ) release_public_cert_parts( PKT_public_cert *cert )
{ {
if( cert->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) { if( cert->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
mpi_free( cert->d.elg.p ); mpi_free( cert->d.elg.p ); cert->d.elg.p = NULL;
mpi_free( cert->d.elg.g ); mpi_free( cert->d.elg.g ); cert->d.elg.g = NULL;
mpi_free( cert->d.elg.y ); mpi_free( cert->d.elg.y ); cert->d.elg.y = NULL;
} }
else if( cert->pubkey_algo == PUBKEY_ALGO_RSA ) { else if( cert->pubkey_algo == PUBKEY_ALGO_RSA ) {
mpi_free( cert->d.rsa.rsa_n ); mpi_free( cert->d.rsa.rsa_n ); cert->d.rsa.rsa_n = NULL;
mpi_free( cert->d.rsa.rsa_e ); mpi_free( cert->d.rsa.rsa_e ); cert->d.rsa.rsa_e = NULL;
} }
md_close( cert->mfx.md ); md_close( cert->mfx.md ); cert->mfx.md = NULL;
}
void
free_public_cert( PKT_public_cert *cert )
{
release_public_cert_parts( cert );
m_free(cert); m_free(cert);
} }
@ -92,22 +98,28 @@ copy_public_cert( PKT_public_cert *d, PKT_public_cert *s )
} }
void void
free_secret_cert( PKT_secret_cert *cert ) release_secret_cert_parts( PKT_secret_cert *cert )
{ {
if( cert->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) { if( cert->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
mpi_free( cert->d.elg.p ); mpi_free( cert->d.elg.p ); cert->d.elg.p = NULL;
mpi_free( cert->d.elg.g ); mpi_free( cert->d.elg.g ); cert->d.elg.g = NULL;
mpi_free( cert->d.elg.y ); mpi_free( cert->d.elg.y ); cert->d.elg.y = NULL;
mpi_free( cert->d.elg.x ); mpi_free( cert->d.elg.x ); cert->d.elg.x = NULL;
} }
else if( cert->pubkey_algo == PUBKEY_ALGO_RSA ) { else if( cert->pubkey_algo == PUBKEY_ALGO_RSA ) {
mpi_free( cert->d.rsa.rsa_n ); mpi_free( cert->d.rsa.rsa_n ); cert->d.rsa.rsa_n = NULL;
mpi_free( cert->d.rsa.rsa_e ); mpi_free( cert->d.rsa.rsa_e ); cert->d.rsa.rsa_e = NULL;
mpi_free( cert->d.rsa.rsa_d ); mpi_free( cert->d.rsa.rsa_d ); cert->d.rsa.rsa_d = NULL;
mpi_free( cert->d.rsa.rsa_p ); mpi_free( cert->d.rsa.rsa_p ); cert->d.rsa.rsa_p = NULL;
mpi_free( cert->d.rsa.rsa_q ); mpi_free( cert->d.rsa.rsa_q ); cert->d.rsa.rsa_q = NULL;
mpi_free( cert->d.rsa.rsa_u ); mpi_free( cert->d.rsa.rsa_u ); cert->d.rsa.rsa_u = NULL;
} }
}
void
free_secret_cert( PKT_secret_cert *cert )
{
release_secret_cert_parts( cert );
m_free(cert); m_free(cert);
} }
@ -240,4 +252,34 @@ free_packet( PACKET *pkt )
pkt->pkt.generic = NULL; pkt->pkt.generic = NULL;
} }
/****************
* Returns 0 if they match.
*/
int
cmp_public_secret_cert( PKT_public_cert *pkc, PKT_secret_cert *skc )
{
if( pkc->timestamp != skc->timestamp )
return -1;
if( pkc->valid_days != skc->valid_days )
return -1;
if( pkc->pubkey_algo != skc->pubkey_algo )
return -1;
if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
if( mpi_cmp( pkc->d.elg.p , skc->d.elg.p ) )
return -1;
if( mpi_cmp( pkc->d.elg.g , skc->d.elg.g ) )
return -1;
if( mpi_cmp( pkc->d.elg.y , skc->d.elg.y ) )
return -1;
}
else if( pkc->pubkey_algo == PUBKEY_ALGO_RSA ) {
if( mpi_cmp( pkc->d.rsa.rsa_n , skc->d.rsa.rsa_n ) )
return -1;
if( mpi_cmp( pkc->d.rsa.rsa_e , skc->d.rsa.rsa_e ) )
return -1;
}
return 0;
}

View File

@ -424,17 +424,36 @@ main( int argc, char **argv )
break; break;
case aSign: /* sign the given file */ case aSign: /* sign the given file */
if( argc > 1 ) sl = NULL;
usage(1); if( detached_sig ) { /* sign all files */
if( (rc = sign_file(fname, detached_sig, locusr, 0, NULL)) ) for( ; argc; argc--, argv++ )
log_error("sign_file('%s'): %s\n", fname_print, g10_errstr(rc) ); add_to_strlist( &sl, *argv );
}
else {
if( argc > 1 )
usage(1);
if( argc ) {
sl = m_alloc_clear( sizeof *sl + strlen(fname));
strcpy(sl->d, fname);
}
}
if( (rc = sign_file( sl, detached_sig, locusr, 0, NULL, NULL)) )
log_error("sign_file: %s\n", g10_errstr(rc) );
free_strlist(sl);
break; break;
case aSignEncr: /* sign and encrypt the given file */ case aSignEncr: /* sign and encrypt the given file */
if( argc > 1 ) if( argc > 1 )
usage(1); usage(1);
if( (rc = sign_file(fname, detached_sig, locusr, 1, remusr)) ) if( argc ) {
sl = m_alloc_clear( sizeof *sl + strlen(fname));
strcpy(sl->d, fname);
}
else
sl = NULL;
if( (rc = sign_file(sl, detached_sig, locusr, 1, remusr, NULL)) )
log_error("sign_file('%s'): %s\n", fname_print, g10_errstr(rc) ); log_error("sign_file('%s'): %s\n", fname_print, g10_errstr(rc) );
free_strlist(sl);
break; break;

View File

@ -51,6 +51,13 @@ typedef struct pkc_cache_entry {
PKT_public_cert *pkc; PKT_public_cert *pkc;
} *pkc_cache_entry_t; } *pkc_cache_entry_t;
typedef struct enum_seckey_context {
int eof;
STRLIST sl;
IOBUF iobuf;
} enum_seckey_context_t;
static STRLIST keyrings; static STRLIST keyrings;
static STRLIST secret_keyrings; static STRLIST secret_keyrings;
@ -351,6 +358,9 @@ get_seckey_byname( PKT_secret_cert *skc, const char *name, int unprotect )
} }
/**************** /****************
* scan the keyring and look for either the keyid or the name. * scan the keyring and look for either the keyid or the name.
*/ */
@ -584,6 +594,69 @@ scan_secret_keyring( PKT_secret_cert *skc, u32 *keyid,
} }
/****************
* Enumerate all secret keys. Caller must use these procedure:
* 1) create a void pointer and initialize it to NULL
* 2) pass this void pointer by reference to this function
* and provide space for the secret key (pass a buffer for skc)
* 3) call this function as long as it does not return -1
* to indicate EOF.
* 4) Always call this function a last time with SKC set to NULL,
* so that can free it's context.
*
* Return
*/
int
enum_secret_keys( void **context, PKT_secret_cert *skc )
{
int rc=0;
PACKET pkt;
int save_mode;
enum_seckey_context_t *c = *context;
if( !c ) { /* make a new context */
c = m_alloc_clear( sizeof *c );
*context = c;
c->sl = secret_keyrings;
}
if( !skc ) { /* free the context */
m_free( c );
*context = NULL;
return 0;
}
if( c->eof )
return -1;
for( ; c->sl; c->sl = c->sl->next ) {
if( !c->iobuf ) {
if( !(c->iobuf = iobuf_open( c->sl->d ) ) ) {
log_error("enum_secret_keys: can't open '%s'\n", c->sl->d );
continue; /* try next file */
}
}
save_mode = set_packet_list_mode(0);
init_packet(&pkt);
while( (rc=parse_packet(c->iobuf, &pkt)) != -1 ) {
if( rc )
; /* e.g. unknown packet */
else if( pkt.pkttype == PKT_SECRET_CERT ) {
copy_secret_cert( skc, pkt.pkt.secret_cert );
set_packet_list_mode(save_mode);
return 0; /* found */
}
free_packet(&pkt);
}
set_packet_list_mode(save_mode);
iobuf_close(c->iobuf); c->iobuf = NULL;
}
c->eof = 1;
return -1;
}
/**************** /****************
* Return a string with a printable representation of the user_id. * Return a string with a printable representation of the user_id.
* this string must be freed by m_free. * this string must be freed by m_free.

View File

@ -97,6 +97,7 @@ int get_pubkey( PKT_public_cert *pkc, u32 *keyid );
int get_pubkey_byname( PKT_public_cert *pkc, const char *name ); int get_pubkey_byname( PKT_public_cert *pkc, const char *name );
int get_seckey( PKT_secret_cert *skc, u32 *keyid ); int get_seckey( PKT_secret_cert *skc, u32 *keyid );
int get_seckey_byname( PKT_secret_cert *skc, const char *name, int unlock ); int get_seckey_byname( PKT_secret_cert *skc, const char *name, int unlock );
int enum_secret_keys( void **context, PKT_secret_cert *skc );
char*get_user_id_string( u32 *keyid ); char*get_user_id_string( u32 *keyid );
char*get_user_id( u32 *keyid, size_t *rn ); char*get_user_id( u32 *keyid, size_t *rn );

View File

@ -41,8 +41,8 @@ int encrypt_filter( void *opaque, int control,
/*-- sign.c --*/ /*-- sign.c --*/
int sign_file( const char *filename, int detached, STRLIST locusr, int sign_file( STRLIST filenames, int detached, STRLIST locusr,
int encrypt, STRLIST remusr ); int encrypt, STRLIST remusr, const char *outfile );
int sign_key( const char *username, STRLIST locusr ); int sign_key( const char *username, STRLIST locusr );
int edit_keysigs( const char *username ); int edit_keysigs( const char *username );
int change_passphrase( const char *username ); int change_passphrase( const char *username );

View File

@ -58,11 +58,13 @@ struct {
#define DBG_MEMORY_VALUE 32 /* debug memory allocation stuff */ #define DBG_MEMORY_VALUE 32 /* debug memory allocation stuff */
#define DBG_CACHE_VALUE 64 /* debug the cacheing */ #define DBG_CACHE_VALUE 64 /* debug the cacheing */
#define DBG_MEMSTAT_VALUE 128 /* show memory statistics */ #define DBG_MEMSTAT_VALUE 128 /* show memory statistics */
#define DBG_TRUST_VALUE 256 /* debug the trustdb */
#define DBG_PACKET (opt.debug & DBG_PACKET_VALUE) #define DBG_PACKET (opt.debug & DBG_PACKET_VALUE)
#define DBG_FILTER (opt.debug & DBG_FILTER_VALUE) #define DBG_FILTER (opt.debug & DBG_FILTER_VALUE)
#define DBG_CACHE (opt.debug & DBG_CACHE_VALUE) #define DBG_CACHE (opt.debug & DBG_CACHE_VALUE)
#define DBG_TRUST (opt.debug & DBG_TRUST_VALUE)
#endif /*G10_OPTIONS_H*/ #endif /*G10_OPTIONS_H*/

View File

@ -98,6 +98,7 @@ typedef struct {
u16 valid_days; /* valid for this number of days */ u16 valid_days; /* valid for this number of days */
byte pubkey_algo; /* algorithm used for public key scheme */ byte pubkey_algo; /* algorithm used for public key scheme */
md_filter_context_t mfx; md_filter_context_t mfx;
u32 local_id; /* internal use, valid if > 0 */
union { union {
struct { struct {
MPI p; /* prime */ MPI p; /* prime */
@ -225,13 +226,16 @@ void hash_public_cert( MD_HANDLE md, PKT_public_cert *pkc );
/*-- free-packet.c --*/ /*-- free-packet.c --*/
void free_pubkey_enc( PKT_pubkey_enc *enc ); void free_pubkey_enc( PKT_pubkey_enc *enc );
void free_seckey_enc( PKT_signature *enc ); void free_seckey_enc( PKT_signature *enc );
void release_public_cert_parts( PKT_public_cert *cert );
void free_public_cert( PKT_public_cert *cert ); void free_public_cert( PKT_public_cert *cert );
void release_secret_cert_parts( PKT_secret_cert *cert );
void free_secret_cert( PKT_secret_cert *cert ); void free_secret_cert( PKT_secret_cert *cert );
void free_user_id( PKT_user_id *uid ); void free_user_id( PKT_user_id *uid );
void free_comment( PKT_comment *rem ); void free_comment( PKT_comment *rem );
void free_packet( PACKET *pkt ); void free_packet( PACKET *pkt );
PKT_public_cert *copy_public_cert( PKT_public_cert *d, PKT_public_cert *s ); PKT_public_cert *copy_public_cert( PKT_public_cert *d, PKT_public_cert *s );
PKT_secret_cert *copy_secret_cert( PKT_secret_cert *d, PKT_secret_cert *s ); PKT_secret_cert *copy_secret_cert( PKT_secret_cert *d, PKT_secret_cert *s );
int cmp_public_secret_cert( PKT_public_cert *pkc, PKT_secret_cert *skc );
/*-- sig-check.c --*/ /*-- sig-check.c --*/

View File

@ -41,6 +41,25 @@
static int static int
do_we_trust( PKT_public_cert *pkc, int trustlevel ) do_we_trust( PKT_public_cert *pkc, int trustlevel )
{ {
int rc;
if( trustlevel & TRUST_NO_PUBKEY ) {
/* No pubkey in trustDB: Insert and check again */
rc = insert_trust_record( pkc );
if( rc ) {
log_error("failed to insert it into the trustdb: %s\n",
g10_errstr(rc) );
return 0; /* no */
}
rc = check_pkc_trust( pkc, &trustlevel );
if( rc )
log_fatal("trust check after insert failed: %s\n",
g10_errstr(rc) );
if( trustlevel & TRUST_NO_PUBKEY )
log_bug(NULL);
}
/* Eventuell fragen falls der trustlevel nicht ausreichend ist */ /* Eventuell fragen falls der trustlevel nicht ausreichend ist */
@ -90,6 +109,7 @@ build_pkc_list( STRLIST remusr, PKC_LIST *ret_pkc_list )
remusr->d, g10_errstr(rc) ); remusr->d, g10_errstr(rc) );
} }
else if( do_we_trust( pkc, trustlevel ) ) { else if( do_we_trust( pkc, trustlevel ) ) {
/* note: do_we_trust may have changed the trustlevel */
PKC_LIST r; PKC_LIST r;
r = m_alloc( sizeof *r ); r = m_alloc( sizeof *r );

View File

@ -64,17 +64,22 @@ complete_sig( PKT_signature *sig, PKT_secret_cert *skc, MD_HANDLE md )
/**************** /****************
* Sign the file with name FILENAME. If DETACHED has the value true, * Sign the files whose names are in FILENAME.
* make a detached signature. If FILENAME is NULL read from stdin * If DETACHED has the value true,
* make a detached signature. If FILENAMES->d is NULL read from stdin
* and ignore the detached mode. Sign the file with all secret keys * and ignore the detached mode. Sign the file with all secret keys
* which can be taken from LOCUSR, if this is NULL, use the default one * which can be taken from LOCUSR, if this is NULL, use the default one
* If ENCRYPT is true, use REMUSER (or ask if it is NULL) to encrypt the * If ENCRYPT is true, use REMUSER (or ask if it is NULL) to encrypt the
* signed data for these users. * signed data for these users.
* If OUTFILE is not NULL; this file is used for output and the function
* does not ask for overwrite permission; output is then always
* uncompressed, non-armored and in binary mode.
*/ */
int int
sign_file( const char *filename, int detached, STRLIST locusr, sign_file( STRLIST filenames, int detached, STRLIST locusr,
int encrypt, STRLIST remusr ) int encrypt, STRLIST remusr, const char *outfile )
{ {
const char *fname;
armor_filter_context_t afx; armor_filter_context_t afx;
compress_filter_context_t zfx; compress_filter_context_t zfx;
md_filter_context_t mfx; md_filter_context_t mfx;
@ -88,6 +93,7 @@ sign_file( const char *filename, int detached, STRLIST locusr,
PKC_LIST pkc_list = NULL; PKC_LIST pkc_list = NULL;
SKC_LIST skc_list = NULL; SKC_LIST skc_list = NULL;
SKC_LIST skc_rover = NULL; SKC_LIST skc_rover = NULL;
int multifile = 0;
memset( &afx, 0, sizeof afx); memset( &afx, 0, sizeof afx);
memset( &zfx, 0, sizeof zfx); memset( &zfx, 0, sizeof zfx);
@ -96,6 +102,16 @@ sign_file( const char *filename, int detached, STRLIST locusr,
memset( &efx, 0, sizeof efx); memset( &efx, 0, sizeof efx);
init_packet( &pkt ); init_packet( &pkt );
if( filenames ) {
fname = filenames->d;
multifile = !!filenames->next;
}
else
fname = NULL;
if( fname && filenames->next && (!detached || encrypt) )
log_bug("multiple files can only be detached signed");
if( (rc=build_skc_list( locusr, &skc_list, 1 )) ) if( (rc=build_skc_list( locusr, &skc_list, 1 )) )
goto leave; goto leave;
if( encrypt ) { if( encrypt ) {
@ -104,28 +120,40 @@ sign_file( const char *filename, int detached, STRLIST locusr,
} }
/* prepare iobufs */ /* prepare iobufs */
if( !(inp = iobuf_open(filename)) ) { if( multifile ) /* have list of filenames */
log_error("can't open %s: %s\n", filename? filename: "[stdin]", inp = NULL; /* we do it later */
else if( !(inp = iobuf_open(fname)) ) {
log_error("can't open %s: %s\n", fname? fname: "[stdin]",
strerror(errno) ); strerror(errno) );
rc = G10ERR_OPEN_FILE; rc = G10ERR_OPEN_FILE;
goto leave; goto leave;
} }
if( !(out = open_outfile( filename, opt.armor? 1: detached? 2:0 )) ) { if( outfile ) {
if( !(out = iobuf_create( outfile )) ) {
log_error("can't create %s: %s\n", outfile, strerror(errno) );
rc = G10ERR_CREATE_FILE;
goto leave;
}
else if( opt.verbose )
log_info("writing to '%s'\n", outfile );
}
else if( !(out = open_outfile( fname, opt.armor? 1: detached? 2:0 )) ) {
rc = G10ERR_CREATE_FILE; rc = G10ERR_CREATE_FILE;
goto leave; goto leave;
} }
/* prepare to calculate the MD over the input */ /* prepare to calculate the MD over the input */
if( opt.textmode && opt.armor ) if( opt.textmode && opt.armor && !outfile )
iobuf_push_filter( inp, text_filter, &tfx ); iobuf_push_filter( inp, text_filter, &tfx );
mfx.md = md_open(DIGEST_ALGO_RMD160, 0); mfx.md = md_open(DIGEST_ALGO_RMD160, 0);
iobuf_push_filter( inp, md_filter, &mfx ); if( !multifile )
iobuf_push_filter( inp, md_filter, &mfx );
if( opt.armor ) if( opt.armor && !outfile )
iobuf_push_filter( out, armor_filter, &afx ); iobuf_push_filter( out, armor_filter, &afx );
write_comment( out, "#Created by G10 pre-release " VERSION ); write_comment( out, "#Created by G10 pre-release " VERSION );
if( opt.compress ) if( opt.compress && !outfile )
iobuf_push_filter( out, compress_filter, &zfx ); iobuf_push_filter( out, compress_filter, &zfx );
if( encrypt ) { if( encrypt ) {
@ -141,7 +169,7 @@ sign_file( const char *filename, int detached, STRLIST locusr,
skc = skc_rover->skc; skc = skc_rover->skc;
ops = m_alloc_clear( sizeof *ops ); ops = m_alloc_clear( sizeof *ops );
ops->sig_class = opt.textmode? 0x01 : 0x00; ops->sig_class = opt.textmode && !outfile ? 0x01 : 0x00;
ops->digest_algo = DIGEST_ALGO_RMD160; ops->digest_algo = DIGEST_ALGO_RMD160;
ops->pubkey_algo = skc->pubkey_algo; ops->pubkey_algo = skc->pubkey_algo;
keyid_from_skc( skc, ops->keyid ); keyid_from_skc( skc, ops->keyid );
@ -161,17 +189,40 @@ sign_file( const char *filename, int detached, STRLIST locusr,
/* setup the inner packet */ /* setup the inner packet */
if( detached ) { if( detached ) {
/* read, so that the filter can calculate the digest */ if( multifile ) {
while( iobuf_get(inp) != -1 ) STRLIST sl = filenames;
;
if( opt.verbose )
log_info("signing:" );
for(; sl; sl = sl->next ) {
if( !(inp = iobuf_open(sl->d)) ) {
log_error("can't open %s: %s\n", sl->d, strerror(errno) );
rc = G10ERR_OPEN_FILE;
goto leave;
}
if( opt.verbose )
fprintf(stderr, " '%s'", sl->d );
iobuf_push_filter( inp, md_filter, &mfx );
while( iobuf_get(inp) != -1 )
;
iobuf_close(inp); inp = NULL;
}
if( opt.verbose )
putc( '\n', stderr );
}
else {
/* read, so that the filter can calculate the digest */
while( iobuf_get(inp) != -1 )
;
}
} }
else { else {
if( filename ) { if( fname ) {
pt = m_alloc( sizeof *pt + strlen(filename) - 1 ); pt = m_alloc( sizeof *pt + strlen(fname) - 1 );
pt->namelen = strlen(filename); pt->namelen = strlen(fname);
memcpy(pt->name, filename, pt->namelen ); memcpy(pt->name, fname, pt->namelen );
if( !(filesize = iobuf_get_filelength(inp)) ) if( !(filesize = iobuf_get_filelength(inp)) )
log_info("warning: '%s' is an empty file\n", filename ); log_info("warning: '%s' is an empty file\n", fname );
} }
else { /* no filename */ else { /* no filename */
pt = m_alloc( sizeof *pt - 1 ); pt = m_alloc( sizeof *pt - 1 );
@ -179,7 +230,7 @@ sign_file( const char *filename, int detached, STRLIST locusr,
filesize = 0; /* stdin */ filesize = 0; /* stdin */
} }
pt->timestamp = make_timestamp(); pt->timestamp = make_timestamp();
pt->mode = opt.textmode? 't':'b'; pt->mode = opt.textmode && !outfile ? 't':'b';
pt->len = filesize; pt->len = filesize;
pt->buf = inp; pt->buf = inp;
pkt.pkttype = PKT_PLAINTEXT; pkt.pkttype = PKT_PLAINTEXT;
@ -203,7 +254,7 @@ sign_file( const char *filename, int detached, STRLIST locusr,
sig = m_alloc_clear( sizeof *sig ); sig = m_alloc_clear( sizeof *sig );
sig->pubkey_algo = skc->pubkey_algo; sig->pubkey_algo = skc->pubkey_algo;
sig->timestamp = make_timestamp(); sig->timestamp = make_timestamp();
sig->sig_class = opt.textmode? 0x01 : 0x00; sig->sig_class = opt.textmode && !outfile? 0x01 : 0x00;
md = md_copy( mfx.md ); md = md_copy( mfx.md );
md_putc( md, sig->sig_class ); md_putc( md, sig->sig_class );

View File

@ -25,6 +25,7 @@
#include <unistd.h> #include <unistd.h>
#include <errno.h> #include <errno.h>
#include <assert.h> #include <assert.h>
#include <fcntl.h>
#include "errors.h" #include "errors.h"
#include "iobuf.h" #include "iobuf.h"
@ -41,7 +42,6 @@ struct trust_record {
byte rectype; byte rectype;
byte reserved; byte reserved;
union { union {
byte raw[TRUST_RECORD_LEN-2];
struct { /* version record: */ struct { /* version record: */
byte magic[2]; byte magic[2];
byte version; /* should be 1 */ byte version; /* should be 1 */
@ -76,10 +76,32 @@ struct trust_record {
} cache; } cache;
} r; } r;
}; };
typedef struct trust_record TRUSTREC;
static void create_db( const char *fname );
static void open_db(void);
static int read_record( u32 recnum, TRUSTREC *rec );
static u32 new_local_id(void);
static char *db_name; static char *db_name;
static int db_fd = -1;
static int no_io_dbg = 0;
#define buftou32( p ) ((*(byte*)(p) << 24) | (*((byte*)(p)+1)<< 16) | \
(*((byte*)(p)+2) << 8) | (*((byte*)(p)+3)))
#define buftou16( p ) ((*((byte*)(p)) << 8) | (*((byte*)(p)+1)))
#define u32tobuf( p, a ) do { \
((byte*)p)[0] = a >> 24; \
((byte*)p)[1] = a >> 16; \
((byte*)p)[2] = a >> 8; \
((byte*)p)[3] = a ; \
} while(0)
#define u16tobuf( p, a ) do { \
((byte*)p)[0] = a >> 8; \
((byte*)p)[1] = a ; \
} while(0)
/************************************************** /**************************************************
************** read and write helpers ************ ************** read and write helpers ************
@ -147,7 +169,7 @@ create_db( const char *fname )
fwrite_32( fp, make_timestamp() ); /* created */ fwrite_32( fp, make_timestamp() ); /* created */
fwrite_32( fp, 0 ); /* not yet modified */ fwrite_32( fp, 0 ); /* not yet modified */
fwrite_32( fp, 0 ); /* not yet validated*/ fwrite_32( fp, 0 ); /* not yet validated*/
fwrite_32( fp, 0 ); /* local-id-counter */ fwrite_32( fp, 0 ); /* local-id-counter (not used) */
fwrite_8( fp, 3 ); /* marginals needed */ fwrite_8( fp, 3 ); /* marginals needed */
fwrite_8( fp, 1 ); /* completes needed */ fwrite_8( fp, 1 ); /* completes needed */
fwrite_8( fp, 4 ); /* max_cet_depth */ fwrite_8( fp, 4 ); /* max_cet_depth */
@ -155,14 +177,255 @@ create_db( const char *fname )
fclose(fp); fclose(fp);
} }
static void
open_db()
{
TRUSTREC rec;
assert( db_fd == -1 );
db_fd = open( db_name, O_RDWR );
if( db_fd == -1 )
log_fatal("can't open %s: %s\n", db_name, strerror(errno) );
if( read_record( 0, &rec ) )
log_fatal("TrustDB %s is invalid\n", db_name );
/* fixme: check ->locked and other stuff */
}
/****************
* read the record with number recnum
* returns: -1 on error, 0 on success
*/
static int
read_record( u32 recnum, TRUSTREC *rec )
{
byte buf[TRUST_RECORD_LEN], *p;
int rc = 0;
int n;
if( db_fd == -1 )
open_db();
if( DBG_TRUST && !no_io_dbg )
log_debug("trustdb: read_record(%lu)\n", (ulong)recnum);
if( lseek( db_fd, recnum * TRUST_RECORD_LEN, SEEK_SET ) == -1 ) {
log_error("trustdb: lseek failed: %s\n", strerror(errno) );
return G10ERR_READ_FILE;
}
n = read( db_fd, buf, TRUST_RECORD_LEN);
if( !n ) {
if( DBG_TRUST )
log_debug("trustdb: no record at %lu\n", (ulong)recnum );
return -1; /* eof */
}
else if( n != TRUST_RECORD_LEN ) {
log_error("trustdb: read failed (n=%d): %s\n", n, strerror(errno) );
return G10ERR_READ_FILE;
}
p = buf;
rec->rectype = *p++;
rec->reserved = *p++;
switch( rec->rectype ) {
case 0: /* unused record */
break;
case 1: /* version record */
rec->r.version.magic[0] = *p++;
rec->r.version.magic[1] = *p++;
rec->r.version.version = *p++;
memcpy( rec->r.version.reserved, p, 3); p += 3;
rec->r.version.locked = buftou32(p); p += 4;
rec->r.version.created = buftou32(p); p += 4;
rec->r.version.modified = buftou32(p); p += 4;
rec->r.version.validated= buftou32(p); p += 4;
rec->r.version.local_id_counter = buftou32(p); p += 4;
rec->r.version.marginals_needed = *p++;
rec->r.version.completes_needed = *p++;
rec->r.version.max_cert_depth = *p++;
if( recnum ) {
log_error("%s: version record with recnum %lu\n",
db_name, (ulong)recnum );
rc = G10ERR_TRUSTDB;
}
if( rec->reserved != 'g' || rec->r.version.magic[0] != '1'
|| rec->r.version.magic[1] != '0' ) {
log_error("%s: not a trustdb file\n", db_name );
rc = G10ERR_TRUSTDB;
}
if( rec->r.version.version != 1 ) {
log_error("%s: invalid file version %d\n",
db_name, rec->r.version.version );
rc = G10ERR_TRUSTDB;
}
break;
case 2:
rec->r.pubkey.local_id = buftou32(p); p += 4;
rec->r.pubkey.keyid[0] = buftou32(p); p += 4;
rec->r.pubkey.keyid[1] = buftou32(p); p += 4;
rec->r.pubkey.algo = *p++;
rec->r.pubkey.reserved = *p++;
memcpy( rec->r.pubkey.fingerprint, p, 20); p += 20;
rec->r.pubkey.ownertrust = *p++;
if( rec->r.pubkey.local_id != recnum ) {
log_error("%s: pubkey local_id != recnum (%lu,%lu)\n",
db_name,
(ulong)rec->r.pubkey.local_id,
(ulong)recnum );
rc = G10ERR_TRUSTDB;
}
break;
case 3:
rec->r.cache.local_id = buftou32(p); p += 4;
rec->r.cache.keyid[0] = buftou32(p); p += 4;
rec->r.cache.keyid[1] = buftou32(p); p += 4;
rec->r.cache.valid = *p++;
rec->r.cache.reserved = *p++;
memcpy(rec->r.cache.blockhash, p, 20); p += 20;
rec->r.cache.n_untrusted = *p++;
rec->r.cache.n_marginal = *p++;
rec->r.cache.n_fully = *p++;
rec->r.cache.trustlevel = *p++;
break;
default:
log_error("%s: invalid record type %d at recnum %lu\n",
db_name, rec->rectype, (ulong)recnum );
rc = G10ERR_TRUSTDB;
break;
}
return rc;
}
/****************
* Write the record at RECNUM
*/
static int
write_record( u32 recnum, TRUSTREC *rec )
{
byte buf[TRUST_RECORD_LEN], *p;
int rc = 0;
int n;
if( db_fd == -1 )
open_db();
if( DBG_TRUST && !no_io_dbg )
log_debug("trustdb: write_record(%lu)\n", (ulong)recnum);
memset(buf, 0, TRUST_RECORD_LEN);
p = buf;
*p++ = rec->rectype;
*p++ = rec->reserved;
switch( rec->rectype ) {
case 0: /* unused record */
break;
case 1: /* version record */
log_bug(NULL);
break;
case 2:
u32tobuf(p, rec->r.pubkey.local_id); p += 4;
u32tobuf(p, rec->r.pubkey.keyid[0]); p += 4;
u32tobuf(p, rec->r.pubkey.keyid[1]); p += 4;
*p++ = rec->r.pubkey.algo;
*p++ = rec->r.pubkey.reserved;
memcpy( p, rec->r.pubkey.fingerprint, 20); p += 20;
*p++ = rec->r.pubkey.ownertrust;
assert( rec->r.pubkey.local_id == recnum );
break;
case 3:
u32tobuf(p, rec->r.cache.local_id); p += 4;
u32tobuf(p, rec->r.cache.keyid[0]); p += 4;
u32tobuf(p, rec->r.cache.keyid[1]); p += 4;
*p++ = rec->r.cache.valid;
*p++ = rec->r.cache.reserved;
memcpy(p, rec->r.cache.blockhash, 20); p += 20;
*p++ = rec->r.cache.n_untrusted;
*p++ = rec->r.cache.n_marginal;
*p++ = rec->r.cache.n_fully;
*p++ = rec->r.cache.trustlevel;
break;
default:
log_bug(NULL);
}
if( lseek( db_fd, recnum * TRUST_RECORD_LEN, SEEK_SET ) == -1 ) {
log_error("trustdb: lseek failed: %s\n", strerror(errno) );
return G10ERR_WRITE_FILE;
}
n = write( db_fd, buf, TRUST_RECORD_LEN);
if( n != TRUST_RECORD_LEN ) {
log_error("trustdb: write failed (n=%d): %s\n", n, strerror(errno) );
return G10ERR_WRITE_FILE;
}
return rc;
}
static u32
new_local_id()
{
off_t offset;
u32 recnum;
/* fixme: look for unused records */
offset = lseek( db_fd, 0, SEEK_END );
if( offset == -1 )
log_fatal("trustdb: lseek to end failed: %s\n", strerror(errno) );
recnum = offset / TRUST_RECORD_LEN;
assert(recnum); /* this is will never be the first record */
return recnum ;
}
/****************
* Scan the trustdb for a record of type RECTYPE which maches PKC
* The local_id is set to the correct value
*/
static int
scan_record( PKT_public_cert *pkc, TRUSTREC *rec, int rectype )
{
u32 recnum;
u32 keyid[2];
byte *fingerprint;
size_t fingerlen;
int dbg = DBG_TRUST;
int rc;
assert( rectype == 2 || rectype == 3 );
if( DBG_TRUST )
log_debug("trustdb: scan_record\n");
keyid_from_pkc( pkc, keyid );
fingerprint = fingerprint_from_pkc( pkc, &fingerlen );
assert( fingerlen == 20 || fingerlen == 16 );
no_io_dbg = 1;
for(recnum=1; !(rc=read_record( recnum, rec)); recnum++ ) {
if( rec->rectype != rectype )
continue;
if( rec->rectype == 2 ) {
if( rec->r.pubkey.keyid[0] == keyid[0]
&& rec->r.pubkey.keyid[1] == keyid[1]
&& rec->r.pubkey.algo == pkc->pubkey_algo
&& !memcmp(rec->r.pubkey.fingerprint, fingerprint, fingerlen)
) { /* found */
/* store the local_id */
if( pkc->local_id && pkc->local_id != recnum )
log_error("%s: found record, but local_id from mem does "
"not match recnum (%lu,%lu)\n", db_name,
(ulong)pkc->local_id, (ulong)recnum );
pkc->local_id = recnum;
no_io_dbg = 0;
return 0;
}
}
else
log_bug("not yet implemented\n");
}
no_io_dbg = 0;
if( DBG_TRUST )
log_debug("trustdb: scan_record: eof or error\n");
if( rc != -1 )
log_error("%s: scan_record failed: %s\n",db_name, g10_errstr(rc) );
return rc;
}
@ -171,7 +434,150 @@ create_db( const char *fname )
************* trust logic ******************* ************* trust logic *******************
***********************************************/ ***********************************************/
/****************
* Verify, that all our public keys are in the trustDB and marked as
* ultimately trusted.
*/
static int
verify_own_certs()
{
int rc;
void *enum_context = NULL;
PKT_secret_cert *skc = m_alloc_clear( sizeof *skc );
PKT_public_cert *pkc = m_alloc_clear( sizeof *pkc );
u32 keyid[2];
int trust;
while( !(rc=enum_secret_keys( &enum_context, skc) ) ) {
/* fixme: to be sure that it is a secret key of our own,
* we should check it, but this needs a passphrase
* for every key and this boring for the user.
* Solution: Sign the secring and the trustring
* and verify this signature during
* startup
*/
keyid_from_skc( skc, keyid );
if( DBG_TRUST )
log_debug("checking secret key %08lX\n", (ulong)keyid[1] );
/* look wether we can access the public key of this secret key */
rc = get_pubkey( pkc, keyid );
if( rc ) {
log_error("keyid %08lX: secret key without public key\n",
(ulong)keyid[1] );
goto leave;
}
if( cmp_public_secret_cert( pkc, skc ) ) {
log_error("keyid %08lX: secret and public key don't match\n",
(ulong)keyid[1] );
rc = G10ERR_GENERAL;
goto leave;
}
/* look into the trustdb */
rc = check_pkc_trust( pkc, &trust );
if( rc ) {
log_info("keyid %08lX: problem in trustdb: %s\n", (ulong)keyid[1],
g10_errstr(rc) );
goto leave;
}
if( trust & TRUST_NO_PUBKEY ) {
log_info("keyid %08lX: not yet in trustdb\n", (ulong)keyid[1] );
/* FIXME: insert */
}
else if( (trust & TRUST_MASK) != TRUST_ULT_TRUST ) {
log_error("keyid %08lX: not marked as ultimately trusted\n",
(ulong)keyid[1] );
/* FIXME: mark */
}
release_secret_cert_parts( skc );
release_public_cert_parts( pkc );
}
if( rc != -1 )
log_error("enum_secret_keys failed: %s\n", g10_errstr(rc) );
else
rc = 0;
leave:
free_secret_cert( skc );
free_public_cert( pkc );
return rc;
}
/****************
* Check all the sigs of the given keyblock and mark them
* as checked.
*/
static int
check_sigs( KBNODE keyblock )
{
KBNODE kbctx;
KBNODE node;
int rc;
for( kbctx=NULL; (node=walk_kbtree( keyblock, &kbctx)) ; ) {
if( node->pkt->pkttype == PKT_SIGNATURE
&& (node->pkt->pkt.signature->sig_class&~3) == 0x10 ) {
PKT_signature *sig = node->pkt->pkt.signature;
rc = check_key_signature( keyblock, node );
if( !rc )
node->flag |= 1; /* mark signature valid */
if( DBG_TRUST )
log_debug("trustdb: sig from %08lX: %s\n",
rc? g10_errstr(rc): "okay" );
}
}
return 0;
}
/****************
* Recursive check the signatures.
*/
static int
walk( KBNODE keyblock, int levels )
{
KBNODE kbctx, node;
check_sigs( keyblock );
if( levels ) { /* check the next level */
for( kbctx=NULL; (node=walk_kbtree( keyblock, &kbctx)) ; ) {
if( node->pkt->pkttype == PKT_SIGNATURE && (node->flag & 1) ) {
/* read the keyblock for this signator */
/* and check his signatures */
/*walk( his_keyblock, levels-1)*/
}
}
}
}
/****************
*
*
*
*
*
*
*
*
*
*
*/
static int
check_trust()
{
}
@ -181,11 +587,13 @@ create_db( const char *fname )
/**************** /****************
* Perform some checks over the trustdb * Perform some checks over the trustdb
* level 0: used on initial program startup * level 0: used for initial program startup
*/ */
int int
check_trustdb( int level ) check_trustdb( int level )
{ {
int rc=0;
if( !level ) { if( !level ) {
char *fname = make_filename("~/.g10", "trustDB", NULL ); char *fname = make_filename("~/.g10", "trustDB", NULL );
if( access( fname, R_OK ) ) { if( access( fname, R_OK ) ) {
@ -200,13 +608,22 @@ check_trustdb( int level )
db_name = fname; db_name = fname;
/* we can verify a signature about our local data (secring and trustdb) /* we can verify a signature about our local data (secring and trustdb)
* in ~/.g10/ here * in ~/.g10/ here */
*/ rc = verify_private_data();
if( !rc ) {
/* verify, that our own certificates are in the trustDB
* or move them to the trustdb. */
rc = verify_own_certs();
/* should we check wether there is no other ultimately trusted
* key in the database? */
}
} }
else else
log_bug(NULL); log_bug(NULL);
return 0; return rc;
} }
@ -234,12 +651,171 @@ check_trustdb( int level )
int int
check_pkc_trust( PKT_public_cert *pkc, int *r_trustlevel ) check_pkc_trust( PKT_public_cert *pkc, int *r_trustlevel )
{ {
TRUSTREC rec;
int trustlevel = 0; int trustlevel = 0;
int rc=0;
if( opt.verbose ) if( opt.verbose )
log_info("check_pkc_trust() called.\n"); log_info("check_pkc_trust() called.\n");
/* get the pubkey record */
if( pkc->local_id ) {
if( read_record( pkc->local_id, &rec ) ) {
log_error("check_pkc_trust: read record failed\n");
return G10ERR_TRUSTDB;
}
}
else { /* no local_id: scan the trustdb */
if( (rc=scan_record( pkc, &rec, 2 )) && rc != -1 ) {
log_error("check_pkc_trust: scan_record(2) failed: %s\n",
g10_errstr(rc));
return G10ERR_TRUSTDB;
}
else if( rc == -1 ) {
log_error("check_pkc_trust: pubkey not in TrustDB\n");
trustlevel = TRUST_NO_PUBKEY;
goto leave;
}
}
/* fixme: do some additional checks on the pubkey record */
leave:
if( opt.verbose )
log_info("check_pkc_trust() returns trustlevel %04x.\n", trustlevel);
*r_trustlevel = trustlevel; *r_trustlevel = trustlevel;
return 0; return 0;
} }
/****************
* Insert a trust record into the TrustDB
* This function failes if this record already exists.
*/
int
insert_trust_record( PKT_public_cert *pkc )
{
TRUSTREC rec;
u32 keyid[2];
u32 recnum;
byte *fingerprint;
size_t fingerlen;
if( DBG_TRUST )
log_debug("trustdb: insert_record\n");
assert( !pkc->local_id );
keyid_from_pkc( pkc, keyid );
fingerprint = fingerprint_from_pkc( pkc, &fingerlen );
/* FIXME: check that we do not have this record. */
recnum = new_local_id();
/* build record */
memset( &rec, 0, sizeof rec );
rec.rectype = 2; /* the pubkey record */
rec.r.pubkey.local_id = recnum;
rec.r.pubkey.keyid[0] = keyid[0];
rec.r.pubkey.keyid[1] = keyid[1];
rec.r.pubkey.algo = pkc->pubkey_algo;
memcpy(rec.r.pubkey.fingerprint, fingerprint, fingerlen );
rec.r.pubkey.ownertrust = 0;
if( write_record( recnum, &rec ) ) {
log_error("insert_trust_record: write failed\n");
return G10ERR_TRUSTDB;
}
pkc->local_id = recnum;
return 0;
}
int
update_trust_record( PKT_public_cert *pkc, int new_trust )
{
TRUSTREC rec;
u32 keyid[2];
u32 recnum;
if( DBG_TRUST )
log_debug("trustdb: update_record\n");
assert( pkc->local_id );
if( read_record( pkc->local_id, &rec ) ) {
log_error("update_trust_record: read failed\n");
return G10ERR_TRUSTDB;
}
/* check keyid, fingerprint etc ? */
recnum = new_local_id();
/* build record */
memset( &rec, 0, sizeof rec );
rec.rectype = 2; /* the pubkey record */
rec.r.pubkey.local_id = recnum;
rec.r.pubkey.keyid[0] = keyid[0];
rec.r.pubkey.keyid[1] = keyid[1];
rec.r.pubkey.algo = pkc->pubkey_algo;
memcpy(rec.r.pubkey.fingerprint, fingerprint, fingerlen );
rec.r.pubkey.ownertrust = 0;
if( write_record( recnum, &rec ) ) {
log_error("insert_trust_record: write failed\n");
return G10ERR_TRUSTDB;
}
pkc->local_id = recnum;
return 0;
}
int
verify_private_data()
{
int rc = 0;
char *sigfile = make_filename("~/.g10", "sig", NULL );
if( access( sigfile, R_OK ) ) {
if( errno != ENOENT ) {
log_error("can't access %s: %s\n", sigfile, strerror(errno) );
rc = G10ERR_TRUSTDB;
goto leave;
}
log_info("private data signature missing; creating ...\n");
rc = sign_private_data();
if( rc ) {
log_error("error creating %s: %s\n", sigfile, g10_errstr(rc) );
goto leave;
}
}
/* FIXME: verify this signature */
leave:
m_free(sigfile);
return rc;
}
int
sign_private_data()
{
int rc;
char *sigfile = make_filename("~/.g10", "sig", NULL );
char *secring = make_filename("~/.g10", "secring.g10", NULL );
STRLIST list = NULL;
add_to_strlist( &list, db_name );
add_to_strlist( &list, secring );
rc = sign_file( list, 1, NULL, 0, NULL, sigfile);
m_free(sigfile);
m_free(secring);
free_strlist(list);
return rc;
}

View File

@ -21,8 +21,22 @@
#ifndef G10_TRUSTDB_H #ifndef G10_TRUSTDB_H
#define G10_TRUSTDB_H #define G10_TRUSTDB_H
#define TRUST_MASK 0x07 /* for the trust leveles */
#define TRUST_UNKNOWN 1 /* unknown */
#define TRUST_NO_TRUST 2 /* not trusted */
#define TRUST_MARG_TRUST 4 /* marginally trusted */
#define TRUST_FULL_TRUST 5 /* fully trusted */
#define TRUST_ULT_TRUST 7 /* ultimately trusted */
/* other bits used with the trustlevel */
#define TRUST_NO_PUBKEY 0x10 /* we do not have the pubkey in out trustDB */
/*-- trustdb.c --*/ /*-- trustdb.c --*/
int check_trustdb( int level ); int check_trustdb( int level );
int check_pkc_trust( PKT_public_cert *pkc, int *r_trustlevel ); int check_pkc_trust( PKT_public_cert *pkc, int *r_trustlevel );
int verify_private_data(void);
int sign_private_data(void);
#endif /*G10_TRUSTDB_H*/ #endif /*G10_TRUSTDB_H*/

View File

@ -91,6 +91,7 @@ int answer_is_yes( const char *s );
/*-- strgutil.c --*/ /*-- strgutil.c --*/
void free_strlist( STRLIST sl ); void free_strlist( STRLIST sl );
#define FREE_STRLIST(a) do { free_strlist((a)); (a) = NULL ; } while(0) #define FREE_STRLIST(a) do { free_strlist((a)); (a) = NULL ; } while(0)
void add_to_strlist( STRLIST *list, const char *string );
char *memistr( char *buf, size_t buflen, const char *sub ); char *memistr( char *buf, size_t buflen, const char *sub );
char *trim_spaces( char *string ); char *trim_spaces( char *string );
int string_count_chr( const char *string, int c ); int string_count_chr( const char *string, int c );

View File

@ -37,6 +37,18 @@ free_strlist( STRLIST sl )
} }
} }
void
add_to_strlist( STRLIST *list, const char *string )
{
STRLIST sl;
sl = m_alloc( sizeof *sl + strlen(string));
strcpy(sl->d, string);
sl->next = *list;
*list = sl;
}
/**************** /****************
* look for the substring SUB in buffer and return a pointer to that * look for the substring SUB in buffer and return a pointer to that
* substring in BUF or NULL if not found. * substring in BUF or NULL if not found.