See ChangeLog: Thu Jul 1 12:47:31 CEST 1999 Werner Koch

This commit is contained in:
Werner Koch 1999-07-01 10:53:35 +00:00
parent 75ed03c960
commit 28eb86c006
31 changed files with 402 additions and 123 deletions

5
NEWS
View File

@ -1,6 +1,9 @@
*
* New options --[no-]utf8-strings.
* New edit-menu commands "enable" and "disable" for entire keys.
* You will be asked for a filename if gpg cannot deduce one.
Noteworthy changes in version 0.9.8
-----------------------------------

5
TODO
View File

@ -1,6 +1,4 @@
* add keylength and type to status output.
* add some status output put for signing and encryption.
replace the putc in primegen with some kind of status-fd outputs.
@ -21,7 +19,7 @@
* find a way to allow the import of non-self-signed keys. This is needed
for the IN ENCR/SIGN hack.
* convert the given user ID to UTF-8 and add an option to suppress this.
* Not all user names are correctly converted to UTF8.
Nice to have
@ -52,4 +50,3 @@ Nice to have
verification status of the message to the output (i.e. write something to
the --output file and not only to stderr.

View File

@ -1,3 +1,9 @@
Thu Jul 1 12:47:31 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* primegen.c, elgamal.c, dsa.c (progess): New and replaced all
fputc with a call to this function.
Sat Jun 26 12:15:59 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>

View File

@ -52,6 +52,13 @@ static void generate( DSA_secret_key *sk, unsigned nbits, MPI **ret_factors );
static void sign(MPI r, MPI s, MPI input, DSA_secret_key *skey);
static int verify(MPI r, MPI s, MPI input, DSA_public_key *pkey);
static void
progress( int c )
{
fputc( c, stderr );
}
/****************
* Generate a random secret exponent k less than q
*/
@ -65,7 +72,7 @@ gen_k( MPI q )
log_debug("choosing a random k ");
for(;;) {
if( DBG_CIPHER )
fputc('.', stderr);
progress('.');
{ char *p = get_random_bits( nbits, 1, 1 );
mpi_set_buffer( k, p, (nbits+7)/8, 0 );
m_free(p);
@ -84,7 +91,7 @@ gen_k( MPI q )
break; /* okay */
}
if( DBG_CIPHER )
fputc('\n', stderr);
progress('\n');
return k;
}
@ -170,7 +177,7 @@ generate( DSA_secret_key *sk, unsigned nbits, MPI **ret_factors )
rndbuf = NULL;
do {
if( DBG_CIPHER )
fputc('.', stderr);
progress('.');
if( !rndbuf )
rndbuf = get_random_bits( qbits, 2, 1 );
else { /* change only some of the higher bits (= 2 bytes)*/
@ -190,7 +197,7 @@ generate( DSA_secret_key *sk, unsigned nbits, MPI **ret_factors )
mpi_powm( y, g, x, p );
if( DBG_CIPHER ) {
fputc('\n', stderr);
progress('\n');
log_mpidump("dsa p= ", p );
log_mpidump("dsa q= ", q );
log_mpidump("dsa g= ", g );

View File

@ -56,6 +56,13 @@ static void sign(MPI a, MPI b, MPI input, ELG_secret_key *skey);
static int verify(MPI a, MPI b, MPI input, ELG_public_key *pkey);
static void
progress( int c )
{
fputc( c, stderr );
}
static void
test_keys( ELG_secret_key *sk, unsigned nbits )
{
@ -108,7 +115,7 @@ gen_k( MPI p )
mpi_sub_ui( p_1, p, 1);
for(;;) {
if( DBG_CIPHER )
fputc('.', stderr);
progress('.');
{ char *pp = get_random_bits( nbits, 1, 1 );
mpi_set_buffer( k, pp, (nbits+7)/8, 0 );
m_free(pp);
@ -128,7 +135,7 @@ gen_k( MPI p )
break; /* okay, k is relatively prime to (p-1) */
}
if( DBG_CIPHER )
fputc('\n', stderr);
progress('\n');
mpi_free(p_1);
mpi_free(temp);
@ -179,7 +186,7 @@ generate( ELG_secret_key *sk, unsigned nbits, MPI **ret_factors )
rndbuf = NULL;
do {
if( DBG_CIPHER )
fputc('.', stderr);
progress('.');
if( rndbuf ) { /* change only some of the higher bits */
if( nbits < 16 ) {/* should never happen ... */
m_free(rndbuf);
@ -202,7 +209,7 @@ generate( ELG_secret_key *sk, unsigned nbits, MPI **ret_factors )
mpi_powm( y, g, x, p );
if( DBG_CIPHER ) {
fputc('\n', stderr);
progress('\n');
log_mpidump("elg p= ", p );
log_mpidump("elg g= ", g );
log_mpidump("elg y= ", y );

View File

@ -39,6 +39,13 @@ static int is_prime( MPI n, int steps, int *count );
static void m_out_of_n( char *array, int m, int n );
static void
progress( int c )
{
fputc( c, stderr );
}
/****************
* Generate a prime number (stored in secure memory)
*/
@ -48,7 +55,7 @@ generate_secret_prime( unsigned nbits )
MPI prime;
prime = gen_prime( nbits, 1, 2 );
fputc('\n', stderr);
progress('\n');
return prime;
}
@ -58,7 +65,7 @@ generate_public_prime( unsigned nbits )
MPI prime;
prime = gen_prime( nbits, 0, 2 );
fputc('\n', stderr);
progress('\n');
return prime;
}
@ -152,7 +159,7 @@ generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
}
if( i == n ) {
m_free(perms); perms = NULL;
fputc('!', stderr);
progress('!');
goto next_try; /* allocate new primes */
}
}
@ -169,7 +176,7 @@ generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
if( ++count1 > 20 ) {
count1 = 0;
qbits++;
fputc('>', stderr);
progress('>');
q = gen_prime( qbits, 0, 1 );
goto next_try;
}
@ -180,7 +187,7 @@ generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
if( ++count2 > 20 ) {
count2 = 0;
qbits--;
fputc('<', stderr);
progress('<');
q = gen_prime( qbits, 0, 1 );
goto next_try;
}
@ -190,7 +197,7 @@ generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
} while( !(nprime == pbits && check_prime( prime, val_2 )) );
if( DBG_CIPHER ) {
putc('\n', stderr);
progress('\n');
log_mpidump( "prime : ", prime );
log_mpidump( "factor q: ", q );
if( mode == 1 )
@ -202,7 +209,7 @@ generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
fprintf(stderr, ", q0=%u", mpi_get_nbits(q_factor) );
for(i=0; i < n; i++ )
fprintf(stderr, ", p%d=%u", i, mpi_get_nbits(factors[i]) );
putc('\n', stderr);
progress('\n');
}
if( ret_factors ) { /* caller wants the factors */
@ -237,7 +244,7 @@ generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
mpi_print( stderr, g, 1 );
}
else
fputc('^', stderr);
progress('^');
for(i=0; i < n+2; i++ ) {
/*fputc('~', stderr);*/
mpi_fdiv_q(tmp, pmin1, factors[i] );
@ -247,7 +254,7 @@ generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
break;
}
if( DBG_CIPHER )
fputc('\n', stderr);
progress('\n');
} while( i < n+2 );
mpi_free(factors[n+1]);
mpi_free(tmp);
@ -255,7 +262,7 @@ generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
mpi_free(pmin1);
}
if( !DBG_CIPHER )
putc('\n', stderr);
progress('\n');
m_free( factors ); /* (factors are shallow copies) */
for(i=0; i < m; i++ )
@ -335,7 +342,7 @@ gen_prime( unsigned nbits, int secret, int randomlevel )
/* perform stronger tests */
if( is_prime(ptest, 5, &count2 ) ) {
if( !mpi_test_bit( ptest, nbits-1 ) ) {
fputc('\n', stderr);
progress('\n');
log_debug("overflow in prime generation\n");
break; /* step loop, continue with a new prime */
}
@ -350,11 +357,11 @@ gen_prime( unsigned nbits, int secret, int randomlevel )
}
}
if( ++dotcount == 10 ) {
fputc('.', stderr);
progress('.');
dotcount = 0;
}
}
fputc(':', stderr); /* restart with a new random value */
progress(':'); /* restart with a new random value */
}
}
@ -383,7 +390,7 @@ check_prime( MPI prime, MPI val_2 )
mpi_free( pminus1 );
if( mpi_cmp_ui( result, 1 ) ) { /* if composite */
mpi_free( result );
fputc('.', stderr);
progress('.');
return 0;
}
mpi_free( result );
@ -392,7 +399,7 @@ check_prime( MPI prime, MPI val_2 )
/* perform stronger tests */
if( is_prime(prime, 5, &count ) )
return 1; /* is probably a prime */
fputc('.', stderr);
progress('.');
return 0;
}
@ -452,7 +459,7 @@ is_prime( MPI n, int steps, int *count )
if( mpi_cmp( y, nminus1 ) )
goto leave; /* not a prime */
}
fputc('+', stderr);
progress('+');
}
rc = 1; /* may be a prime */

View File

@ -85,8 +85,11 @@ more arguments in future versions.
unique ids - others may yield duplicated ones when they
have been created in the same second.
ENC_TO <long keyid>
ENC_TO <long keyid> <keytype> <keylength>
The message is encrypted to this keyid.
keytype is the numerical value of the public key algorithm,
kenlength is the length of the key or 0 if it is not known
(which is currently always the case).
NODATA <what>
No data has been found. Codes for what are:
@ -122,8 +125,11 @@ more arguments in future versions.
SHM_GET_BOOL
SHM_GET_HIDDEN
NEED_PASSPHRASE <long keyid>
NEED_PASSPHRASE <long keyid> <keytype> <keylength>
Issued whenever a passphrase is needed.
keytype is the numerical value of the public key algorithm
or 0 if this is not applicable, keylength is the length
of the key or 0 if it is not known (this is currently always the case).
NEED_PASSPHRASE_SYM <cipher_algo> <s2k_mode> <s2k_hash>
Issued whenever a passphrase for symmetric encryption is needed.

View File

@ -268,6 +268,12 @@ certificate should be generated.</para></listitem></varlistentry>
<listitem><para>
Change the owner trust value. This updates the
trust-db immediately and no save is required.</para></listitem></varlistentry>
<varlistentry>
<term>disable</term>
<term>enable</term>
<listitem><para>
Disable or enable an entire key. A disabled key can normally not be used
for encryption.</para></listitem></varlistentry>
<varlistentry>
<term>adduid</term>
<listitem><para>
@ -537,7 +543,8 @@ in the options file and may be used together with
an own user-id as an "encrypt-to-self". These keys
are only used when there are other recipients given
either by use of --recipient or by the asked user id.
No trust checking is performed for these user ids.
No trust checking is performed for these user ids and
even disabled keys can be used.
</para></listitem></varlistentry>
@ -698,6 +705,18 @@ Valid values for &ParmName; are:</para>
</listitem></varlistentry>
<varlistentry>
<term>--utf8-strings</term>
<term>--no-utf8-strings</term>
<listitem><para>
Assume that the arguments are already given as UTF8 strings. The default
(--no-utf8-strings)
is to assume that arguments are encoded in the character set as specified
by --charset. These options effects all following arguments. Both options may
used multiple times.
</para></listitem></varlistentry>
<varlistentry>
<term>--options &ParmFile;</term>
<listitem><para>

