mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-02 22:46:30 +02:00
can create v4 signatures
This commit is contained in:
parent
69cf10ffab
commit
0e5a31d7be
42 changed files with 1101 additions and 325 deletions
|
@ -1,3 +1,29 @@
|
|||
Wed May 13 11:48:27 1998 Werner Koch (wk@isil.d.shuttle.de)
|
||||
|
||||
* build-packet.c (do_signature): Support for v4 pakets.
|
||||
* keyedit.c (make_keysig_packet): Ditto.
|
||||
* build-packet.c (build_sig_subpkt_from_sig): New.
|
||||
(build_sig_subpkt): New.
|
||||
|
||||
* elg.c (g10_elg_sign): removed keyid_from_skc.
|
||||
* dsa.c (g10_dsa_sign): Ditto.
|
||||
* rsa.c (g10_rsa_sign): Ditto.
|
||||
* keyedit.c (make_keysig_packet): Add call to keyid_from_skc
|
||||
|
||||
* sign.c (clearsign_file): Support for v4 signatures.
|
||||
(sign_file): Ditto.
|
||||
|
||||
Wed May 6 09:31:24 1998 Werner Koch (wk@isil.d.shuttle.de)
|
||||
|
||||
* parse-packet.c (do_parse): add support for 5 byte length leader.
|
||||
(parse_subpkt): Ditto.
|
||||
* build-packet.c (write_new_header): Ditto.
|
||||
|
||||
* packet.h (SIGSUBPKT_): New constants.
|
||||
* parse-packet.c (parse_sig_subpkt): Changed name, made global,
|
||||
and arg to return packet length, chnaged all callers
|
||||
|
||||
|
||||
Tue May 5 22:11:59 1998 Werner Koch (wk@isil.d.shuttle.de)
|
||||
|
||||
* keygen.c (gen_dsa): New.
|
||||
|
|
|
@ -225,11 +225,11 @@ hash_public_cert( MD_HANDLE md, PKT_public_cert *pkc )
|
|||
int rc = 0;
|
||||
int c;
|
||||
IOBUF a = iobuf_temp();
|
||||
#if 0
|
||||
#if 1
|
||||
FILE *fp = fopen("dump.pkc", "a");
|
||||
int i=0;
|
||||
|
||||
fprintf(fp, "\nHashing PKC:\n");
|
||||
fprintf(fp, "\nHashing PKC (v%d):\n", pkc->version);
|
||||
#endif
|
||||
|
||||
/* build the packet */
|
||||
|
@ -239,7 +239,7 @@ hash_public_cert( MD_HANDLE md, PKT_public_cert *pkc )
|
|||
if( (rc = build_packet( a, &pkt )) )
|
||||
log_fatal("build public_cert for hashing failed: %s\n", g10_errstr(rc));
|
||||
while( (c=iobuf_get(a)) != -1 ) {
|
||||
#if 0
|
||||
#if 1
|
||||
fprintf( fp," %02x", c );
|
||||
if( (++i == 24) ) {
|
||||
putc('\n', fp);
|
||||
|
@ -248,7 +248,7 @@ hash_public_cert( MD_HANDLE md, PKT_public_cert *pkc )
|
|||
#endif
|
||||
md_putc( md, c );
|
||||
}
|
||||
#if 0
|
||||
#if 1
|
||||
putc('\n', fp);
|
||||
fclose(fp);
|
||||
#endif
|
||||
|
@ -480,6 +480,169 @@ do_compressed( IOBUF out, int ctb, PKT_compressed *cd )
|
|||
}
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* Find a subpacket of type REQTYPE in BUFFER and a return a pointer
|
||||
* to the first byte of that subpacket data.
|
||||
* And return the length of the packet in RET_N and the number of
|
||||
* header bytes in RET_HLEN (length header and type byte).
|
||||
*/
|
||||
byte *
|
||||
find_subpkt( byte *buffer, sigsubpkttype_t reqtype,
|
||||
size_t *ret_hlen, size_t *ret_n )
|
||||
{
|
||||
int buflen;
|
||||
sigsubpkttype_t type;
|
||||
byte *bufstart;
|
||||
size_t n;
|
||||
|
||||
if( !buffer )
|
||||
return NULL;
|
||||
buflen = (*buffer << 8) | buffer[1];
|
||||
buffer += 2;
|
||||
for(;;) {
|
||||
if( !buflen )
|
||||
return NULL; /* end of packets; not found */
|
||||
bufstart = buffer;
|
||||
n = *buffer++; buflen--;
|
||||
if( n == 255 ) {
|
||||
if( buflen < 4 )
|
||||
break;
|
||||
n = (buffer[0] << 24) | (buffer[1] << 16)
|
||||
| (buffer[2] << 8) | buffer[3];
|
||||
buffer += 4;
|
||||
buflen -= 4;
|
||||
}
|
||||
else if( n >= 192 ) {
|
||||
if( buflen < 2 )
|
||||
break;
|
||||
n = (( n - 192 ) << 8) + *buffer + 192;
|
||||
buflen--;
|
||||
}
|
||||
if( buflen < n )
|
||||
break;
|
||||
type = *buffer & 0x7f;
|
||||
if( type == reqtype ) {
|
||||
buffer++;
|
||||
n--;
|
||||
if( n > buflen )
|
||||
break;
|
||||
if( ret_hlen )
|
||||
*ret_hlen = buffer - bufstart;
|
||||
if( ret_n )
|
||||
*ret_n = n;
|
||||
return buffer;
|
||||
}
|
||||
buffer += n; buflen -=n;
|
||||
}
|
||||
|
||||
log_error("find_subpkt: buffer shorter than subpacket\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Create or update a signature subpacket for SIG of TYPE.
|
||||
* This functions know, where to put the data (hashed or unhashed).
|
||||
* The function may move data from the unhased part to the hashed one.
|
||||
* Note: All pointers into sig->[un]hashed are not valid after a call
|
||||
* to this function. The data to but into the subpaket should be
|
||||
* in buffer with a length of buflen.
|
||||
*/
|
||||
void
|
||||
build_sig_subpkt( PKT_signature *sig, sigsubpkttype_t type,
|
||||
const byte *buffer, size_t buflen )
|
||||
{
|
||||
|
||||
byte *data;
|
||||
size_t hlen, dlen;
|
||||
int found, hashed, realloced;
|
||||
size_t n, n0;
|
||||
|
||||
if( (data = find_subpkt( sig->hashed_data, type, &hlen, &dlen )) )
|
||||
found = 1;
|
||||
else if( (data = find_subpkt( sig->unhashed_data, type, &hlen, &dlen )))
|
||||
found = 2;
|
||||
else
|
||||
found = 0;
|
||||
|
||||
if( found )
|
||||
log_bug("build_sig_packet: update nyi\n");
|
||||
if( buflen+1 >= 192 )
|
||||
log_bug("build_sig_packet: long subpackets are nyi\n");
|
||||
|
||||
switch( type ) {
|
||||
case SIGSUBPKT_SIG_CREATED:
|
||||
hashed = 1; break;
|
||||
default: hashed = 0; break;
|
||||
}
|
||||
|
||||
if( hashed ) {
|
||||
n0 = sig->hashed_data ? ((*sig->hashed_data << 8)
|
||||
| sig->hashed_data[1]) : 0;
|
||||
n = n0 + 1 + 1 + buflen; /* length, type, buffer */
|
||||
realloced = !!sig->hashed_data;
|
||||
data = sig->hashed_data ? m_realloc( sig->hashed_data, n+2 )
|
||||
: m_alloc( n+2 );
|
||||
}
|
||||
else {
|
||||
n0 = sig->unhashed_data ? ((*sig->unhashed_data << 8)
|
||||
| sig->unhashed_data[1]) : 0;
|
||||
n = n0 + 1 + 1 + buflen; /* length, type, buffer */
|
||||
realloced = !!sig->unhashed_data;
|
||||
data = sig->unhashed_data ? m_realloc( sig->unhashed_data, n+2 )
|
||||
: m_alloc( n+2 );
|
||||
}
|
||||
|
||||
data[n0+0] = (n >> 8) & 0xff;
|
||||
data[n0+1] = n & 0xff;
|
||||
data[n0+2] = buflen+1;
|
||||
data[n0+3] = type;
|
||||
memcpy(data+n0+4, buffer, buflen );
|
||||
|
||||
if( hashed ) {
|
||||
if( !realloced )
|
||||
m_free(sig->hashed_data);
|
||||
sig->hashed_data = data;
|
||||
}
|
||||
else {
|
||||
if( !realloced )
|
||||
m_free(sig->unhashed_data);
|
||||
sig->unhashed_data = data;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Put all the required stuff from SIG into subpackets of sig.
|
||||
*/
|
||||
void
|
||||
build_sig_subpkt_from_sig( PKT_signature *sig )
|
||||
{
|
||||
u32 u;
|
||||
byte buf[8];
|
||||
|
||||
u = sig->keyid[0];
|
||||
buf[0] = (u >> 24) & 0xff;
|
||||
buf[1] = (u >> 16) & 0xff;
|
||||
buf[2] = (u >> 8) & 0xff;
|
||||
buf[3] = u & 0xff;
|
||||
u = sig->keyid[1];
|
||||
buf[4] = (u >> 24) & 0xff;
|
||||
buf[5] = (u >> 16) & 0xff;
|
||||
buf[6] = (u >> 8) & 0xff;
|
||||
buf[7] = u & 0xff;
|
||||
build_sig_subpkt( sig, SIGSUBPKT_ISSUER, buf, 8 );
|
||||
|
||||
u = sig->timestamp;
|
||||
buf[0] = (u >> 24) & 0xff;
|
||||
buf[1] = (u >> 16) & 0xff;
|
||||
buf[2] = (u >> 8) & 0xff;
|
||||
buf[3] = u & 0xff;
|
||||
build_sig_subpkt( sig, SIGSUBPKT_SIG_CREATED, buf, 4 );
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
do_signature( IOBUF out, int ctb, PKT_signature *sig )
|
||||
{
|
||||
|
@ -501,8 +664,20 @@ do_signature( IOBUF out, int ctb, PKT_signature *sig )
|
|||
iobuf_put(a, sig->pubkey_algo );
|
||||
iobuf_put(a, sig->digest_algo );
|
||||
if( sig->version >= 4 ) {
|
||||
/* fixme: write v4 subpackets here */
|
||||
log_error("WARNING: note writing of v4 subpackets is not implemented\n");
|
||||
size_t n;
|
||||
/* timestamp and keyid must have been packed into the
|
||||
* subpackets prior to the call of this function, because
|
||||
* these subpackets are hashed */
|
||||
n = sig->hashed_data?((sig->hashed_data[0]<<8)
|
||||
|sig->hashed_data[1]) :0;
|
||||
write_16(a, n);
|
||||
if( n )
|
||||
iobuf_write( a, sig->hashed_data+2, n );
|
||||
n = sig->unhashed_data?((sig->unhashed_data[0]<<8)
|
||||
|sig->unhashed_data[1]) :0;
|
||||
write_16(a, n);
|
||||
if( n )
|
||||
iobuf_write( a, sig->unhashed_data+2, n );
|
||||
}
|
||||
iobuf_put(a, sig->digest_start[0] );
|
||||
iobuf_put(a, sig->digest_start[1] );
|
||||
|
@ -674,8 +849,18 @@ write_new_header( IOBUF out, int ctb, u32 len, int hdrlen )
|
|||
if( iobuf_put( out, (len % 256) ) )
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
log_bug("need a partial header to code a length %lu\n", (ulong)len);
|
||||
else {
|
||||
if( iobuf_put( out, 0xff ) )
|
||||
return -1;
|
||||
if( iobuf_put( out, (len >> 24)&0xff ) )
|
||||
return -1;
|
||||
if( iobuf_put( out, (len >> 16)&0xff ) )
|
||||
return -1;
|
||||
if( iobuf_put( out, (len >> 8)&0xff ) )
|
||||
return -1;
|
||||
if( iobuf_put( out, len & 0xff ) )
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -47,7 +47,6 @@ g10_dsa_sign( PKT_secret_cert *skc, PKT_signature *sig,
|
|||
digest_algo = md_get_algo(md);
|
||||
|
||||
dp = md_read( md, digest_algo );
|
||||
keyid_from_skc( skc, sig->keyid );
|
||||
sig->digest_algo = digest_algo;
|
||||
sig->digest_start[0] = dp[0];
|
||||
sig->digest_start[1] = dp[1];
|
||||
|
|
|
@ -73,7 +73,6 @@ g10_elg_sign( PKT_secret_cert *skc, PKT_signature *sig,
|
|||
digest_algo = md_get_algo(md);
|
||||
|
||||
dp = md_read( md, digest_algo );
|
||||
keyid_from_skc( skc, sig->keyid );
|
||||
sig->digest_algo = digest_algo;
|
||||
sig->digest_start[0] = dp[0];
|
||||
sig->digest_start[1] = dp[1];
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "util.h"
|
||||
|
|
|
@ -191,8 +191,10 @@ remove_keysigs( KBNODE keyblock, u32 *keyid, int all )
|
|||
else if( node->flag & 4 )
|
||||
tty_printf("The signature could not be checked!\n");
|
||||
|
||||
if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] )
|
||||
if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) {
|
||||
tty_printf("Skipped self-signature\n");
|
||||
continue; /* do not remove self-signatures */
|
||||
}
|
||||
|
||||
answer = tty_get("\nRemove this signature? ");
|
||||
tty_kill_prompt();
|
||||
|
@ -348,8 +350,7 @@ sign_key( const char *username, STRLIST locusr )
|
|||
rc = make_keysig_packet( &sig, pkc,
|
||||
node->pkt->pkt.user_id,
|
||||
skc_rover->skc,
|
||||
0x10,
|
||||
DIGEST_ALGO_RMD160 );
|
||||
0x10, 0 );
|
||||
if( rc ) {
|
||||
log_error("make_keysig_packet failed: %s\n", g10_errstr(rc));
|
||||
goto leave;
|
||||
|
@ -684,6 +685,7 @@ change_passphrase( const char *username )
|
|||
* Create a signature packet for the given public key certificate
|
||||
* and the user id and return it in ret_sig. User signature class SIGCLASS
|
||||
* user-id is not used (and may be NULL if sigclass is 0x20)
|
||||
* If digest_algo is 0 the function selects an appropriate one.
|
||||
*/
|
||||
int
|
||||
make_keysig_packet( PKT_signature **ret_sig, PKT_public_cert *pkc,
|
||||
|
@ -695,25 +697,75 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_cert *pkc,
|
|||
MD_HANDLE md;
|
||||
|
||||
assert( (sigclass >= 0x10 && sigclass <= 0x13) || sigclass == 0x20 );
|
||||
if( !digest_algo ) {
|
||||
switch( skc->pubkey_algo ) {
|
||||
case PUBKEY_ALGO_DSA: digest_algo = DIGEST_ALGO_SHA1; break;
|
||||
case PUBKEY_ALGO_RSA_S:
|
||||
case PUBKEY_ALGO_RSA: digest_algo = DIGEST_ALGO_MD5; break;
|
||||
default: digest_algo = DIGEST_ALGO_RMD160; break;
|
||||
}
|
||||
}
|
||||
md = md_open( digest_algo, 0 );
|
||||
md_start_debug( md, "make" );
|
||||
|
||||
/* hash the public key certificate and the user id */
|
||||
hash_public_cert( md, pkc );
|
||||
if( sigclass != 0x20 )
|
||||
if( sigclass != 0x20 ) {
|
||||
if( skc->version >=4 ) {
|
||||
byte buf[5];
|
||||
buf[0] = 0xb4; /* indicates a userid packet */
|
||||
buf[1] = uid->len >> 24; /* always use 4 length bytes */
|
||||
buf[2] = uid->len >> 16;
|
||||
buf[3] = uid->len >> 8;
|
||||
buf[4] = uid->len;
|
||||
md_write( md, buf, 5 );
|
||||
}
|
||||
md_write( md, uid->name, uid->len );
|
||||
}
|
||||
/* and make the signature packet */
|
||||
sig = m_alloc_clear( sizeof *sig );
|
||||
sig->version = skc->version;
|
||||
keyid_from_skc( skc, sig->keyid );
|
||||
sig->pubkey_algo = skc->pubkey_algo;
|
||||
sig->digest_algo = digest_algo;
|
||||
sig->timestamp = make_timestamp();
|
||||
sig->sig_class = sigclass;
|
||||
|
||||
if( sig->version >= 4 ) {
|
||||
build_sig_subpkt_from_sig( sig );
|
||||
md_putc( md, sig->version );
|
||||
}
|
||||
md_putc( md, sig->sig_class );
|
||||
{ u32 a = sig->timestamp;
|
||||
if( sig->version < 4 ) {
|
||||
u32 a = sig->timestamp;
|
||||
md_putc( md, (a >> 24) & 0xff );
|
||||
md_putc( md, (a >> 16) & 0xff );
|
||||
md_putc( md, (a >> 8) & 0xff );
|
||||
md_putc( md, a & 0xff );
|
||||
}
|
||||
else {
|
||||
byte buf[6];
|
||||
size_t n;
|
||||
|
||||
md_putc( md, sig->pubkey_algo );
|
||||
md_putc( md, sig->digest_algo );
|
||||
if( sig->hashed_data ) {
|
||||
n = (sig->hashed_data[0] << 8) | sig->hashed_data[1];
|
||||
md_write( md, sig->hashed_data, n+2 );
|
||||
n += 6;
|
||||
}
|
||||
else
|
||||
n = 6;
|
||||
/* add some magic */
|
||||
buf[0] = sig->version;
|
||||
buf[1] = 0xff;
|
||||
buf[2] = n >> 24; /* hmmm, n is only 16 bit, so tthis is always 0 */
|
||||
buf[3] = n >> 16;
|
||||
buf[4] = n >> 8;
|
||||
buf[5] = n;
|
||||
md_write( md, buf, 6 );
|
||||
|
||||
}
|
||||
md_final(md);
|
||||
|
||||
rc = complete_sig( sig, skc, md );
|
||||
|
|
|
@ -79,7 +79,7 @@ write_selfsig( KBNODE root, KBNODE pub_root, PKT_secret_cert *skc )
|
|||
pkc = node->pkt->pkt.public_cert;
|
||||
|
||||
/* and make the signature */
|
||||
rc = make_keysig_packet( &sig, pkc, uid, skc, 0x13, DIGEST_ALGO_RMD160 );
|
||||
rc = make_keysig_packet( &sig, pkc, uid, skc, 0x13, 0 );
|
||||
if( rc ) {
|
||||
log_error("make_keysig_packet failed: %s\n", g10_errstr(rc) );
|
||||
return rc;
|
||||
|
@ -290,7 +290,7 @@ gen_dsa(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
|
|||
/* don't know whether it makes sense to have the factors, so for now
|
||||
* we store them in the secret keyring (but they are not secret)
|
||||
* p = 2 * q * f1 * f2 * ... * fn
|
||||
* We store only f1 to f_n-1 - fn can be calculated because p and q
|
||||
* We store only f1 to f_n-1; fn can be calculated because p and q
|
||||
* are known.
|
||||
*/
|
||||
pkt = m_alloc_clear(sizeof *pkt);
|
||||
|
|
31
g10/packet.h
31
g10/packet.h
|
@ -211,6 +211,33 @@ struct packet_struct {
|
|||
(a)->pkt.generic = NULL; \
|
||||
} while(0)
|
||||
|
||||
typedef enum {
|
||||
SIGSUBPKT_LIST_UNHASHED=-2,
|
||||
SIGSUBPKT_LIST_HASHED =-1,
|
||||
SIGSUBPKT_NONE = 0,
|
||||
SIGSUBPKT_SIG_CREATED = 2, /* signature creation time */
|
||||
SIGSUBPKT_SIG_EXPIRE = 3, /* signature expiration time */
|
||||
SIGSUBPKT_EXPORTABLE = 4, /* exportable */
|
||||
SIGSUBPKT_TRUST = 5, /* trust signature */
|
||||
SIGSUBPKT_REGEXP = 6, /* regular expression */
|
||||
SIGSUBPKT_REVOCABLE = 7, /* revocable */
|
||||
SIGSUBPKT_KEY_EXPIRE = 9, /* key expiration time */
|
||||
SIGSUBPKT_ARR =10, /* additional recipient request */
|
||||
SIGSUBPKT_PREF_SYM =11, /* preferred symmetric algorithms */
|
||||
SIGSUBPKT_REV_KEY =12, /* revocation key */
|
||||
SIGSUBPKT_ISSUER =16, /* issuer key ID */
|
||||
SIGSUBPKT_NOTATION =20, /* notation data */
|
||||
SIGSUBPKT_PREF_HASH =21, /* preferred hash algorithms */
|
||||
SIGSUBPKT_PREF_COMPR =22, /* preferred compression algorithms */
|
||||
SIGSUBPKT_KS_FLAGS =23, /* key server preferences */
|
||||
SIGSUBPKT_PREF_KS =24, /* preferred key server */
|
||||
SIGSUBPKT_PRIMARY_UID =25, /* primary user id */
|
||||
SIGSUBPKT_POLICY =26, /* policy URL */
|
||||
SIGSUBPKT_KEY_FLAGS =27, /* key flags */
|
||||
SIGSUBPKT_SIGNERS_UID =28 /* signer's user id */
|
||||
} sigsubpkttype_t;
|
||||
|
||||
|
||||
/*-- mainproc.c --*/
|
||||
int proc_packets( IOBUF a );
|
||||
int proc_signature_packets( IOBUF a, STRLIST signedfiles );
|
||||
|
@ -224,11 +251,15 @@ 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 );
|
||||
const byte *parse_sig_subpkt( const byte *buffer, int reqtype, size_t *ret_n );
|
||||
|
||||
/*-- build-packet.c --*/
|
||||
int build_packet( IOBUF inp, PACKET *pkt );
|
||||
u32 calc_packet_length( PACKET *pkt );
|
||||
void hash_public_cert( MD_HANDLE md, PKT_public_cert *pkc );
|
||||
void build_sig_subpkt( PKT_signature *sig, sigsubpkttype_t type,
|
||||
const byte *buffer, size_t buflen );
|
||||
void build_sig_subpkt_from_sig( PKT_signature *sig );
|
||||
|
||||
/*-- free-packet.c --*/
|
||||
void free_symkey_enc( PKT_symkey_enc *enc );
|
||||
|
|
|
@ -197,7 +197,7 @@ parse( IOBUF inp, PACKET *pkt, int reqtype, ulong *retpos,
|
|||
{
|
||||
int rc, c, ctb, pkttype, lenbytes;
|
||||
unsigned long pktlen;
|
||||
byte hdr[5];
|
||||
byte hdr[8];
|
||||
int hdrlen;
|
||||
int pgp3 = 0;
|
||||
|
||||
|
@ -233,8 +233,17 @@ parse( IOBUF inp, PACKET *pkt, int reqtype, ulong *retpos,
|
|||
hdr[hdrlen++] = c;
|
||||
pktlen += c + 192;
|
||||
}
|
||||
else if( c < 255 ) {
|
||||
pktlen = (hdr[hdrlen++] = iobuf_get_noeof(inp)) << 24;
|
||||
pktlen |= (hdr[hdrlen++] = iobuf_get_noeof(inp)) << 16;
|
||||
pktlen |= (hdr[hdrlen++] = iobuf_get_noeof(inp)) << 8;
|
||||
if( (c = iobuf_get(inp)) == -1 ) {
|
||||
log_error("%s: 4 byte length invalid\n", iobuf_where(inp) );
|
||||
return G10ERR_INVALID_PACKET;
|
||||
}
|
||||
pktlen |= (hdr[hdrlen++] = c );
|
||||
}
|
||||
else { /* partial body length */
|
||||
pktlen = 1 << (c & 0x1f);
|
||||
log_debug("partial body length of %lu bytes\n", pktlen );
|
||||
iobuf_set_partial_block_mode(inp, pktlen);
|
||||
pktlen = 0;/* to indicate partial length */
|
||||
|
@ -543,20 +552,32 @@ parse_pubkeyenc( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
|
|||
}
|
||||
|
||||
|
||||
static const byte *
|
||||
parse_subpkt( const byte *buffer, int reqtype )
|
||||
const byte *
|
||||
parse_sig_subpkt( const byte *buffer, sigsubpkttype_t reqtype, size_t *ret_n )
|
||||
{
|
||||
int buflen = (*buffer << 8) | buffer[1];
|
||||
int buflen;
|
||||
int type;
|
||||
int critical;
|
||||
size_t n;
|
||||
|
||||
if( !buffer )
|
||||
return NULL;
|
||||
buflen = (*buffer << 8) | buffer[1];
|
||||
buffer += 2;
|
||||
for(;;) {
|
||||
if( !buflen )
|
||||
return NULL; /* end of packets; not found */
|
||||
n = *buffer++; buflen--;
|
||||
if( n >= 192 ) {
|
||||
if( n == 255 ) {
|
||||
if( buflen < 4 )
|
||||
goto too_short;
|
||||
n = (buffer[0] << 24) | (buffer[1] << 16)
|
||||
| (buffer[2] << 8) | buffer[3];
|
||||
buffer += 4;
|
||||
buflen -= 4;
|
||||
|
||||
}
|
||||
else if( n >= 192 ) {
|
||||
if( buflen < 2 )
|
||||
goto too_short;
|
||||
n = (( n - 192 ) << 8) + *buffer + 192;
|
||||
|
@ -573,27 +594,27 @@ parse_subpkt( const byte *buffer, int reqtype )
|
|||
critical = 0;
|
||||
if( reqtype < 0 ) { /* list packets */
|
||||
printf("\t%ssubpacket %d of length %u (%s)\n",
|
||||
reqtype == -1 ? "hashed ":"", type, (unsigned)n,
|
||||
type == 2 ? "signature creation time"
|
||||
: type == 3 ? "signature expiration time"
|
||||
: type == 4 ? "exportable"
|
||||
: type == 5 ? "trust signature"
|
||||
: type == 6 ? "regular expression"
|
||||
: type == 7 ? "revocable"
|
||||
: type == 9 ? "key expiration time"
|
||||
: type ==10 ? "additional recipient request"
|
||||
: type ==11 ? "preferred symmetric algorithms"
|
||||
: type ==12 ? "revocation key"
|
||||
: type ==16 ? "issuer key ID"
|
||||
: type ==20 ? "notation data"
|
||||
: type ==21 ? "preferred hash algorithms"
|
||||
: type ==22 ? "preferred compression algorithms"
|
||||
: type ==23 ? "key server preferences"
|
||||
: type ==24 ? "preferred key server"
|
||||
: type ==25 ? "primary user id"
|
||||
: type ==26 ? "policy URL"
|
||||
: type ==27 ? "key flags"
|
||||
: type ==28 ? "signer's user id"
|
||||
reqtype == SIGSUBPKT_LIST_HASHED ? "hashed ":"", type, (unsigned)n,
|
||||
type == SIGSUBPKT_SIG_CREATED ? "signature creation time"
|
||||
: type == SIGSUBPKT_SIG_EXPIRE ? "signature expiration time"
|
||||
: type == SIGSUBPKT_EXPORTABLE ? "exportable"
|
||||
: type == SIGSUBPKT_TRUST ? "trust signature"
|
||||
: type == SIGSUBPKT_REGEXP ? "regular expression"
|
||||
: type == SIGSUBPKT_REVOCABLE ? "revocable"
|
||||
: type == SIGSUBPKT_KEY_EXPIRE ? "key expiration time"
|
||||
: type == SIGSUBPKT_ARR ? "additional recipient request"
|
||||
: type == SIGSUBPKT_PREF_SYM ? "preferred symmetric algorithms"
|
||||
: type == SIGSUBPKT_REV_KEY ? "revocation key"
|
||||
: type == SIGSUBPKT_ISSUER ? "issuer key ID"
|
||||
: type == SIGSUBPKT_NOTATION ? "notation data"
|
||||
: type == SIGSUBPKT_PREF_HASH ? "preferred hash algorithms"
|
||||
: type == SIGSUBPKT_PREF_COMPR ? "preferred compression algorithms"
|
||||
: type == SIGSUBPKT_KS_FLAGS ? "key server preferences"
|
||||
: type == SIGSUBPKT_PREF_KS ? "preferred key server"
|
||||
: type == SIGSUBPKT_PRIMARY_UID ? "primary user id"
|
||||
: type == SIGSUBPKT_POLICY ? "policy URL"
|
||||
: type == SIGSUBPKT_KEY_FLAGS ? "key flags"
|
||||
: type == SIGSUBPKT_SIGNERS_UID ? "signer's user id"
|
||||
: "?");
|
||||
}
|
||||
else if( type == reqtype )
|
||||
|
@ -604,29 +625,17 @@ parse_subpkt( const byte *buffer, int reqtype )
|
|||
n--;
|
||||
if( n > buflen )
|
||||
goto too_short;
|
||||
if( ret_n )
|
||||
*ret_n = n;
|
||||
switch( type ) {
|
||||
case 2: /* signature creation time */
|
||||
case SIGSUBPKT_SIG_CREATED:
|
||||
if( n < 4 )
|
||||
break;
|
||||
return buffer;
|
||||
case 16:/* issuer key ID */
|
||||
case SIGSUBPKT_ISSUER:/* issuer key ID */
|
||||
if( n < 8 )
|
||||
break;
|
||||
return buffer;
|
||||
case 3: /* signature expiration time */
|
||||
case 4: /* exportable */
|
||||
case 5: /* trust signature */
|
||||
case 6: /* regular expression */
|
||||
case 7: /* revocable */
|
||||
case 9: /* key expiration time */
|
||||
case 10:/* additional recipient request */
|
||||
case 11:/* preferred symmetric algorithms */
|
||||
case 12:/* revocation key */
|
||||
case 20:/* notation data */
|
||||
case 21:/* preferred hash algorithms */
|
||||
case 22:/* preferred compression algorithms */
|
||||
case 23:/* key server preferences */
|
||||
case 24:/* preferred key server */
|
||||
default: BUG(); /* not yet needed */
|
||||
}
|
||||
log_error("subpacket of type %d too short\n", type);
|
||||
|
@ -718,12 +727,12 @@ parse_signature( IOBUF inp, int pkttype, unsigned long pktlen,
|
|||
|
||||
if( is_v4 ) { /*extract required information */
|
||||
const byte *p;
|
||||
p = parse_subpkt( sig->hashed_data, 2 );
|
||||
p = parse_sig_subpkt( sig->hashed_data, SIGSUBPKT_SIG_CREATED, NULL );
|
||||
if( !p )
|
||||
log_error("signature packet without timestamp\n");
|
||||
else
|
||||
sig->timestamp = buffer_to_u32(p);
|
||||
p = parse_subpkt( sig->unhashed_data, 16 );
|
||||
p = parse_sig_subpkt( sig->unhashed_data, SIGSUBPKT_ISSUER, NULL );
|
||||
if( !p )
|
||||
log_error("signature packet without keyid\n");
|
||||
else {
|
||||
|
@ -742,8 +751,8 @@ parse_signature( IOBUF inp, int pkttype, unsigned long pktlen,
|
|||
sig->digest_algo,
|
||||
sig->digest_start[0], sig->digest_start[1] );
|
||||
if( is_v4 ) {
|
||||
parse_subpkt( sig->hashed_data, -1 );
|
||||
parse_subpkt( sig->unhashed_data, -2 );
|
||||
parse_sig_subpkt( sig->hashed_data, SIGSUBPKT_LIST_HASHED, NULL );
|
||||
parse_sig_subpkt( sig->unhashed_data,SIGSUBPKT_LIST_UNHASHED, NULL);
|
||||
}
|
||||
}
|
||||
if( is_ELGAMAL(sig->pubkey_algo) ) {
|
||||
|
|
|
@ -159,7 +159,7 @@ gen_revoke( const char *uname )
|
|||
|
||||
|
||||
/* create it */
|
||||
rc = make_keysig_packet( &sig, pkc, NULL, skc, 0x20, DIGEST_ALGO_RMD160);
|
||||
rc = make_keysig_packet( &sig, pkc, NULL, skc, 0x20, 0);
|
||||
if( rc ) {
|
||||
log_error("make_keysig_packet failed: %s\n", g10_errstr(rc));
|
||||
goto leave;
|
||||
|
|
|
@ -71,7 +71,6 @@ g10_rsa_sign( PKT_secret_cert *skc, PKT_signature *sig,
|
|||
digest_algo = md_get_algo(md);
|
||||
|
||||
dp = md_read( md, digest_algo );
|
||||
keyid_from_skc( skc, sig->keyid );
|
||||
sig->digest_algo = digest_algo;
|
||||
sig->digest_start[0] = dp[0];
|
||||
sig->digest_start[1] = dp[1];
|
||||
|
|
|
@ -134,6 +134,7 @@ do_check( PKT_public_cert *pkc, PKT_signature *sig, MD_HANDLE digest )
|
|||
md_write( digest, buf, 6 );
|
||||
}
|
||||
md_final( digest );
|
||||
|
||||
result = mpi_alloc( (md_digest_length(sig->digest_algo)
|
||||
+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB );
|
||||
mpi_set_buffer( result, md_read(digest, sig->digest_algo),
|
||||
|
@ -344,6 +345,7 @@ check_key_signature( KBNODE root, KBNODE node, int *is_selfsig )
|
|||
|
||||
keyid_from_pkc( pkc, keyid );
|
||||
md = md_open( algo, 0 );
|
||||
md_start_debug(md, "check");
|
||||
hash_public_cert( md, pkc );
|
||||
hash_uid_node( unode, md, sig );
|
||||
if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) {
|
||||
|
|
67
g10/sign.c
67
g10/sign.c
|
@ -266,19 +266,51 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
|
|||
skc = skc_rover->skc;
|
||||
|
||||
/* build the signature packet */
|
||||
/* fixme: this code is partly duplicated in make_keysig_packet */
|
||||
sig = m_alloc_clear( sizeof *sig );
|
||||
sig->version = skc->version;
|
||||
keyid_from_skc( skc, sig->keyid );
|
||||
sig->pubkey_algo = skc->pubkey_algo;
|
||||
sig->timestamp = make_timestamp();
|
||||
sig->sig_class = opt.textmode && !outfile? 0x01 : 0x00;
|
||||
|
||||
md = md_copy( mfx.md );
|
||||
|
||||
if( sig->version >= 4 ) {
|
||||
build_sig_subpkt_from_sig( sig );
|
||||
md_putc( md, sig->version );
|
||||
}
|
||||
md_putc( md, sig->sig_class );
|
||||
{ u32 a = sig->timestamp;
|
||||
if( sig->version < 4 ) {
|
||||
u32 a = sig->timestamp;
|
||||
md_putc( md, (a >> 24) & 0xff );
|
||||
md_putc( md, (a >> 16) & 0xff );
|
||||
md_putc( md, (a >> 8) & 0xff );
|
||||
md_putc( md, a & 0xff );
|
||||
}
|
||||
else {
|
||||
byte buf[6];
|
||||
size_t n;
|
||||
|
||||
md_putc( md, sig->pubkey_algo );
|
||||
md_putc( md, sig->digest_algo );
|
||||
if( sig->hashed_data ) {
|
||||
n = (sig->hashed_data[0] << 8) | sig->hashed_data[1];
|
||||
md_write( md, sig->hashed_data, n+2 );
|
||||
n += 6;
|
||||
}
|
||||
else
|
||||
n = 6;
|
||||
/* add some magic */
|
||||
buf[0] = sig->version;
|
||||
buf[1] = 0xff;
|
||||
buf[2] = n >> 24; /* hmmm, n is only 16 bit, so this is always 0 */
|
||||
buf[3] = n >> 16;
|
||||
buf[4] = n >> 8;
|
||||
buf[5] = n;
|
||||
md_write( md, buf, 6 );
|
||||
|
||||
}
|
||||
md_final( md );
|
||||
|
||||
if( is_ELGAMAL(sig->pubkey_algo) )
|
||||
|
@ -431,19 +463,50 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile )
|
|||
skc = skc_rover->skc;
|
||||
|
||||
/* build the signature packet */
|
||||
/* fixme: this code is duplicated above */
|
||||
sig = m_alloc_clear( sizeof *sig );
|
||||
sig->version = skc->version;
|
||||
keyid_from_skc( skc, sig->keyid );
|
||||
sig->pubkey_algo = skc->pubkey_algo;
|
||||
sig->timestamp = make_timestamp();
|
||||
sig->sig_class = 0x01;
|
||||
|
||||
md = md_copy( textmd );
|
||||
if( sig->version >= 4 ) {
|
||||
build_sig_subpkt_from_sig( sig );
|
||||
md_putc( md, sig->version );
|
||||
}
|
||||
md_putc( md, sig->sig_class );
|
||||
{ u32 a = sig->timestamp;
|
||||
if( sig->version < 4 ) {
|
||||
u32 a = sig->timestamp;
|
||||
md_putc( md, (a >> 24) & 0xff );
|
||||
md_putc( md, (a >> 16) & 0xff );
|
||||
md_putc( md, (a >> 8) & 0xff );
|
||||
md_putc( md, a & 0xff );
|
||||
}
|
||||
else {
|
||||
byte buf[6];
|
||||
size_t n;
|
||||
|
||||
md_putc( md, sig->pubkey_algo );
|
||||
md_putc( md, sig->digest_algo );
|
||||
if( sig->hashed_data ) {
|
||||
n = (sig->hashed_data[0] << 8) | sig->hashed_data[1];
|
||||
md_write( md, sig->hashed_data, n+2 );
|
||||
n += 6;
|
||||
}
|
||||
else
|
||||
n = 6;
|
||||
/* add some magic */
|
||||
buf[0] = sig->version;
|
||||
buf[1] = 0xff;
|
||||
buf[2] = n >> 24; /* hmmm, n is only 16 bit, so this is always 0 */
|
||||
buf[3] = n >> 16;
|
||||
buf[4] = n >> 8;
|
||||
buf[5] = n;
|
||||
md_write( md, buf, 6 );
|
||||
|
||||
}
|
||||
md_final( md );
|
||||
|
||||
if( is_ELGAMAL(sig->pubkey_algo) )
|
||||
|
|
|
@ -24,8 +24,8 @@
|
|||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue