1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-02 22:46:30 +02:00

a couple of changes; but some parts are now broken

This commit is contained in:
Werner Koch 1998-02-11 03:25:44 +00:00
parent d6fa02add6
commit 4c0c155922
46 changed files with 1879 additions and 433 deletions

View file

@ -174,7 +174,7 @@ g10maint_LDFLAGS =
CFLAGS = @CFLAGS@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
LINK = $(CC) $(CFLAGS) $(LDFLAGS) -o $@
DIST_COMMON = Makefile.am Makefile.in
DIST_COMMON = ChangeLog Makefile.am Makefile.in
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)

View file

@ -291,7 +291,7 @@ main( int argc, char **argv )
configname, strerror(errno) );
m_free(configname); configname = NULL;
}
if( parse_verbose > 1 )
if( parse_verbose > 1 && configname )
log_info(_("reading options from '%s'\n"), configname );
default_config = 0;
}
@ -640,7 +640,7 @@ main( int argc, char **argv )
void
g10_exit( int rc )
{
if( opt.verbose )
if( opt.debug )
secmem_dump_stats();
secmem_term();
rc = rc? rc : log_get_errorcount(0)? 2:0;

View file

@ -478,7 +478,7 @@ main( int argc, char **argv )
}
break;
case aTest: do_test( argc? atoi(*argv): 0 ); break;
case aTest: do_test( argc? atoi(*argv): 1 ); break;
case aListTrustDB:
if( !argc )
@ -603,27 +603,41 @@ print_mds( const char *fname )
static void
do_test(int times)
{
#if 0
MPI t = mpi_alloc( 50 );
MPI m = mpi_alloc( 50 );
MPI a = mpi_alloc( 50 );
MPI b = mpi_alloc( 50 );
MPI p = mpi_alloc( 50 );
MPI x = mpi_alloc( 50 );
MPI base[4];
MPI exp[4];
MPI t1 = mpi_alloc(50);
MPI t2 = mpi_alloc(50);
MPI t3 = mpi_alloc(50);
MPI tmp= mpi_alloc(50);
MPI m = mpi_alloc(50);
MPI res = mpi_alloc(50);
/* output = b/(a^x) mod p */
log_debug("invm %d times ", times);
for( ; times > 0; times -- ) {
mpi_fromstr(a, "0xef45678343589854354a4545545454554545455"
"aaaaaaaaaaaaa44444fffdecb33434343443331" );
mpi_fromstr(b, "0x8765765589854354a4545545454554545455"
"aaaaaaa466577778decb36666343443331" );
mpi_invm( t, a, b );
fputc('.', stderr); fflush(stderr);
}
mpi_fromstr( m, "0x10000000000000000000000000" );
base[0] = mpi_alloc_set_ui( 3 );
mpi_fromstr( base[0], "0x145984358945989898495ffdd13" );
base[1] = mpi_alloc_set_ui( 5 );
mpi_fromstr( base[1], "0x000effff9999000000001100001" );
base[2] = mpi_alloc_set_ui( 2 );
mpi_fromstr( base[2], "0x499eeeaaaaa0444444545466672" );
base[3] = NULL;
exp[0] = mpi_alloc_set_ui( 30 );
exp[1] = mpi_alloc_set_ui( 10 );
mpi_fromstr( exp[1], "0x3457878888888888aabbbccccc1" );
exp[2] = mpi_alloc_set_ui( 24 );
exp[3] = NULL;
mpi_powm( t1, base[0], exp[0], m );
mpi_powm( t2, base[1], exp[1], m );
mpi_powm( t3, base[2], exp[2], m );
mpi_mulm( tmp, t1, t2, m );
mpi_mulm( t1, tmp, t3, m );
log_mpidump("X=", t1 );
mpi_mulpowm( res, base, exp, m );
log_mpidump("X=", res );
m_check(NULL);
#endif
}

View file

