mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-02 22:46:30 +02:00
nearly ready for 0.3.0
This commit is contained in:
parent
e6ac5acbbf
commit
06fd61d081
52 changed files with 1335 additions and 312 deletions
|
@ -1,3 +1,20 @@
|
|||
Wed Jun 24 16:40:22 1998 Werner Koch (wk@isil.d.shuttle.de)
|
||||
|
||||
* armor.c (armor_filter): Now creates valid onepass_sig packets
|
||||
with all detected hash algorithms.
|
||||
* mainproc.c (proc_plaintext): Now uses the hash algos as specified
|
||||
in the onepass_sig packets (if there are any)
|
||||
|
||||
Mon Jun 22 11:54:08 1998 Werner Koch (wk@isil.d.shuttle.de)
|
||||
|
||||
* plaintext.c (handle_plaintext): add arg to disable outout
|
||||
* mainproc.c (proc_plaintext): disable output when in sigs_only mode.
|
||||
|
||||
Thu Jun 18 13:17:27 1998 Werner Koch (wk@isil.d.shuttle.de)
|
||||
|
||||
* keygen.c: Removed all rsa packet stuff, chnaged defaults
|
||||
for key generation.
|
||||
|
||||
Sun Jun 14 21:28:31 1998 Werner Koch (wk@isil.d.shuttle.de)
|
||||
|
||||
* misc.c (checksum_u16): Fixed a stupid bug which caused a
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl -I../intl
|
||||
EXTRA_DIST = OPTIONS pubring.asc
|
||||
OMIT_DEPENDENCIES = zlib.h zconf.h
|
||||
LDFLAGS = -rdynamic
|
||||
LDFLAGS = @LDFLAGS@ @DYNLINK_LDFLAGS@
|
||||
needed_libs = ../cipher/libcipher.a ../mpi/libmpi.a ../util/libutil.a
|
||||
|
||||
noinst_PROGRAMS = gpgd
|
||||
|
|
86
g10/armor.c
86
g10/armor.c
|
@ -100,8 +100,10 @@ static char *tail_strings[] = {
|
|||
};
|
||||
|
||||
|
||||
static fhdr_state_t find_header( fhdr_state_t state, byte *buf,
|
||||
size_t *r_buflen, IOBUF a, size_t n, unsigned *r_empty);
|
||||
static fhdr_state_t find_header( fhdr_state_t state,
|
||||
byte *buf, size_t *r_buflen,
|
||||
IOBUF a, size_t n,
|
||||
unsigned *r_empty, int *r_hashes );
|
||||
|
||||
|
||||
static void
|
||||
|
@ -227,7 +229,7 @@ parse_hash_header( const char *line )
|
|||
found |= 2;
|
||||
else if( !strncmp( s, "MD5", s2-s ) )
|
||||
found |= 4;
|
||||
else if( !strncmp( s, "MD2", s2-s ) )
|
||||
else if( !strncmp( s, "TIGER", s2-s ) )
|
||||
found |= 8;
|
||||
else
|
||||
return 0;
|
||||
|
@ -250,7 +252,7 @@ parse_hash_header( const char *line )
|
|||
*/
|
||||
static fhdr_state_t
|
||||
find_header( fhdr_state_t state, byte *buf, size_t *r_buflen,
|
||||
IOBUF a, size_t n, unsigned *r_empty)
|
||||
IOBUF a, size_t n, unsigned *r_empty, int *r_hashes )
|
||||
{
|
||||
int c=0, i;
|
||||
const char *s;
|
||||
|
@ -319,6 +321,7 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen,
|
|||
if( n < buflen || c == '\n' ) {
|
||||
if( n && buf[0] != '\r') { /* maybe a header */
|
||||
if( strchr( buf, ':') ) { /* yes */
|
||||
int hashes;
|
||||
if( buf[n-1] == '\r' )
|
||||
buf[--n] = 0;
|
||||
if( opt.verbose ) {
|
||||
|
@ -326,12 +329,15 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen,
|
|||
print_string( stderr, buf, n, 0 );
|
||||
putc('\n', stderr);
|
||||
}
|
||||
if( clearsig && !parse_hash_header( buf ) ) {
|
||||
if( clearsig && !(hashes=parse_hash_header( buf )) ) {
|
||||
log_error("invalid clearsig header\n");
|
||||
state = fhdrERROR;
|
||||
}
|
||||
else
|
||||
else {
|
||||
state = fhdrWAITHeader;
|
||||
if( r_hashes )
|
||||
*r_hashes |= hashes;
|
||||
}
|
||||
}
|
||||
else
|
||||
state = fhdrCHECKDashEscaped3;
|
||||
|
@ -602,7 +608,8 @@ check_input( armor_filter_context_t *afx, IOBUF a )
|
|||
state = fhdrHASArmor;
|
||||
|
||||
n = DIM(afx->helpbuf);
|
||||
state = find_header( state, afx->helpbuf, &n, a, afx->helplen, &emplines);
|
||||
state = find_header( state, afx->helpbuf, &n, a,
|
||||
afx->helplen, &emplines, &afx->hashes);
|
||||
switch( state ) {
|
||||
case fhdrNOArmor:
|
||||
afx->inp_checked = 1;
|
||||
|
@ -684,7 +691,8 @@ fake_packet( armor_filter_context_t *afx, IOBUF a,
|
|||
/* read a new one */
|
||||
n = DIM(afx->helpbuf);
|
||||
afx->helpidx = 0;
|
||||
state = find_header( state, afx->helpbuf, &n, a, 0, &emplines );
|
||||
state = find_header( state, afx->helpbuf, &n, a, 0,
|
||||
&emplines, &afx->hashes );
|
||||
switch( state) {
|
||||
case fhdrERROR:
|
||||
invalid_armor();
|
||||
|
@ -884,7 +892,7 @@ armor_filter( void *opaque, int control,
|
|||
*ret_len = n;
|
||||
}
|
||||
else if( control == IOBUFCTRL_UNDERFLOW ) {
|
||||
if( size < 30 )
|
||||
if( size < 15+(4*15) ) /* need space for up to 4 onepass_sigs */
|
||||
BUG(); /* supplied buffer too short */
|
||||
|
||||
if( afx->inp_eof ) {
|
||||
|
@ -907,27 +915,53 @@ armor_filter( void *opaque, int control,
|
|||
afx->helplen = 0;
|
||||
}
|
||||
else if( afx->faked ) {
|
||||
/* the buffer is at least 30 bytes long, so it
|
||||
unsigned hashes = afx->hashes;
|
||||
/* the buffer is at least 15+n*15 bytes long, so it
|
||||
* is easy to construct the packets */
|
||||
|
||||
/* first a onepass signature packet */
|
||||
buf[0] = 0x90; /* old packet format, type 4, 1 length byte */
|
||||
buf[1] = 13; /* length */
|
||||
buf[2] = 3; /* version */
|
||||
buf[3] = 0x01; /* sigclass 0x01 (data in canonical text mode)*/
|
||||
buf[4] = 0; /* digest algo (don't know) */
|
||||
buf[5] = 0; /* public key algo (don't know) */
|
||||
memset(buf+6, 0, 8); /* don't know the keyid */
|
||||
buf[14] = 1; /* this is the last one */
|
||||
hashes &= 1|2|4|8;
|
||||
if( !hashes )
|
||||
hashes |= 4; /* default to MD 5 */
|
||||
n=0;
|
||||
do {
|
||||
/* first some onepass signature packets */
|
||||
buf[n++] = 0x90; /* old format, type 4, 1 length byte */
|
||||
buf[n++] = 13; /* length */
|
||||
buf[n++] = 3; /* version */
|
||||
buf[n++] = 0x01; /* sigclass 0x01 (canonical text mode)*/
|
||||
if( hashes & 1 ) {
|
||||
hashes &= ~1;
|
||||
buf[n++] = DIGEST_ALGO_RMD160;
|
||||
}
|
||||
else if( hashes & 2 ) {
|
||||
hashes &= ~2;
|
||||
buf[n++] = DIGEST_ALGO_SHA1;
|
||||
}
|
||||
else if( hashes & 4 ) {
|
||||
hashes &= ~4;
|
||||
buf[n++] = DIGEST_ALGO_MD5;
|
||||
}
|
||||
else if( hashes & 8 ) {
|
||||
hashes &= ~8;
|
||||
buf[n++] = DIGEST_ALGO_TIGER;
|
||||
}
|
||||
else
|
||||
buf[n++] = 0; /* (don't know) */
|
||||
|
||||
buf[n++] = 0; /* public key algo (don't know) */
|
||||
memset(buf+n, 0, 8); /* don't know the keyid */
|
||||
n += 8;
|
||||
buf[n++] = !hashes; /* last one */
|
||||
} while( hashes );
|
||||
|
||||
/* followed by a plaintext packet */
|
||||
buf[15] = 0xaf; /* old packet format, type 11, var length */
|
||||
buf[16] = 0; /* set the length header */
|
||||
buf[17] = 6;
|
||||
buf[18] = 't'; /* canonical text mode */
|
||||
buf[19] = 0; /* namelength */
|
||||
memset(buf+20, 0, 4); /* timestamp */
|
||||
n = 24;
|
||||
buf[n++] = 0xaf; /* old packet format, type 11, var length */
|
||||
buf[n++] = 0; /* set the length header */
|
||||
buf[n++] = 6;
|
||||
buf[n++] = 't'; /* canonical text mode */
|
||||
buf[n++] = 0; /* namelength */
|
||||
memset(buf+n, 0, 4); /* timestamp */
|
||||
n += 4;
|
||||
}
|
||||
else if( !rc )
|
||||
rc = radix64_read( afx, a, &n, buf, size );
|
||||
|
|
|
@ -517,6 +517,11 @@ build_sig_subpkt( PKT_signature *sig, sigsubpkttype_t type,
|
|||
switch( type ) {
|
||||
case SIGSUBPKT_SIG_CREATED:
|
||||
case SIGSUBPKT_PRIV_ADD_SIG:
|
||||
case SIGSUBPKT_PREF_SYM:
|
||||
case SIGSUBPKT_PREF_HASH:
|
||||
case SIGSUBPKT_PREF_COMPR:
|
||||
case SIGSUBPKT_KS_FLAGS:
|
||||
case SIGSUBPKT_KEY_EXPIRE:
|
||||
hashed = 1; break;
|
||||
default: hashed = 0; break;
|
||||
}
|
||||
|
@ -538,8 +543,8 @@ build_sig_subpkt( PKT_signature *sig, sigsubpkttype_t type,
|
|||
: m_alloc( n+2 );
|
||||
}
|
||||
|
||||
data[n0+0] = (n >> 8) & 0xff;
|
||||
data[n0+1] = n & 0xff;
|
||||
data[0] = (n >> 8) & 0xff;
|
||||
data[1] = n & 0xff;
|
||||
data[n0+2] = buflen+1;
|
||||
data[n0+3] = type;
|
||||
memcpy(data+n0+4, buffer, buflen );
|
||||
|
|
|
@ -37,6 +37,7 @@ typedef struct {
|
|||
byte helpbuf[100];
|
||||
int helpidx, helplen;
|
||||
unsigned empty; /* empty line counter */
|
||||
int hashes; /* detected hash algorithms */
|
||||
int faked;
|
||||
int parse_state;
|
||||
int inp_checked; /* set if inp has been checked */
|
||||
|
|
54
g10/getkey.c
54
g10/getkey.c
|
@ -30,6 +30,7 @@
|
|||
#include "iobuf.h"
|
||||
#include "keydb.h"
|
||||
#include "options.h"
|
||||
#include "main.h"
|
||||
|
||||
#define MAX_PKC_CACHE_ENTRIES 500
|
||||
|
||||
|
@ -595,6 +596,58 @@ compare_name( const char *uid, size_t uidlen, const char *name, int mode )
|
|||
}
|
||||
|
||||
|
||||
|
||||
/****************
|
||||
* Assume that knode points to a public key packet and keyblock is
|
||||
* the entire keyblock. This function adds all relevant information from
|
||||
* a selfsignature to the public key.
|
||||
*/
|
||||
|
||||
static void
|
||||
add_stuff_from_selfsig( KBNODE keyblock, KBNODE knode )
|
||||
{
|
||||
PKT_public_cert *pkc = knode->pkt->pkt.public_cert;
|
||||
PKT_signature *sig;
|
||||
KBNODE k;
|
||||
u32 kid[2];
|
||||
|
||||
assert( knode->pkt->pkttype == PKT_PUBLIC_CERT
|
||||
|| knode->pkt->pkttype == PKT_PUBKEY_SUBCERT );
|
||||
|
||||
if( pkc->version < 4 )
|
||||
return; /* this is only needed for version >=4 packets */
|
||||
|
||||
/* find the selfsignature */
|
||||
if( knode->pkt->pkttype == PKT_PUBKEY_SUBCERT ) {
|
||||
k = find_kbnode( keyblock, PKT_PUBLIC_CERT );
|
||||
if( !k )
|
||||
BUG(); /* keyblock without primary key!!! */
|
||||
keyid_from_pkc( knode->pkt->pkt.public_cert, kid );
|
||||
}
|
||||
else
|
||||
keyid_from_pkc( pkc, kid );
|
||||
for(k=keyblock; k; k = k->next ) {
|
||||
if( k->pkt->pkttype == PKT_SIGNATURE
|
||||
&& (sig=k->pkt->pkt.signature)->sig_class >= 0x10
|
||||
&& sig->sig_class <= 0x13
|
||||
&& sig->keyid[0] == kid[0]
|
||||
&& sig->keyid[1] == kid[1]
|
||||
&& sig->version > 3 ) {
|
||||
/* okay this is (the first) self-signature which can be used
|
||||
* fixme: Check how to handle subkey bindings
|
||||
* FIXME: We should only use this if the signature is valid
|
||||
* but this is time consuming - we muts provide another
|
||||
* way to handle this
|
||||
*/
|
||||
const byte *p;
|
||||
p = parse_sig_subpkt( sig->hashed_data, SIGSUBPKT_KEY_EXPIRE, NULL );
|
||||
pkc->valid_days = p? ((buffer_to_u32(p)+86399L)/86400L):0;
|
||||
/* fixme: add usage etc. to pkc */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************
|
||||
* Lookup a key by scanning all keyrings
|
||||
* mode 1 = lookup by NAME (exact)
|
||||
|
@ -718,6 +771,7 @@ lookup( PKT_public_cert *pkc, int mode, u32 *keyid,
|
|||
assert( k->pkt->pkttype == PKT_PUBLIC_CERT
|
||||
|| k->pkt->pkttype == PKT_PUBKEY_SUBCERT );
|
||||
copy_public_cert( pkc, k->pkt->pkt.public_cert );
|
||||
add_stuff_from_selfsig( keyblock, k );
|
||||
if( ret_keyblock ) {
|
||||
*ret_keyblock = keyblock;
|
||||
keyblock = NULL;
|
||||
|
|
|
@ -347,7 +347,7 @@ sign_key( const char *username, STRLIST locusr )
|
|||
node->pkt->pkt.user_id,
|
||||
NULL,
|
||||
skc_rover->skc,
|
||||
0x10, 0 );
|
||||
0x10, 0, NULL, NULL );
|
||||
if( rc ) {
|
||||
log_error("make_keysig_packet failed: %s\n", g10_errstr(rc));
|
||||
goto leave;
|
||||
|
@ -720,7 +720,9 @@ int
|
|||
make_keysig_packet( PKT_signature **ret_sig, PKT_public_cert *pkc,
|
||||
PKT_user_id *uid, PKT_public_cert *subpkc,
|
||||
PKT_secret_cert *skc,
|
||||
int sigclass, int digest_algo )
|
||||
int sigclass, int digest_algo,
|
||||
int (*mksubpkt)(PKT_signature *, void *), void *opaque
|
||||
)
|
||||
{
|
||||
PKT_signature *sig;
|
||||
int rc=0;
|
||||
|
@ -763,45 +765,50 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_cert *pkc,
|
|||
sig->digest_algo = digest_algo;
|
||||
sig->timestamp = make_timestamp();
|
||||
sig->sig_class = sigclass;
|
||||
|
||||
if( sig->version >= 4 ) {
|
||||
if( sig->version >= 4 )
|
||||
build_sig_subpkt_from_sig( sig );
|
||||
md_putc( md, sig->version );
|
||||
}
|
||||
md_putc( md, sig->sig_class );
|
||||
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;
|
||||
if( sig->version >= 4 && mksubpkt )
|
||||
rc = (*mksubpkt)( sig, opaque );
|
||||
|
||||
if( !rc ) {
|
||||
if( sig->version >= 4 )
|
||||
md_putc( md, sig->version );
|
||||
md_putc( md, sig->sig_class );
|
||||
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
|
||||
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 );
|
||||
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);
|
||||
|
||||
rc = complete_sig( sig, skc, md );
|
||||
}
|
||||
md_final(md);
|
||||
|
||||
rc = complete_sig( sig, skc, md );
|
||||
|
||||
md_close( md );
|
||||
if( rc )
|
||||
|
|
242
g10/keygen.c
242
g10/keygen.c
|
@ -35,11 +35,6 @@
|
|||
#include "i18n.h"
|
||||
|
||||
|
||||
#if 0
|
||||
#define ENABLE_RSA_KEYGEN 1
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
write_uid( KBNODE root, const char *s )
|
||||
{
|
||||
|
@ -54,6 +49,65 @@ write_uid( KBNODE root, const char *s )
|
|||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
add_key_expire( PKT_signature *sig, void *opaque )
|
||||
{
|
||||
PKT_secret_cert *skc = opaque;
|
||||
byte buf[8];
|
||||
u32 u;
|
||||
|
||||
if( skc->valid_days ) {
|
||||
u = skc->valid_days * 86400L;
|
||||
buf[0] = (u >> 24) & 0xff;
|
||||
buf[1] = (u >> 16) & 0xff;
|
||||
buf[2] = (u >> 8) & 0xff;
|
||||
buf[3] = u & 0xff;
|
||||
build_sig_subpkt( sig, SIGSUBPKT_KEY_EXPIRE, buf, 4 );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Add preference to the self signature packet.
|
||||
* This is only called for packets with version > 3.
|
||||
*/
|
||||
static int
|
||||
add_prefs( PKT_signature *sig, void *opaque )
|
||||
{
|
||||
byte buf[8];
|
||||
|
||||
add_key_expire( sig, opaque );
|
||||
|
||||
buf[0] = CIPHER_ALGO_BLOWFISH;
|
||||
buf[1] = CIPHER_ALGO_CAST5;
|
||||
build_sig_subpkt( sig, SIGSUBPKT_PREF_SYM, buf, 2 );
|
||||
|
||||
buf[0] = DIGEST_ALGO_RMD160;
|
||||
buf[1] = DIGEST_ALGO_SHA1;
|
||||
buf[2] = DIGEST_ALGO_TIGER;
|
||||
buf[3] = DIGEST_ALGO_MD5;
|
||||
build_sig_subpkt( sig, SIGSUBPKT_PREF_HASH, buf, 4 );
|
||||
|
||||
buf[0] = 2;
|
||||
buf[1] = 1;
|
||||
build_sig_subpkt( sig, SIGSUBPKT_PREF_COMPR, buf, 2 );
|
||||
|
||||
buf[0] = 0x80; /* no modify - It is reasonable that a key holder
|
||||
* has the possibility to reject signatures from users
|
||||
* who are known to sign everything without any
|
||||
* validation - so a signed key should be send
|
||||
* to the holder who in turn can put it on a keyserver
|
||||
*/
|
||||
build_sig_subpkt( sig, SIGSUBPKT_KS_FLAGS, buf, 1 );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
write_selfsig( KBNODE root, KBNODE pub_root, PKT_secret_cert *skc )
|
||||
{
|
||||
|
@ -79,7 +133,8 @@ 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, NULL, skc, 0x13, 0 );
|
||||
rc = make_keysig_packet( &sig, pkc, uid, NULL, skc, 0x13, 0,
|
||||
add_prefs, skc );
|
||||
if( rc ) {
|
||||
log_error("make_keysig_packet failed: %s\n", g10_errstr(rc) );
|
||||
return rc;
|
||||
|
@ -119,7 +174,8 @@ write_keybinding( KBNODE root, KBNODE pub_root, PKT_secret_cert *skc )
|
|||
BUG();
|
||||
|
||||
/* and make the signature */
|
||||
rc = make_keysig_packet( &sig, pkc, NULL, subpkc, skc, 0x18, 0 );
|
||||
rc = make_keysig_packet( &sig, pkc, NULL, subpkc, skc, 0x18, 0,
|
||||
add_key_expire, skc );
|
||||
if( rc ) {
|
||||
log_error("make_keysig_packet failed: %s\n", g10_errstr(rc) );
|
||||
return rc;
|
||||
|
@ -134,7 +190,7 @@ write_keybinding( KBNODE root, KBNODE pub_root, PKT_secret_cert *skc )
|
|||
|
||||
|
||||
static int
|
||||
gen_elg(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
|
||||
gen_elg(int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
|
||||
STRING2KEY *s2k, PKT_secret_cert **ret_skc, u16 valid_days,
|
||||
int version )
|
||||
{
|
||||
|
@ -146,7 +202,8 @@ gen_elg(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
|
|||
MPI skey[4];
|
||||
MPI *factors;
|
||||
|
||||
rc = pubkey_generate( PUBKEY_ALGO_ELGAMAL, nbits, skey, &factors );
|
||||
assert( is_ELGAMAL(algo) );
|
||||
rc = pubkey_generate( algo, nbits, skey, &factors );
|
||||
if( rc ) {
|
||||
log_error("pubkey_generate failed: %s\n", g10_errstr(rc) );
|
||||
return rc;
|
||||
|
@ -157,7 +214,7 @@ gen_elg(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
|
|||
skc->timestamp = pkc->timestamp = make_timestamp();
|
||||
skc->version = pkc->version = version;
|
||||
skc->valid_days = pkc->valid_days = valid_days;
|
||||
skc->pubkey_algo = pkc->pubkey_algo = PUBKEY_ALGO_ELGAMAL;
|
||||
skc->pubkey_algo = pkc->pubkey_algo = algo;
|
||||
pkc->pkey[0] = mpi_copy( skey[0] );
|
||||
pkc->pkey[1] = mpi_copy( skey[1] );
|
||||
pkc->pkey[2] = mpi_copy( skey[2] );
|
||||
|
@ -203,73 +260,6 @@ gen_elg(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
|
|||
}
|
||||
|
||||
|
||||
|
||||
#ifdef ENABLE_RSA_KEYGEN
|
||||
static int
|
||||
gen_rsa(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
|
||||
STRING2KEY *s2k, PKT_secret_cert **ret_skc, u16 valid_days )
|
||||
{
|
||||
int rc;
|
||||
PACKET *pkt;
|
||||
PKT_secret_cert *skc;
|
||||
PKT_public_cert *pkc;
|
||||
RSA_public_key pk;
|
||||
RSA_secret_key sk;
|
||||
|
||||
rsa_generate( &pk, &sk, nbits );
|
||||
|
||||
skc = m_alloc_clear( sizeof *skc );
|
||||
pkc = m_alloc_clear( sizeof *pkc );
|
||||
skc->timestamp = pkc->timestamp = make_timestamp();
|
||||
skc->valid_days = pkc->valid_days = valid_days;
|
||||
skc->pubkey_algo = pkc->pubkey_algo = PUBKEY_ALGO_RSA;
|
||||
memset(&pkc->mfx, 0, sizeof pkc->mfx);
|
||||
pkc->d.rsa.rsa_n = pk.n;
|
||||
pkc->d.rsa.rsa_e = pk.e;
|
||||
skc->d.rsa.rsa_n = sk.n;
|
||||
skc->d.rsa.rsa_e = sk.e;
|
||||
skc->d.rsa.rsa_d = sk.d;
|
||||
skc->d.rsa.rsa_p = sk.p;
|
||||
skc->d.rsa.rsa_q = sk.q;
|
||||
skc->d.rsa.rsa_u = sk.u;
|
||||
skc->d.rsa.csum = checksum_mpi_counted_nbits( skc->d.rsa.rsa_d );
|
||||
skc->d.rsa.csum += checksum_mpi_counted_nbits( skc->d.rsa.rsa_p );
|
||||
skc->d.rsa.csum += checksum_mpi_counted_nbits( skc->d.rsa.rsa_q );
|
||||
skc->d.rsa.csum += checksum_mpi_counted_nbits( skc->d.rsa.rsa_u );
|
||||
|
||||
if( ret_skc ) /* not a subkey: return an unprotected version of the skc */
|
||||
*ret_skc = copy_secret_cert( NULL, skc );
|
||||
|
||||
if( dek ) {
|
||||
skc->d.rsa.is_protected = 1;
|
||||
skc->d.rsa.protect_algo = CIPHER_ALGO_BLOWFISH;
|
||||
randomize_buffer( skc->d.rsa.protect.blowfish.iv, 8, 1);
|
||||
skc->d.rsa.csum += checksum_counted_nbits(
|
||||
skc->d.rsa.protect.blowfish.iv, 8 );
|
||||
rc = protect_secret_key( skc, dek );
|
||||
if( rc ) {
|
||||
log_error("protect_secret_key failed: %s\n", g10_errstr(rc) );
|
||||
free_public_cert(pkc);
|
||||
free_secret_cert(skc);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
pkt = m_alloc_clear(sizeof *pkt);
|
||||
pkt->pkttype = ret_skc ? PKT_PUBLIC_CERT : PKT_PUBKEY_SUBCERT;
|
||||
pkt->pkt.public_cert = pkc;
|
||||
add_kbnode(pub_root, new_kbnode( pkt ));
|
||||
|
||||
pkt = m_alloc_clear(sizeof *pkt);
|
||||
pkt->pkttype = ret_skc ? PKT_SECRET_CERT : PKT_SECKEY_SUBCERT;
|
||||
pkt->pkt.secret_cert = skc;
|
||||
add_kbnode(sec_root, new_kbnode( pkt ));
|
||||
|
||||
return rc;
|
||||
}
|
||||
#endif /*ENABLE_RSA_KEYGEN*/
|
||||
|
||||
|
||||
/****************
|
||||
* Generate a DSA key
|
||||
*/
|
||||
|
@ -298,15 +288,12 @@ gen_dsa(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
|
|||
pkc = m_alloc_clear( sizeof *pkc );
|
||||
skc->timestamp = pkc->timestamp = make_timestamp();
|
||||
skc->version = pkc->version = 4;
|
||||
/* valid days are not stored in the packet, but it is
|
||||
* used here to put it into the signature.
|
||||
*/
|
||||
skc->valid_days = pkc->valid_days = valid_days;
|
||||
skc->pubkey_algo = pkc->pubkey_algo = PUBKEY_ALGO_DSA;
|
||||
pkc->pkey[0] = skey[0];
|
||||
pkc->pkey[1] = skey[1];
|
||||
pkc->pkey[2] = skey[2];
|
||||
pkc->pkey[3] = skey[3];
|
||||
pkc->pkey[0] = mpi_copy( skey[0] );
|
||||
pkc->pkey[1] = mpi_copy( skey[1] );
|
||||
pkc->pkey[2] = mpi_copy( skey[2] );
|
||||
pkc->pkey[3] = mpi_copy( skey[3] );
|
||||
skc->skey[0] = skey[0];
|
||||
skc->skey[1] = skey[1];
|
||||
skc->skey[2] = skey[2];
|
||||
|
@ -317,7 +304,7 @@ gen_dsa(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
|
|||
|
||||
skc->csum = checksum_mpi_counted_nbits( skc->skey[4] );
|
||||
if( ret_skc ) /* not a subkey: return an unprotected version of the skc */
|
||||
*ret_skc = copy_secret_cert( NULL, skc );
|
||||
*ret_skc = copy_secret_cert( NULL, skc );
|
||||
|
||||
if( dek ) {
|
||||
skc->protect.algo = dek->algo;
|
||||
|
@ -383,47 +370,52 @@ check_valid_days( const char *s )
|
|||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Returns o to create both a DSA and a ElGamal key.
|
||||
*/
|
||||
static int
|
||||
ask_algo( int *ret_v4 )
|
||||
ask_algo( int *ret_v4, int addmode )
|
||||
{
|
||||
char *answer;
|
||||
int algo;
|
||||
|
||||
tty_printf(_("Please select the algorithm to use:\n"
|
||||
" (1) ElGamal is the suggested one.\n"
|
||||
" (2) ElGamal using v4 packets (OpenPGP)\n"
|
||||
" (3) DSA can only be used for signatures.\n"));
|
||||
#ifdef ENABLE_RSA_KEYGEN
|
||||
tty_printf(_(" (4) RSA cannot be used in the U.S.\n"));
|
||||
#endif
|
||||
tty_printf(_("Please select what kind of key you want:\n"));
|
||||
if( !addmode )
|
||||
tty_printf(_(" (%d) DSA and ElGamal (default)\n"), 1 );
|
||||
tty_printf( _(" (%d) ElGamal (sign and encrypt)\n"), 2 );
|
||||
tty_printf( _(" (%d) ElGamal (encrypt only)\n"), 3 );
|
||||
tty_printf( _(" (%d) DSA (sign only)\n"), 4 );
|
||||
tty_printf( _(" (%d) ElGamal in a v3 packet\n"), 5 );
|
||||
|
||||
*ret_v4 = 0;
|
||||
*ret_v4 = 1;
|
||||
for(;;) {
|
||||
#ifdef ENABLE_RSA_KEYGEN
|
||||
answer = tty_get(_("Your selection? (1,2,3,4) "));
|
||||
#else
|
||||
answer = tty_get(_("Your selection? (1,2,3) "));
|
||||
#endif
|
||||
answer = tty_get(_("Your selection? "));
|
||||
tty_kill_prompt();
|
||||
algo = *answer? atoi(answer): 1;
|
||||
m_free(answer);
|
||||
if( algo == 1 || algo == 2 ) {
|
||||
if( algo == 2 )
|
||||
*ret_v4 = 1;
|
||||
if( algo == 1 && !addmode ) {
|
||||
algo = 0; /* create both keys */
|
||||
break;
|
||||
}
|
||||
else if( algo == 2 ) {
|
||||
algo = PUBKEY_ALGO_ELGAMAL;
|
||||
break;
|
||||
}
|
||||
else if( algo == 3 ) {
|
||||
*ret_v4 = 1;
|
||||
algo = PUBKEY_ALGO_ELGAMAL_E;
|
||||
break;
|
||||
}
|
||||
else if( algo == 4 ) {
|
||||
algo = PUBKEY_ALGO_DSA;
|
||||
break;
|
||||
}
|
||||
#ifdef ENABLE_RSA_KEYGEN
|
||||
else if( algo == 4 ) {
|
||||
algo = PUBKEY_ALGO_RSA;
|
||||
else if( algo == 5 ) {
|
||||
algo = PUBKEY_ALGO_ELGAMAL_E;
|
||||
*ret_v4 = 0;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
tty_printf(_("Invalid selection.\n"));
|
||||
}
|
||||
return algo;
|
||||
}
|
||||
|
@ -703,13 +695,9 @@ do_create( int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root,
|
|||
"network and the disks) during the prime generation; this gives the random\n"
|
||||
"number generator a better chance to gain enough entropy.\n") );
|
||||
|
||||
if( algo == PUBKEY_ALGO_ELGAMAL )
|
||||
rc = gen_elg(nbits, pub_root, sec_root, dek, s2k,
|
||||
if( algo == PUBKEY_ALGO_ELGAMAL || algo == PUBKEY_ALGO_ELGAMAL_E )
|
||||
rc = gen_elg(algo, nbits, pub_root, sec_root, dek, s2k,
|
||||
skc, valid_days, v4_packet? 4:3 );
|
||||
#ifdef ENABLE_RSA_KEYGEN
|
||||
else if( algo == PUBKEY_ALGO_RSA )
|
||||
rc = gen_rsa(nbits, pub_root, sec_root, dek, s2k, skc, valid_days );
|
||||
#endif
|
||||
else if( algo == PUBKEY_ALGO_DSA )
|
||||
rc = gen_dsa(nbits, pub_root, sec_root, dek, s2k, skc, valid_days);
|
||||
else
|
||||
|
@ -745,13 +733,19 @@ generate_keypair()
|
|||
int algo;
|
||||
int ndays;
|
||||
int v4;
|
||||
int both = 0;
|
||||
|
||||
if( opt.batch || opt.answer_yes || opt.answer_no ) {
|
||||
log_error(_("Key generation can only be used in interactive mode\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
algo = ask_algo( &v4 );
|
||||
algo = ask_algo( &v4, 0 );
|
||||
if( !algo ) {
|
||||
algo = PUBKEY_ALGO_ELGAMAL;
|
||||
both = 1;
|
||||
tty_printf(_("DSA keypair will have 1024 bits.\n"));
|
||||
}
|
||||
nbits = ask_keysize( algo );
|
||||
ndays = ask_valid_days();
|
||||
uid = ask_user_id();
|
||||
|
@ -774,7 +768,12 @@ generate_keypair()
|
|||
pub_root = make_comment_node("#"); delete_kbnode(pub_root);
|
||||
sec_root = make_comment_node("#"); delete_kbnode(sec_root);
|
||||
|
||||
rc = do_create( algo, nbits, pub_root, sec_root, dek, s2k, &skc, ndays, v4);
|
||||
if( both )
|
||||
rc = do_create( PUBKEY_ALGO_DSA, 1024, pub_root, sec_root,
|
||||
dek, s2k, &skc, ndays, 1);
|
||||
else
|
||||
rc = do_create( algo, nbits, pub_root, sec_root,
|
||||
dek, s2k, &skc, ndays, v4);
|
||||
if( !rc )
|
||||
write_uid(pub_root, uid );
|
||||
if( !rc )
|
||||
|
@ -784,6 +783,16 @@ generate_keypair()
|
|||
if( !rc )
|
||||
rc = write_selfsig(sec_root, pub_root, skc);
|
||||
|
||||
if( both ) {
|
||||
rc = do_create( algo, nbits, pub_root, sec_root,
|
||||
dek, s2k, NULL, ndays, 1 );
|
||||
if( !rc )
|
||||
rc = write_keybinding(pub_root, pub_root, skc);
|
||||
if( !rc )
|
||||
rc = write_keybinding(sec_root, pub_root, skc);
|
||||
}
|
||||
|
||||
|
||||
if( !rc ) {
|
||||
KBPOS pub_kbpos;
|
||||
KBPOS sec_kbpos;
|
||||
|
@ -958,7 +967,8 @@ generate_subkeypair( const char *username )
|
|||
goto leave;
|
||||
|
||||
|
||||
algo = ask_algo( &v4 );
|
||||
algo = ask_algo( &v4, 1 );
|
||||
assert(algo);
|
||||
nbits = ask_keysize( algo );
|
||||
ndays = ask_valid_days();
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@ u16 checksum_u16( unsigned n );
|
|||
u16 checksum( byte *p, unsigned n );
|
||||
u16 checksum_mpi( MPI a );
|
||||
u16 checksum_mpi_counted_nbits( MPI a );
|
||||
u32 buffer_to_u32( const byte *buffer );
|
||||
|
||||
/*-- encode.c --*/
|
||||
int encode_symmetric( const char *filename );
|
||||
|
|
|
@ -232,25 +232,42 @@ static void
|
|||
proc_plaintext( CTX c, PACKET *pkt )
|
||||
{
|
||||
PKT_plaintext *pt = pkt->pkt.plaintext;
|
||||
int rc;
|
||||
int any, rc;
|
||||
KBNODE n;
|
||||
|
||||
if( opt.verbose )
|
||||
log_info("original file name='%.*s'\n", pt->namelen, pt->name);
|
||||
free_md_filter_context( &c->mfx );
|
||||
/* FIXME: take the digest algo(s) to use from the
|
||||
* onepass_sig packet (if we have these)
|
||||
* And look at the sigclass to check whether we should use the
|
||||
* textmode filter (sigclass 0x01)
|
||||
/* fixme: look at the sigclass to check whether we should use the
|
||||
* textmode filter (sigclass 0x01)
|
||||
*/
|
||||
c->mfx.md = md_open( DIGEST_ALGO_RMD160, 0);
|
||||
/*md_start_debug(c->mfx.md, "proc_plaintext");*/
|
||||
md_enable( c->mfx.md, DIGEST_ALGO_SHA1 );
|
||||
md_enable( c->mfx.md, DIGEST_ALGO_MD5 );
|
||||
if( !check_digest_algo(DIGEST_ALGO_TIGER) )
|
||||
md_enable( c->mfx.md, DIGEST_ALGO_TIGER );
|
||||
rc = handle_plaintext( pt, &c->mfx );
|
||||
c->mfx.md = md_open( 0, 0);
|
||||
any = 0;
|
||||
for(n=c->list; n; n = n->next ) {
|
||||
if( n->pkt->pkttype == PKT_ONEPASS_SIG
|
||||
&& n->pkt->pkt.onepass_sig->digest_algo ) {
|
||||
md_enable( c->mfx.md, n->pkt->pkt.onepass_sig->digest_algo );
|
||||
any = 1;
|
||||
}
|
||||
}
|
||||
if( !any ) { /* no onepass sig packet: enable all algos */
|
||||
md_enable( c->mfx.md, DIGEST_ALGO_RMD160 );
|
||||
md_enable( c->mfx.md, DIGEST_ALGO_SHA1 );
|
||||
md_enable( c->mfx.md, DIGEST_ALGO_MD5 );
|
||||
}
|
||||
if( c->mfx.md ) {
|
||||
m_check(c->mfx.md);
|
||||
if( c->mfx.md->list )
|
||||
m_check( c->mfx.md->list );
|
||||
}
|
||||
rc = handle_plaintext( pt, &c->mfx, c->sigs_only );
|
||||
if( rc )
|
||||
log_error( "handle plaintext failed: %s\n", g10_errstr(rc));
|
||||
if( c->mfx.md ) {
|
||||
m_check(c->mfx.md);
|
||||
if( c->mfx.md->list )
|
||||
m_check( c->mfx.md->list );
|
||||
}
|
||||
free_packet(pkt);
|
||||
c->last_was_session_key = 0;
|
||||
}
|
||||
|
@ -312,6 +329,12 @@ do_check_sig( CTX c, KBNODE node, int *is_selfsig )
|
|||
if( (rc=check_digest_algo(algo)) )
|
||||
return rc;
|
||||
|
||||
if( c->mfx.md ) {
|
||||
m_check(c->mfx.md);
|
||||
if( c->mfx.md->list )
|
||||
m_check( c->mfx.md->list );
|
||||
}
|
||||
|
||||
if( sig->sig_class == 0x00 ) {
|
||||
if( c->mfx.md )
|
||||
md = md_copy( c->mfx.md );
|
||||
|
@ -792,7 +815,7 @@ check_sig_and_print( CTX c, KBNODE node )
|
|||
tstr = asctime(localtime (&stamp));
|
||||
astr = pubkey_algo_to_string( sig->pubkey_algo );
|
||||
log_info(_("Signature made %.*s using %s key ID %08lX\n"),
|
||||
strlen(tstr)-1, tstr, astr? astr: "?", (ulong)sig->keyid[1] );
|
||||
(int)strlen(tstr)-1, tstr, astr? astr: "?", (ulong)sig->keyid[1] );
|
||||
|
||||
rc = do_check_sig(c, node, NULL );
|
||||
if( !rc || rc == G10ERR_BAD_SIGN ) {
|
||||
|
|
12
g10/misc.c
12
g10/misc.c
|
@ -152,3 +152,15 @@ checksum_mpi_counted_nbits( MPI a )
|
|||
return csum;
|
||||
}
|
||||
|
||||
|
||||
u32
|
||||
buffer_to_u32( const byte *buffer )
|
||||
{
|
||||
unsigned long a;
|
||||
a = *buffer << 24;
|
||||
a |= buffer[1] << 16;
|
||||
a |= buffer[2] << 8;
|
||||
a |= buffer[3];
|
||||
return a;
|
||||
}
|
||||
|
||||
|
|
|
@ -276,7 +276,7 @@ int decrypt_data( PKT_encrypted *ed, DEK *dek );
|
|||
int encrypt_data( PKT_encrypted *ed, DEK *dek );
|
||||
|
||||
/*-- plaintext.c --*/
|
||||
int handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx );
|
||||
int handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,int nooutput);
|
||||
int ask_for_detached_datafile( md_filter_context_t *mfx, const char *inname );
|
||||
|
||||
/*-- comment.c --*/
|
||||
|
@ -286,6 +286,8 @@ int write_comment( IOBUF out, const char *s );
|
|||
int make_keysig_packet( PKT_signature **ret_sig, PKT_public_cert *pkc,
|
||||
PKT_user_id *uid, PKT_public_cert *subpkc,
|
||||
PKT_secret_cert *skc,
|
||||
int sigclass, int digest_algo );
|
||||
int sigclass, int digest_algo,
|
||||
int (*mksubpkt)(PKT_signature *, void *),
|
||||
void *opaque );
|
||||
|
||||
#endif /*G10_PACKET_H*/
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "memory.h"
|
||||
#include "filter.h"
|
||||
#include "options.h"
|
||||
#include "main.h"
|
||||
|
||||
static int mpi_print_mode = 0;
|
||||
static int list_mode = 0;
|
||||
|
@ -85,16 +86,6 @@ read_32(IOBUF inp)
|
|||
return a;
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
buffer_to_u32( const byte *buffer )
|
||||
{
|
||||
unsigned long a;
|
||||
a = *buffer << 24;
|
||||
a |= buffer[1] << 16;
|
||||
a |= buffer[2] << 8;
|
||||
a |= buffer[3];
|
||||
return a;
|
||||
}
|
||||
|
||||
int
|
||||
set_packet_list_mode( int mode )
|
||||
|
@ -622,6 +613,8 @@ parse_sig_subpkt( const byte *buffer, sigsubpkttype_t reqtype, size_t *ret_n )
|
|||
*ret_n = n;
|
||||
switch( type ) {
|
||||
case SIGSUBPKT_SIG_CREATED:
|
||||
case SIGSUBPKT_SIG_EXPIRE:
|
||||
case SIGSUBPKT_KEY_EXPIRE:
|
||||
if( n < 4 )
|
||||
break;
|
||||
return buffer;
|
||||
|
|
|
@ -40,16 +40,18 @@
|
|||
* bytes from the plaintext.
|
||||
*/
|
||||
int
|
||||
handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx )
|
||||
handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx, int nooutput )
|
||||
{
|
||||
char *fname;
|
||||
char *fname = NULL;
|
||||
FILE *fp = NULL;
|
||||
int rc = 0;
|
||||
int c;
|
||||
int convert = pt->mode == 't';
|
||||
|
||||
/* create the filename as C string */
|
||||
if( opt.outfile ) {
|
||||
if( nooutput )
|
||||
;
|
||||
else if( opt.outfile ) {
|
||||
fname = m_alloc( strlen( opt.outfile ) + 1);
|
||||
strcpy(fname, opt.outfile );
|
||||
}
|
||||
|
@ -59,14 +61,16 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx )
|
|||
fname[pt->namelen] = 0;
|
||||
}
|
||||
|
||||
if( !*fname || (*fname=='-' && !fname[1])) {
|
||||
if( nooutput )
|
||||
;
|
||||
else if( !*fname || (*fname=='-' && !fname[1])) {
|
||||
/* no filename or "-" given; write to stdout */
|
||||
fp = stdout;
|
||||
}
|
||||
else if( overwrite_filep( fname ) )
|
||||
goto leave;
|
||||
|
||||
if( fp )
|
||||
if( fp || nooutput )
|
||||
;
|
||||
else if( !(fp = fopen(fname,"wb")) ) {
|
||||
log_error("Error creating '%s': %s\n", fname, strerror(errno) );
|
||||
|
@ -86,10 +90,13 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx )
|
|||
md_putc(mfx->md, c );
|
||||
if( convert && c == '\r' )
|
||||
continue; /* FIXME: this hack is too simple */
|
||||
if( putc( c, fp ) == EOF ) {
|
||||
log_error("Error writing to '%s': %s\n", fname, strerror(errno) );
|
||||
rc = G10ERR_WRITE_FILE;
|
||||
goto leave;
|
||||
if( fp ) {
|
||||
if( putc( c, fp ) == EOF ) {
|
||||
log_error("Error writing to '%s': %s\n",
|
||||
fname, strerror(errno) );
|
||||
rc = G10ERR_WRITE_FILE;
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -99,11 +106,13 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx )
|
|||
md_putc(mfx->md, c );
|
||||
if( convert && c == '\r' )
|
||||
continue; /* FIXME: this hack is too simple */
|
||||
if( putc( c, fp ) == EOF ) {
|
||||
log_error("Error writing to '%s': %s\n",
|
||||
fname, strerror(errno) );
|
||||
rc = G10ERR_WRITE_FILE;
|
||||
goto leave;
|
||||
if( fp ) {
|
||||
if( putc( c, fp ) == EOF ) {
|
||||
log_error("Error writing to '%s': %s\n",
|
||||
fname, strerror(errno) );
|
||||
rc = G10ERR_WRITE_FILE;
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
}
|
||||
iobuf_clear_eof(pt->buf);
|
||||
|
|
|
@ -159,7 +159,7 @@ gen_revoke( const char *uname )
|
|||
|
||||
|
||||
/* create it */
|
||||
rc = make_keysig_packet( &sig, pkc, NULL, NULL, skc, 0x20, 0);
|
||||
rc = make_keysig_packet( &sig, pkc, NULL, NULL, skc, 0x20, 0, NULL, NULL);
|
||||
if( rc ) {
|
||||
log_error("make_keysig_packet failed: %s\n", g10_errstr(rc));
|
||||
goto leave;
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "cipher.h"
|
||||
#include "main.h"
|
||||
#include "status.h"
|
||||
#include "i18n.h"
|
||||
|
||||
struct cmp_help_context_s {
|
||||
PKT_signature *sig;
|
||||
|
@ -148,6 +149,7 @@ do_check( PKT_public_cert *pkc, PKT_signature *sig, MD_HANDLE digest )
|
|||
MPI result = NULL;
|
||||
int rc=0;
|
||||
struct cmp_help_context_s ctx;
|
||||
u32 cur_time;
|
||||
|
||||
if( pkc->version == 4 && pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E ) {
|
||||
log_info("this is a PGP generated "
|
||||
|
@ -158,6 +160,21 @@ do_check( PKT_public_cert *pkc, PKT_signature *sig, MD_HANDLE digest )
|
|||
if( pkc->timestamp > sig->timestamp )
|
||||
return G10ERR_TIME_CONFLICT; /* pubkey newer that signature */
|
||||
|
||||
cur_time = make_timestamp();
|
||||
if( pkc->timestamp > cur_time ) {
|
||||
log_info(_("public key created in future (time warp or clock problem)\n"));
|
||||
return G10ERR_TIME_CONFLICT;
|
||||
}
|
||||
|
||||
if( pkc->valid_days && add_days_to_timestamp(pkc->timestamp,
|
||||
pkc->valid_days) < cur_time ) {
|
||||
log_info(_("warning: signature key expired %s\n"), strtimestamp(
|
||||
add_days_to_timestamp(pkc->timestamp,
|
||||
pkc->valid_days)));
|
||||
write_status(STATUS_SIGEXPIRED);
|
||||
}
|
||||
|
||||
|
||||
if( (rc=check_digest_algo(sig->digest_algo)) )
|
||||
return rc;
|
||||
if( (rc=check_pubkey_algo(sig->pubkey_algo)) )
|
||||
|
|
34
g10/sign.c
34
g10/sign.c
|
@ -98,7 +98,22 @@ hash_for(int pubkey_algo )
|
|||
return DEFAULT_DIGEST_ALGO;
|
||||
}
|
||||
|
||||
static int
|
||||
only_old_style( SKC_LIST skc_list )
|
||||
{
|
||||
SKC_LIST skc_rover = NULL;
|
||||
int old_style = 0;
|
||||
|
||||
/* if there are only old style capable key we use the old sytle */
|
||||
for( skc_rover = skc_list; skc_rover; skc_rover = skc_rover->next ) {
|
||||
PKT_secret_cert *skc = skc_rover->skc;
|
||||
if( skc->pubkey_algo == PUBKEY_ALGO_RSA && skc->version < 4 )
|
||||
old_style = 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
return old_style;
|
||||
}
|
||||
|
||||
/****************
|
||||
* Sign the files whose names are in FILENAME.
|
||||
|
@ -131,6 +146,8 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
|
|||
SKC_LIST skc_list = NULL;
|
||||
SKC_LIST skc_rover = NULL;
|
||||
int multifile = 0;
|
||||
int old_style = opt.rfc1991;
|
||||
|
||||
|
||||
memset( &afx, 0, sizeof afx);
|
||||
memset( &zfx, 0, sizeof zfx);
|
||||
|
@ -151,6 +168,8 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
|
|||
|
||||
if( (rc=build_skc_list( locusr, &skc_list, 1, 1 )) )
|
||||
goto leave;
|
||||
if( !old_style )
|
||||
old_style = only_old_style( skc_list );
|
||||
if( encrypt ) {
|
||||
if( (rc=build_pkc_list( remusr, &pkc_list, 2 )) )
|
||||
goto leave;
|
||||
|
@ -204,11 +223,13 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
|
|||
iobuf_push_filter( out, encrypt_filter, &efx );
|
||||
}
|
||||
|
||||
if( opt.compress && !outfile )
|
||||
if( opt.compress && !outfile ) {
|
||||
if( old_style )
|
||||
zfx.algo = 1;
|
||||
iobuf_push_filter( out, compress_filter, &zfx );
|
||||
}
|
||||
|
||||
|
||||
if( !detached && !opt.rfc1991 ) {
|
||||
if( !detached && !old_style ) {
|
||||
/* loop over the secret certificates and build headers */
|
||||
for( skc_rover = skc_list; skc_rover; skc_rover = skc_rover->next ) {
|
||||
PKT_secret_cert *skc;
|
||||
|
@ -439,6 +460,7 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile )
|
|||
int rc = 0;
|
||||
SKC_LIST skc_list = NULL;
|
||||
SKC_LIST skc_rover = NULL;
|
||||
int old_style = opt.rfc1991;
|
||||
|
||||
memset( &afx, 0, sizeof afx);
|
||||
memset( &tfx, 0, sizeof tfx);
|
||||
|
@ -446,6 +468,8 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile )
|
|||
|
||||
if( (rc=build_skc_list( locusr, &skc_list, 1, 1 )) )
|
||||
goto leave;
|
||||
if( !old_style )
|
||||
old_style = only_old_style( skc_list );
|
||||
|
||||
/* prepare iobufs */
|
||||
if( !(inp = iobuf_open(fname)) ) {
|
||||
|
@ -469,9 +493,9 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile )
|
|||
goto leave;
|
||||
}
|
||||
|
||||
/* FIXME: This stuff is not correct if mutliple hash algos are used*/
|
||||
/* FIXME: This stuff is not correct if multiple hash algos are used*/
|
||||
iobuf_writestr(out, "-----BEGIN PGP SIGNED MESSAGE-----\n" );
|
||||
if( opt.rfc1991
|
||||
if( old_style
|
||||
|| (opt.def_digest_algo?opt.def_digest_algo:DEFAULT_DIGEST_ALGO)
|
||||
== DIGEST_ALGO_MD5 )
|
||||
iobuf_writestr(out, "\n" );
|
||||
|
|
|
@ -53,6 +53,7 @@ write_status_text( int no, const char *text)
|
|||
case STATUS_LEAVE : s = "LEAVE\n"; break;
|
||||
case STATUS_ABORT : s = "ABORT\n"; break;
|
||||
case STATUS_GOODSIG: s = "GOODSIG\n"; break;
|
||||
case STATUS_SIGEXPIRED: s = "SIGEXPIRED\n"; break;
|
||||
case STATUS_BADSIG : s = "BADSIG\n"; break;
|
||||
case STATUS_ERRSIG : s = "ERRSIG\n"; break;
|
||||
case STATUS_BADARMOR : s = "BADARMOR\n"; break;
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#define STATUS_BADARMOR 7
|
||||
|
||||
#define STATUS_RSA_OR_IDEA 8
|
||||
|
||||
#define STATUS_SIGEXPIRED 9
|
||||
|
||||
/*-- status.c --*/
|
||||
void set_status_fd( int fd );
|
||||
|
|
|
@ -1705,7 +1705,7 @@ check_trust( PKT_public_cert *pkc, unsigned *r_trustlevel )
|
|||
TRUSTREC rec;
|
||||
unsigned trustlevel = TRUST_UNKNOWN;
|
||||
int rc=0;
|
||||
int cur_time;
|
||||
u32 cur_time;
|
||||
|
||||
if( DBG_TRUST )
|
||||
log_info("check_trust() called.\n");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue