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

fingerprints and self signatures added

This commit is contained in:
Werner Koch 1997-12-09 12:46:23 +00:00
parent 3b1b6f9d98
commit 935965049d
23 changed files with 783 additions and 444 deletions

View file

@ -169,13 +169,13 @@ do_public_cert( IOBUF out, int ctb, PKT_public_cert *pkc )
write_16(a, pkc->valid_days );
iobuf_put(a, pkc->pubkey_algo );
if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
mpi_encode(a, pkc->d.elg.p );
mpi_encode(a, pkc->d.elg.g );
mpi_encode(a, pkc->d.elg.y );
mpi_write(a, pkc->d.elg.p );
mpi_write(a, pkc->d.elg.g );
mpi_write(a, pkc->d.elg.y );
}
else if( pkc->pubkey_algo == PUBKEY_ALGO_RSA ) {
mpi_encode(a, pkc->d.rsa.rsa_n );
mpi_encode(a, pkc->d.rsa.rsa_e );
mpi_write(a, pkc->d.rsa.rsa_n );
mpi_write(a, pkc->d.rsa.rsa_e );
}
else {
rc = G10ERR_PUBKEY_ALGO;
@ -191,6 +191,31 @@ do_public_cert( IOBUF out, int ctb, PKT_public_cert *pkc )
return rc;
}
/****************
* Make a hash value from the public key certificate
*/
void
hash_public_cert( MD_HANDLE *md, PKT_public_cert *pkc )
{
PACKET pkt;
int rc = 0;
int c;
IOBUF a = iobuf_temp();
/* build the packet */
init_packet(&pkt);
pkt.pkttype = PKT_PUBLIC_CERT;
pkt.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 )
md_putchar( md, c );
iobuf_cancel(a);
}
static int
do_secret_cert( IOBUF out, int ctb, PKT_secret_cert *skc )
{
@ -202,48 +227,33 @@ do_secret_cert( IOBUF out, int ctb, PKT_secret_cert *skc )
write_16(a, skc->valid_days );
iobuf_put(a, skc->pubkey_algo );
if( skc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
mpi_encode(a, skc->d.elg.p );
mpi_encode(a, skc->d.elg.g );
mpi_encode(a, skc->d.elg.y );
mpi_write(a, skc->d.elg.p );
mpi_write(a, skc->d.elg.g );
mpi_write(a, skc->d.elg.y );
iobuf_put(a, skc->d.elg.protect_algo );
skc->d.elg.calc_csum = 0;
if( skc->d.elg.protect_algo ) {
assert( skc->d.elg.is_protected == 1 );
assert( skc->d.elg.protect_algo == CIPHER_ALGO_BLOWFISH );
iobuf_write(a, skc->d.elg.protect.blowfish.iv, 8 );
mpi_write_csum(a, (byte*)skc->d.elg.x, &skc->d.elg.calc_csum );
}
else { /* not protected */
assert( !skc->d.elg.is_protected );
mpi_encode_csum(a, skc->d.elg.x, &skc->d.elg.calc_csum );
}
write_16(a, skc->d.elg.calc_csum );
mpi_write(a, skc->d.elg.x );
write_16(a, skc->d.elg.csum );
}
else if( skc->pubkey_algo == PUBKEY_ALGO_RSA ) {
mpi_encode(a, skc->d.rsa.rsa_n );
mpi_encode(a, skc->d.rsa.rsa_e );
mpi_write(a, skc->d.rsa.rsa_n );
mpi_write(a, skc->d.rsa.rsa_e );
iobuf_put(a, skc->d.rsa.protect_algo );
skc->d.rsa.calc_csum = 0;
if( skc->d.rsa.protect_algo ) {
assert( skc->d.rsa.is_protected == 1 );
assert( skc->d.rsa.protect_algo == CIPHER_ALGO_BLOWFISH );
iobuf_write(a, skc->d.rsa.protect.blowfish.iv, 8 );
mpi_write_csum(a, (byte*)skc->d.rsa.rsa_d, &skc->d.rsa.calc_csum );
mpi_write_csum(a, (byte*)skc->d.rsa.rsa_p, &skc->d.rsa.calc_csum );
mpi_write_csum(a, (byte*)skc->d.rsa.rsa_q, &skc->d.rsa.calc_csum );
mpi_write_csum(a, (byte*)skc->d.rsa.rsa_u, &skc->d.rsa.calc_csum );
}
else { /* Not protected: You fool you! */
assert( !skc->d.rsa.is_protected );
mpi_encode_csum(a, skc->d.rsa.rsa_d, &skc->d.rsa.calc_csum );
mpi_encode_csum(a, skc->d.rsa.rsa_p, &skc->d.rsa.calc_csum );
mpi_encode_csum(a, skc->d.rsa.rsa_q, &skc->d.rsa.calc_csum );
mpi_encode_csum(a, skc->d.rsa.rsa_u, &skc->d.rsa.calc_csum );
}
write_16(a, skc->d.rsa.calc_csum );
mpi_write(a, skc->d.rsa.rsa_d );
mpi_write(a, skc->d.rsa.rsa_p );
mpi_write(a, skc->d.rsa.rsa_q );
mpi_write(a, skc->d.rsa.rsa_u );
write_16(a, skc->d.rsa.csum );
}
else {
rc = G10ERR_PUBKEY_ALGO;
@ -270,11 +280,11 @@ do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc )
write_32(a, enc->keyid[1] );
iobuf_put(a,enc->pubkey_algo );
if( enc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
mpi_encode(a, enc->d.elg.a );
mpi_encode(a, enc->d.elg.b );
mpi_write(a, enc->d.elg.a );
mpi_write(a, enc->d.elg.b );
}
else if( enc->pubkey_algo == PUBKEY_ALGO_RSA ) {
mpi_encode(a, enc->d.rsa.rsa_integer );
mpi_write(a, enc->d.rsa.rsa_integer );
}
else {
rc = G10ERR_PUBKEY_ALGO;
@ -379,14 +389,14 @@ do_signature( IOBUF out, int ctb, PKT_signature *sig )
iobuf_put(a, sig->d.elg.digest_algo );
iobuf_put(a, sig->d.elg.digest_start[0] );
iobuf_put(a, sig->d.elg.digest_start[1] );
mpi_encode(a, sig->d.elg.a );
mpi_encode(a, sig->d.elg.b );
mpi_write(a, sig->d.elg.a );
mpi_write(a, sig->d.elg.b );
}
else if( sig->pubkey_algo == PUBKEY_ALGO_RSA ) {
iobuf_put(a, sig->d.rsa.digest_algo );
iobuf_put(a, sig->d.rsa.digest_start[0] );
iobuf_put(a, sig->d.rsa.digest_start[1] );
mpi_encode(a, sig->d.rsa.rsa_integer );
mpi_write(a, sig->d.rsa.rsa_integer );
}
else {
rc = G10ERR_PUBKEY_ALGO;

View file

@ -100,26 +100,15 @@ free_secret_cert( PKT_secret_cert *cert )
mpi_free( cert->d.elg.p );
mpi_free( cert->d.elg.g );
mpi_free( cert->d.elg.y );
if( cert->d.rsa.is_protected )
m_free( cert->d.elg.x );
else
mpi_free( cert->d.elg.x );
mpi_free( cert->d.elg.x );
}
else if( cert->pubkey_algo == PUBKEY_ALGO_RSA ) {
mpi_free( cert->d.rsa.rsa_n );
mpi_free( cert->d.rsa.rsa_e );
if( cert->d.rsa.is_protected ) {
m_free( cert->d.rsa.rsa_d );
m_free( cert->d.rsa.rsa_p );
m_free( cert->d.rsa.rsa_q );
m_free( cert->d.rsa.rsa_u );
}
else {
mpi_free( cert->d.rsa.rsa_d );
mpi_free( cert->d.rsa.rsa_p );
mpi_free( cert->d.rsa.rsa_q );
mpi_free( cert->d.rsa.rsa_u );
}
mpi_free( cert->d.rsa.rsa_d );
mpi_free( cert->d.rsa.rsa_p );
mpi_free( cert->d.rsa.rsa_q );
mpi_free( cert->d.rsa.rsa_u );
}
m_free(cert);
}

View file

@ -124,6 +124,8 @@ main( int argc, char **argv )
{ 512, "cache-all" ,0, "hold everything in memory"},
{ 513, "gen-prime" , 1, "\rgenerate a prime of length n" },
{ 514, "test" , 0, "\rdevelopment usage" },
{ 515, "change-passphrase", 0, "change the passphrase of your secret keyring"},
{ 515, "fingerprint", 0, "show the fingerprints"},
{0} };
ARGPARSE_ARGS pargs = { &argc, &argv, 0 };
IOBUF a;
@ -136,11 +138,14 @@ main( int argc, char **argv )
int nrings=0;
armor_filter_context_t afx;
const char *s;
int detached_sig = 0;
opt.compress = -1; /* defaults to default compression level */
while( arg_parse( &pargs, opts) ) {
switch( pargs.r_opt ) {
case 'v': opt.verbose++; break;
case 'v': opt.verbose++;
opt.list_sigs=1;
break;
case 'z':
opt.compress = pargs.r.ret_int;
break;
@ -151,7 +156,7 @@ main( int argc, char **argv )
opt.outfile_is_stdout = 1;
break;
case 'e': action = action == aSign? aSignEncr : aEncr; break;
case 'b': opt.detached_sig = 1;
case 'b': detached_sig = 1;
/* fall trough */
case 's': action = action == aEncr? aSignEncr : aSign; break;
case 'l': /* store the local users */
@ -171,13 +176,14 @@ main( int argc, char **argv )
case 502: opt.answer_no = 1; break;
case 503: action = aKeygen; break;
case 507: action = aStore; break;
case 508: opt.check_sigs = 1; break;
case 508: opt.check_sigs = 1; opt.list_sigs = 1; break;
case 509: add_keyring(pargs.r.ret_str); nrings++; break;
case 510: opt.debug |= pargs.r.ret_ulong; break;
case 511: opt.debug = ~0; break;
case 512: opt.cache_all = 1; break;
case 513: action = aPrimegen; break;
case 514: action = aTest; break;
case 515: opt.fingerprint = 1; break;
default : pargs.err = 2; break;
}
}
@ -230,7 +236,7 @@ main( int argc, char **argv )
case aSign: /* sign the given file */
if( argc > 1 )
usage(1);
if( (rc = sign_file(fname, opt.detached_sig, locusr)) )
if( (rc = sign_file(fname, detached_sig, locusr)) )
log_error("sign_file('%s'): %s\n", fname_print, g10_errstr(rc) );
break;

View file

@ -50,6 +50,8 @@ unsigned nbits_from_skc( PKT_secret_cert *skc );
const char *datestr_from_pkc( PKT_public_cert *pkc );
const char *datestr_from_skc( PKT_secret_cert *skc );
const char *datestr_from_sig( PKT_signature *sig );
byte *fingerprint_from_skc( PKT_secret_cert *skc, size_t *ret_len );
byte *fingerprint_from_pkc( PKT_public_cert *pkc, size_t *ret_len );

View file

@ -51,9 +51,44 @@ answer_is_yes( const char *s )
}
static u16
checksum_u16( unsigned n )
{
u16 a;
a = (n >> 8) & 0xff;
a |= n & 0xff;
return a;
}
static u16
checksum( byte *p, unsigned n )
{
u16 a;
for(a=0; n; n-- )
a += *p++;
return a;
}
static u16
checksum_mpi( MPI a )
{
u16 csum;
byte *buffer;
unsigned nbytes;
buffer = mpi_get_buffer( a, &nbytes, NULL );
csum = checksum_u16( nbytes*8 );
csum += checksum( buffer, nbytes );
m_free( buffer );
return csum;
}
static void
write_uid( IOBUF out, const char *s )
write_uid( IOBUF out, const char *s, PKT_user_id **upkt )
{
PACKET pkt;
size_t n = strlen(s);
@ -65,13 +100,44 @@ write_uid( IOBUF out, const char *s )
strcpy(pkt.pkt.user_id->name, s);
if( (rc = build_packet( out, &pkt )) )
log_error("build_packet(user_id) failed: %s\n", g10_errstr(rc) );
if( upkt ) {
*upkt = pkt.pkt.user_id;
pkt.pkt.user_id = NULL;
}
free_packet( &pkt );
}
static int
write_selfsig( IOBUF out, PKT_public_cert *pkc, PKT_user_id *uid,
PKT_secret_cert *skc )
{
PACKET pkt;
PKT_signature *sig;
int rc=0;
if( opt.verbose )
log_info("writing self signature\n");
rc = make_keysig_packet( &sig, pkc, uid, skc, 0x13, DIGEST_ALGO_RMD160 );
if( rc ) {
log_error("make_keysig_packet failed: %s\n", g10_errstr(rc) );
return rc;
}
pkt.pkttype = PKT_SIGNATURE;
pkt.pkt.signature = sig;
if( (rc = build_packet( out, &pkt )) )
log_error("build_packet(signature) failed: %s\n", g10_errstr(rc) );
free_packet( &pkt );
return rc;
}
#ifdef HAVE_RSA_CIPHER
static int
gen_rsa(unsigned nbits, IOBUF pub_io, IOBUF sec_io)
gen_rsa(unsigned nbits, IOBUF pub_io, IOBUF sec_io, DEK *dek,
PKT_public_cert **ret_pkc, PKT_secret_cert **ret_skc )
{
int rc;
PACKET pkt1, pkt2;
@ -80,6 +146,9 @@ gen_rsa(unsigned nbits, IOBUF pub_io, IOBUF sec_io)
RSA_public_key pk;
RSA_secret_key sk;
init_packet(&pkt1);
init_packet(&pkt2);
rsa_generate( &pk, &sk, nbits );
skc = m_alloc( sizeof *skc );
@ -96,15 +165,28 @@ gen_rsa(unsigned nbits, IOBUF pub_io, IOBUF sec_io)
skc->d.rsa.rsa_p = sk.p;
skc->d.rsa.rsa_q = sk.q;
skc->d.rsa.rsa_u = sk.u;
skc->d.rsa.calc_csum = 0;
skc->d.rsa.is_protected = 0; /* FIXME!!! */
skc->d.rsa.protect_algo = 0; /* should be blowfish */
/*memcpy(skc->d.rsa.protect.blowfish.iv,"12345678", 8);*/
skc->d.rsa.csum = checksum_mpi( skc->d.rsa.rsa_d );
skc->d.rsa.csum += checksum_mpi( skc->d.rsa.rsa_p );
skc->d.rsa.csum += checksum_mpi( skc->d.rsa.rsa_q );
skc->d.rsa.csum += checksum_mpi( skc->d.rsa.rsa_u );
if( !dek ) {
skc->d.rsa.is_protected = 0;
skc->d.rsa.protect_algo = 0;
}
else {
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( 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) );
goto leave;
}
}
init_packet(&pkt1);
pkt1.pkttype = PKT_PUBLIC_CERT;
pkt1.pkt.public_cert = pkc;
init_packet(&pkt2);
pkt2.pkttype = PKT_SECRET_CERT;
pkt2.pkt.secret_cert = skc;
@ -116,6 +198,10 @@ gen_rsa(unsigned nbits, IOBUF pub_io, IOBUF sec_io)
log_error("build secret_cert packet failed: %s\n", g10_errstr(rc) );
goto leave;
}
*ret_pkc = pkt1.pkt.public_cert;
pkt1.pkt.public_cert = NULL;
*ret_skc = pkt1.pkt.secret_cert;
pkt1.pkt.secret_cert = NULL;
leave:
free_packet(&pkt1);
@ -125,14 +211,19 @@ gen_rsa(unsigned nbits, IOBUF pub_io, IOBUF sec_io)
#endif /*HAVE_RSA_CIPHER*/
static int
gen_elg(unsigned nbits, IOBUF pub_io, IOBUF sec_io)
gen_elg(unsigned nbits, IOBUF pub_io, IOBUF sec_io, DEK *dek,
PKT_public_cert **ret_pkc, PKT_secret_cert **ret_skc )
{
int rc;
PACKET pkt1, pkt2;
PKT_secret_cert *skc;
PKT_secret_cert *skc, *unprotected_skc;
PKT_public_cert *pkc;
ELG_public_key pk;
ELG_secret_key sk;
unsigned nbytes;
init_packet(&pkt1);
init_packet(&pkt2);
elg_generate( &pk, &sk, nbits );
@ -150,15 +241,25 @@ gen_elg(unsigned nbits, IOBUF pub_io, IOBUF sec_io)
skc->d.elg.y = sk.y;
skc->d.elg.x = sk.x;
skc->d.elg.calc_csum = 0;
skc->d.elg.is_protected = 0; /* FIXME!!! */
skc->d.elg.protect_algo = 0; /* should be blowfish */
/*memcpy(skc->d.elg.protect.blowfish.iv,"12345678", 8);*/
skc->d.elg.csum = checksum_mpi( skc->d.elg.x );
unprotected_skc = copy_secret_cert( NULL, skc );
if( !dek ) {
skc->d.elg.is_protected = 0;
skc->d.elg.protect_algo = 0;
}
else {
skc->d.elg.is_protected = 0;
skc->d.elg.protect_algo = CIPHER_ALGO_BLOWFISH;
randomize_buffer(skc->d.elg.protect.blowfish.iv, 8, 1);
rc = protect_secret_key( skc, dek );
if( rc ) {
log_error("protect_secret_key failed: %s\n", g10_errstr(rc) );
goto leave;
}
}
init_packet(&pkt1);
pkt1.pkttype = PKT_PUBLIC_CERT;
pkt1.pkt.public_cert = pkc;
init_packet(&pkt2);
pkt2.pkttype = PKT_SECRET_CERT;
pkt2.pkt.secret_cert = skc;
@ -170,10 +271,17 @@ gen_elg(unsigned nbits, IOBUF pub_io, IOBUF sec_io)
log_error("build secret_cert packet failed: %s\n", g10_errstr(rc) );
goto leave;
}
*ret_pkc = pkt1.pkt.public_cert;
pkt1.pkt.public_cert = NULL;
*ret_skc = unprotected_skc;
unprotected_skc = NULL;
leave:
free_packet(&pkt1);
free_packet(&pkt2);
if( unprotected_skc )
free_secret_cert( unprotected_skc );
return rc;
}
@ -192,6 +300,10 @@ generate_keypair()
char *uid = NULL;
IOBUF pub_io = NULL;
IOBUF sec_io = NULL;
PKT_public_cert *pkc = NULL;
PKT_secret_cert *skc = NULL;
PKT_user_id *upkt = NULL;
DEK *dek = NULL;
int rc;
int algo;
const char *algo_name;
@ -301,6 +413,28 @@ generate_keypair()
}
}
#endif
tty_printf( "You need a Passphrase to protect your secret key.\n\n" );
dek = m_alloc_secure( sizeof *dek );
dek->algo = CIPHER_ALGO_BLOWFISH;
rc = make_dek_from_passphrase( dek , 2 );
if( rc == -1 ) {
m_free(dek); dek = NULL;
tty_printf(
"You don't what a passphrase - this is probably a *bad* idea!\n"
"I will do it anyway. You can change your passphrase at anytime,\n"
"using this program with the option \"--change-passphrase\"\n\n" );
}
else if( rc ) {
m_free(dek); dek = NULL;
m_free(uid);
log_error("Error getting the passphrase: %s\n", g10_errstr(rc) );
return;
}
/* now check wether we a are allowed to write the keyrings */
if( !(rc=overwrite_filep( pub_fname )) ) {
if( !(pub_io = iobuf_create( pub_fname )) )
@ -334,23 +468,41 @@ generate_keypair()
return;
}
write_comment( pub_io, "#public key created by G10 pre-release " VERSION );
write_comment( sec_io, "#secret key created by G10 pre-release " VERSION );
if( algo == PUBKEY_ALGO_ELGAMAL )
gen_elg(nbits, pub_io, sec_io);
rc = gen_elg(nbits, pub_io, sec_io, dek, &pkc, &skc);
#ifdef HAVE_RSA_CIPHER
else if( algo == PUBKEY_ALGO_RSA )
gen_rsa(nbits, pub_io, sec_io);
rc = gen_rsa(nbits, pub_io, sec_io, dek, &pkc, &skc);
#endif
else
log_bug(NULL);
write_uid(pub_io, uid );
write_uid(sec_io, uid );
m_free(uid);
if( !rc )
write_uid(pub_io, uid, &upkt );
if( !rc )
write_uid(sec_io, uid, NULL );
if( !rc )
rc = write_selfsig(pub_io, pkc, upkt, skc );
iobuf_close(pub_io);
iobuf_close(sec_io);
if( rc ) {
iobuf_cancel(pub_io);
iobuf_cancel(sec_io);
tty_printf("Key generation failed: %s\n", g10_errstr(rc) );
}
else {
iobuf_close(pub_io);
iobuf_close(sec_io);
tty_printf("public and secret key created and signed.\n" );
}
if( pkc )
free_public_cert( pkc );
if( skc )
free_secret_cert( skc );
if( upkt )
free_user_id( upkt );
m_free(uid);
m_free(dek);
}

View file

@ -171,3 +171,110 @@ datestr_from_sig( PKT_signature *sig )
return buffer;
}
/**************** .
* Return a byte array with the fingerprint for the given PKC/SKC
* The length of the array is returned in ret_len. Caller must free
* the array.
*/
byte *
fingerprint_from_skc( PKT_secret_cert *skc, size_t *ret_len )
{
PKT_public_cert pkc;
byte *p;
pkc.pubkey_algo = skc->pubkey_algo;
if( pkc.pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
pkc.timestamp = skc->timestamp;
pkc.valid_days = skc->valid_days;
pkc.pubkey_algo = skc->pubkey_algo;
pkc.d.elg.p = skc->d.elg.p;
pkc.d.elg.g = skc->d.elg.g;
pkc.d.elg.y = skc->d.elg.y;
}
else if( pkc.pubkey_algo == PUBKEY_ALGO_RSA ) {
pkc.d.rsa.rsa_n = skc->d.rsa.rsa_n;
pkc.d.rsa.rsa_e = skc->d.rsa.rsa_e;
}
p = fingerprint_from_pkc( &pkc, ret_len );
memset(&pkc, 0, sizeof pkc); /* not really needed */
return p;
}
byte *
fingerprint_from_pkc( PKT_public_cert *pkc, size_t *ret_len )
{
byte *p, *buf, *array;
size_t len;
unsigned n;
if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
RMDHANDLE md;
const char *dp;
md = rmd160_open(0);
{ u32 a = pkc->timestamp;
rmd160_putchar( md, a >> 24 );
rmd160_putchar( md, a >> 16 );
rmd160_putchar( md, a >> 8 );
rmd160_putchar( md, a );
}
{ u16 a = pkc->valid_days;
rmd160_putchar( md, a >> 8 );
rmd160_putchar( md, a );
}
rmd160_putchar( md, pkc->pubkey_algo );
p = buf = mpi_get_buffer( pkc->d.elg.p, &n, NULL );
for( ; !*p && n; p++, n-- )
;
rmd160_putchar( md, n>>8); rmd160_putchar( md, n ); rmd160_write( md, p, n );
m_free(buf);
p = buf = mpi_get_buffer( pkc->d.elg.g, &n, NULL );
for( ; !*p && n; p++, n-- )
;
rmd160_putchar( md, n>>8); rmd160_putchar( md, n ); rmd160_write( md, p, n );
m_free(buf);
p = buf = mpi_get_buffer( pkc->d.elg.y, &n, NULL );
for( ; !*p && n; p++, n-- )
;
rmd160_putchar( md, n>>8); rmd160_putchar( md, n ); rmd160_write( md, p, n );
m_free(buf);
dp = rmd160_final(md);
array = m_alloc( 20 );
len = 20;
memcpy(array, dp, 20 );
rmd160_close(md);
}
else if( pkc->pubkey_algo == PUBKEY_ALGO_RSA ) {
MD5HANDLE md;
md = md5_open(0);
p = buf = mpi_get_buffer( pkc->d.rsa.rsa_n, &n, NULL );
for( ; !*p && n; p++, n-- )
;
md5_write( md, p, n );
m_free(buf);
p = buf = mpi_get_buffer( pkc->d.rsa.rsa_e, &n, NULL );
for( ; !*p && n; p++, n-- )
;
md5_write( md, p, n );
m_free(buf);
md5_final(md);
array = m_alloc( 16 );
len = 16;
memcpy(array, md5_read(md), 16 );
md5_close(md);
}
else {
array = m_alloc(1);
len = 0; /* ooops */
}
*ret_len = len;
return array;
}

View file

@ -342,7 +342,7 @@ proc_plaintext( CTX c, PACKET *pkt )
printf("txt: plain text data name='%.*s'\n", pt->namelen, pt->name);
free_md_filter_context( &c->mfx );
/* fixme: take the digest algo to use from the
* onpass_sig packet (if we have these) */
* onepass_sig packet (if we have these) */
c->mfx.md = md_open(DIGEST_ALGO_RMD160, 0);
result = handle_plaintext( pt, &c->mfx );
if( !result )
@ -450,6 +450,34 @@ print_userid( PACKET *pkt )
}
static void
print_fingerprint( PKT_public_cert *pkc, PKT_secret_cert *skc )
{
byte *array, *p;
size_t i, n;
p = array = skc? fingerprint_from_skc( skc, &n )
: fingerprint_from_pkc( pkc, &n );
printf(" Key fingerprint =");
if( n == 20 ) {
for(i=0; i < n ; i++, i++, p += 2 ) {
if( i == 10 )
putchar(' ');
printf(" %02X%02X", *p, p[1] );
}
}
else {
for(i=0; i < n ; i++, p++ ) {
if( i && !(i%8) )
putchar(' ');
printf(" %02X", *p );
}
}
putchar('\n');
m_free(array);
}
/****************
* List the certificate in a user friendly way
*/
@ -478,6 +506,8 @@ list_node( CTX c, NODE node )
printf( "%*s", 31, "" );
print_userid( n2->pkt );
putchar('\n');
if( opt.fingerprint && n2 == node->child )
print_fingerprint( pkc, NULL );
list_node(c, n2 );
}
}
@ -491,18 +521,20 @@ list_node( CTX c, NODE node )
datestr_from_skc( skc ) );
n2 = node->child;
if( !n2 )
printf("ERROR: no user id!");
printf("ERROR: no user id!\n");
else {
print_userid( n2->pkt );
putchar('\n');
if( opt.fingerprint && n2 == node->child )
print_fingerprint( NULL, skc );
}
putchar('\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 );
}
else if( node->pkt->pkttype == PKT_SIGNATURE ) {
else if( node->pkt->pkttype == PKT_SIGNATURE ) {
PKT_signature *sig = node->pkt->pkt.signature;
int rc2;
size_t n;
@ -510,6 +542,9 @@ list_node( CTX c, NODE node )
int sigrc = ' ';
assert( !node->child );
if( !opt.list_sigs )
return;
if( opt.check_sigs ) {
switch( (rc2=do_check_sig( c, node )) ) {

View file

@ -32,8 +32,8 @@ struct {
int answer_no; /* answer no on most questions */
int check_sigs; /* check key signatures */
int cache_all;
int detached_sig;
int reserved3;
int fingerprint; /* list fingerprints */
int list_sigs; /* list signatures */
int reserved4;
int reserved5;
int reserved6;

View file

@ -124,7 +124,6 @@ typedef struct {
MPI rsa_q; /* secret second prime number */
MPI rsa_u; /* secret multiplicative inverse */
u16 csum; /* checksum */
u16 calc_csum; /* and a place to store the calculated csum */
byte is_protected; /* The above infos are protected and must */
/* be decrypteded before use */
byte protect_algo; /* cipher used to protect the secret informations*/
@ -142,7 +141,6 @@ typedef struct {
MPI y; /* g^x mod p */
MPI x; /* secret exponent */
u16 csum; /* checksum */
u16 calc_csum; /* and a place to store the calculated csum */
byte is_protected; /* The above infos are protected and must */
/* be decrypteded before use */
byte protect_algo; /* cipher used to protect the secret informations*/
@ -220,6 +218,7 @@ int parse_packet( IOBUF inp, PACKET *ret_pkt);
/*-- 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 );
/*-- free-packet.c --*/
void free_pubkey_enc( PKT_pubkey_enc *enc );
@ -238,6 +237,7 @@ int signature_check( PKT_signature *sig, MD_HANDLE *digest );
/*-- seckey-cert.c --*/
int check_secret_key( PKT_secret_cert *cert );
int protect_secret_key( PKT_secret_cert *cert, DEK *dek );
/*-- pubkey-enc.c --*/
int get_session_key( PKT_pubkey_enc *k, DEK *dek );
@ -256,5 +256,9 @@ int ask_for_detached_datafile( md_filter_context_t *mfx );
/*-- comment.c --*/
int write_comment( IOBUF out, const char *s );
/*-- sign.c --*/
int make_keysig_packet( PKT_signature **ret_sig, PKT_public_cert *pkc,
PKT_user_id *uid, PKT_secret_cert *skc,
int sigclass, int digest_algo );
#endif /*G10_PACKET_H*/

View file

@ -239,8 +239,8 @@ parse_publickey( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
k->keyid[0], k->keyid[1]);
if( k->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
n = pktlen;
k->d.elg.a = mpi_decode(inp, &n ); pktlen -=n;
k->d.elg.b = mpi_decode(inp, &n ); pktlen -=n;
k->d.elg.a = mpi_read(inp, &n, 0); pktlen -=n;
k->d.elg.b = mpi_read(inp, &n, 0 ); pktlen -=n;
if( list_mode ) {
printf("\telg a: ");
mpi_print(stdout, k->d.elg.a, mpi_print_mode );
@ -251,7 +251,7 @@ parse_publickey( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
}
else if( k->pubkey_algo == PUBKEY_ALGO_RSA ) {
n = pktlen;
k->d.rsa.rsa_integer = mpi_decode(inp, &n ); pktlen -=n;
k->d.rsa.rsa_integer = mpi_read(inp, &n, 0 ); pktlen -=n;
if( list_mode ) {
printf("\trsa integer: ");
mpi_print(stdout, k->d.rsa.rsa_integer, mpi_print_mode );
@ -304,8 +304,8 @@ parse_signature( IOBUF inp, int pkttype, unsigned long pktlen,
sig->d.elg.digest_start[0] = iobuf_get_noeof(inp); pktlen--;
sig->d.elg.digest_start[1] = iobuf_get_noeof(inp); pktlen--;
n = pktlen;
sig->d.elg.a = mpi_decode(inp, &n ); pktlen -=n;
sig->d.elg.b = mpi_decode(inp, &n ); pktlen -=n;
sig->d.elg.a = mpi_read(inp, &n, 0 ); pktlen -=n;
sig->d.elg.b = mpi_read(inp, &n, 0 ); pktlen -=n;
if( list_mode ) {
printf("\tdigest algo %d, begin of digest %02x %02x\n",
sig->d.elg.digest_algo,
@ -313,7 +313,7 @@ parse_signature( IOBUF inp, int pkttype, unsigned long pktlen,
printf("\telg a: ");
mpi_print(stdout, sig->d.elg.a, mpi_print_mode );
printf("\n\telg b: ");
mpi_print(stdout, sig->d.elg.a, mpi_print_mode );
mpi_print(stdout, sig->d.elg.b, mpi_print_mode );
putchar('\n');
}
}
@ -326,7 +326,7 @@ parse_signature( IOBUF inp, int pkttype, unsigned long pktlen,
sig->d.rsa.digest_start[0] = iobuf_get_noeof(inp); pktlen--;
sig->d.rsa.digest_start[1] = iobuf_get_noeof(inp); pktlen--;
n = pktlen;
sig->d.rsa.rsa_integer = mpi_decode(inp, &n ); pktlen -=n;
sig->d.rsa.rsa_integer = mpi_read(inp, &n, 0 ); pktlen -=n;
if( list_mode ) {
printf("\tdigest algo %d, begin of digest %02x %02x\n",
sig->d.rsa.digest_algo,
@ -439,9 +439,9 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen,
if( algorithm == PUBKEY_ALGO_ELGAMAL ) {
MPI elg_p, elg_g, elg_y;
n = pktlen; elg_p = mpi_decode(inp, &n ); pktlen -=n;
n = pktlen; elg_g = mpi_decode(inp, &n ); pktlen -=n;
n = pktlen; elg_y = mpi_decode(inp, &n ); pktlen -=n;
n = pktlen; elg_p = mpi_read(inp, &n, 0 ); pktlen -=n;
n = pktlen; elg_g = mpi_read(inp, &n, 0 ); pktlen -=n;
n = pktlen; elg_y = mpi_read(inp, &n, 0 ); pktlen -=n;
if( list_mode ) {
printf( "\telg p: ");
mpi_print(stdout, elg_p, mpi_print_mode );
@ -483,32 +483,24 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen,
else
cert->d.elg.is_protected = 0;
n = pktlen; mpibuf = mpi_read(inp, &n ); pktlen -=n; assert(n>=2);
cert->d.elg.x = (MPI)mpibuf;
n = pktlen; cert->d.elg.x = mpi_read(inp, &n, 1 ); pktlen -=n;
cert->d.elg.csum = read_16(inp); pktlen -= 2;
cert->d.elg.calc_csum = 0;
if( list_mode ) {
printf("\t[secret value x is not shown]\n"
"\tchecksum: %04hx\n", cert->d.elg.csum);
}
if( !cert->d.elg.is_protected ) { /* convert buffer to MPIs */
mpibuf = (byte*)cert->d.elg.x;
cert->d.elg.calc_csum += checksum( mpibuf );
cert->d.elg.x = mpi_decode_buffer( mpibuf );
m_free( mpibuf );
/*log_mpidump("elg p=", cert->d.elg.p );
log_mpidump("elg g=", cert->d.elg.g );
log_mpidump("elg y=", cert->d.elg.y );
log_mpidump("elg x=", cert->d.elg.x ); */
}
/*log_mpidump("elg p=", cert->d.elg.p );
log_mpidump("elg g=", cert->d.elg.g );
log_mpidump("elg y=", cert->d.elg.y );
log_mpidump("elg x=", cert->d.elg.x ); */
}
}
else if( algorithm == PUBKEY_ALGO_RSA ) {
MPI rsa_pub_mod, rsa_pub_exp;
n = pktlen; rsa_pub_mod = mpi_decode(inp, &n ); pktlen -=n;
n = pktlen; rsa_pub_exp = mpi_decode(inp, &n ); pktlen -=n;
n = pktlen; rsa_pub_mod = mpi_read(inp, &n, 0); pktlen -=n;
n = pktlen; rsa_pub_exp = mpi_read(inp, &n, 0 ); pktlen -=n;
if( list_mode ) {
printf( "\tpublic modulus n: ");
mpi_print(stdout, rsa_pub_mod, mpi_print_mode );
@ -546,43 +538,22 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen,
else
cert->d.rsa.is_protected = 0;
n = pktlen; mpibuf = mpi_read(inp, &n ); pktlen -=n; assert(n>=2);
cert->d.rsa.rsa_d = (MPI)mpibuf;
n = pktlen; mpibuf = mpi_read(inp, &n ); pktlen -=n; assert(n>=2);
cert->d.rsa.rsa_p = (MPI)mpibuf;
n = pktlen; mpibuf = mpi_read(inp, &n ); pktlen -=n; assert(n>=2);
cert->d.rsa.rsa_q = (MPI)mpibuf;
n = pktlen; mpibuf = mpi_read(inp, &n ); pktlen -=n; assert(n>=2);
cert->d.rsa.rsa_u = (MPI)mpibuf;
n = pktlen; cert->d.rsa.rsa_d = mpi_read(inp, &n, 1 ); pktlen -=n;
n = pktlen; cert->d.rsa.rsa_p = mpi_read(inp, &n, 1 ); pktlen -=n;
n = pktlen; cert->d.rsa.rsa_q = mpi_read(inp, &n, 1 ); pktlen -=n;
n = pktlen; cert->d.rsa.rsa_u = mpi_read(inp, &n, 1 ); pktlen -=n;
cert->d.rsa.csum = read_16(inp); pktlen -= 2;
cert->d.rsa.calc_csum = 0;
if( list_mode ) {
printf("\t[secret values d,p,q,u are not shown]\n"
"\tchecksum: %04hx\n", cert->d.rsa.csum);
}
if( !cert->d.rsa.is_protected ) { /* convert buffer to MPIs */
#define X(a) do { \
mpibuf = (byte*)cert->d.rsa.rsa_##a; \
cert->d.rsa.calc_csum += checksum( mpibuf ); \
cert->d.rsa.rsa_##a = mpi_decode_buffer( mpibuf ); \
m_free( mpibuf ); \
} while(0)
X(d);
X(p);
X(q);
X(u);
#undef X
/* log_mpidump("rsa n=", cert->d.rsa.rsa_n );
log_mpidump("rsa e=", cert->d.rsa.rsa_e );
log_mpidump("rsa d=", cert->d.rsa.rsa_d );
log_mpidump("rsa p=", cert->d.rsa.rsa_p );
log_mpidump("rsa q=", cert->d.rsa.rsa_q );
log_mpidump("rsa u=", cert->d.rsa.rsa_u ); */
}
/* log_mpidump("rsa n=", cert->d.rsa.rsa_n );
log_mpidump("rsa e=", cert->d.rsa.rsa_e );
log_mpidump("rsa d=", cert->d.rsa.rsa_d );
log_mpidump("rsa p=", cert->d.rsa.rsa_p );
log_mpidump("rsa q=", cert->d.rsa.rsa_q );
log_mpidump("rsa u=", cert->d.rsa.rsa_u ); */
}
}
else if( list_mode )
@ -671,34 +642,9 @@ parse_trust( IOBUF inp, int pkttype, unsigned long pktlen )
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."
/* This one (3) requires either:
* - 1 ultimately trusted signature (SIGTRUST=7)
* - COMPLETES_NEEDED completely trusted signatures (SIGTRUST=6)
* - MARGINALS_NEEDED marginally trusted signatures (SIGTRUST=5)
*/
if( c & 0x80 )
"warnonly"
else if( prev_packet_is_a_signature ) {
Bits 0-2 - SIGTRUST bits - Trust bits for this signature. Value is
copied directly from OWNERTRUST bits of signer:
000 - undefined, or uninitialized trust.
001 - unknown
010 - We do not trust this signature.
011 - reserved
100 - reserved
101 - We reasonably trust this signature.
110 - We completely trust this signature.
111 - ultimately trusted signature (from the owner of the ring)
Bit 6 - CHECKED bit - This means that the key checking pass (pgp -kc,
also invoked automatically whenever keys are added to the
keyring) has tested this signature and found it good. If
this bit is not set, the maintenance pass considers this
signature untrustworthy.
Bit 7 - CONTIG bit - Means this signature leads up a contiguous trusted
certification path all the way back to the ultimately-
trusted keyring owner, where the buck stops. This bit is derived
from other trust packets. It is currently not used for anything
in PGP.
}
#endif
}

View file

@ -44,13 +44,13 @@ get_passphrase_hash( u32 *keyid, char *text )
DEK *dek;
if( keyid ) {
tty_printf("Need a pass phrase to unlock the secret key!\n");
tty_printf("\nNeed a pass phrase to unlock the secret key!\n");
tty_printf("KeyID: %08lX\n\n", keyid[1] );
}
if( keyid && (p=getenv("PGPPATHPHRASE")) ) {
if( keyid && (p=getenv("G10PASSPHRASE")) ) {
pw = m_alloc_secure(strlen(p)+1);
strcpy(pw,p);
tty_printf("Taking it from $PGPPATHPHRASE !\n", keyid[1] );
tty_printf("Taking it from $G10PASSPHRASE !\n", keyid[1] );
}
else
pw = tty_get_hidden("Enter pass phrase: " );
@ -61,7 +61,7 @@ get_passphrase_hash( u32 *keyid, char *text )
m_free(pw); /* is allocated in secure memory, so it will be burned */
if( !p ) {
tty_kill_prompt();
tty_printf("\n\n");
tty_printf("\n");
}
return dek;
}
@ -70,6 +70,7 @@ get_passphrase_hash( u32 *keyid, char *text )
/****************
* This function is used to construct a DEK from a user input.
* It uses the default CIPHER
* Returns: 0 = okay, -1 No passphrase entered, > 0 error
*/
int
make_dek_from_passphrase( DEK *dek, int mode )
@ -88,7 +89,10 @@ make_dek_from_passphrase( DEK *dek, int mode )
}
m_free(pw2);
}
rc = hash_passphrase( dek, pw );
if( !*pw )
rc = -1;
else
rc = hash_passphrase( dek, pw );
m_free(pw);
return rc;
}

View file

@ -35,12 +35,20 @@
#endif
static u16
checksum( byte *p )
checksum_u16( unsigned n )
{
u16 n, a;
u16 a;
a = (n >> 8) & 0xff;
a |= n & 0xff;
return a;
}
static u16
checksum( byte *p, unsigned n )
{
u16 a;
n = *p++ << 8;
n |= *p++;
for(a=0; n; n-- )
a += *p++;
return a;
@ -51,16 +59,16 @@ checksum( byte *p )
static int
check_elg( PKT_secret_cert *cert )
{
byte iv[8];
byte *mpibuf;
u16 n;
MPI temp_mpi;
byte *buffer;
u16 n, csum=0;
int res;
unsigned nbytes;
u32 keyid[2];
ELG_secret_key skey;
if( cert->d.elg.is_protected ) { /* remove the protection */
DEK *dek = NULL;
MPI test_x;
BLOWFISH_context *blowfish_ctx=NULL;
switch( cert->d.elg.protect_algo ) {
@ -68,47 +76,87 @@ check_elg( PKT_secret_cert *cert )
case CIPHER_ALGO_BLOWFISH:
keyid_from_skc( cert, keyid );
dek = get_passphrase_hash( keyid, NULL );
m_free(dek); /* pw is in secure memory, so m_free() burns it */
memset( iv, 0, BLOWFISH_BLOCKSIZE );
blowfish_ctx = m_alloc_secure( sizeof *blowfish_ctx );
blowfish_setiv( blowfish_ctx, iv );
blowfish_setkey( blowfish_ctx, dek->key, dek->keylen );
m_free(dek); /* pw is in secure memory, so m_free() burns it */
blowfish_setiv( blowfish_ctx, NULL );
blowfish_decode_cfb( blowfish_ctx,
cert->d.elg.protect.blowfish.iv,
cert->d.elg.protect.blowfish.iv, 8 );
cert->d.elg.calc_csum = 0;
mpibuf = (byte*)cert->d.elg.x;
n = ((mpibuf[0] << 8) | mpibuf[1])-2;
blowfish_decode_cfb( blowfish_ctx, mpibuf+4, mpibuf+4, n );
cert->d.elg.calc_csum += checksum( mpibuf );
cert->d.elg.x = mpi_decode_buffer( mpibuf );
m_free( mpibuf );
buffer = mpi_get_buffer( cert->d.elg.x, &nbytes, NULL );
csum = checksum_u16( nbytes*8 );
blowfish_decode_cfb( blowfish_ctx, buffer, buffer, nbytes );
csum += checksum( buffer, nbytes );
test_x = mpi_alloc_secure( mpi_get_nlimbs(cert->d.elg.x) );
mpi_set_buffer( test_x, buffer, nbytes, 0 );
m_free( buffer );
m_free( blowfish_ctx );
cert->d.elg.is_protected = 0;
/* now let's see wether we have used the right passphrase */
if( cert->d.elg.calc_csum != cert->d.elg.csum )
if( csum != cert->d.elg.csum ) {
mpi_free(test_x);
return G10ERR_BAD_PASS;
}
skey.p = cert->d.elg.p;
skey.g = cert->d.elg.g;
skey.y = cert->d.elg.y;
skey.x = cert->d.elg.x;
skey.x = test_x;
res = elg_check_secret_key( &skey );
memset( &skey, 0, sizeof skey );
if( !res )
if( !res ) {
mpi_free(test_x);
return G10ERR_BAD_PASS;
}
mpi_set(cert->d.elg.x, test_x);
mpi_free(test_x);
cert->d.elg.is_protected = 0;
break;
default:
return G10ERR_CIPHER_ALGO; /* unsupport protection algorithm */
}
}
/* must check the checksum here, because we didn't do it when
* parsing an unprotected certificate */
if( cert->d.elg.calc_csum != cert->d.elg.csum ) {
log_error("checksum in secret key certificate is wrong\n");
log_debug("stored csum=%04hx calculated csum=%04hx\n",
cert->d.elg.csum, cert->d.elg.calc_csum );
return G10ERR_CHECKSUM;
else { /* not protected */
buffer = mpi_get_buffer( cert->d.elg.x, &nbytes, NULL );
csum = checksum_u16( nbytes*8 );
csum += checksum( buffer, nbytes );
m_free( buffer );
if( csum != cert->d.elg.csum )
return G10ERR_CHECKSUM;
}
return 0;
}
static int
protect_elg( PKT_secret_cert *cert, DEK *dek )
{
byte *buffer;
unsigned nbytes;
if( !cert->d.elg.is_protected ) { /* add the protection */
BLOWFISH_context *blowfish_ctx=NULL;
switch( cert->d.elg.protect_algo ) {
case CIPHER_ALGO_NONE: log_bug(NULL); break;
case CIPHER_ALGO_BLOWFISH:
blowfish_ctx = m_alloc_secure( sizeof *blowfish_ctx );
blowfish_setkey( blowfish_ctx, dek->key, dek->keylen );
blowfish_setiv( blowfish_ctx, NULL );
blowfish_encode_cfb( blowfish_ctx,
cert->d.elg.protect.blowfish.iv,
cert->d.elg.protect.blowfish.iv, 8 );
buffer = mpi_get_buffer( cert->d.elg.x, &nbytes, NULL );
blowfish_encode_cfb( blowfish_ctx, buffer, buffer, nbytes );
mpi_set_buffer( cert->d.elg.x, buffer, nbytes, 0 );
m_free( buffer );
m_free( blowfish_ctx );
cert->d.elg.is_protected = 1;
break;
default:
return G10ERR_CIPHER_ALGO; /* unsupport protection algorithm */
}
}
return 0;
}
@ -118,80 +166,86 @@ check_elg( PKT_secret_cert *cert )
static int
check_rsa( PKT_secret_cert *cert )
{
byte iv[8];
byte *mpibuf;
u16 n;
MPI temp_mpi;
byte *buffer;
u16 n, csum=0;
int res;
unsigned nbytes;
u32 keyid[2];
RSA_secret_key skey;
if( cert->d.rsa.is_protected ) { /* remove the protection */
DEK *dek = NULL;
BLOWFISH_context *blowfish_ctx=NULL;
switch( cert->d.rsa.protect_algo ) {
case CIPHER_ALGO_NONE:
log_bug("unprotect secret_cert is flagged protected\n");
break;
/* FIXME: use test variables to check for the correct key */
case CIPHER_ALGO_NONE: log_bug(NULL); break;
case CIPHER_ALGO_BLOWFISH:
keyid_from_skc( cert, keyid );
dek = get_passphrase_hash( keyid, NULL );
m_free(dek); /* pw is in secure memory, so m_free() burns it */
memset( iv, 0, BLOWFISH_BLOCKSIZE );
blowfish_ctx = m_alloc_secure( sizeof *blowfish_ctx );
blowfish_setiv( blowfish_ctx, iv );
blowfish_setkey( blowfish_ctx, dek->key, dek->keylen );
m_free(dek); /* pw is in secure memory, so m_free() burns it */
blowfish_setiv( blowfish_ctx, NULL );
blowfish_decode_cfb( blowfish_ctx,
cert->d.rsa.protect.blowfish.iv,
cert->d.rsa.protect.blowfish.iv, 8 );
cert->d.rsa.calc_csum = 0;
#define X(a) do { \
mpibuf = (byte*)cert->d.rsa.rsa_##a; \
n = ((mpibuf[0] << 8) | mpibuf[1])-2; \
blowfish_decode_cfb( blowfish_ctx, \
mpibuf+4, mpibuf+4, n ); \
cert->d.rsa.calc_csum += checksum( mpibuf ); \
cert->d.rsa.rsa_##a = mpi_decode_buffer( mpibuf ); \
m_free( mpibuf ); \
} while(0)
csum = 0;
#define X(a) do { \
buffer = mpi_get_buffer( cert->d.rsa.rsa_##a, &nbytes, NULL );\
csum += checksum_u16( nbytes*8 ); \
blowfish_decode_cfb( blowfish_ctx, buffer, buffer, nbytes ); \
csum += checksum( buffer, nbytes ); \
mpi_set_buffer(cert->d.rsa.rsa_##a, buffer, nbytes, 0 ); \
m_free( buffer ); \
} while(0)
X(d);
X(p);
X(q);
X(u);
#undef X
m_free( blowfish_ctx );
cert->d.rsa.is_protected = 0;
#if 0
#define X(a) do { printf("\tRSA " #a ": "); \
mpi_print(stdout, cert->d.rsa.rsa_##a, 1 ); \
putchar('\n'); \
} while(0)
X(n); X(e); X(d); X(p); X(q); X(u);
#undef X
#endif
cert->d.rsa.is_protected = 0;
m_free( blowfish_ctx );
/* now let's see wether we have used the right passphrase */
if( cert->d.rsa.calc_csum != cert->d.rsa.csum )
if( csum != cert->d.rsa.csum )
return G10ERR_BAD_PASS;
temp_mpi = mpi_alloc(40);
mpi_mul(temp_mpi, cert->d.rsa.rsa_p, cert->d.rsa.rsa_q );
res = mpi_cmp( temp_mpi, cert->d.rsa.rsa_n );
mpi_free(temp_mpi);
if( res )
skey.d = cert->d.rsa.rsa_d;
skey.p = cert->d.rsa.rsa_p;
skey.q = cert->d.rsa.rsa_q;
skey.u = cert->d.rsa.rsa_u;
res = rsa_check_secret_key( &skey );
memset( &skey, 0, sizeof skey );
if( !res )
return G10ERR_BAD_PASS;
break;
default:
return G10ERR_CIPHER_ALGO; /* unsupport protection algorithm */
return G10ERR_CIPHER_ALGO; /* unsupported protection algorithm */
}
}
/* must check the checksum here, because we didn't do it when
* parsing an unprotected certificate */
if( cert->d.rsa.calc_csum != cert->d.rsa.csum ) {
log_error("checksum in secret key certificate is wrong\n");
log_debug("stored csum=%04hx calculated csum=%04hx\n",
cert->d.rsa.csum, cert->d.rsa.calc_csum );
return G10ERR_CHECKSUM;
else { /* not protected */
csum =0;
buffer = mpi_get_buffer( cert->d.rsa.rsa_d, &nbytes, NULL );
csum += checksum_u16( nbytes*8 );
csum += checksum( buffer, nbytes );
m_free( buffer );
buffer = mpi_get_buffer( cert->d.rsa.rsa_p, &nbytes, NULL );
csum += checksum_u16( nbytes*8 );
csum += checksum( buffer, nbytes );
m_free( buffer );
buffer = mpi_get_buffer( cert->d.rsa.rsa_q, &nbytes, NULL );
csum += checksum_u16( nbytes*8 );
csum += checksum( buffer, nbytes );
m_free( buffer );
buffer = mpi_get_buffer( cert->d.rsa.rsa_u, &nbytes, NULL );
csum += checksum_u16( nbytes*8 );
csum += checksum( buffer, nbytes );
m_free( buffer );
if( csum != cert->d.rsa.csum )
return G10ERR_CHECKSUM;
}
return 0;
}
#endif /*HAVE_RSA_CIPHER*/
@ -201,15 +255,44 @@ check_rsa( PKT_secret_cert *cert )
/****************
* Check the secret key certificate
* Ask up to 3 time for a correct passphrase
*/
int
check_secret_key( PKT_secret_cert *cert )
{
int rc = G10ERR_BAD_PASS;
int i;
for(i=0; i < 3 && rc == G10ERR_BAD_PASS; i++ ) {
if( i )
log_error("Invalid passphrase; please try again ...\n");
if( cert->pubkey_algo == PUBKEY_ALGO_ELGAMAL )
rc = check_elg( cert );
#ifdef HAVE_RSA_CIPHER
else if( cert->pubkey_algo == PUBKEY_ALGO_RSA )
rc = check_rsa( cert );
#endif
else
rc = G10ERR_PUBKEY_ALGO;
}
return rc;
}
/****************
* Protect the secret key certificate with the passphrase from DEK
*/
int
protect_secret_key( PKT_secret_cert *cert, DEK *dek )
{
if( !dek )
return 0;
if( cert->pubkey_algo == PUBKEY_ALGO_ELGAMAL )
return check_elg( cert );
#ifdef HAVE_RSA_CIPHER
return protect_elg( cert, dek );
#ifdef 0 /* noy yet implemented */
else if( cert->pubkey_algo == PUBKEY_ALGO_RSA )
return check_rsa( cert );
return protect_rsa( cert, dek );
#endif
else
return G10ERR_PUBKEY_ALGO;

View file

@ -212,3 +212,5 @@ signature_check( PKT_signature *sig, MD_HANDLE *digest )
return rc;
}