mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
Sicherung
This commit is contained in:
parent
5c1cca042e
commit
cccf1efa4b
9
TODO
9
TODO
@ -6,7 +6,6 @@
|
||||
function of iobuf.
|
||||
* filter all output read from the input when displaying it to the user.
|
||||
* keyring editing
|
||||
* remove some debugging stuff (e.g. the listing mode in mainproc)
|
||||
* add trust stuff
|
||||
* make ttyio.c work (hide passwords etc..)
|
||||
* add detached signatures
|
||||
@ -24,3 +23,11 @@
|
||||
* add signal handling
|
||||
* enable a SIGSEGV handler while using zlib functions
|
||||
|
||||
* PGP writes the signature and then the file, this is not
|
||||
a good idea, we can't write such files if we take input rom stdin.
|
||||
So the solution will: accept such packet, but write
|
||||
signature the corret way: first the data and then the signature[s]
|
||||
this is much easier to check, also we must read the entire data
|
||||
before we can check wether we have the pubkey or not. The one-pass
|
||||
signature packets should be implemented to avoid this.
|
||||
|
||||
|
@ -44,6 +44,7 @@ static int do_plaintext( IOBUF out, int ctb, PKT_plaintext *pt );
|
||||
static int do_encrypted( IOBUF out, int ctb, PKT_encrypted *ed );
|
||||
static int do_compressed( IOBUF out, int ctb, PKT_compressed *cd );
|
||||
static int do_signature( IOBUF out, int ctb, PKT_signature *sig );
|
||||
static int do_onepass_sig( IOBUF out, int ctb, PKT_onepass_sig *ops );
|
||||
|
||||
static int calc_header_length( u32 len );
|
||||
static int write_16(IOBUF inp, u16 a);
|
||||
@ -95,6 +96,9 @@ build_packet( IOBUF out, PACKET *pkt )
|
||||
case PKT_SIGNATURE:
|
||||
rc = do_signature( out, ctb, pkt->pkt.signature );
|
||||
break;
|
||||
case PKT_ONEPASS_SIG:
|
||||
rc = do_onepass_sig( out, ctb, pkt->pkt.onepass_sig );
|
||||
break;
|
||||
case PKT_RING_TRUST:
|
||||
default:
|
||||
log_bug("invalid packet type in build_packet()");
|
||||
@ -124,6 +128,7 @@ calc_packet_length( PACKET *pkt )
|
||||
case PKT_PUBKEY_ENC:
|
||||
case PKT_ENCRYPTED:
|
||||
case PKT_SIGNATURE:
|
||||
case PKT_ONEPASS_SIG:
|
||||
case PKT_RING_TRUST:
|
||||
case PKT_COMPRESSED:
|
||||
default:
|
||||
@ -398,6 +403,30 @@ do_signature( IOBUF out, int ctb, PKT_signature *sig )
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
do_onepass_sig( IOBUF out, int ctb, PKT_onepass_sig *ops )
|
||||
{
|
||||
int rc = 0;
|
||||
IOBUF a = iobuf_temp();
|
||||
|
||||
write_version( a, ctb );
|
||||
iobuf_put(a, ops->sig_class );
|
||||
iobuf_put(a, ops->digest_algo );
|
||||
iobuf_put(a, ops->pubkey_algo );
|
||||
write_32(a, ops->keyid[0] );
|
||||
write_32(a, ops->keyid[1] );
|
||||
iobuf_put(a, ops->last );
|
||||
|
||||
write_header(out, ctb, iobuf_get_temp_length(a) );
|
||||
if( iobuf_write_temp( out, a ) )
|
||||
rc = G10ERR_WRITE_FILE;
|
||||
|
||||
leave:
|
||||
iobuf_close(a);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
write_16(IOBUF out, u16 a)
|
||||
{
|
||||
|
@ -230,7 +230,7 @@ main( int argc, char **argv )
|
||||
case aSign: /* sign the given file */
|
||||
if( argc > 1 )
|
||||
usage(1);
|
||||
if( (rc = sign_file(fname, 0, locusr)) )
|
||||
if( (rc = sign_file(fname, opt.detached_sig, locusr)) )
|
||||
log_error("sign_file('%s'): %s\n", fname_print, g10_errstr(rc) );
|
||||
break;
|
||||
|
||||
|
@ -75,6 +75,7 @@ typedef struct {
|
||||
|
||||
|
||||
static void list_node( CTX c, NODE node );
|
||||
static void proc_tree( CTX c, NODE node );
|
||||
|
||||
static int
|
||||
pubkey_letter( int algo )
|
||||
@ -142,12 +143,31 @@ release_cert( CTX c )
|
||||
{
|
||||
if( !c->cert )
|
||||
return;
|
||||
list_node(c, c->cert );
|
||||
proc_tree(c, c->cert );
|
||||
release_node( c->cert );
|
||||
c->cert = NULL;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
add_onepass_sig( CTX c, PACKET *pkt )
|
||||
{
|
||||
if( c->cert ) { /* add another packet */
|
||||
NODE node;
|
||||
|
||||
if( c->cert->pkt->pkttype != PKT_ONEPASS_SIG ) {
|
||||
log_error("add_onepass_sig: another packet is in the way\n");
|
||||
release_cert( c );
|
||||
}
|
||||
node = new_node( pkt );
|
||||
node->next = c->cert;
|
||||
c->cert = node;
|
||||
}
|
||||
else /* insert the first one */
|
||||
c->cert = new_node( pkt );
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
add_public_cert( CTX c, PACKET *pkt )
|
||||
@ -205,10 +225,24 @@ add_signature( CTX c, PACKET *pkt )
|
||||
NODE node, n1, n2;
|
||||
|
||||
if( !c->cert ) {
|
||||
log_error("orphaned signature (no certificate)\n" );
|
||||
/* orphaned signature (no certificate)
|
||||
* this is the first signature for a following datafile
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
assert( c->cert->pkt );
|
||||
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)
|
||||
*/
|
||||
node = new_node( pkt );
|
||||
node->next = c->cert->child;
|
||||
c->cert->child = node;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
if( !c->cert->child ) {
|
||||
log_error("orphaned signature (no userid)\n" );
|
||||
return 0;
|
||||
@ -531,6 +565,7 @@ proc_packets( IOBUF a )
|
||||
case PKT_ENCRYPTED: proc_encrypted( c, pkt ); break;
|
||||
case PKT_PLAINTEXT: proc_plaintext( c, pkt ); break;
|
||||
case PKT_COMPRESSED: proc_compressed( c, pkt ); break;
|
||||
case PKT_ONEPASS_SIG: newpkt = add_onepass_sig( c, pkt ); break;
|
||||
default: newpkt = 0; break;
|
||||
}
|
||||
if( newpkt == -1 )
|
||||
@ -553,3 +588,61 @@ proc_packets( IOBUF a )
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
print_keyid( FILE *fp, u32 *keyid )
|
||||
{
|
||||
size_t n;
|
||||
char *p = get_user_id( keyid, &n );
|
||||
print_string( fp, p, n );
|
||||
m_free(p);
|
||||
}
|
||||
|
||||
/****************
|
||||
* Preocess the tree which starts at node
|
||||
*/
|
||||
static void
|
||||
proc_tree( CTX c, NODE node )
|
||||
{
|
||||
NODE n1;
|
||||
int rc;
|
||||
|
||||
if( node->pkt->pkttype == PKT_PUBLIC_CERT )
|
||||
list_node( c, 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 followin data\n");
|
||||
else if( node->child->pkt->pkttype != PKT_SIGNATURE )
|
||||
log_error("proc_tree: onepass_sig not followed by signature\n");
|
||||
else { /* check all signature */
|
||||
for(n1=node->child; n1; n1 = n1->next ) {
|
||||
PKT_signature *sig = n1->pkt->pkt.signature;
|
||||
|
||||
rc = do_check_sig(c, n1 );
|
||||
if( !rc ) {
|
||||
log_info("Good signature from ");
|
||||
print_keyid( stderr, sig->keyid );
|
||||
putc('\n', stderr);
|
||||
}
|
||||
else if( rc == G10ERR_BAD_SIGN ) {
|
||||
log_error("BAD signature from ");
|
||||
print_keyid( stderr, sig->keyid );
|
||||
putc('\n', stderr);
|
||||
}
|
||||
else
|
||||
log_error("Can't check signature made by %08lX: %s\n",
|
||||
sig->keyid[1], g10_errstr(rc) );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( node->pkt->pkttype == PKT_SIGNATURE ) {
|
||||
log_info("proc_tree: old style signature\n");
|
||||
}
|
||||
else
|
||||
log_error("proc_tree: invalid root packet\n");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
16
g10/packet.h
16
g10/packet.h
@ -63,6 +63,15 @@ typedef struct {
|
||||
} PKT_pubkey_enc;
|
||||
|
||||
|
||||
typedef struct {
|
||||
u32 keyid[2]; /* 64 bit keyid */
|
||||
byte sig_class; /* sig classification */
|
||||
byte digest_algo; /* algorithm used for digest */
|
||||
byte pubkey_algo; /* algorithm used for public key scheme */
|
||||
byte last; /* a stupid flag */
|
||||
} PKT_onepass_sig;
|
||||
|
||||
|
||||
typedef struct {
|
||||
u32 keyid[2]; /* 64 bit keyid */
|
||||
u32 timestamp; /* signature made */
|
||||
@ -182,12 +191,10 @@ typedef struct {
|
||||
/* combine all packets into a union */
|
||||
struct packet_struct {
|
||||
pkttype_t pkttype;
|
||||
PKT_public_cert *pkc_parent; /* the pubkey to which it belongs */
|
||||
PKT_secret_cert *skc_parent; /* the seckey to which it belongs */
|
||||
PKT_user_id *user_parent; /* the user_id to which it belongs */
|
||||
union {
|
||||
void *generic;
|
||||
PKT_pubkey_enc *pubkey_enc; /* PKT_PUBKEY_ENC */
|
||||
PKT_onepass_sig *onepass_sig; /* PKT_ONEPASS_SIG */
|
||||
PKT_signature *signature; /* PKT_SIGNATURE */
|
||||
PKT_public_cert *public_cert; /* PKT_PUBLIC_CERT */
|
||||
PKT_secret_cert *secret_cert; /* PKT_SECRET_CERT */
|
||||
@ -200,9 +207,6 @@ struct packet_struct {
|
||||
};
|
||||
|
||||
#define init_packet(a) do { (a)->pkttype = 0; \
|
||||
(a)->pkc_parent = NULL; \
|
||||
(a)->skc_parent = NULL; \
|
||||
(a)->user_parent = NULL; \
|
||||
(a)->pkt.generic = NULL; \
|
||||
} while(0)
|
||||
|
||||
|
@ -42,6 +42,8 @@ static int parse_publickey( IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
PACKET *packet );
|
||||
static int parse_signature( IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
PKT_signature *sig );
|
||||
static int parse_onepass_sig( IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
PKT_onepass_sig *ops );
|
||||
static int parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
byte *hdr, int hdrlen, PACKET *packet );
|
||||
static int parse_user_id( IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
@ -159,6 +161,10 @@ parse_packet( IOBUF inp, PACKET *pkt )
|
||||
pkt->pkt.signature = m_alloc_clear(sizeof *pkt->pkt.signature );
|
||||
rc = parse_signature(inp, pkttype, pktlen, pkt->pkt.signature );
|
||||
break;
|
||||
case PKT_ONEPASS_SIG:
|
||||
pkt->pkt.onepass_sig = m_alloc_clear(sizeof *pkt->pkt.onepass_sig );
|
||||
rc = parse_onepass_sig(inp, pkttype, pktlen, pkt->pkt.onepass_sig );
|
||||
break;
|
||||
case PKT_USER_ID:
|
||||
rc = parse_user_id(inp, pkttype, pktlen, pkt );
|
||||
break;
|
||||
@ -340,6 +346,42 @@ parse_signature( IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
parse_onepass_sig( IOBUF inp, int pkttype, unsigned long pktlen,
|
||||
PKT_onepass_sig *ops )
|
||||
{
|
||||
int version;
|
||||
unsigned n;
|
||||
|
||||
if( pktlen < 13 ) {
|
||||
log_error("packet(%d) too short\n", pkttype);
|
||||
goto leave;
|
||||
}
|
||||
version = iobuf_get_noeof(inp); pktlen--;
|
||||
if( version != 3 ) {
|
||||
log_error("onepass_sig with unknown version %d\n", version);
|
||||
goto leave;
|
||||
}
|
||||
ops->sig_class = iobuf_get_noeof(inp); pktlen--;
|
||||
ops->digest_algo = iobuf_get_noeof(inp); pktlen--;
|
||||
ops->pubkey_algo = iobuf_get_noeof(inp); pktlen--;
|
||||
ops->keyid[0] = read_32(inp); pktlen -= 4;
|
||||
ops->keyid[1] = read_32(inp); pktlen -= 4;
|
||||
ops->last = iobuf_get_noeof(inp); pktlen--;
|
||||
if( list_mode )
|
||||
printf(":onepass_sig packet: keyid %08lX%08lX\n"
|
||||
"\tversion %d, sigclass %02x, digest %d, pubkey %d, last=%d\n",
|
||||
ops->keyid[0], ops->keyid[1],
|
||||
version, ops->sig_class,
|
||||
ops->digest_algo, ops->pubkey_algo, ops->last );
|
||||
|
||||
|
||||
leave:
|
||||
skip_rest(inp, pktlen);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static int
|
||||
|
@ -283,7 +283,7 @@ iobuf_cancel( IOBUF a )
|
||||
{
|
||||
const char *s;
|
||||
|
||||
if( a->usage == 2 ) {
|
||||
if( a && a->usage == 2 ) {
|
||||
s = iobuf_get_fname(a);
|
||||
if( s && *s )
|
||||
remove(s); /* remove the file. Fixme: this will fail for MSDOZE*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user