mirror of
git://git.gnupg.org/gnupg.git
synced 2024-11-10 21:38:50 +01:00
*** empty log message ***
This commit is contained in:
parent
ed36092588
commit
922e57dd57
@ -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");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
11
doc/DETAILS
11
doc/DETAILS
@ -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
|
||||||
|
@ -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 );
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
29
g10/g10.c
29
g10/g10.c
@ -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;
|
||||||
|
|
||||||
|
|
||||||
|
73
g10/getkey.c
73
g10/getkey.c
@ -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.
|
||||||
|
@ -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 );
|
||||||
|
|
||||||
|
@ -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 );
|
||||||
|
@ -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*/
|
||||||
|
@ -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 --*/
|
||||||
|
@ -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 );
|
||||||
|
95
g10/sign.c
95
g10/sign.c
@ -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 );
|
||||||
|
588
g10/trustdb.c
588
g10/trustdb.c
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -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*/
|
||||||
|
@ -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 );
|
||||||
|
@ -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.
|
||||||
|
Loading…
Reference in New Issue
Block a user