View File

@ -1,3 +1,28 @@
Thu Jul 1 12:47:31 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* keyedit.c (show_key_with_all_names): Print a notice for disabled keys.
(enable_disable_keys): Add functionality
* pkclist.c (edit_ownertrust): preserve disabled state.
(build_pk_list): Skip disabled keys.
* trustdb.c (upd_one_ownertrust): Ditto.
(build_cert_tree): Mask the ownertrust.
(trust_letter): Mask the value.
(do_check): Take disabled flag into account.
* passphrase.c (passphrase_to_dek): Add a pubkey_alfo arg and changed
all callers.
* g10.c (utf8_strings): 2 new options.
* trustdb.c (insert_trust_record_by_pk): New, replaces the next one.
(insert_trust_record): Now takes a keyblock as arg. Changed all
callers to use the appropritae function.
* openfile.c (ask_outfile_name): New.
* plaintext.c (handle_plaintext): Ask for filename if there is
no valid syntax. Don't use fname varbatim but filter it.
Tue Jun 29 21:44:25 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>

View File

@ -102,7 +102,7 @@ encode_simple( const char *filename, int mode )
s2k->mode = opt.rfc1991? 0:opt.s2k_mode;
s2k->hash_algo = opt.def_digest_algo ? opt.def_digest_algo
: opt.s2k_digest_algo;
cfx.dek = passphrase_to_dek( NULL,
cfx.dek = passphrase_to_dek( NULL, 0,
opt.def_cipher_algo ? opt.def_cipher_algo
: opt.s2k_cipher_algo , s2k, 2 );
if( !cfx.dek || !cfx.dek->keylen ) {

View File

@ -166,6 +166,8 @@ enum cmd_and_opt_values { aNull = 0,
oEncryptTo,
oNoEncryptTo,
oLoggerFD,
oUtf8Strings,
oNoUtf8Strings,
aTest };
@ -315,13 +317,15 @@ static ARGPARSE_OPTS opts[] = {
{ oLockMultiple, "lock-multiple", 0, "@" },
{ oLoggerFD, "logger-fd",1, "@" },
{ oUseEmbeddedFilename, "use-embedded-filename", 0, "@" },
{ oUtf8Strings, "utf8-strings", 0, "@" },
{ oNoUtf8Strings, "no-utf8-strings", 0, "@" },
{0} };
int g10_errors_seen = 0;
static int utf8_strings = 0;
static int maybe_setuid = 1;
static char *build_list( const char *text,
@ -761,16 +765,16 @@ main( int argc, char **argv )
case oNoEncryptTo: opt.no_encrypt_to = 1; break;
case oEncryptTo: /* store the recipient in the second list */
sl = add_to_strlist( &remusr, pargs.r.ret_str );
sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
sl->flags = 1;
break;
case oRecipient: /* store the recipient */
add_to_strlist( &remusr, pargs.r.ret_str );
add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
break;
case oTextmodeShort: opt.textmode = 2; break;
case oTextmode: opt.textmode=1; break;
case oUser: /* store the local users */
add_to_strlist( &locusr, pargs.r.ret_str );
add_to_strlist2( &locusr, pargs.r.ret_str, utf8_strings );
break;
case oCompress: opt.compress = pargs.r.ret_int; break;
case oPasswdFD: pwfd = pargs.r.ret_int; break;
@ -788,6 +792,8 @@ main( int argc, char **argv )
case oLockMultiple: opt.lock_once = 0; break;
case oKeyServer: opt.keyserver_name = pargs.r.ret_str; break;
case oNotation: add_notation_data( pargs.r.ret_str ); break;
case oUtf8Strings: utf8_strings = 1; break;
case oNoUtf8Strings: utf8_strings = 0; break;
default : pargs.err = configfp? 1:2; break;
}
@ -1025,7 +1031,7 @@ main( int argc, char **argv )
if( argc > 1 ) {
sl = NULL;
for( argc--, argv++ ; argc; argc--, argv++ )
append_to_strlist( &sl, *argv );
append_to_strlist2( &sl, *argv, utf8_strings );
keyedit_menu( fname, locusr, sl );
free_strlist(sl);
}
@ -1040,6 +1046,7 @@ main( int argc, char **argv )
if( argc != 1 )
wrong_args(_("--delete-key username"));
/* note: fname is the user id! */
/* fixme: do utf8 conversion */
if( (rc = delete_key(fname, cmd==aDeleteSecretKey)) )
log_error("%s: delete key failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
break;
@ -1482,11 +1489,8 @@ add_notation_data( const char *string )
highbit = 1;
}
if( highbit ) { /* must use UTF8 encoding */
char *p = native_to_utf8( string );
sl = add_to_strlist( &opt.notation_data, p );
m_free( p );
}
if( highbit ) /* must use UTF8 encoding */
sl = add_to_strlist2( &opt.notation_data, string, utf8_strings );
else
sl = add_to_strlist( &opt.notation_data, string );

View File

@ -208,10 +208,17 @@ static struct helptexts { const char *key; const char *help; } helptexts[] = {
"Give the name fo the file to which the signature applies"
},
/* openfile.c (overwrite_filep) */
{ N_("openfile.overwrite.okay"),
"Answer \"yes\" if it is okay to overwrite the file"
},
/* openfile.c (ask_outfile_name) */
{ N_("openfile.askoutname"),
"Please enter a new filename. If you just hit RETURN the default\n"
"file (which is shown in brackets) will be used."
},
/* end of list */
{ NULL, NULL } };

View File

@ -376,10 +376,10 @@ import_one( const char *fname, KBNODE keyblock, int fast )
log_info( _("writing to `%s'\n"),
keyblock_resource_name(&kbpos) );
if( (rc=lock_keyblock( &kbpos )) )
log_error(_("can't lock keyring `%s': %s\n"),
log_error(_("can't lock keyring `%s': %s\n"),
keyblock_resource_name(&kbpos), g10_errstr(rc) );
else if( (rc=insert_keyblock( &kbpos, keyblock )) )
log_error( _("error writing keyring `%s': %s\n"),
log_error( _("error writing keyring `%s': %s\n"),
keyblock_resource_name(&kbpos), g10_errstr(rc) );
unlock_keyblock( &kbpos );
/* we are ready */
@ -402,9 +402,6 @@ import_one( const char *fname, KBNODE keyblock, int fast )
goto leave;
}
/* See whether we have only non-self-signature on one user id; if not
* ask the user what to do. <--- fixme */
/* now read the original keyblock */
rc = find_keyblock_bypk( &kbpos, pk_orig );
if( rc ) {
@ -432,7 +429,7 @@ import_one( const char *fname, KBNODE keyblock, int fast )
mod_key = 1;
/* keyblock_orig has been updated; write */
if( (rc=lock_keyblock( &kbpos )) )
log_error( _("can't lock keyring `%s': %s\n"),
log_error( _("can't lock keyring `%s': %s\n"),
keyblock_resource_name(&kbpos), g10_errstr(rc) );
else if( (rc=update_keyblock( &kbpos, keyblock_orig )) )
log_error( _("error writing keyring `%s': %s\n"),
@ -475,7 +472,7 @@ import_one( const char *fname, KBNODE keyblock, int fast )
if( rc && rc != -1 )
log_error("trustdb error: %s\n", g10_errstr(rc) );
else if( rc == -1 ) { /* not found trustdb */
rc = insert_trust_record( new_key? pk : pk_orig );
rc = insert_trust_record( new_key? keyblock : keyblock_orig );
if( rc )
log_error("key %08lX: trustdb insert failed: %s\n",
(ulong)keyid[1], g10_errstr(rc) );

View File

@ -125,7 +125,8 @@ int build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list,
/*-- passphrase.h --*/
int have_static_passphrase(void);
void read_passphrase_from_fd( int fd );
DEK *passphrase_to_dek( u32 *keyid, int cipher_algo, STRING2KEY *s2k, int mode);
DEK *passphrase_to_dek( u32 *keyid, int pubkey_algo,
int cipher_algo, STRING2KEY *s2k, int mode);
void set_next_passphrase( const char *s );
char *get_last_passphrase(void);

View File

@ -451,7 +451,7 @@ change_passphrase( KBNODE keyblock )
for(;;) {
s2k->mode = opt.s2k_mode;
s2k->hash_algo = opt.s2k_digest_algo;
dek = passphrase_to_dek( NULL, opt.s2k_cipher_algo, s2k, 2 );
dek = passphrase_to_dek( NULL, 0, opt.s2k_cipher_algo, s2k, 2 );
if( !dek ) {
tty_printf(_("passphrase not correctly repeated; try again.\n"));
}
@ -1033,6 +1033,12 @@ show_key_with_all_names( KBNODE keyblock, int only_marked,
expirestr_from_pk(pk) );
if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
tty_printf(" trust: %c/%c", otrust, trust );
if( node->pkt->pkttype == PKT_PUBLIC_KEY
&& (get_ownertrust( pk->local_id )&TRUST_FLAG_DISABLED)) {
tty_printf("\n*** ");
tty_printf(_("This key has been disabled"));
}
if( with_fpr ) {
tty_printf("\n");
show_fingerprint( pk );
@ -1872,12 +1878,20 @@ menu_revkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
static int
enable_disable_key( KBNODE keyblock, int disable )
{
int entire;
int changed = 0;
ulong lid = find_kbnode( keyblock, PKT_PUBLIC_KEY )
->pkt->pkt.public_key->local_id;
unsigned int trust, newtrust;
entire = !count_selected_keys( keyblock );
return changed;
/* Note: Because the keys have beed displayed, we have
* ensured that local_id has been set */
trust = newtrust = get_ownertrust( lid );
newtrust &= ~TRUST_FLAG_DISABLED;
if( disable )
newtrust |= TRUST_FLAG_DISABLED;
if( trust == newtrust )
return 0; /* already in that state */
if( !update_ownertrust( lid, newtrust ) )
return 1;
return 0;
}

View File

@ -743,7 +743,7 @@ ask_passphrase( STRING2KEY **ret_s2k )
for(;;) {
s2k->mode = opt.s2k_mode;
s2k->hash_algo = opt.s2k_digest_algo;
dek = passphrase_to_dek( NULL, opt.s2k_cipher_algo, s2k, 2 );
dek = passphrase_to_dek( NULL, 0, opt.s2k_cipher_algo, s2k, 2 );
if( !dek ) {
tty_printf(_("passphrase not correctly repeated; try again.\n"));
}
@ -1045,7 +1045,7 @@ generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock )
s2k->mode = opt.s2k_mode;
s2k->hash_algo = opt.s2k_digest_algo;
set_next_passphrase( passphrase );
dek = passphrase_to_dek( NULL, opt.s2k_cipher_algo, s2k, 2 );
dek = passphrase_to_dek( NULL, 0, opt.s2k_cipher_algo, s2k, 2 );
}
rc = do_create( algo, nbits, pub_keyblock, sec_keyblock,

View File

@ -97,6 +97,7 @@ int generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock );
/*-- openfile.c --*/
int overwrite_filep( const char *fname );
char *make_outfile_name( const char *iname );
char *ask_outfile_name( const char *name, size_t namelen );
int open_outfile( const char *iname, int mode, IOBUF *a );
IOBUF open_sigfile( const char *iname );
void copy_options_file( const char *destdir );

View File

@ -163,7 +163,7 @@ proc_symkey_enc( CTX c, PACKET *pkt )
log_error( "symkey_enc packet with session keys are not supported!\n");
else {
c->last_was_session_key = 2;
c->dek = passphrase_to_dek( NULL, enc->cipher_algo, &enc->s2k, 0 );
c->dek = passphrase_to_dek( NULL, 0, enc->cipher_algo, &enc->s2k, 0 );
}
free_packet(pkt);
}
@ -185,7 +185,8 @@ proc_pubkey_enc( CTX c, PACKET *pkt )
if( is_status_enabled() ) {
char buf[50];
sprintf(buf, "%08lX%08lX", (ulong)enc->keyid[0], (ulong)enc->keyid[1]);
sprintf(buf, "%08lX%08lX %d 0",
(ulong)enc->keyid[0], (ulong)enc->keyid[1], enc->pubkey_algo );
write_status_text( STATUS_ENC_TO, buf );
}
@ -230,7 +231,7 @@ proc_encrypted( CTX c, PACKET *pkt )
/*log_debug("dat: %sencrypted data\n", c->dek?"":"conventional ");*/
if( !c->dek && !c->last_was_session_key ) {
/* assume this is old conventional encrypted data */
c->dek = passphrase_to_dek( NULL,
c->dek = passphrase_to_dek( NULL, 0,
opt.def_cipher_algo ? opt.def_cipher_algo
: DEFAULT_CIPHER_ALGO, NULL, 0 );
}

View File

@ -99,6 +99,44 @@ make_outfile_name( const char *iname )
}
/****************
* Ask for a outputfilename and use the given one as default.
* Return NULL if no file has been given or it is not possible to
* ask the user.
*/
char *
ask_outfile_name( const char *name, size_t namelen )
{
size_t n;
const char *s;
char *prompt;
char *fname;
char *defname;
if( opt.batch )
return NULL;
s = _("Enter new filename");
n = strlen(s) + namelen + 10;
defname = name && namelen? make_printable_string( name, namelen, 0): NULL;
prompt = m_alloc(n);
if( defname )
sprintf(prompt, "%s [%s]: ", s, defname );
else
sprintf(prompt, "%s: ", s );
fname = cpr_get("openfile.askoutname", prompt );
cpr_kill_prompt();
m_free(prompt);
if( !*fname ) {
m_free( fname ); fname = NULL;
fname = defname; defname = NULL;
}
m_free(defname);
return fname;
}
/****************
* Make an output filename for the inputfile INAME.

View File

@ -114,9 +114,11 @@ read_passphrase_from_fd( int fd )
* (only for mode 2)
* a dek->keylen of 0 means: no passphrase entered.
* (only for mode 2)
* pubkey_algo is only informational.
*/
DEK *
passphrase_to_dek( u32 *keyid, int cipher_algo, STRING2KEY *s2k, int mode )
passphrase_to_dek( u32 *keyid, int pubkey_algo,
int cipher_algo, STRING2KEY *s2k, int mode )
{
char *pw = NULL;
DEK *dek;
@ -139,8 +141,8 @@ passphrase_to_dek( u32 *keyid, int cipher_algo, STRING2KEY *s2k, int mode )
sprintf( buf, "%08lX%08lX", (ulong)keyid[0], (ulong)keyid[1] );
if( keyid[2] && keyid[3] && keyid[0] != keyid[2]
&& keyid[1] != keyid[3] )
sprintf( buf+strlen(buf), " %08lX%08lX",
(ulong)keyid[2], (ulong)keyid[3] );
sprintf( buf+strlen(buf), " %08lX%08lX %d 0",
(ulong)keyid[2], (ulong)keyid[3], pubkey_algo );
write_status_text( STATUS_NEED_PASSPHRASE, buf );
}
else {

View File

@ -206,7 +206,7 @@ do_edit_ownertrust( ulong lid, int mode, unsigned *new_trust )
int
edit_ownertrust( ulong lid, int mode )
{
unsigned trust;
unsigned int trust;
for(;;) {
switch( do_edit_ownertrust( lid, mode, &trust ) ) {
@ -216,6 +216,8 @@ edit_ownertrust( ulong lid, int mode )
show_paths( lid, 1 );
break;
case 1:
trust &= ~TRUST_FLAG_DISABLED;
trust |= get_ownertrust( lid ) & TRUST_FLAG_DISABLED;
if( !update_ownertrust( lid, trust ) )
return 1;
return 0;
@ -301,7 +303,7 @@ do_we_trust( PKT_public_key *pk, int trustlevel )
switch( (trustlevel & TRUST_MASK) ) {
case TRUST_UNKNOWN: /* No pubkey in trustDB: Insert and check again */
rc = insert_trust_record( pk );
rc = insert_trust_record_by_pk( pk );
if( rc ) {
log_error("failed to insert it into the trustdb: %s\n",
g10_errstr(rc) );
@ -462,7 +464,7 @@ check_signatures_trust( PKT_signature *sig )
switch( (trustlevel & TRUST_MASK) ) {
case TRUST_UNKNOWN: /* No pubkey in trustDB: Insert and check again */
rc = insert_trust_record( pk );
rc = insert_trust_record_by_pk( pk );
if( rc ) {
log_error("failed to insert it into the trustdb: %s\n",
g10_errstr(rc) );
@ -633,6 +635,9 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use )
log_error("error checking pk of `%s': %s\n",
answer, g10_errstr(rc) );
}
else if( (trustlevel & TRUST_FLAG_DISABLED) ) {
tty_printf(_("Public key is disabled.\n") );
}
else if( do_we_trust_pre( pk, trustlevel ) ) {
PK_LIST r;
@ -673,6 +678,11 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use )
log_error(_("%s: error checking key: %s\n"),
remusr->d, g10_errstr(rc) );
}
else if( (trustlevel & TRUST_FLAG_DISABLED) ) {
free_public_key(pk); pk = NULL;
log_info(_("%s: skipped: public key is disabled\n"),
remusr->d);
}
else if( do_we_trust_pre( pk, trustlevel ) ) {
/* note: do_we_trust may have changed the trustlevel */

View File

@ -65,15 +65,15 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
}
else if( !opt.use_embedded_filename ) {
fname = make_outfile_name( iobuf_get_real_fname(pt->buf) );
if( !fname )
fname = ask_outfile_name( pt->name, pt->namelen );
if( !fname ) {
rc = G10ERR_CREATE_FILE;
goto leave;
}
}
else {
fname = m_alloc( pt->namelen +1 );
memcpy( fname, pt->name, pt->namelen );
fname[pt->namelen] = 0;
fname = make_printable_string( pt->name, pt->namelen, 0 );
}
if( nooutput )

View File

@ -64,7 +64,7 @@ do_check( PKT_secret_key *sk )
keyid_from_sk( sk2, keyid+2 );
free_secret_key( sk2 );
}
dek = passphrase_to_dek( keyid, sk->protect.algo,
dek = passphrase_to_dek( keyid, sk->pubkey_algo, sk->protect.algo,
&sk->protect.s2k, 0 );
cipher_hd = cipher_open( sk->protect.algo,
CIPHER_MODE_AUTO_CFB, 1);

View File

@ -412,6 +412,11 @@ check_key_signature( KBNODE root, KBNODE node, int *is_selfsig )
pk = root->pkt->pkt.public_key;
sig = node->pkt->pkt.signature;
algo = sig->digest_algo;
if( sig->flags.checked )
log_debug("check_key_signature: already checked: %s\n",
sig->flags.valid? "good":"bad" );
if( (rc=check_digest_algo(algo)) )
return rc;

View File

@ -503,7 +503,7 @@ import_ownertrust( const char *fname )
if( rc != -1 )
log_error_f(fname, _("Oops: key is now in trustdb???\n"));
else {
rc = insert_trust_record( pk );
rc = insert_trust_record_by_pk( pk );
if( !rc )
goto repeat; /* update the ownertrust */
log_error_f(fname, _("insert trust record failed: %s\n"),

View File

@ -513,7 +513,7 @@ verify_own_keys(void)
/* make sure that the pubkey is in the trustdb */
rc = query_trust_record( pk );
if( rc == -1 ) { /* put it into the trustdb */
rc = insert_trust_record( pk );
rc = insert_trust_record_by_pk( pk );
if( rc ) {
log_error(_("key %08lX: can't put it into the trustdb\n"),
(ulong)keyid[1] );
@ -633,10 +633,14 @@ print_user_id( FILE *fp, const char *text, u32 *keyid )
/****************
* This function returns a letter for a trustvalue Trust flags
* are ignore.
*/
int
trust_letter( unsigned value )
{
switch( value ) {
switch( (value & TRUST_MASK) ) {
case TRUST_UNKNOWN: return '-';
case TRUST_EXPIRED: return 'e';
case TRUST_UNDEFINED: return 'q';
@ -994,6 +998,10 @@ check_keybinding( KBNODE keyblock, KBNODE keynode, u32 *mainkid,
int is_main = (keynode->pkt->pkttype == PKT_PUBLIC_KEY);
int rc;
if( DBG_TRUST )
log_debug("check_keybinding: %08lX.%lu\n",
(ulong)mainkid[1], lid );
if( is_main ) {
/* a primary key is always valid (user IDs are handled elsewhere)*/
keyflags = KEYF_CHECKED | KEYF_VALID;
@ -1134,6 +1142,10 @@ check_uidsigs( KBNODE keyblock, KBNODE keynode, u32 *mainkid, ulong lid )
PKT_signature *selfsig = NULL; /* the latest valid self signature */
int rc;
if( DBG_TRUST )
log_debug("check_uidsigs: %08lX.%lu\n",
(ulong)mainkid[1], lid );
/* first we check only the selfsignatures */
for( node=keynode->next; node; node = node->next ) {
if( node->pkt->pkttype == PKT_USER_ID
@ -1217,6 +1229,10 @@ check_sig_record( KBNODE keyblock, KBNODE signode,
TRUSTREC tmp;
int revocation=0, rc;
if( DBG_TRUST )
log_debug("check_sig_record: %08lX.%lu %lu[%d]\n",
(ulong)keyid[1], lid, siglid, sigidx );
if( (sig->sig_class&~3) == 0x10 ) /* regular certification */
;
else if( sig->sig_class == 0x30 ) /* cert revocation */
@ -1447,6 +1463,8 @@ update_trust_record( KBNODE keyblock, int recheck, int *modified )
primary_pk->local_id = drec.recnum;
keyid_from_pk( primary_pk, keyid );
if( DBG_TRUST )
log_debug("update_trust_record: %08lX.%lu\n", (ulong)keyid[1], drec.recnum );
rc = tdbio_begin_transaction();
if( rc )
@ -1512,14 +1530,11 @@ update_trust_record( KBNODE keyblock, int recheck, int *modified )
* This function assumes that the record does not yet exist.
*/
int
insert_trust_record( PKT_public_key *orig_pk )
insert_trust_record( KBNODE keyblock )
{
TRUSTREC dirrec;
TRUSTREC shadow;
KBNODE keyblock = NULL;
KBNODE node;
byte fingerprint[MAX_FINGERPRINT_LEN];
size_t fingerlen;
int rc = 0;
PKT_public_key *pk;
@ -1529,39 +1544,11 @@ insert_trust_record( PKT_public_key *orig_pk )
init_trustdb();
fingerprint_from_pk( orig_pk, fingerprint, &fingerlen );
/* fixme: assert that we do not have this record.
* we can do this by searching for the primary keyid
*
* fixme: If there is no such key we should look whether one
* of the subkeys has been used to sign another key and in this case
* we got the key anyway - this is because a secondary key can't be used
* without a primary key (it is needed to bind the secondary one
* to the primary one which has the user ids etc.)
*/
if( orig_pk->local_id )
log_debug("insert_trust_record with pk->local_id=%lu (1)\n",
orig_pk->local_id );
/* get the keyblock which has the key */
rc = get_keyblock_byfprint( &keyblock, fingerprint, fingerlen );
if( rc ) { /* that should never happen */
log_error( _("insert_trust_record: keyblock not found: %s\n"),
g10_errstr(rc) );
goto leave;
}
/* make sure that we use the primary key */
pk = find_kbnode( keyblock, PKT_PUBLIC_KEY )->pkt->pkt.public_key;
if( pk->local_id ) {
orig_pk->local_id = pk->local_id;
log_debug("insert_trust_record with pk->local_id=%lu (2)\n",
pk->local_id );
rc = update_trust_record( keyblock, 1, NULL );
release_kbnode( keyblock );
return rc;
}
@ -1581,9 +1568,8 @@ insert_trust_record( PKT_public_key *orig_pk )
dirrec.r.dir.lid = dirrec.recnum;
write_record( &dirrec );
/* put the LID into the in-memory copy of the keyblock */
/* put the LID into the keyblock */
pk->local_id = dirrec.r.dir.lid;
orig_pk->local_id = dirrec.r.dir.lid;
for( node=keyblock; node; node = node->next ) {
if( node->pkt->pkttype == PKT_PUBLIC_KEY
|| node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
@ -1602,12 +1588,40 @@ insert_trust_record( PKT_public_key *orig_pk )
/* and put all the other stuff into the keydb */
rc = update_trust_record( keyblock, 1, NULL );
leave:
release_kbnode( keyblock );
do_sync();
return rc;
}
/****************
* Insert a trust record indentified by a PK into the TrustDB
*/
int
insert_trust_record_by_pk( PKT_public_key *pk )
{
KBNODE keyblock = NULL;
byte fingerprint[MAX_FINGERPRINT_LEN];
size_t fingerlen;
int rc;
/* get the keyblock */
fingerprint_from_pk( pk, fingerprint, &fingerlen );
rc = get_keyblock_byfprint( &keyblock, fingerprint, fingerlen );
if( rc ) { /* that should never happen */
log_debug( "insert_trust_record_by_pk: keyblock not found: %s\n",
g10_errstr(rc) );
}
else {
rc = insert_trust_record( keyblock );
if( !rc ) /* copy the LID into the PK */
pk->local_id = find_kbnode( keyblock, PKT_PUBLIC_KEY )
->pkt->pkt.public_key->local_id;
}
release_kbnode( keyblock );
return rc;
}
/****************
* Walk over the keyrings and create trustdb records for all keys
@ -1633,8 +1647,9 @@ update_trustdb()
rc = update_trust_record( keyblock, 1, &modified );
if( rc == -1 ) { /* not yet in trustdb: insert */
PKT_public_key *pk = keyblock->pkt->pkt.public_key;
rc = insert_trust_record( pk );
PKT_public_key *pk;
rc = insert_trust_record( keyblock );
pk = keyblock->pkt->pkt.public_key;
if( rc && !pk->local_id ) {
log_error(_("lid ?: insert failed: %s\n"),
g10_errstr(rc) );
@ -1782,7 +1797,7 @@ build_cert_tree( ulong lid, int depth, int max_depth, TN helproot )
m_free(keynode);
return NULL;
}
keynode->n.k.ownertrust = dirrec.r.dir.ownertrust;
keynode->n.k.ownertrust = dirrec.r.dir.ownertrust & TRUST_MASK;
/* loop over all user ids */
for( uidrno = dirrec.r.dir.uidlist; uidrno; uidrno = uidrec.r.uid.next ) {
@ -1872,12 +1887,17 @@ upd_one_ownertrust( ulong lid, unsigned new_trust, unsigned *retflgs )
log_debug("upd_one_ownertrust of %lu from %u to %u\n",
lid, (unsigned)rec.r.dir.ownertrust, new_trust );
if( retflgs ) {
if( new_trust > rec.r.dir.ownertrust )
if( (new_trust & TRUST_MASK) > (rec.r.dir.ownertrust & TRUST_MASK) )
*retflgs |= 16; /* modified up */
else
*retflgs |= 32; /* modified down */
}
rec.r.dir.ownertrust = new_trust;
/* we preserve the disabled state here */
if( (rec.r.dir.ownertrust & TRUST_FLAG_DISABLED) )
rec.r.dir.ownertrust = new_trust | TRUST_FLAG_DISABLED;
else
rec.r.dir.ownertrust = new_trust & ~TRUST_FLAG_DISABLED;
write_record( &rec );
}
@ -2072,8 +2092,9 @@ do_check( TRUSTREC *dr, unsigned *validity,
if( retflgs )
*retflgs &= ~(16|32); /* reset the 2 special flags */
if( namehash ) {
if( (dr->r.dir.ownertrust & TRUST_FLAG_DISABLED) )
*validity = 0; /* no need to check further */
else if( namehash ) {
/* Fixme: use the cache */
*validity = verify_key( opt.max_cert_depth, dr, namehash,
add_fnc, retflgs );
@ -2091,6 +2112,9 @@ do_check( TRUSTREC *dr, unsigned *validity,
if( !(*validity & TRUST_MASK) )
*validity = TRUST_UNDEFINED;
if( (dr->r.dir.ownertrust & TRUST_FLAG_DISABLED) )
*validity |= TRUST_FLAG_DISABLED;
if( dr->r.dir.dirflags & DIRF_REVOKED )
*validity |= TRUST_FLAG_REVOKED;
@ -2223,7 +2247,7 @@ check_trust( PKT_public_key *pk, unsigned *r_trustlevel,
return rc;
}
else if( rc == -1 ) { /* not found - insert */
rc = insert_trust_record( pk );
rc = insert_trust_record_by_pk( pk );
if( rc ) {
log_error(_("key %08lX: insert trust record failed: %s\n"),
(ulong)keyid[1], g10_errstr(rc));
@ -2247,7 +2271,7 @@ check_trust( PKT_public_key *pk, unsigned *r_trustlevel,
log_info(_("key %08lX.%lu: expired at %s\n"),
(ulong)keyid[1], pk->local_id,
asctimestamp( pk->expiredate) );
trustlevel = TRUST_EXPIRED;
trustlevel = TRUST_EXPIRED;
}
else {
rc = do_check( &rec, &trustlevel, namehash, add_fnc, retflgs );
@ -2364,7 +2388,7 @@ list_trust_path( const char *username )
username, g10_errstr(rc));
else if( rc == -1 ) {
log_info(_("user '%s' not in trustdb - inserting\n"), username);
rc = insert_trust_record( pk );
rc = insert_trust_record_by_pk( pk );
if( rc )
log_error(_("failed to put '%s' into trustdb: %s\n"),
username, g10_errstr(rc));

View File

@ -64,8 +64,9 @@ int keyid_from_lid( ulong lid, u32 *keyid );
ulong lid_from_keyblock( KBNODE keyblock );
int query_trust_record( PKT_public_key *pk );
int clear_trust_checked_flag( PKT_public_key *pk );
int insert_trust_record( PKT_public_key *pk );
int update_trust_record( KBNODE keyblock, int fast, int *modified );
int insert_trust_record( KBNODE keyblock );
int insert_trust_record_by_pk( PKT_public_key *pk );
int update_ownertrust( ulong lid, unsigned new_trust );
int trust_letter( unsigned value );

View File

@ -153,6 +153,7 @@ const char *strtimevalue( u32 stamp );
const char *strtimestamp( u32 stamp ); /* GMT */
const char *asctimestamp( u32 stamp ); /* localized */
void print_string( FILE *fp, const byte *p, size_t n, int delim );
char *make_printable_string( const byte *p, size_t n, int delim );
int answer_is_yes( const char *s );
int answer_is_yes_no_quit( const char *s );
@ -160,7 +161,9 @@ int answer_is_yes_no_quit( const char *s );
void free_strlist( STRLIST sl );
#define FREE_STRLIST(a) do { free_strlist((a)); (a) = NULL ; } while(0)
STRLIST add_to_strlist( STRLIST *list, const char *string );
STRLIST add_to_strlist2( STRLIST *list, const char *string, int is_utf8 );
STRLIST append_to_strlist( STRLIST *list, const char *string );
STRLIST append_to_strlist2( STRLIST *list, const char *string, int is_utf8 );
STRLIST strlist_prev( STRLIST head, STRLIST node );
STRLIST strlist_last( STRLIST node );
const char *memistr( const char *buf, size_t buflen, const char *sub );

View File

@ -1,3 +1,10 @@
Thu Jul 1 12:47:31 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* miscutil.c (make_printable_string): New.
* strgutil.c (add_to_strlist2,append_to_strlist2): New.
Tue Jun 29 21:44:25 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>

View File

@ -149,6 +149,60 @@ print_string( FILE *fp, const byte *p, size_t n, int delim )
putc(*p, fp);
}
/****************
* This function returns a string which is suitable for printing
* Caller must release it with m_free()
*/
char *
make_printable_string( const byte *p, size_t n, int delim )
{
size_t save_n, buflen;
const byte *save_p;
char *buffer, *d;
/* first count length */
for(save_n = n, save_p = p, buflen=1 ; n; n--, p++ ) {
if( iscntrl( *p ) || *p == delim ) {
if( *p=='\n' || *p=='\r' || *p=='\f'
|| *p=='\v' || *p=='\b' || !*p )
buflen += 2;
else
buflen += 3;
}
else
buflen++;
}
p = save_p;
n = save_n;
/* and now make the string */
d = buffer = m_alloc( buflen );
for( ; n; n--, p++ ) {
if( iscntrl( *p ) || *p == delim ) {
*d++ = '\\';
if( *p == '\n' )
*d++ = 'n';
else if( *p == '\r' )
*d++ = 'r';
else if( *p == '\f' )
*d++ = 'f';
else if( *p == '\v' )
*d++ = 'v';
else if( *p == '\b' )
*d++ = 'b';
else if( !*p )
*d++ = '0';
else {
sprintf(d, "x%02x", *p );
d += 2;
}
}
else
*d++ = *p;
}
*d = 0;
return buffer;
}
int
answer_is_yes( const char *s )

View File

@ -94,6 +94,25 @@ add_to_strlist( STRLIST *list, const char *string )
return sl;
}
/****************
* ame as add_to_strlist() but if is_utf8 is *not* set a conversion
* to UTF8 is done
*/
STRLIST
add_to_strlist2( STRLIST *list, const char *string, int is_utf8 )
{
STRLIST sl;
if( is_utf8 )
sl = add_to_strlist( list, string );
else {
char *p = native_to_utf8( string );
sl = add_to_strlist( list, p );
m_free( p );
}
return sl;
}
STRLIST
append_to_strlist( STRLIST *list, const char *string )
{
@ -113,6 +132,20 @@ append_to_strlist( STRLIST *list, const char *string )
return sl;
}
STRLIST
append_to_strlist2( STRLIST *list, const char *string, int is_utf8 )
{
STRLIST sl;
if( is_utf8 )
sl = append_to_strlist( list, string );
else {
char *p = native_to_utf8( string );
sl = append_to_strlist( list, p );
m_free( p );
}
return sl;
}
STRLIST