aboutsummaryrefslogtreecommitdiffstats
path: root/g10/ringedit.c
diff options
context:
space:
mode:
Diffstat (limited to 'g10/ringedit.c')
-rw-r--r--g10/ringedit.c75
1 files changed, 70 insertions, 5 deletions
diff --git a/g10/ringedit.c b/g10/ringedit.c
index 10aa7c947..f1b18d24d 100644
--- a/g10/ringedit.c
+++ b/g10/ringedit.c
@@ -53,6 +53,7 @@
#include "mpi.h"
#include "iobuf.h"
#include "keydb.h"
+#include <unistd.h> /* for truncate */
struct resource_table_struct {
@@ -383,6 +384,7 @@ keyring_read( KBPOS *kbpos, KBNODE *ret_root )
KBNODE root = NULL;
KBNODE node, n1, n2;
IOBUF a;
+ u32 offset, last_offset;
if( !(rentry=check_pos(kbpos)) )
return G10ERR_GENERAL;
@@ -399,7 +401,6 @@ keyring_read( KBPOS *kbpos, KBNODE *ret_root )
return G10ERR_KEYRING_OPEN;
}
-
pkt = m_alloc( sizeof *pkt );
init_packet(pkt);
while( (rc=parse_packet(a, pkt)) != -1 ) {
@@ -407,11 +408,13 @@ keyring_read( KBPOS *kbpos, KBNODE *ret_root )
free_packet( pkt );
continue;
}
+ if( root && ( pkt->pkttype == PKT_PUBLIC_CERT
+ || pkt->pkttype == PKT_SECRET_CERT ) )
+ goto ready;
+ offset = iobuf_tell(a);
switch( pkt->pkttype ) {
case PKT_PUBLIC_CERT:
case PKT_SECRET_CERT:
- if( root )
- goto ready;
root = new_kbnode( pkt );
pkt = m_alloc( sizeof *pkt );
init_packet(pkt);
@@ -423,6 +426,7 @@ keyring_read( KBPOS *kbpos, KBNODE *ret_root )
rc = G10ERR_INV_KEYRING; /* or wrong kbpos */
goto ready;
}
+ offset = last_offset;
/* append the user id */
node = new_kbnode( pkt );
if( !(n1=root->child) )
@@ -477,7 +481,7 @@ keyring_read( KBPOS *kbpos, KBNODE *ret_root )
release_kbnode( root );
else {
*ret_root = root;
- kbpos->length = iobuf_tell( a ) - kbpos->offset;
+ kbpos->length = offset - kbpos->offset;
}
free_packet( pkt );
m_free( pkt );
@@ -529,7 +533,68 @@ keyring_insert( KBPOS *kbpos, KBNODE root )
static int
keyring_delete( KBPOS *kbpos )
{
- return -1;
+ RESTBL *rentry;
+ IOBUF fp;
+ KBNODE kbctx, node;
+ 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;
+ }
+
+ if( iobuf_seek( fp, kbpos->offset ) ) {
+ log_error("can't seek to %lu: %s\n", kbpos->offset, g10_errstr(rc));
+ iobuf_close(fp);
+ return G10ERR_WRITE_FILE;
+ }
+
+ len = kbpos->length;
+ log_debug("writing a dummy packet of length %lu\n", (ulong)len);
+
+ if( len < 2 )
+ log_bug(NULL);
+
+ 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 ) ) {
+ iobuf_close(fp);
+ return G10ERR_WRITE_FILE;
+ }
+
+ iobuf_close(fp);
+
+ return 0;
}