@ -36,7 +36,6 @@ new_kbnode( PACKET *pkt )
KBNODE n = m_alloc( sizeof *n );
n->next = NULL;
n->pkt = pkt;
n->child = NULL;
n->flag = 0;
n->private_flag=0; /* kludge to delete a node */
return n;
@ -50,7 +49,6 @@ release_kbnode( KBNODE n )
while( n ) {
n2 = n->next;
release_kbnode( n->child );
free_packet( n->pkt );
m_free( n );
n = n2;
@ -60,7 +58,7 @@ release_kbnode( KBNODE n )
/****************
* Delete NODE from ROOT, ROOT must exist!
* Note does only work with walk_kbtree!!
* Note: This does only work with walk_kbnode!!
*/
void
delete_kbnode( KBNODE root, KBNODE node )
@ -82,56 +80,97 @@ add_kbnode( KBNODE root, KBNODE node )
}
/****************
* Append NODE to ROOT as child of ROOT
* Insert NODE into the list after root but before a packet with type PKTTYPE
* (only if PKTTYPE != 0)
*/
void
add_kbnode_as_child( KBNODE root, KBNODE node )
insert_kbnode( KBNODE root, KBNODE node, int pkttype )
{
KBNODE n1;
if( !(n1=root->child) )
root->child = node;
if( !pkttype ) {
node->next = root->next;
root->next = node;
}
else {
for( ; n1->next; n1 = n1->next)
;
KBNODE n1;
for(n1=root; n1->next; n1 = n1->next)
if( pkttype == n1->next->pkt->pkttype ) {
node->next = n1->next;
n1->next = node;
return;
}
/* no such packet, append */
node->next = NULL;
n1->next = node;
}
}
/****************
* Return the parent node of KBNODE from the tree with ROOT
* Find the previous node (if PKTTYPE = 0) or the previous node
* with pkttype PKTTYPE in the list starting with ROOT of NODE.
*/
KBNODE
find_kbparent( KBNODE root, KBNODE node )
find_prev_kbnode( KBNODE root, KBNODE node, int pkttype )
{
KBNODE n, n2;
KBNODE n1;
for( ; root; root = root->child) {
for( n = root; n; n = n->next) {
for( n2 = n->child; n2; n2 = n2->next ) {
if( n2 == node )
return n;
}
}
for(n1=NULL ; root && root != node; root = root->next )
if( !pkttype || root->pkt->pkttype == pkttype )
n1 = root;
return n1;
}
/****************
* Ditto, but find the next package. The behaviour is trivial if
* PKTTYPE is 0 but if it is specified, the next node with a packet
* of this type is returned. The function has some knowledge about
* the valid ordering of packets: e.g. if the next signature packet
* is requested, the function will not return one if it encounters
* a user-id.
*/
KBNODE
find_next_kbnode( KBNODE node, int pkttype )
{
for( node=node->next ; node; node = node->next ) {
if( !pkttype )
return node;
else if( pkttype == PKT_USER_ID
&& ( node->pkt->pkttype == PKT_PUBLIC_CERT
|| node->pkt->pkttype == PKT_SECRET_CERT ) )
return NULL;
else if( pkttype == PKT_SIGNATURE
&& ( node->pkt->pkttype == PKT_USER_ID
|| node->pkt->pkttype == PKT_PUBLIC_CERT
|| node->pkt->pkttype == PKT_SECRET_CERT ) )
return NULL;
else if( node->pkt->pkttype == pkttype )
return node;
}
return NULL;
}
KBNODE
find_kbnode( KBNODE node, int pkttype )
{
for( ; node; node = node->next ) {
if( node->pkt->pkttype == pkttype )
return node;
}
return NULL;
}
/****************
* Walk through a tree of kbnodes. This functions returns
* Walk through a list of kbnodes. This functions returns
* the next kbnode for each call; before using the function the first
* time, the caller must set CONTEXT to NULL (This has simply the effect
* to start with ROOT).
*/
KBNODE
walk_kbtree( KBNODE root, KBNODE *context )
{
return walk_kbtree2( root, context, 0 );
}
KBNODE
walk_kbtree2( KBNODE root, KBNODE *context, int all )
walk_kbnode( KBNODE root, KBNODE *context, int all )
{
KBNODE n;
@ -142,15 +181,7 @@ walk_kbtree2( KBNODE root, KBNODE *context, int all )
}
n = *context;
if( n->child ) {
n = n->child;
*context = n;
}
else if( n->next ) {
n = n->next;
*context = n;
}
else if( (n = find_kbparent( root, n )) ) {
if( n->next ) {
n = n->next;
*context = n;
}
@ -163,7 +194,6 @@ void
clear_kbnode_flags( KBNODE n )
{
for( ; n; n = n->next ) {
clear_kbnode_flags( n->child );
n->flag = 0;
}
}

View file

@ -37,9 +37,8 @@
typedef struct kbnode_struct *KBNODE;
struct kbnode_struct {
KBNODE next;
PACKET *pkt;
KBNODE next; /* used to form a link list */
KBNODE child;
int flag;
int private_flag;
};
@ -49,10 +48,9 @@ struct kbnode_struct {
* of a keyblock.
*/
struct keyblock_pos_struct {
int resno; /* resource number */
ulong offset; /* position information */
ulong length; /* length of thge keyblock */
int last_block;
int resno; /* resource number */
ulong offset; /* position information */
unsigned count; /* length of the keyblock in packets */
};
typedef struct keyblock_pos_struct KBPOS;
@ -130,10 +128,11 @@ KBNODE new_kbnode( PACKET *pkt );
void release_kbnode( KBNODE n );
void delete_kbnode( KBNODE root, KBNODE node );
void add_kbnode( KBNODE root, KBNODE node );
void add_kbnode_as_child( KBNODE root, KBNODE node );
KBNODE find_kbparent( KBNODE root, KBNODE node );
KBNODE walk_kbtree( KBNODE root, KBNODE *context );
KBNODE walk_kbtree2( KBNODE root, KBNODE *context, int all );
void insert_kbnode( KBNODE root, KBNODE node, int pkttype );
KBNODE find_prev_kbnode( KBNODE root, KBNODE node, int pkttype );
KBNODE find_next_kbnode( KBNODE node, int pkttype );
KBNODE find_kbnode( KBNODE node, int pkttype );
KBNODE walk_kbnode( KBNODE root, KBNODE *context, int all );
void clear_kbnode_flags( KBNODE n );
/*-- ringedit.c --*/

View file

@ -102,25 +102,19 @@ write_selfsig( KBNODE root, KBNODE pub_root, PKT_secret_cert *skc )
PKT_signature *sig;
PKT_user_id *uid;
int rc=0;
KBNODE kbctx, node;
KBNODE node;
PKT_public_cert *pkc;
if( opt.verbose )
log_info(_("writing self signature\n"));
/* get the uid packet from the tree */
for( kbctx=NULL; (node=walk_kbtree( root, &kbctx)) ; ) {
if( node->pkt->pkttype == PKT_USER_ID )
break;
}
/* get the uid packet from the list */
node = find_kbnode( root, PKT_USER_ID );
if( !node )
BUG(); /* no user id packet in tree */
uid = node->pkt->pkt.user_id;
/* get the pkc packet from the pub_tree */
for( kbctx=NULL; (node=walk_kbtree( pub_root, &kbctx)) ; ) {
if( node->pkt->pkttype == PKT_PUBLIC_CERT )
break;
}
node = find_kbnode( root, PKT_PUBLIC_CERT );
if( !node )
BUG();
pkc = node->pkt->pkt.public_cert;

View file

@ -110,13 +110,13 @@ add_secret_cert( CTX c, PACKET *pkt )
static int
add_user_id( CTX c, PACKET *pkt )
{
KBNODE node, n1, n2;
KBNODE node, n1;
if( !c->cert ) {
log_error("orphaned user id\n" );
return 0;
}
/* goto the last certificate (currently ther is only one) */
/* goto the last certificate */
for(n1=c->cert; n1->next; n1 = n1->next )
;
assert( n1->pkt );
@ -127,13 +127,7 @@ add_user_id( CTX c, PACKET *pkt )
}
/* add a new user id node at the end */
node = new_kbnode( pkt );
if( !(n2=n1->child) )
n1->child = node;
else {
for( ; n2->next; n2 = n2->next)
;
n2->next = node;
}
add_kbnode( n1, node );
return 1;
}
@ -147,49 +141,36 @@ add_signature( CTX c, PACKET *pkt )
/* This is the first signature for a following datafile.
* G10 does not write such packets, instead it always uses
* onepass-sig packets. The drawback of PGP's method
* of writing prepending the signtaure to the data is,
* that it is not possible to make a signature from data
* read from stdin. But we are able to read these stuff. */
* of prepending the signtaure to the data is,
* that it is not possible to make a signature from data read
* from stdin. (Anyway, G10 is are able to read these stuff) */
node = new_kbnode( pkt );
node->next = c->cert;
c->cert = node;
return 1;
}
else if( !c->cert )
return 0;
return 0; /* oops */
else if( !c->cert->pkt )
BUG();
else if( c->cert->pkt->pkttype == PKT_ONEPASS_SIG ) {
/* The root is a onepass signature, so we are signing data
* The childs direct under the root are the signatures
* (there is no need to keep the correct sequence of packets) */
/* The root is a onepass signature, so we are signing data */
node = new_kbnode( pkt );
node->next = c->cert->child;
c->cert->child = node;
add_kbnode( c->cert, node );
return 1;
}
else if( !c->cert->child ) {
log_error("orphaned signature (no userid)\n" );
return 0;
}
/* goto the last user id */
for(n1=c->cert->child; n1->next; n1 = n1->next )
;
assert( n1->pkt );
if( n1->pkt->pkttype != PKT_USER_ID ) {
log_error("invalid parent type %d for sig\n", n1->pkt->pkttype);
for(n2=NULL, n1=c->cert; n1->next; n1 = n1->next )
if( n1->pkt->pkttype == PKT_USER_ID )
n2 = n1;
if( !n2 ) {
log_error("no user id for signature packet\n");
return 0;
}
n1 = n2;
/* and add a new signature node id at the end */
node = new_kbnode( pkt );
if( !(n2=n1->child) )
n1->child = node;
else {
for( ; n2->next; n2 = n2->next)
;
n2->next = node;
}
insert_kbnode( n1, node, PKT_USER_ID );
return 1;
}
@ -333,10 +314,9 @@ do_check_sig( CTX c, KBNODE node )
}
else if( (sig->sig_class&~3) == 0x10 ) { /* classes 0x10 .. 0x13 */
if( c->cert->pkt->pkttype == PKT_PUBLIC_CERT ) {
KBNODE n1 = find_kbparent( c->cert, node );
if( n1 && n1->pkt->pkttype == PKT_USER_ID ) {
KBNODE n1 = find_prev_kbnode( c->cert, node, PKT_USER_ID );
if( n1 ) {
if( c->cert->pkt->pkt.public_cert->mfx.md )
md = md_copy( c->cert->pkt->pkt.public_cert->mfx.md );
else
@ -411,7 +391,7 @@ print_fingerprint( PKT_public_cert *pkc, PKT_secret_cert *skc )
static void
list_node( CTX c, KBNODE node )
{
register KBNODE n2;
int any=0;
if( !node )
;
@ -422,21 +402,19 @@ list_node( CTX c, KBNODE node )
pubkey_letter( pkc->pubkey_algo ),
(ulong)keyid_from_pkc( pkc, NULL ),
datestr_from_pkc( pkc ) );
n2 = node->child;
if( !n2 )
printf("ERROR: no user id!\n");
else {
/* and now list all userids with their signatures */
for( ; n2; n2 = n2->next ) {
if( n2 != node->child )
printf( "%*s", 31, "" );
print_userid( n2->pkt );
putchar('\n');
if( opt.fingerprint && n2 == node->child )
print_fingerprint( pkc, NULL );
list_node(c, n2 );
}
/* and now list all userids with their signatures */
while( (node = find_next_kbnode(node, PKT_USER_ID)) ) {
if( any )
printf( "%*s", 31, "" );
print_userid( node->pkt );
putchar('\n');
if( opt.fingerprint && !any )
print_fingerprint( pkc, NULL );
list_node(c, node );
any=1;
}
if( !any )
printf("ERROR: no user id!\n");
}
else if( node->pkt->pkttype == PKT_SECRET_CERT ) {
PKT_secret_cert *skc = node->pkt->pkt.secret_cert;
@ -445,20 +423,21 @@ list_node( CTX c, KBNODE node )
pubkey_letter( skc->pubkey_algo ),
(ulong)keyid_from_skc( skc, NULL ),
datestr_from_skc( skc ) );
n2 = node->child;
if( !n2 )
printf("ERROR: no user id!\n");
else {
print_userid( n2->pkt );
/* and now list all userids */
while( (node = find_next_kbnode(node, PKT_USER_ID)) ) {
print_userid( node->pkt );
putchar('\n');
if( opt.fingerprint && n2 == node->child )
if( opt.fingerprint && !any )
print_fingerprint( NULL, skc );
any=1;
}
if( !any )
printf("ERROR: no user id!\n");
}
else if( node->pkt->pkttype == PKT_USER_ID ) {
/* list everything under this user id */
for(n2=node->child; n2; n2 = n2->next )
list_node(c, n2 );
while( (node = find_next_kbnode(node, 0 )) )
list_node(c, node );
}
else if( node->pkt->pkttype == PKT_SIGNATURE ) {
PKT_signature *sig = node->pkt->pkt.signature;
@ -467,7 +446,6 @@ list_node( CTX c, KBNODE node )
char *p;
int sigrc = ' ';
assert( !node->child );
if( !opt.list_sigs )
return;
@ -626,31 +604,26 @@ proc_tree( CTX c, KBNODE node )
else if( node->pkt->pkttype == PKT_SECRET_CERT )
list_node( c, node );
else if( node->pkt->pkttype == PKT_ONEPASS_SIG ) {
if( !node->child )
log_error("proc_tree: onepass_sig without data\n");
else if( node->child->pkt->pkttype != PKT_SIGNATURE )
log_error("proc_tree: onepass_sig not followed by signature\n");
else { /* check all signatures */
if( !c->have_data ) {
free_md_filter_context( &c->mfx );
/* prepare to create all requested message digests */
c->mfx.md = md_open(0, 0);
for(n1=node->child; n1; n1 = n1->next ) {
md_enable( c->mfx.md,
digest_algo_from_sig(n1->pkt->pkt.signature));
}
/* ask for file and hash it */
rc = ask_for_detached_datafile( &c->mfx,
iobuf_get_fname(c->iobuf));
if( rc ) {
log_error("can't hash datafile: %s\n", g10_errstr(rc));
return;
}
/* check all signatures */
if( !c->have_data ) {
free_md_filter_context( &c->mfx );
/* prepare to create all requested message digests */
c->mfx.md = md_open(0, 0);
for( n1 = node; (n1 = find_next_kbnode(n1, PKT_SIGNATURE )); ) {
md_enable( c->mfx.md,
digest_algo_from_sig(n1->pkt->pkt.signature));
}
/* ask for file and hash it */
rc = ask_for_detached_datafile( &c->mfx,
iobuf_get_fname(c->iobuf));
if( rc ) {
log_error("can't hash datafile: %s\n", g10_errstr(rc));
return;
}
for(n1=node->child; n1; n1 = n1->next )
check_sig_and_print( c, n1 );
}
for( n1 = node; (n1 = find_next_kbnode(n1, PKT_SIGNATURE )); )
check_sig_and_print( c, n1 );
}
else if( node->pkt->pkttype == PKT_SIGNATURE ) {
PKT_signature *sig = node->pkt->pkt.signature;

View file

@ -221,6 +221,9 @@ int list_packets( IOBUF a );
int set_packet_list_mode( int mode );
int search_packet( IOBUF inp, PACKET *pkt, int pkttype, ulong *retpos );
int parse_packet( IOBUF inp, PACKET *ret_pkt);
int copy_all_packets( IOBUF inp, IOBUF out );
int copy_some_packets( IOBUF inp, IOBUF out, ulong stopoff );
int skip_some_packets( IOBUF inp, unsigned n );
/*-- build-packet.c --*/
int build_packet( IOBUF inp, PACKET *pkt );

View file

@ -37,7 +37,9 @@ static mpi_print_mode = 0;
static list_mode = 0;
static int parse( IOBUF inp, PACKET *pkt, int reqtype,
ulong *retpos, int *skip );
ulong *retpos, int *skip, IOBUF out, int do_skip );
static int copy_packet( IOBUF inp, IOBUF out, int pkttype,
unsigned long pktlen );
static void skip_packet( IOBUF inp, int pkttype, unsigned long pktlen );
static void skip_rest( IOBUF inp, unsigned long pktlen );
static int parse_publickey( IOBUF inp, int pkttype, unsigned long pktlen,
@ -51,7 +53,8 @@ static int parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen,
static int parse_user_id( IOBUF inp, int pkttype, unsigned long pktlen,
PACKET *packet );
static void parse_subkey( IOBUF inp, int pkttype, unsigned long pktlen );
static void parse_comment( IOBUF inp, int pkttype, unsigned long pktlen );
static int parse_comment( IOBUF inp, int pkttype, unsigned long pktlen,
PACKET *packet );
static void parse_trust( IOBUF inp, int pkttype, unsigned long pktlen );
static int parse_plaintext( IOBUF inp, int pkttype, unsigned long pktlen,
PACKET *pkt );
@ -116,13 +119,13 @@ parse_packet( IOBUF inp, PACKET *pkt )
int skip, rc;
do {
rc = parse( inp, pkt, 0, NULL, &skip );
rc = parse( inp, pkt, 0, NULL, &skip, NULL, 0 );
} while( skip );
return rc;
}
/****************
* Like parse packet, but do only return packet of the given type.
* Like parse packet, but do only return packets of the given type.
*/
int
search_packet( IOBUF inp, PACKET *pkt, int pkttype, ulong *retpos )
@ -130,20 +133,68 @@ search_packet( IOBUF inp, PACKET *pkt, int pkttype, ulong *retpos )
int skip, rc;
do {
rc = parse( inp, pkt, pkttype, retpos, &skip );
rc = parse( inp, pkt, pkttype, retpos, &skip, NULL, 0 );
} while( skip );
return rc;
}
/****************
* Copy all packets from INP to OUT, thereby removing unused spaces.
*/
int
copy_all_packets( IOBUF inp, IOBUF out )
{
PACKET pkt;
int skip, rc=0;
do {
init_packet(&pkt);
} while( !(rc = parse( inp, &pkt, 0, NULL, &skip, out, 0 )));
return rc;
}
/****************
* Copy some packets from INP to OUT, thereby removing unused spaces.
* Stop after at offset STOPoff (i.e. don't copy the packet at this offset)
*/
int
copy_some_packets( IOBUF inp, IOBUF out, ulong stopoff )
{
PACKET pkt;
int skip, rc=0;
do {
if( iobuf_tell(inp) >= stopoff )
return 0;
init_packet(&pkt);
} while( !(rc = parse( inp, &pkt, 0, NULL, &skip, out, 0 )) );
return rc;
}
/****************
* Skip over N packets
*/
int
skip_some_packets( IOBUF inp, unsigned n )
{
int skip, rc=0;
PACKET pkt;
for( ;n && !rc; n--) {
init_packet(&pkt);
rc = parse( inp, &pkt, 0, NULL, &skip, NULL, 1 );
}
return rc;
}
/****************
* Parse packet. Set the variable skip points to to 1 if the packet
* should be skipped; this is the case if either there is a
* requested packet type and the parsed packet doesn't match or the
* packet-type is 0, indicating deleted stuff.
* if OUT is not NULL, a special copymode is used.
*/
static int
parse( IOBUF inp, PACKET *pkt, int reqtype, ulong *retpos, int *skip )
parse( IOBUF inp, PACKET *pkt, int reqtype, ulong *retpos,
int *skip, IOBUF out, int do_skip )
{
int rc, c, ctb, pkttype, lenbytes;
unsigned long pktlen;
@ -206,7 +257,15 @@ parse( IOBUF inp, PACKET *pkt, int reqtype, ulong *retpos, int *skip )
}
}
if( !pkttype || (reqtype && pkttype != reqtype) ) {
if( out && pkttype ) {
if( iobuf_write( out, hdr, hdrlen ) == -1 )
rc = G10ERR_WRITE_FILE;
else
rc = copy_packet(inp, out, pkttype, pktlen );
return rc;
}
if( do_skip || !pkttype || (reqtype && pkttype != reqtype) ) {
skip_packet(inp, pkttype, pktlen);
*skip = 1;
return 0;
@ -245,7 +304,7 @@ parse( IOBUF inp, PACKET *pkt, int reqtype, ulong *retpos, int *skip )
parse_subkey(inp, pkttype, pktlen);
break;
case PKT_COMMENT:
parse_comment(inp, pkttype, pktlen);
rc = parse_comment(inp, pkttype, pktlen, pkt);
break;
case PKT_RING_TRUST:
parse_trust(inp, pkttype, pktlen);
@ -284,6 +343,37 @@ dump_hex_line( int c, int *i )
}
static int
copy_packet( IOBUF inp, IOBUF out, int pkttype, unsigned long pktlen )
{
int n;
char buf[100];
if( iobuf_in_block_mode(inp) ) {
while( (n = iobuf_read( inp, buf, 100 )) != -1 )
if( iobuf_write(out, buf, n ) )
return G10ERR_WRITE_FILE; /* write error */
}
else if( !pktlen && pkttype == PKT_COMPRESSED ) {
/* compressed packet, copy till EOF */
while( (n = iobuf_read( inp, buf, 100 )) != -1 )
if( iobuf_write(out, buf, n ) )
return G10ERR_WRITE_FILE; /* write error */
}
else {
for( ; pktlen; pktlen -= n ) {
n = pktlen > 100 ? 100 : pktlen;
n = iobuf_read( inp, buf, n );
if( n == -1 )
return G10ERR_READ_FILE;
if( iobuf_write(out, buf, n ) )
return G10ERR_WRITE_FILE; /* write error */
}
}
return 0;
}
static void
skip_packet( IOBUF inp, int pkttype, unsigned long pktlen )
{
@ -738,22 +828,29 @@ parse_subkey( IOBUF inp, int pkttype, unsigned long pktlen )
static void
parse_comment( IOBUF inp, int pkttype, unsigned long pktlen )
static int
parse_comment( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
{
byte *p;
packet->pkt.comment = m_alloc(sizeof *packet->pkt.comment + pktlen - 1);
packet->pkt.comment->len = pktlen;
p = packet->pkt.comment->data;
for( ; pktlen; pktlen--, p++ )
*p = iobuf_get_noeof(inp);
if( list_mode ) {
printf(":comment packet: \"" );
for( ; pktlen; pktlen-- ) {
int c;
c = iobuf_get_noeof(inp);
if( c >= ' ' && c <= 'z' )
putchar(c);
int n = packet->pkt.comment->len;
printf(":comment packet: \"");
for(p=packet->pkt.comment->data; n; p++, n-- ) {
if( *p >= ' ' && *p <= 'z' )
putchar(*p);
else
printf("\\x%02x", c );
printf("\\x%02x", *p );
}
printf("\"\n");
}
skip_rest(inp, pktlen);
return 0;
}
@ -765,33 +862,6 @@ parse_trust( IOBUF inp, int pkttype, unsigned long pktlen )
c = iobuf_get_noeof(inp);
if( list_mode )
printf(":trust packet: flag=%02x\n", c );
#if 0 /* fixme: depending on the context we have different interpretations*/
if( prev_packet_is_a_key_packet ) {
int ot = c & 7; /* ownertrust bits (for the key owner) */
!ot ? "undefined" :
ot == 1 ? "unknown" : /* we don't know the owner of this key */
ot == 2 ? "no" : /* usually we do not trust this key owner */
/* to sign other keys */
ot == 5 ? "usually" : /* usually we trust this key owner to sign */
ot == 6 ? "always" : /* always trust this key owner to sign */
ot == 7 ? "ultimate" : /* also present in the secret keyring */
"" /* reserved value */
if( c & (1<<5) )
"key is disabled"
if( c & (1<<7) )
"buckstop"
else if( prev_packet_is_user_is_packet ) {
int kl = c & 3; /* keylegit bits */
0 = "unknown, undefined, or uninitialized trust"
1 = "we do not trust this key's ownership"
2 = "we have marginal confidence of this key's ownership"
3 = "we completely trust this key's ownership."
if( c & 0x80 )
"warnonly"
else if( prev_packet_is_a_signature ) {
}
#endif
}

View file

@ -35,7 +35,6 @@
*
* - Delete a key block
*
* FIXME: Add backup stuff
* FIXME: Keep track of all nodes, so that a change is propagated
* to all nodes. (or use shallow copies and ref-counting?)
*/
@ -46,6 +45,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <assert.h>
#include "util.h"
#include "packet.h"
@ -75,8 +77,7 @@ static int keyring_search( PACKET *pkt, KBPOS *kbpos, IOBUF iobuf );
static int keyring_search2( PUBKEY_FIND_INFO info, KBPOS *kbpos,
const char *fname);
static int keyring_read( KBPOS *kbpos, KBNODE *ret_root );
static int keyring_insert( KBPOS *kbpos, KBNODE root );
static int keyring_delete( KBPOS *kbpos );
static int keyring_copy( KBPOS *kbpos, int mode, KBNODE root );
@ -308,7 +309,7 @@ insert_keyblock( KBPOS *kbpos, KBNODE root )
if( !check_pos(kbpos) )
return G10ERR_GENERAL;
rc = keyring_insert( kbpos, root );
rc = keyring_copy( kbpos, 1, root );
return rc;
}
@ -327,7 +328,7 @@ delete_keyblock( KBPOS *kbpos )
if( !check_pos(kbpos) )
return G10ERR_GENERAL;
rc = keyring_delete( kbpos );
rc = keyring_copy( kbpos, 2, NULL );
return rc;
}
@ -340,14 +341,11 @@ int
update_keyblock( KBPOS *kbpos, KBNODE root )
{
int rc;
KBPOS kbpos2;
/* we do it the simple way: */
memset( &kbpos2, 0, sizeof kbpos2 );
kbpos2.resno = kbpos->resno;
rc = insert_keyblock( &kbpos2, root );
if( !rc )
rc = delete_keyblock( kbpos );
if( !check_pos(kbpos) )
return G10ERR_GENERAL;
rc = keyring_copy( kbpos, 3, root );
return rc;
}
@ -451,20 +449,12 @@ keyring_search2( PUBKEY_FIND_INFO info, KBPOS *kbpos, const char *fname )
init_packet(&pkt);
save_mode = set_packet_list_mode(0);
#if 0
if( iobuf_seek( iobuf, 0 ) ) {
log_error("can't rewind keyring file: %s\n", g10_errstr(rc));
rc = G10ERR_KEYRING_OPEN;
goto leave;
}
#else
iobuf = iobuf_open( fname );
if( !iobuf ) {
log_error("can't open '%s'\n", fname );
rc = G10ERR_OPEN_FILE;
goto leave;
}
#endif
while( !(rc=search_packet(iobuf, &pkt, PKT_PUBLIC_CERT, &offset)) ) {
PKT_public_cert *pkc = pkt.pkt.public_cert;
@ -505,9 +495,8 @@ keyring_read( KBPOS *kbpos, KBNODE *ret_root )
int rc;
RESTBL *rentry;
KBNODE root = NULL;
KBNODE node, n1, n2;
IOBUF a;
u32 offset, last_offset;
int in_cert = 0;
if( !(rentry=check_pos(kbpos)) )
return G10ERR_GENERAL;
@ -526,77 +515,37 @@ keyring_read( KBPOS *kbpos, KBNODE *ret_root )
pkt = m_alloc( sizeof *pkt );
init_packet(pkt);
kbpos->count=0;
while( (rc=parse_packet(a, pkt)) != -1 ) {
if( rc ) { /* ignore errors */
if( rc != G10ERR_UNKNOWN_PACKET ) {
log_error("read_keyblock: read error: %s\n", g10_errstr(rc) );
rc = G10ERR_INV_KEYRING;
goto ready;
}
kbpos->count++;
free_packet( pkt );
continue;
}
if( root && ( pkt->pkttype == PKT_PUBLIC_CERT
|| pkt->pkttype == PKT_SECRET_CERT ) )
goto ready;
offset = iobuf_tell(a);
/* make a linked list of all packets */
switch( pkt->pkttype ) {
case PKT_PUBLIC_CERT:
case PKT_SECRET_CERT:
root = new_kbnode( pkt );
pkt = m_alloc( sizeof *pkt );
init_packet(pkt);
break;
case PKT_USER_ID:
if( !root ) {
log_error("read_keyblock: orphaned user id\n" );
rc = G10ERR_INV_KEYRING; /* or wrong kbpos */
if( in_cert )
goto ready;
}
offset = last_offset;
/* append the user id */
node = new_kbnode( pkt );
if( !(n1=root->child) )
root->child = node;
else {
for( ; n1->next; n1 = n1->next)
;
n1->next = node;
}
in_cert = 1;
default:
kbpos->count++;
if( !root )
root = new_kbnode( pkt );
else
add_kbnode( root, new_kbnode( pkt ) );
pkt = m_alloc( sizeof *pkt );
init_packet(pkt);
break;
case PKT_SIGNATURE:
if( !root ) {
log_error("read_keyblock: no root for signature\n" );
rc = G10ERR_INV_KEYRING; /* or wrong kbpos */
break;
}
if( !root->child ) {
log_error("read_keyblock: no userid for signature\n" );
rc = G10ERR_INV_KEYRING;
break;
}
/* goto the last user id */
for(n1=root->child; n1->next; n1 = n1->next )
;
/* append the signature node */
node = new_kbnode( pkt );
if( !(n2=n1->child) )
n1->child = node;
else {
for( ; n2->next; n2 = n2->next)
;
n2->next = node;
}
pkt = m_alloc( sizeof *pkt );
init_packet(pkt);
break;
default: /* ignore all other packets. FIXME: we should not do this */
free_packet( pkt );
break;
}
}
ready:
kbpos->last_block = rc == -1; /* flag, that this is the last block */
if( rc == -1 && root )
rc = 0;
@ -604,7 +553,6 @@ keyring_read( KBPOS *kbpos, KBNODE *ret_root )
release_kbnode( root );
else {
*ret_root = root;
kbpos->length = offset - kbpos->offset;
}
free_packet( pkt );
m_free( pkt );
@ -613,111 +561,175 @@ keyring_read( KBPOS *kbpos, KBNODE *ret_root )
}
/****************
* Insert the keyblock described by ROOT into the keyring described
* by KBPOS. This actually appends the data to the keyfile.
* Peromf insert/delete/update operation.
* mode 1 = insert
* 2 = delete
* 3 = update
*/
static int
keyring_insert( KBPOS *kbpos, KBNODE root )
keyring_copy( KBPOS *kbpos, int mode, KBNODE root )
{
RESTBL *rentry;
IOBUF fp;
KBNODE kbctx, node;
IOBUF fp, newfp;
int rc;
char *bakfname = NULL;
char *tmpfname = NULL;
if( !(rentry = check_pos( kbpos )) )
return G10ERR_GENERAL;
/* FIXME: we must close the file if it's already open, due to
* 2 reasons:
* - cannot open the same file twice on DOSish OSes
* - must sync with iobufs somehow
*/
/* open the file for append */
fp = iobuf_append( rentry->fname );
if( !fp ) {
log_error("can't append to '%s'\n", rentry->fname );
return G10ERR_OPEN_FILE;
}
/* open the source file */
fp = iobuf_open( rentry->fname );
if( mode == 1 && !fp && errno == ENOENT ) { /* no file yet */
KBNODE kbctx, node;
kbctx=NULL;
while( (node = walk_kbtree( root, &kbctx )) ) {
if( (rc = build_packet( fp, node->pkt )) ) {
log_error("build_packet(%d) failed: %s\n",
node->pkt->pkttype, g10_errstr(rc) );
/* insert: create a new file */
newfp = iobuf_create( rentry->fname );
if( !newfp ) {
log_error("%s: can't create: %s\n", rentry->fname, strerror(errno));
return G10ERR_OPEN_FILE;
}
kbctx=NULL;
while( (node = walk_kbnode( root, &kbctx, 0 )) ) {
if( (rc = build_packet( newfp, node->pkt )) ) {
log_error("build_packet(%d) failed: %s\n",
node->pkt->pkttype, g10_errstr(rc) );
iobuf_cancel(newfp);
return G10ERR_WRITE_FILE;
}
}
if( iobuf_close(newfp) ) {
log_error("%s: close failed: %s\n", rentry->fname, strerror(errno));
return G10ERR_CLOSE_FILE;
}
if( chmod( rentry->fname, S_IRUSR | S_IWUSR ) ) {
log_error("%s: chmod failed: %s\n",
rentry->fname, strerror(errno) );
return G10ERR_WRITE_FILE;
}
return 0;
}
iobuf_close(fp);
return 0;
}
static int
keyring_delete( KBPOS *kbpos )
{
RESTBL *rentry;
IOBUF fp;
int rc;
u32 len;
int ctb;
if( !(rentry = check_pos( kbpos )) )
return G10ERR_GENERAL;
/* open the file for read/write */
fp = iobuf_openrw( rentry->fname );
if( !fp ) {
log_error("can't open '%s' for writing\n", rentry->fname );
return G10ERR_OPEN_FILE;
log_error("%s: can't open: %s\n", rentry->fname, strerror(errno) );
rc = G10ERR_OPEN_FILE;
goto leave;
}
if( iobuf_seek( fp, kbpos->offset ) ) {
log_error("can't seek to %lu: %s\n", kbpos->offset, g10_errstr(rc));
/* create the new file */
bakfname = m_alloc( strlen( rentry->fname ) + 2 );
strcpy(stpcpy(bakfname,rentry->fname),"~");
tmpfname = m_alloc( strlen( rentry->fname ) + 5 );
strcpy(stpcpy(tmpfname,rentry->fname),".tmp");
newfp = iobuf_create( tmpfname );
if( !newfp ) {
log_error("%s: can't create: %s\n", tmpfname, strerror(errno) );
iobuf_close(fp);
return G10ERR_WRITE_FILE;
rc = G10ERR_OPEN_FILE;
goto leave;
}
len = kbpos->length;
assert( len < 100000 ); /* there is a bug somewhere */
/*log_debug("writing a dummy packet of length %lu\n", (ulong)len);*/
if( len < 2 )
BUG();
if( len < 256 ) {
ctb = 0x80;
len -= 2;
}
else if( len < 65536 ) {
ctb = 0x81;
len -= 3;
}
else {
ctb = 0x82;
len -= 5;
}
iobuf_put(fp, ctb );
if( ctb & 2 ) {
iobuf_put(fp, len >> 24 );
iobuf_put(fp, len >> 16 );
}
if( ctb & 3 )
iobuf_put(fp, len >> 8 );
if( iobuf_put(fp, len ) ) {
iobuf_close(fp);
return G10ERR_WRITE_FILE;
}
for( ; len; len-- )
if( iobuf_put(fp, 0xff ) ) {
if( mode == 1 ) { /* insert */
/* copy everything to the new file */
rc = copy_all_packets( fp, newfp );
if( rc != -1 ) {
log_error("%s: copy to %s failed: %s\n",
rentry->fname, tmpfname, g10_errstr(rc) );
iobuf_close(fp);
return G10ERR_WRITE_FILE;
iobuf_cancel(newfp);
goto leave;
}
rc = 0;
}
if( mode == 2 || mode == 3 ) { /* delete or update */
/* copy first part to the new file */
rc = copy_some_packets( fp, newfp, kbpos->offset );
if( rc ) { /* should never get EOF here */
log_error("%s: copy to %s failed: %s\n",
rentry->fname, tmpfname, g10_errstr(rc) );
iobuf_close(fp);
iobuf_cancel(newfp);
goto leave;
}
/* skip this keyblock */
assert( kbpos->count );
rc = skip_some_packets( fp, kbpos->count );
if( rc ) {
log_error("%s: skipping %u packets failed: %s\n",
rentry->fname, kbpos->count, g10_errstr(rc));
iobuf_close(fp);
iobuf_cancel(newfp);
goto leave;
}
}
if( mode == 1 || mode == 3 ) { /* insert or update */
KBNODE kbctx, node;
/* append the new data */
kbctx=NULL;
while( (node = walk_kbnode( root, &kbctx, 0 )) ) {
if( (rc = build_packet( newfp, node->pkt )) ) {
log_error("build_packet(%d) failed: %s\n",
node->pkt->pkttype, g10_errstr(rc) );
iobuf_close(fp);
iobuf_cancel(newfp);
rc = G10ERR_WRITE_FILE;
goto leave;
}
}
}
if( mode == 2 || mode == 3 ) { /* delete or update */
/* copy the rest */
rc = copy_all_packets( fp, newfp );
if( rc != -1 ) {
log_error("%s: copy to %s failed: %s\n",
rentry->fname, tmpfname, g10_errstr(rc) );
iobuf_close(fp);
iobuf_cancel(newfp);
goto leave;
}
rc = 0;
}
/* close both files */
iobuf_close(fp);
if( iobuf_close(newfp) ) {
log_error("%s: close failed: %s\n", tmpfname, strerror(errno) );
rc = G10ERR_CLOSE_FILE;
goto leave;
}
/* if the new file is a secring, restrict the permissions */
if( rentry->secret ) {
if( chmod( tmpfname, S_IRUSR | S_IWUSR ) ) {
log_error("%s: chmod failed: %s\n",
tmpfname, strerror(errno) );
rc = G10ERR_WRITE_FILE;
goto leave;
}
}
/* rename and make backup file */
if( rename( rentry->fname, bakfname ) ) {
log_error("%s: rename to %s failed: %s\n",
rentry->fname, bakfname, strerror(errno) );
rc = G10ERR_RENAME_FILE;
goto leave;
}
if( rename( tmpfname, rentry->fname ) ) {
log_error("%s: rename to %s failed: %s\n",
tmpfname, rentry->fname,strerror(errno) );
rc = G10ERR_RENAME_FILE;
goto leave;
}
return 0;
leave:
m_free(bakfname);
m_free(tmpfname);
return rc;
}

View file

@ -248,9 +248,9 @@ check_key_signature( KBNODE root, KBNODE node, int *is_selfsig )
if( (rc=check_digest_algo(algo)) )
return rc;
unode = find_kbparent( root, node );
unode = find_prev_kbnode( root, node, PKT_USER_ID );
if( unode && unode->pkt->pkttype == PKT_USER_ID ) {
if( unode ) {
PKT_user_id *uid = unode->pkt->pkt.user_id;
if( is_selfsig ) {

View file

@ -527,7 +527,7 @@ check_all_keysigs( KBNODE keyblock )
int no_key = 0;
int oth_err = 0;
for( kbctx=NULL; (node=walk_kbtree( keyblock, &kbctx)) ; ) {
for( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx, 0)) ; ) {
if( node->pkt->pkttype == PKT_SIGNATURE
&& (node->pkt->pkt.signature->sig_class&~3) == 0x10 ) {
PKT_signature *sig = node->pkt->pkt.signature;
@ -579,7 +579,7 @@ remove_keysigs( KBNODE keyblock, int all )
int count;
count = 0;
for( kbctx=NULL; (node=walk_kbtree( keyblock, &kbctx)) ; ) {
for( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx, 0)) ; ) {
if( ((node->flag & 7) || all )
&& node->pkt->pkttype == PKT_SIGNATURE
&& (node->pkt->pkt.signature->sig_class&~3) == 0x10 ) {
@ -625,7 +625,7 @@ remove_keysigs( KBNODE keyblock, int all )
if( !yes )
return 0;
for( kbctx=NULL; (node=walk_kbtree2( keyblock, &kbctx, 1)) ; ) {
for( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx, 1)) ; ) {
if( node->flag & 128)
delete_kbnode( keyblock, node );
}
@ -677,10 +677,7 @@ sign_key( const char *username, STRLIST locusr )
}
/* get the keyid from the keyblock */
for( kbctx=NULL; (node=walk_kbtree( keyblock, &kbctx)) ; ) {
if( node->pkt->pkttype == PKT_PUBLIC_CERT )
break;
}
node = find_kbnode( keyblock, PKT_PUBLIC_CERT );
if( !node ) {
log_error("Oops; public key not found anymore!\n");
rc = G10ERR_GENERAL;
@ -719,7 +716,7 @@ sign_key( const char *username, STRLIST locusr )
u32 akeyid[2];
keyid_from_skc( skc_rover->skc, akeyid );
for( kbctx=NULL; (node=walk_kbtree( keyblock, &kbctx)) ; ) {
for( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx, 0)) ; ) {
if( node->pkt->pkttype == PKT_SIGNATURE
&& (node->pkt->pkt.signature->sig_class&~3) == 0x10 ) {
if( akeyid[0] == node->pkt->pkt.signature->keyid[0]
@ -744,7 +741,7 @@ sign_key( const char *username, STRLIST locusr )
for( skc_rover = skc_list; skc_rover; skc_rover = skc_rover->next ) {
if( skc_rover->mark )
continue;
for( kbctx=NULL; (node=walk_kbtree( keyblock, &kbctx)) ; ) {
for( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx, 0)) ; ) {
if( node->pkt->pkttype == PKT_USER_ID ) {
if( sign_it_p( pkc, node->pkt->pkt.user_id ) ) {
PACKET *pkt;
@ -763,7 +760,7 @@ sign_key( const char *username, STRLIST locusr )
pkt = m_alloc_clear( sizeof *pkt );
pkt->pkttype = PKT_SIGNATURE;
pkt->pkt.signature = sig;
add_kbnode_as_child( node, new_kbnode( pkt ) );
insert_kbnode( node, new_kbnode(pkt), PKT_USER_ID );
}
}
}
@ -789,7 +786,7 @@ edit_keysigs( const char *username )
{
int rc = 0;
KBNODE keyblock = NULL;
KBNODE kbctx, node;
KBNODE node;
KBPOS kbpos;
PKT_public_cert *pkc;
u32 pkc_keyid[2];
@ -809,10 +806,7 @@ edit_keysigs( const char *username )
}
/* get the keyid from the keyblock */
for( kbctx=NULL; (node=walk_kbtree( keyblock, &kbctx)) ; ) {
if( node->pkt->pkttype == PKT_PUBLIC_CERT )
break;
}
node = find_kbnode( keyblock, PKT_PUBLIC_CERT );
if( !node ) {
log_error("Oops; public key not found anymore!\n");
rc = G10ERR_GENERAL;
@ -855,7 +849,7 @@ change_passphrase( const char *username )
{
int rc = 0;
KBNODE keyblock = NULL;
KBNODE kbctx, node;
KBNODE node;
KBPOS kbpos;
PKT_secret_cert *skc;
u32 skc_keyid[2];
@ -877,10 +871,7 @@ change_passphrase( const char *username )
}
/* get the keyid from the keyblock */
for( kbctx=NULL; (node=walk_kbtree( keyblock, &kbctx)) ; ) {
if( node->pkt->pkttype == PKT_SECRET_CERT )
break;
}
node = find_kbnode( keyblock, PKT_SECRET_CERT );
if( !node ) {
log_error("Oops; secret key not found anymore!\n");
rc = G10ERR_GENERAL;

View file

@ -1090,7 +1090,7 @@ check_sigs( KBNODE keyblock, int *selfsig_okay )
LOCAL_ID_INFO *dups = NULL;
*selfsig_okay = 0;
for( kbctx=NULL; (node=walk_kbtree( keyblock, &kbctx)) ; ) {
for( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx,0)) ; ) {
if( node->pkt->pkttype == PKT_SIGNATURE
&& (node->pkt->pkt.signature->sig_class&~3) == 0x10 ) {
int selfsig;
@ -1190,7 +1190,7 @@ build_sigrecs( ulong pubkeyid )
rec.rectype = RECTYPE_SIG;
i = 0;
rnum = rnum2 = 0;
for( kbctx=NULL; (node=walk_kbtree( keyblock, &kbctx)) ; ) {
for( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx, 0)) ; ) {
/* insert sigs which are not a selfsig nor a duplicate */
if( (node->flag & 1) && !(node->flag & 4) ) {
assert( node->pkt->pkttype == PKT_SIGNATURE );