summaryrefslogtreecommitdiffstats
path: root/g10
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>1998-09-28 21:25:31 +0200
committerWerner Koch <wk@gnupg.org>1998-09-28 21:25:31 +0200
commit41fa8a3345aecf9b85c1eebb33f9b961a558db1c (patch)
tree4f5745dc77207f40dabd7f9a176b7255e8994223 /g10
parent. (diff)
downloadgnupg2-41fa8a3345aecf9b85c1eebb33f9b961a558db1c.tar.xz
gnupg2-41fa8a3345aecf9b85c1eebb33f9b961a558db1c.zip
*** empty log message ***
Diffstat (limited to 'g10')
-rw-r--r--g10/ChangeLog94
-rw-r--r--g10/Makefile.am2
-rw-r--r--g10/OPTIONS2
-rw-r--r--g10/armor.c48
-rw-r--r--g10/encode.c16
-rw-r--r--g10/filter.h2
-rw-r--r--g10/g10.c116
-rw-r--r--g10/getkey.c27
-rw-r--r--g10/gpgd.c9
-rw-r--r--g10/import.c15
-rw-r--r--g10/keydb.h4
-rw-r--r--g10/keyedit.c12
-rw-r--r--g10/keygen.c12
-rw-r--r--g10/ks-proto.c299
-rw-r--r--g10/mainproc.c4
-rw-r--r--g10/options.h3
-rw-r--r--g10/parse-packet.c3
-rw-r--r--g10/passphrase.c138
-rw-r--r--g10/pkclist.c16
-rw-r--r--g10/seckey-cert.c2
-rw-r--r--g10/sig-check.c4
-rw-r--r--g10/status.c17
-rw-r--r--g10/trustdb.c24
23 files changed, 453 insertions, 416 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog
index 84ebb78bd..e767f75be 100644
--- a/g10/ChangeLog
+++ b/g10/ChangeLog
@@ -1,21 +1,67 @@
-Fri Sep 18 16:50:32 1998 Werner Koch (wk@(none))
+Mon Sep 28 12:57:12 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * g10.c (verify_own_keys): Add warning if a key is not protected.
+
+ * passphrase (hash_passphrase): Fixed iterated+salted mode and
+ setup for keysizes > hashsize.
+
+ * g10.c (main): New options: --s2k-{cipher,digest,mode}.
+
+Fri Sep 25 09:34:23 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * g10.c: Chnaged some help texts.
+
+Tue Sep 22 19:34:39 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * passphrase.c (read_passphrase_from_fd): fixed bug for long
+ passphrases.
+
+Mon Sep 21 11:28:05 1998 Werner Koch (wk@(none))
+
+ * getkey.c (lookup): Add code to use the sub key if the primary one
+ does not match the usage.
+
+ * armor.c (armor_filter): New error message: no valid data found.
+ (radix64_read): Changes to support multiple messages.
+ (i18n.h): New.
+ * mainproc.c (add_onepass_sig): bug fix.
+
+Mon Sep 21 08:03:16 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * pkclist.c (do_we_trust): Add keyid to most messages.
+
+ * passphrase.c (read_passphrase_from_fd): New.
+ (have_static_passphrase): New
+ (get_passphrase_fd): Removed.
+ (set_passphrase_fd): Removed.
+ * g10.c (main): passphrase is now read here.
+
+ * keyedit.c (keyedit_menu): "help" texts should now translate fine.
+
+Mon Sep 21 06:40:02 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * encode.c (encode_simple): Now disables compression
+ when --rfc1991 is used.
+ (encode_crypt): Ditto.
+
+Fri Sep 18 16:50:32 1998 Werner Koch (wk@isil.d.shuttle.de)
* getkey.c (merge_key_and_selfsig): New.
-Fri Sep 18 10:20:11 1998 Werner Koch (wk@(none))
+Fri Sep 18 10:20:11 1998 Werner Koch (wk@isil.d.shuttle.de)
- * pkclist.c (select_algo_from_prefs): Removed 3DEs kludge.
+ * pkclist.c (select_algo_from_prefs): Removed 3DES kludge.
* seskey.c (make_session_key): Fixed SERIOUS bug introduced
by adding the weak key detection code.
* sign.c (sign_file): Changed aremor header in certain cases.
-Tue Sep 15 17:52:55 1998 Werner Koch (wk@(none))
+Tue Sep 15 17:52:55 1998 Werner Koch (wk@isil.d.shuttle.de)
* mainproc.c (check_sig_and_print): Replaced ascime by asctimestamp.
-Mon Sep 14 11:40:52 1998 Werner Koch (wk@(none))
+Mon Sep 14 11:40:52 1998 Werner Koch (wk@isil.d.shuttle.de)
* seskey.c (make_session_key): Now detects weak keys.
@@ -24,17 +70,17 @@ Mon Sep 14 11:40:52 1998 Werner Koch (wk@(none))
* plaintext.c (handle_plaintext): Does no anymore suppress CR from
cleartext signed messages.
-Sun Sep 13 12:54:29 1998 Werner Koch (wk@(none))
+Sun Sep 13 12:54:29 1998 Werner Koch (wk@isil.d.shuttle.de)
* trustdb.c (insert_trust_record): Fixed a stupid bug in the free
liunked list loops.
-Sat Sep 12 15:49:16 1998 Werner Koch (wk@(none))
+Sat Sep 12 15:49:16 1998 Werner Koch (wk@isil.d.shuttle.de)
* status.c (remove_shmid): New.
(init_shm_comprocess): Now sets permission to the real uid.
-Wed Sep 9 11:15:03 1998 Werner Koch (wk@(none))
+Wed Sep 9 11:15:03 1998 Werner Koch (wk@isil.d.shuttle.de)
* packet.h (PKT_pubkey_enc): New flah throw_keyid, and add logic to
implement it.
@@ -42,11 +88,11 @@ Wed Sep 9 11:15:03 1998 Werner Koch (wk@(none))
* getkey.c (enum_secret_keys): Add new ar and changed all callers.
-Tue Sep 8 20:04:09 1998 Werner Koch (wk@(none))
+Tue Sep 8 20:04:09 1998 Werner Koch (wk@isil.d.shuttle.de)
* delkey.c (delete_key): Moved from keyedit.c.
-Mon Sep 7 16:37:52 1998 Werner Koch (wk@(none))
+Mon Sep 7 16:37:52 1998 Werner Koch (wk@isil.d.shuttle.de)
* build-packet.c (calc_length_header): New arg new_ctb to correctly
calculate the length of new style packets.
@@ -55,7 +101,7 @@ Mon Sep 7 16:37:52 1998 Werner Koch (wk@(none))
* pkclist.c (select_algo_from_prefs): 3DEs substitute is now CAST5.
-Tue Aug 11 17:54:50 1998 Werner Koch (wk@(none))
+Tue Aug 11 17:54:50 1998 Werner Koch (wk@isil.d.shuttle.de)
* build-packet.c (do_secret_key): Fixed handling of old keys.
@@ -63,7 +109,7 @@ Tue Aug 11 17:54:50 1998 Werner Koch (wk@(none))
* openfile.c (open_outfile): Changed arguments and all callers.
-Tue Aug 11 09:14:35 1998 Werner Koch (wk@(none))
+Tue Aug 11 09:14:35 1998 Werner Koch (wk@isil.d.shuttle.de)
* encode.c (encode_simple): Applied option set-filename and comment.
(encode_crypt): Ditto.
@@ -87,7 +133,7 @@ Tue Aug 11 09:14:35 1998 Werner Koch (wk@(none))
* status.c (cpr_get_answer_is_yes): add display_help.
-Mon Aug 10 10:11:28 1998 Werner Koch (wk@(none))
+Mon Aug 10 10:11:28 1998 Werner Koch (wk@isil.d.shuttle.de)
* getkey.c (lookup_sk): Now always returns the primary if arg
primary is true.
@@ -96,15 +142,15 @@ Mon Aug 10 10:11:28 1998 Werner Koch (wk@(none))
(get_seckey_byname): Ditto.
-Mon Aug 10 08:34:03 1998 Werner Koch (wk@(none))
+Mon Aug 10 08:34:03 1998 Werner Koch (wk@isil.d.shuttle.de)
* keyid.c (pubkey_letter): ELG_E is now a small g.
-Sat Aug 8 17:26:12 1998 Werner Koch (wk@(none))
+Sat Aug 8 17:26:12 1998 Werner Koch (wk@isil.d.shuttle.de)
* openfile (overwrite_filep): Changed semantics and all callers.
-Sat Aug 8 12:17:07 1998 Werner Koch (wk@(none))
+Sat Aug 8 12:17:07 1998 Werner Koch (wk@isil.d.shuttle.de)
* status.c (display_help): New.
@@ -118,7 +164,7 @@ Thu Aug 6 07:34:56 1998 Werner Koch,mobil,,, (wk@tobold)
secret keyrings and add additional warning in case of
a failed secret keyring operation.
-Wed Aug 5 11:54:37 1998 Werner Koch (wk@(none))
+Wed Aug 5 11:54:37 1998 Werner Koch (wk@isil.d.shuttle.de)
* g10.c (check_opts): Moved to main. Changed def_cipher_algo
semantics and chnaged all users.
@@ -131,7 +177,7 @@ Wed Aug 5 11:54:37 1998 Werner Koch (wk@(none))
* build-packet.c (do_secret_key): Ditto.
(do_symkey_enc): Ditto.
-Tue Aug 4 08:59:10 1998 Werner Koch (wk@(none))
+Tue Aug 4 08:59:10 1998 Werner Koch (wk@isil.d.shuttle.de)
* getkey.c (enum_secret_keys): Now returns only primary keys.
@@ -142,36 +188,36 @@ Tue Aug 4 08:59:10 1998 Werner Koch (wk@(none))
* sign.c (sign_file): one-pass sigs are now emiited reverse.
Preference data is considered when selecting the compress algo.
-Wed Jul 29 12:53:03 1998 Werner Koch (wk@(none))
+Wed Jul 29 12:53:03 1998 Werner Koch (wk@isil.d.shuttle.de)
* free-packet.c (copy_signature): New.
* keygen.c (generate_subkeypair): rewritten
* g10.c (aKeyadd): Removed option --add-key
-Mon Jul 27 10:37:28 1998 Werner Koch (wk@(none))
+Mon Jul 27 10:37:28 1998 Werner Koch (wk@isil.d.shuttle.de)
* seckey-cert.c (do_check): Additional check on cipher blocksize.
(protect_secret_key): Ditto.
* encr-data.c: Support for other blocksizes.
* cipher.c (write_header): Ditto.
-Fri Jul 24 16:47:59 1998 Werner Koch (wk@(none))
+Fri Jul 24 16:47:59 1998 Werner Koch (wk@isil.d.shuttle.de)
* kbnode.c (insert_kbnode): Changed semantics and all callers.
* keyedit.c : More or less a complete rewrite
-Wed Jul 22 17:10:04 1998 Werner Koch (wk@(none))
+Wed Jul 22 17:10:04 1998 Werner Koch (wk@isil.d.shuttle.de)
* build-packet.c (write_sign_packet_header): New.
-Tue Jul 21 14:37:09 1998 Werner Koch (wk@(none))
+Tue Jul 21 14:37:09 1998 Werner Koch (wk@isil.d.shuttle.de)
* import.c (import_one): Now creates a trustdb record.
* g10.c (main): New command --check-trustdb
-Mon Jul 20 11:15:07 1998 Werner Koch (wk@(none))
+Mon Jul 20 11:15:07 1998 Werner Koch (wk@isil.d.shuttle.de)
* genkey.c (generate_keypair): Default key is now DSA with
encryption only ElGamal subkey.
diff --git a/g10/Makefile.am b/g10/Makefile.am
index c6d5b135e..b38037d28 100644
--- a/g10/Makefile.am
+++ b/g10/Makefile.am
@@ -71,6 +71,8 @@ gpgm_SOURCES = dearmor.c \
#gpgd_SOURCES = gpgd.c \
# ks-proto.h \
# ks-proto.c \
+# ks-db.c \
+# ks-db.h \
# $(common_source)
diff --git a/g10/OPTIONS b/g10/OPTIONS
index 9555ce06a..4ec4192e3 100644
--- a/g10/OPTIONS
+++ b/g10/OPTIONS
@@ -49,7 +49,7 @@ compress-sigs
run-as-shm-coprocess [request-locked-shm-size]
# very special :-)
# You will have to use "--status-fd" too
-
+# Note: This option dioes only work if given on the command line.
set-filename <name>
# Set <name> as the filename into the plaintext packet
diff --git a/g10/armor.c b/g10/armor.c
index 38e1b190d..c72526a98 100644
--- a/g10/armor.c
+++ b/g10/armor.c
@@ -34,6 +34,7 @@
#include "options.h"
#include "main.h"
#include "status.h"
+#include "i18n.h"
#define CRCINIT 0xB704CE
@@ -51,7 +52,7 @@ static int is_initialized;
typedef enum {
- fhdrHASArmor,
+ fhdrHASArmor = 0,
fhdrNOArmor,
fhdrINIT,
fhdrINITCont,
@@ -331,12 +332,12 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen,
if( buf[n-1] == '\r' )
buf[--n] = 0;
if( opt.verbose ) {
- log_info("armor header: ");
+ log_info(_("armor header: "));
print_string( stderr, buf, n, 0 );
putc('\n', stderr);
}
if( clearsig && !(hashes=parse_hash_header( buf )) ) {
- log_error("invalid clearsig header\n");
+ log_error(_("invalid clearsig header\n"));
state = fhdrERROR;
}
else {
@@ -362,7 +363,7 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen,
}
}
else {
- log_error("invalid armor header: ");
+ log_error(_("invalid armor header: "));
print_string( stderr, buf, n, 0 );
putc('\n', stderr);
state = fhdrERROR;
@@ -371,7 +372,7 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen,
else if( c != -1 ) {
if( strchr( buf, ':') ) { /* buffer to short, but this is okay*/
if( opt.verbose ) {
- log_info("armor header: ");
+ log_info(_("armor header: "));
print_string( stderr, buf, n, 0 );
fputs("[...]\n", stderr); /* indicate it is truncated */
}
@@ -436,7 +437,7 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen,
if( hdr_line == BEGIN_SIGNED_MSG_IDX )
clearsig = 1;
if( opt.verbose > 1 )
- log_info("armor: %s\n", head_strings[hdr_line]);
+ log_info(_("armor: %s\n"), head_strings[hdr_line]);
break;
case fhdrCLEARSIG:
@@ -480,7 +481,7 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen,
fhdrREADClearsig : fhdrTESTSpaces;
}
else {
- log_error("invalid dash escaped line: ");
+ log_error(_("invalid dash escaped line: "));
print_string( stderr, buf, n, 0 );
putc('\n', stderr);
state = fhdrERROR;
@@ -549,7 +550,7 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen,
} break;
case fhdrERRORShow:
- log_error("invalid clear text header: ");
+ log_error(_("invalid clear text header: "));
print_string( stderr, buf, n, 0 );
putc('\n', stderr);
state = fhdrERROR;
@@ -779,7 +780,7 @@ radix64_read( armor_filter_context_t *afx, IOBUF a, size_t *retn,
break;
}
else if( (c = asctobin[(c2=c)]) == 255 ) {
- log_error("invalid radix64 character %02x skipped\n", c2);
+ log_error(_("invalid radix64 character %02x skipped\n"), c2);
continue;
}
switch(idx) {
@@ -797,7 +798,10 @@ radix64_read( armor_filter_context_t *afx, IOBUF a, size_t *retn,
afx->idx = idx;
afx->radbuf[0] = val;
if( checkcrc ) {
- afx->inp_eof = 1; /*assume eof */
+ afx->any_data = 1;
+ afx->inp_checked=0;
+ afx->faked = 0;
+ afx->parse_state = 0;
for(;;) { /* skip lf and pad characters */
if( afx->helpidx < afx->helplen )
c = afx->helpbuf[afx->helpidx++];
@@ -809,7 +813,7 @@ radix64_read( armor_filter_context_t *afx, IOBUF a, size_t *retn,
break;
}
if( c == -1 )
- log_error("premature eof (no CRC)\n");
+ log_error(_("premature eof (no CRC)\n"));
else {
u32 mycrc = 0;
idx = 0;
@@ -828,15 +832,15 @@ radix64_read( armor_filter_context_t *afx, IOBUF a, size_t *retn,
break;
} while( ++idx < 4 );
if( c == -1 ) {
- log_error("premature eof (in CRC)\n");
+ log_error(_("premature eof (in CRC)\n"));
rc = G10ERR_INVALID_ARMOR;
}
else if( idx != 4 ) {
- log_error("malformed CRC\n");
+ log_error(_("malformed CRC\n"));
rc = G10ERR_INVALID_ARMOR;
}
else if( mycrc != afx->crc ) {
- log_error("CRC error; %06lx - %06lx\n",
+ log_error(_("CRC error; %06lx - %06lx\n"),
(ulong)afx->crc, (ulong)mycrc);
rc = G10ERR_INVALID_ARMOR;
}
@@ -855,11 +859,11 @@ radix64_read( armor_filter_context_t *afx, IOBUF a, size_t *retn,
if( rc == -1 )
rc = 0;
else if( rc == 2 ) {
- log_error("premature eof (in Trailer)\n");
+ log_error(_("premature eof (in Trailer)\n"));
rc = G10ERR_INVALID_ARMOR;
}
else {
- log_error("error in trailer line\n");
+ log_error(_("error in trailer line\n"));
rc = G10ERR_INVALID_ARMOR;
}
#endif
@@ -874,7 +878,6 @@ radix64_read( armor_filter_context_t *afx, IOBUF a, size_t *retn,
return rc;
}
-
/****************
* This filter is used to handle the armor stuff
*/
@@ -914,13 +917,6 @@ armor_filter( void *opaque, int control,
if( size < 15+(4*15) ) /* need space for up to 4 onepass_sigs */
BUG(); /* supplied buffer too short */
- if( afx->inp_eof ) {
- *ret_len = 0;
- if( DBG_FILTER )
- log_debug("armor-filter: eof due to inp_eof flag\n" );
- return -1;
- }
-
if( afx->faked )
rc = fake_packet( afx, a, &n, buf, size );
else if( !afx->inp_checked ) {
@@ -1021,7 +1017,7 @@ armor_filter( void *opaque, int control,
}
else
iobuf_writestr(a,
- "Comment: Get GNUPG from ftp://ftp.guug.de/pub/gcrypt/\n");
+ "Comment: For info finger gcrypt@ftp.guug.de\n");
if( afx->hdrlines )
iobuf_writestr(a, afx->hdrlines);
iobuf_put(a, '\n');
@@ -1120,6 +1116,8 @@ armor_filter( void *opaque, int control,
iobuf_writestr(a, tail_strings[afx->what] );
iobuf_writestr(a, "-----\n");
}
+ else if( !afx->any_data && !afx->inp_bypass )
+ log_error(_("no valid RFC1991 or OpenPGP data found.\n"));
}
else if( control == IOBUFCTRL_DESC )
*(char**)buf = "armor_filter";
diff --git a/g10/encode.c b/g10/encode.c
index ae8b26116..bc4742607 100644
--- a/g10/encode.c
+++ b/g10/encode.c
@@ -76,6 +76,7 @@ encode_simple( const char *filename, int mode )
cipher_filter_context_t cfx;
armor_filter_context_t afx;
compress_filter_context_t zfx;
+ int do_compress = opt.compress && !opt.rfc1991;
memset( &cfx, 0, sizeof cfx);
memset( &afx, 0, sizeof afx);
@@ -92,12 +93,12 @@ encode_simple( const char *filename, int mode )
cfx.dek = NULL;
if( mode ) {
s2k = m_alloc_clear( sizeof *s2k );
- s2k->mode = opt.rfc1991? 0:1;
+ s2k->mode = opt.rfc1991? 0:opt.s2k_mode;
s2k->hash_algo = opt.def_digest_algo ? opt.def_digest_algo
- : DEFAULT_DIGEST_ALGO;
+ : opt.s2k_digest_algo;
cfx.dek = passphrase_to_dek( NULL,
opt.def_cipher_algo ? opt.def_cipher_algo
- : DEFAULT_CIPHER_ALGO , s2k, 2 );
+ : opt.s2k_cipher_algo , s2k, 2 );
if( !cfx.dek || !cfx.dek->keylen ) {
rc = G10ERR_PASSPHRASE;
m_free(cfx.dek);
@@ -158,13 +159,13 @@ encode_simple( const char *filename, int mode )
pt->buf = inp;
pkt.pkttype = PKT_PLAINTEXT;
pkt.pkt.plaintext = pt;
- cfx.datalen = filesize && !opt.compress ? calc_packet_length( &pkt ) : 0;
+ cfx.datalen = filesize && !do_compress ? calc_packet_length( &pkt ) : 0;
/* register the cipher filter */
if( mode )
iobuf_push_filter( out, cipher_filter, &cfx );
/* register the compress filter */
- if( opt.compress )
+ if( do_compress )
iobuf_push_filter( out, compress_filter, &zfx );
/* do the work */
@@ -197,6 +198,7 @@ encode_crypt( const char *filename, STRLIST remusr )
armor_filter_context_t afx;
compress_filter_context_t zfx;
PK_LIST pk_list;
+ int do_compress = opt.compress && !opt.rfc1991;
memset( &cfx, 0, sizeof cfx);
memset( &afx, 0, sizeof afx);
@@ -270,12 +272,12 @@ encode_crypt( const char *filename, STRLIST remusr )
pt->buf = inp;
pkt.pkttype = PKT_PLAINTEXT;
pkt.pkt.plaintext = pt;
- cfx.datalen = filesize && !opt.compress? calc_packet_length( &pkt ) : 0;
+ cfx.datalen = filesize && !do_compress? calc_packet_length( &pkt ) : 0;
/* register the cipher filter */
iobuf_push_filter( out, cipher_filter, &cfx );
/* register the compress filter */
- if( opt.compress ) {
+ if( do_compress ) {
int compr_algo = select_algo_from_prefs( pk_list, PREFTYPE_COMPR );
if( !compr_algo )
; /* don't use compression */
diff --git a/g10/filter.h b/g10/filter.h
index 2dc8a3e87..d48b75627 100644
--- a/g10/filter.h
+++ b/g10/filter.h
@@ -42,7 +42,7 @@ typedef struct {
int parse_state;
int inp_checked; /* set if inp has been checked */
int inp_bypass; /* set if the input is not armored */
- int inp_eof;
+ int any_data;
const char *hdrlines;
} armor_filter_context_t;
diff --git a/g10/g10.c b/g10/g10.c
index dac154d56..891da839e 100644
--- a/g10/g10.c
+++ b/g10/g10.c
@@ -135,6 +135,9 @@ enum cmd_and_opt_values { aNull = 0,
oSetFilename,
oComment,
oThrowKeyid,
+ oS2KMode,
+ oS2KDigest,
+ oS2KCipher,
aTest };
@@ -212,6 +215,11 @@ static ARGPARSE_OPTS opts[] = {
{ oMarginalsNeeded, "marginals-needed", 1, N_("(default is 3)")},
{ oLoadExtension, "load-extension" ,2, N_("|file|load extension module")},
{ oRFC1991, "rfc1991", 0, N_("emulate the mode described in RFC1991")},
+ { oS2KMode, "s2k-mode", 1, N_("|N| use passphrase mode N")},
+ { oS2KDigest, "s2k-digest-algo",2,
+ N_("|NAME| use message digest algorithm NAME for passphrases")},
+ { oS2KCipher, "s2k-cipher-algo",2,
+ N_("|NAME| use cipher algorithm NAME for passphrases")},
#ifdef IS_G10
{ oCipherAlgo, "cipher-algo", 2 , N_("|NAME|use cipher algorithm NAME")},
{ oDigestAlgo, "digest-algo", 2 , N_("|NAME|use message digest algorithm NAME")},
@@ -226,10 +234,10 @@ static ARGPARSE_OPTS opts[] = {
#ifdef IS_G10
{ 302, NULL, 0, N_("@\nExamples:\n\n"
" -se -r Bob [file] sign and encrypt for user Bob\n"
- " -sat [file] make a clear text signature\n"
- " -sb [file] make a detached signature\n"
- " -k [userid] show keys\n"
- " -kc [userid] show fingerprint\n" ) },
+ " --clearsign [file] make a clear text signature\n"
+ " --detach-sign [file] make a detached signature\n"
+ " --list-keys [names] show keys\n"
+ " --fingerprint [names] show fingerprints\n" ) },
#endif
/* hidden options */
@@ -472,11 +480,15 @@ main( int argc, char **argv )
const char *trustdb_name = NULL;
char *def_cipher_string = NULL;
char *def_digest_string = NULL;
+ char *s2k_cipher_string = NULL;
+ char *s2k_digest_string = NULL;
+ int pwfd = -1;
#ifdef USE_SHM_COPROCESSING
ulong requested_shm_size=0;
#endif
trap_unaligned();
+ secmem_set_flags( secmem_get_flags() | 2 ); /* suspend warnings */
#ifdef IS_G10MAINT
secmem_init( 0 ); /* disable use of secmem */
maybe_setuid = 0;
@@ -497,6 +509,9 @@ main( int argc, char **argv )
opt.def_cipher_algo = 0;
opt.def_digest_algo = 0;
opt.def_compress_algo = 2;
+ opt.s2k_mode = 1; /* salted */
+ opt.s2k_digest_algo = DIGEST_ALGO_RMD160;
+ opt.s2k_cipher_algo = CIPHER_ALGO_BLOWFISH;
opt.completes_needed = 1;
opt.marginals_needed = 3;
opt.homedir = getenv("GNUPGHOME");
@@ -527,8 +542,34 @@ main( int argc, char **argv )
default_config = 0; /* --no-options */
else if( pargs.r_opt == oHomedir )
opt.homedir = pargs.r.ret_str;
+ #ifdef USE_SHM_COPROCESSING
+ else if( pargs.r_opt == oRunAsShmCP ) {
+ /* does not make sense in a options file, we do it here,
+ * so that we are the able to drop setuid as soon as possible */
+ opt.shm_coprocess = 1;
+ requested_shm_size = pargs.r.ret_ulong;
+ }
+ #endif
}
+
+ #ifdef USE_SHM_COPROCESSING
+ if( opt.shm_coprocess ) {
+ #ifdef IS_G10
+ init_shm_coprocessing(requested_shm_size, 1 );
+ #else
+ init_shm_coprocessing(requested_shm_size, 0 );
+ #endif
+ }
+ #endif
+ #ifdef IS_G10
+ /* initialize the secure memory. */
+ secmem_init( 16384 );
+ maybe_setuid = 0;
+ /* Okay, we are now working under our real uid */
+ #endif
+
+
if( default_config )
configname = make_filename(opt.homedir, "options", NULL );
@@ -550,7 +591,7 @@ main( int argc, char **argv )
else {
log_error(_("option file '%s': %s\n"),
configname, strerror(errno) );
- g10_exit(1);
+ g10_exit(2);
}
m_free(configname); configname = NULL;
}
@@ -654,16 +695,18 @@ main( int argc, char **argv )
case oDoNotExportRSA: opt.do_not_export_rsa = 1; break;
case oCompressSigs: opt.compress_sigs = 1; break;
case oRunAsShmCP:
- #ifdef USE_SHM_COPROCESSING
- opt.shm_coprocess = 1;
- requested_shm_size = pargs.r.ret_ulong;
- #else
+ #ifndef USE_SHM_COPROCESSING
+ /* not possible in the option file,
+ * but we print the warning here anyway */
log_error("shared memory coprocessing is not available\n");
#endif
break;
case oSetFilename: opt.set_filename = pargs.r.ret_str; break;
case oComment: opt.comment_string = pargs.r.ret_str; break;
case oThrowKeyid: opt.throw_keyid = 1; break;
+ case oS2KMode: opt.s2k_mode = pargs.r.ret_int; break;
+ case oS2KDigest: s2k_digest_string = m_strdup(pargs.r.ret_str); break;
+ case oS2KCipher: s2k_cipher_string = m_strdup(pargs.r.ret_str); break;
#ifdef IS_G10
case oRemote: /* store the remote users */
@@ -680,7 +723,7 @@ main( int argc, char **argv )
locusr = sl;
break;
case oCompress: opt.compress = pargs.r.ret_int; break;
- case oPasswdFD: set_passphrase_fd( pargs.r.ret_int ); break;
+ case oPasswdFD: pwfd = pargs.r.ret_int; break;
case oCipherAlgo: def_cipher_string = m_strdup(pargs.r.ret_str); break;
case oDigestAlgo: def_digest_string = m_strdup(pargs.r.ret_str); break;
case oNoSecmemWarn: secmem_set_flags( secmem_get_flags() | 1 ); break;
@@ -709,22 +752,7 @@ main( int argc, char **argv )
tty_printf("%s\n", strusage(15) );
}
- #ifdef USE_SHM_COPROCESSING
- if( opt.shm_coprocess ) {
- #ifdef IS_G10
- init_shm_coprocessing(requested_shm_size, 1 );
- #else
- init_shm_coprocessing(requested_shm_size, 0 );
- #endif
- }
- #endif
- #ifdef IS_G10
- /* initialize the secure memory. */
- secmem_init( 16384 );
- maybe_setuid = 0;
- /* Okay, we are now working under our real uid */
- #endif
-
+ secmem_set_flags( secmem_get_flags() & ~2 ); /* resume warnings */
set_debug();
@@ -742,12 +770,29 @@ main( int argc, char **argv )
if( check_digest_algo(opt.def_digest_algo) )
log_error(_("selected digest algorithm is invalid\n"));
}
+ if( s2k_cipher_string ) {
+ opt.s2k_cipher_algo = string_to_cipher_algo(s2k_cipher_string);
+ m_free(s2k_cipher_string); s2k_cipher_string = NULL;
+ if( check_cipher_algo(opt.s2k_cipher_algo) )
+ log_error(_("selected cipher algorithm is invalid\n"));
+ }
+ if( s2k_digest_string ) {
+ opt.s2k_digest_algo = string_to_digest_algo(s2k_digest_string);
+ m_free(s2k_digest_string); s2k_digest_string = NULL;
+ if( check_digest_algo(opt.s2k_digest_algo) )
+ log_error(_("selected digest algorithm is invalid\n"));
+ }
if( opt.def_compress_algo < 1 || opt.def_compress_algo > 2 )
log_error(_("compress algorithm must be in range %d..%d\n"), 1, 2);
if( opt.completes_needed < 1 )
log_error(_("completes-needed must be greater than 0\n"));
if( opt.marginals_needed < 2 )
log_error(_("marginals-needed must be greater than 1\n"));
+ switch( opt.s2k_mode ) {
+ case 0: case 1: case 3: break;
+ default:
+ log_error(_("invalid S2K mode; must be 0, 1 or 3\n"));
+ }
if( log_get_errorcount(0) )
g10_exit(2);
@@ -795,20 +840,11 @@ main( int argc, char **argv )
FREE_STRLIST(nrings);
FREE_STRLIST(sec_nrings);
- if( argc )
- fname = *argv;
- else {
- fname = NULL;
- if( get_passphrase_fd() == 0 ) {
- /* reading data and passphrase from stdin:
- * we assume the first line is the passphrase, so
- * we should read it now.
- *
- * We should do it here, but for now it is not needed.
- * Anyway, this password scheme is not quite good
- */
- }
- }
+
+ if( pwfd != -1 ) /* read the passphrase now. */
+ read_passphrase_from_fd( pwfd );
+
+ fname = argc? *argv : NULL;
switch( cmd ) {
case aPrimegen:
diff --git a/g10/getkey.c b/g10/getkey.c
index f9f4c9f43..eed62e916 100644
--- a/g10/getkey.c
+++ b/g10/getkey.c
@@ -31,6 +31,7 @@
#include "keydb.h"
#include "options.h"
#include "main.h"
+#include "i18n.h"
#define MAX_PK_CACHE_ENTRIES 500
@@ -789,9 +790,6 @@ lookup( PKT_public_key *pk, int mode, u32 *keyid,
}
}
else { /* keyid or fingerprint lookup */
- /* No need to compare the usage here, as we already have the
- * keyid to use
- */
if( DBG_CACHE && (mode== 10 || mode==11) ) {
log_debug("lookup keyid=%08lx%08lx req_algo=%d mode=%d\n",
(ulong)keyid[0], (ulong)keyid[1],
@@ -867,6 +865,29 @@ lookup( PKT_public_key *pk, int mode, u32 *keyid,
merge_one_pk_and_selfsig( keyblock, keyblock );
}
else {
+ if( primary && pk->pubkey_usage
+ && check_pubkey_algo2( k->pkt->pkt.public_key->pubkey_algo,
+ pk->pubkey_usage ) == G10ERR_WR_PUBKEY_ALGO ) {
+ /* if the usage is not correct, try to use a subkey */
+ KBNODE save_k = k;
+
+ for( ; k; k = k->next ) {
+ if( k->pkt->pkttype == PKT_PUBLIC_SUBKEY
+ && !check_pubkey_algo2(
+ k->pkt->pkt.public_key->pubkey_algo,
+ pk->pubkey_usage ) )
+ break;
+ }
+ if( !k )
+ k = save_k;
+ else
+ log_info(_("using secondary key %08lX "
+ "instead of primary key %08lX\n"),
+ (ulong)keyid_from_pk( k->pkt->pkt.public_key, NULL),
+ (ulong)keyid_from_pk( save_k->pkt->pkt.public_key, NULL)
+ );
+ }
+
copy_public_key_new_namehash( pk, k->pkt->pkt.public_key,
use_namehash? namehash:NULL);
merge_one_pk_and_selfsig( keyblock, k );
diff --git a/g10/gpgd.c b/g10/gpgd.c
index da7a990dc..ce92c95d7 100644
--- a/g10/gpgd.c
+++ b/g10/gpgd.c
@@ -18,6 +18,15 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
+/****************
+ * This is a spinning server for most purposes, the server does only
+ * fork for updates (which may require signature checks and lengthy DB
+ * operations).
+ *
+ * see ks-proto.c for the used protocol.
+ * see ks-db.c for the layout of the database.
+ */
+
#include <config.h>
#include <stdio.h>
#include <errno.h>
diff --git a/g10/import.c b/g10/import.c
index 7ef916d27..12a2a099d 100644
--- a/g10/import.c
+++ b/g10/import.c
@@ -459,7 +459,7 @@ import_secret_one( const char *fname, KBNODE keyblock )
_("can't lock secret keyring: %s\n"), g10_errstr(rc) );
else if( (rc=insert_keyblock( &kbpos, keyblock )) )
log_error_f(keyblock_resource_name(&kbpos),
- _("can't write keyring\n"), g10_errstr(rc) );
+ _("can't write keyring: %s\n"), g10_errstr(rc) );
unlock_keyblock( &kbpos );
/* we are ready */
log_info_f(fname, _("key %08lX: secret key imported\n"), (ulong)keyid[1]);
@@ -655,16 +655,17 @@ delete_inv_parts( const char *fname, KBNODE keyblock, u32 *keyid )
else if( node->pkt->pkttype == PKT_SIGNATURE
&& node->pkt->pkt.signature->sig_class == 0x20 ) {
if( uid_seen ) {
- log_error_f(fname, _("key %08lX: revocation certificate at wrong "
- "place - skipped\n"), fname, (ulong)keyid[1]);
+ log_error_f(fname, _("key %08lX: revocation certificate "
+ "at wrong place - skipped\n"),
+ (ulong)keyid[1]);
delete_kbnode( node );
}
else {
int rc = check_key_signature( keyblock, node, NULL);
if( rc ) {
- log_error_f(fname, _("key %08lX: invalid revocation certificate"
- ": %s - skipped\n"),
- fname, (ulong)keyid[1], g10_errstr(rc));
+ log_error_f(fname, _("key %08lX: invalid revocation "
+ "certificate: %s - skipped\n"),
+ (ulong)keyid[1], g10_errstr(rc));
delete_kbnode( node );
}
}
@@ -788,7 +789,7 @@ append_uid( KBNODE keyblock, KBNODE node, int *n_sigs,
/* at lease a self signature comes next to the user-id */
if( node->next->pkt->pkttype == PKT_USER_ID ) {
log_error_f(fname, _("key %08lX: our copy has no self-signature\n"),
- fname, (ulong)keyid[1]);
+ (ulong)keyid[1]);
return G10ERR_GENERAL;
}
diff --git a/g10/keydb.h b/g10/keydb.h
index c16dc4b80..c7fb26db1 100644
--- a/g10/keydb.h
+++ b/g10/keydb.h
@@ -99,8 +99,8 @@ int build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list,
int unlock, unsigned usage );
/*-- passphrase.h --*/
-void set_passphrase_fd( int fd );
-int get_passphrase_fd(void);
+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);
void set_next_passphrase( const char *s );
char *get_last_passphrase(void);
diff --git a/g10/keyedit.c b/g10/keyedit.c
index 13fa24c8c..9387a762e 100644
--- a/g10/keyedit.c
+++ b/g10/keyedit.c
@@ -199,7 +199,6 @@ check_all_keysigs( KBNODE keyblock, int only_selected )
}
-
/****************
* Loop over all locusr and and sign the uids after asking.
* If no user id is marked, all user ids will be signed;
@@ -259,10 +258,9 @@ sign_uids( KBNODE keyblock, STRLIST locusr, int *ret_modified )
(ulong)sk_keyid[1] );
continue;
}
- /* Ask whether we realy should sign these user id(s) */
+ /* Ask whether we really should sign these user id(s) */
tty_printf("\n");
show_key_with_all_names( keyblock, 1, 1, 0, 0 );
- tty_printf("\n");
tty_printf(_(
"Are you really sure that you want to sign this key\n"
"with your key: \""));
@@ -372,9 +370,9 @@ change_passphrase( KBNODE keyblock )
set_next_passphrase( NULL );
for(;;) {
- s2k->mode = 1;
- s2k->hash_algo = DIGEST_ALGO_RMD160;
- dek = passphrase_to_dek( NULL, CIPHER_ALGO_BLOWFISH, s2k, 2 );
+ s2k->mode = opt.s2k_mode;
+ s2k->hash_algo = opt.s2k_digest_algo;
+ dek = passphrase_to_dek( NULL, opt.s2k_cipher_algo, s2k, 2 );
if( !dek ) {
tty_printf(_("passphrase not correctly repeated; try again.\n"));
}
@@ -556,7 +554,7 @@ keyedit_menu( const char *username, STRLIST locusr )
if( cmds[i].need_sk && !sec_keyblock )
; /* skip if we do not have the secret key */
else if( cmds[i].desc )
- tty_printf("%-10s %s\n", cmds[i].name, cmds[i].desc );
+ tty_printf("%-10s %s\n", cmds[i].name, _(cmds[i].desc) );
}
break;
diff --git a/g10/keygen.c b/g10/keygen.c
index 47a24b2ae..1d1cdbfc2 100644
--- a/g10/keygen.c
+++ b/g10/keygen.c
@@ -687,9 +687,9 @@ ask_passphrase( STRING2KEY **ret_s2k )
s2k = m_alloc_secure( sizeof *s2k );
for(;;) {
- s2k->mode = 1;
- s2k->hash_algo = DIGEST_ALGO_RMD160;
- dek = passphrase_to_dek( NULL, CIPHER_ALGO_BLOWFISH, s2k, 2 );
+ s2k->mode = opt.s2k_mode;
+ s2k->hash_algo = opt.s2k_digest_algo;
+ dek = passphrase_to_dek( NULL, opt.s2k_cipher_algo, s2k, 2 );
if( !dek ) {
tty_printf(_("passphrase not correctly repeated; try again.\n"));
}
@@ -970,10 +970,10 @@ generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock )
if( passphrase ) {
s2k = m_alloc_secure( sizeof *s2k );
- s2k->mode = 1;
- s2k->hash_algo = DIGEST_ALGO_RMD160;
+ s2k->mode = opt.s2k_mode;
+ s2k->hash_algo = opt.s2k_digest_algo;
set_next_passphrase( passphrase );
- dek = passphrase_to_dek( NULL, CIPHER_ALGO_BLOWFISH, s2k, 2 );
+ dek = passphrase_to_dek( NULL, opt.s2k_cipher_algo, s2k, 2 );
}
rc = do_create( algo, nbits, pub_keyblock, sec_keyblock,
diff --git a/g10/ks-proto.c b/g10/ks-proto.c
index b862357fb..b5109f2ad 100644
--- a/g10/ks-proto.c
+++ b/g10/ks-proto.c
@@ -42,245 +42,114 @@
* X-Key-MTime: <last modification time>
* X-Key-LID: <local_key_id_used_for_update_etc>
* [fixme: is X-.... allowed?]
+ *
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <errno.h>
+#include <ctype.h>
#include "util.h"
#include "ks-proto.h"
-#if 0
-/****************
- * Read a protocol line
- */
-static int
-read_line( FILE *fp )
-{
- return -1;
-}
-
-
-
-
-/****************
- * Send a HKP request
- */
-int
-hkp_request( int operation, const char *user_id )
-{
-
-}
-
-
-
-
-
-/************************************************
- ******* client communication stuff ************
- ************************************************/
-
-/****************
- * Initialisieren des clients
- * Es wird ein Handle zurückgegeben oder -1 bei einem fehler.
- * z.Z. ist nut eine Verbindung gleichzeitig möglich.
- * Wenn einer serverpid von 0 angegeben wird, so wird diese
- * der environment variabeln ATEXDB_PID entnommen.
- */
-
-int
-hkp_open( const char *serverurl )
-{
- const char *s;
-
- s = SERVER_NAME_TEMPLATE;
- client.serv_name = xmalloc(strlen(s) + 10 );
- sprintf(client.serv_name,s, serverpid );
- if( opt.verbose )
- Info("Using unix domain stream '%s'", client.serv_name );
-
- memset( &client.serv_addr, 0, sizeof client.serv_addr );
- client.serv_addr.sun_family = AF_UNIX;
- strcpy( client.serv_addr.sun_path, client.serv_name );
- client.serv_addr_len = strlen(client.serv_addr.sun_path)
- + sizeof client.serv_addr.sun_family;
-
- client.sockfd = -1;
- if( DoCheckVersion() )
- return -1;
- return 0;
-}
-
-
-static int
-DoConnect()
-{
- if( client.sockfd != -1 )
- DoDisconnect();
- if( (client.sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1 ) {
- Error(1000,"can't open unix domain socket");
- return 1;
- }
- if( connect(client.sockfd, (struct sockaddr*)&client.serv_addr,
- client.serv_addr_len) == -1 ) {
- Error(1000,"can't connect to '%s'",client.serv_addr.sun_path);
- return 1;
- }
-
- return 0; /* okay */
-}
-
-static int
-DoDisconnect()
-{
- if( client.sockfd != -1 ) {
- close(client.sockfd);
- client.sockfd = -1;
- }
- return 0; /* okay */
-}
-/****************
- * NBYTES auf den aktuellen stream schreiben.
- */
static int
-DoWrite( void *buf, size_t nbytes )
+do_read( int fd, char *buffer, size_t bufsize, int *ret_nread )
{
- size_t nleft = nbytes;
- ssize_t nwritten;
-
- while( nleft > 0 ) {
- /* FIXME: add EINTR handling */
- nwritten = write(client.sockfd, buf, nleft);
- if( nwritten < 0 ) {
- Error(1000,"error writing to server");
+ int n;
+ fd_set rfds;
+ struct timeval tv;
+ int rc;
+
+ *ret_nread = 0;
+ do {
+ FD_ZERO(&rfds);
+ FD_SET(fd, &rfds);
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+ if( !(rc=select(fd+1, &rfds, NULL, NULL, &tv)) )
+ return 0; /* timeout */
+ if( rc == -1 ) {
+ log_error("select() error: %s\n", strerror(errno));
return -1;
}
- nleft -= nwritten;
- buf = (char*)buf + nwritten;
- }
- return 0;
-}
-
-static int
-DoWriteStr( const char *s )
-{
- return DoWrite((char *)s, strlen(s) );
-}
-
-
-static int
-DoRead( void *buf, size_t buflen, size_t *ret_nread, int stop)
-{
- size_t nleft = buflen;
- int nread;
- char *p;
-
- p = buf;
- while( nleft > 0 ) {
- /* FIXME: add EINTR handling */
- nread = read(client.sockfd, buf, stop? 1 : nleft);
- if( nread < 0 ) {
- Error(1000,"error reading from server");
- return -1;
- }
- else if( !nread )
- break; /* EOF */
- nleft -= nread;
- buf = (char*)buf + nread;
- if( stop )
- for(; p < (char*)buf ; p++ )
- if( *p == '\n' )
- goto leave;
- }
- leave:
- if( ret_nread )
- *ret_nread = buflen - nleft;
- return 0;
-}
-
-/****************
- * Like DoRead(), but append the received data to the given strgbuf.
- * read a maximum of nbytes;
- */
-static int
-DoReadIntoStrgbuf( strgbuf_t *strgbuf, size_t nbytes, size_t *ret_nread)
-{
- size_t ntotal, nleft;
- int nread;
- byte *p, buffer[1000];
- ntotal = 0;
- nleft = nbytes;
- while( nleft ) {
- nread = read(client.sockfd, buffer,
- nleft > DIM(buffer)? DIM(buffer) : nleft);
- if( nread < 0 ) {
- Error(1000,"error reading from server");
+ do {
+ n = read(fd, buffer, bufsize );
+ if( n >= 0 && n > bufsize )
+ log_bug("bogus read from fd %d (n=%d)\n", fd, n );
+ } while( n == -1 && errno == EINTR );
+ if( n == -1 ) {
+ log_error("read error on fd %d: %s\n", fd, strerror(errno) );
return -1;
}
- else if( !nread )
- break; /* EOF */
- nleft -= nread;
- ntotal += nread;
- /* ab in den stringbuffer */
- for(p=buffer; nread; nread--, p++ )
- PutStrgbuf(strgbuf, *p );
- }
-
- if( ret_nread )
- *ret_nread = ntotal;
+ } while( !n );
+ *ret_nread = n;
return 0;
}
-/****************
- * In retval wird das numerische argument nach OK zurückgegeben
- */
-static int
-DoRequest( char *request, long *retval )
-{
- if( DoWrite(request, strlen(request)) )
- return -1;
- return DoWaitReply( retval );
-}
-
-static int
-DoWaitReply( long *retval )
+int
+ks_get_request( int fd, KS_TRANS *req )
{
- char *p, buf[200]; /* enough room for messages */
- size_t nread;
+ char *p, *p2, buf[500];
+ int nread, n;
+ int state = 0;
+
+ req->err = 0;
+ req->data = NULL;
+ while( !do_read( fd, buf, DIM(buf)-1, &nread ) {
+ p = buf;
+ if( !state ) {
+ /* replace the trailing LF with a 0 */
+ for(p2=p,n=0; n < nread && *p2 != '\n'; p2++ )
+ ;
+ if( *p2 != '\n' ) {
+ req->err = KS_ERR_REQ_TOO_LONG;
+ break;
+ }
+ *p2++ = 0;
+ n++;
+
+ /* now look at the request. Note that the isspace() will work
+ * because there is still a CR before the 0 */
+ if( (p[0] == 'G' || p[0] == 'g')
+ && (p[1] == 'E' || p[1] == 'e')
+ && (p[2] == 'T' || p[2] == 't') && isspace( p[3] ) ) {
+ req->cmd = KS_REQ_GET;
+ p += 4;
+ }
+ else if( (p[0] == 'H' || p[0] == 'h')
+ && (p[1] == 'E' || p[1] == 'e')
+ && (p[2] == 'A' || p[2] == 'a')
+ && (p[3] == 'D' || p[3] == 'd') && isspace( p[4] ) ) {
+ req->cmd = KS_REQ_HEAD;
+ p += 5;
+ }
+ else if( (p[0] == 'H' || p[0] == 'h')
+ && (p[1] == 'E' || p[1] == 'e')
+ && (p[2] == 'L' || p[2] == 'l')
+ && (p[3] == 'P' || p[3] == 'p') && isspace( p[4] ) ) {
+ req->cmd = KS_REQ_HELP;
+ p += 5;
+ }
+ else
+ req->cmd = KS_REQ_UNKNOWN;
+ /* skip spaces, store args and remaining data */
+ while( *p == ' ' || *p == '\t' )
+ p++;
+ /* fixme: remove trailing blanks from args */
+ req->args = p;
+ p = p2; /* p now points to the remaining n bytes in the buffer */
+ state = 1;
+ }
+ if( state == 1 ) {
+ /* read the option lines */
+ }
- /* read but stop at the first newline */
- if( DoRead(buf, DIM(buf)-2, &nread, 1 ) )
- return -1;
- buf[DIM(buf)-1] = 0;
- /* fixme: should check, that we have the linefeed and otherwise
- * perform a dummy read */
- if( p = strchr(buf, '\n') )
- *p = 0;
- if( *buf == 'O' && buf[1] == 'K' && (buf[2]==' ' || !buf[2]) ) {
- if( retval )
- *retval = buf[2]? strtol(buf+3, NULL, 10 ):0;
- return 0;
}
- Error(0, "Server replied: %.60s", buf );
- return -1;
}
-
-
-
-
-
-
-
-
-
-
-#endif
-
-
-
diff --git a/g10/mainproc.c b/g10/mainproc.c
index 1e8af7e21..bcbc4bd92 100644
--- a/g10/mainproc.c
+++ b/g10/mainproc.c
@@ -88,8 +88,10 @@ add_onepass_sig( CTX c, PACKET *pkt )
if( c->list->pkt->pkttype != PKT_ONEPASS_SIG ) {
log_error("add_onepass_sig: another packet is in the way\n");
release_list( c );
+ c->list = new_kbnode( pkt );
}
- add_kbnode( c->list, new_kbnode( pkt ));
+ else
+ add_kbnode( c->list, new_kbnode( pkt ));
}
else /* insert the first one */
c->list = node = new_kbnode( pkt );
diff --git a/g10/options.h b/g10/options.h
index a4b4167c4..d674ada12 100644
--- a/g10/options.h
+++ b/g10/options.h
@@ -55,6 +55,9 @@ struct {
const char *set_filename;
const char *comment_string;
int throw_keyid;
+ int s2k_mode;
+ int s2k_digest_algo;
+ int s2k_cipher_algo;
} opt;
diff --git a/g10/parse-packet.c b/g10/parse-packet.c
index 2601e1571..1cd14acfb 100644
--- a/g10/parse-packet.c
+++ b/g10/parse-packet.c
@@ -1068,6 +1068,9 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
}
sk->protect.s2k.count = iobuf_get(inp);
pktlen--;
+ if( list_mode )
+ printf("\tprotect count: %lu\n",
+ (ulong)sk->protect.s2k.count);
}
}
else { /* old version; no S2K, so we set mode to 0, hash MD5 */
diff --git a/g10/passphrase.c b/g10/passphrase.c
index 7dbaeb466..2e649119d 100644
--- a/g10/passphrase.c
+++ b/g10/passphrase.c
@@ -34,22 +34,16 @@
#include "i18n.h"
#include "status.h"
-static int pwfd = -1;
+static char *fd_passwd = NULL;
static char *next_pw = NULL;
static char *last_pw = NULL;
static void hash_passphrase( DEK *dek, char *pw, STRING2KEY *s2k, int create );
-void
-set_passphrase_fd( int fd )
-{
- pwfd = fd;
-}
-
int
-get_passphrase_fd()
+have_static_passphrase()
{
- return pwfd;
+ return !!fd_passwd;
}
/****************
@@ -81,6 +75,36 @@ get_last_passphrase()
}
+void
+read_passphrase_from_fd( int fd )
+{
+ int i, len;
+ char *pw;
+
+ if( !opt.batch )
+ tty_printf("Reading passphrase from file descriptor %d ...", fd );
+ for( pw = NULL, i = len = 100; ; i++ ) {
+ if( i >= len-1 ) {
+ char *pw2 = pw;
+ len += 100;
+ pw = m_alloc_secure( len );
+ if( pw2 )
+ memcpy(pw, pw2, i );
+ else
+ i=0;
+ }
+ if( read( fd, pw+i, 1) != 1 || pw[i] == '\n' )
+ break;
+ }
+ pw[i] = 0;
+ if( !opt.batch )
+ tty_printf("\b\b\b \n" );
+
+ m_free( fd_passwd );
+ fd_passwd = pw;
+}
+
+
/****************
* Get a passphrase for the secret key with KEYID, display TEXT
* if the user needs to enter the passphrase.
@@ -140,26 +164,9 @@ passphrase_to_dek( u32 *keyid, int cipher_algo, STRING2KEY *s2k, int mode )
pw = next_pw;
next_pw = NULL;
}
- else if( pwfd != -1 ) { /* read the passphrase from the file */
- int i, len;
-
- if( !opt.batch )
- tty_printf("Reading from file descriptor %d ...", pwfd );
- for( pw = NULL, i = len = 100; ; i++ ) {
- if( i >= len-1 ) {
- char *pw2 = pw;
- len += 100;
- pw = m_alloc_secure( len );
- if( pw2 )
- memcpy(pw, pw2, i );
- i=0;
- }
- if( read( pwfd, pw+i, 1) != 1 || pw[i] == '\n' )
- break;
- }
- pw[i] = 0;
- if( !opt.batch )
- tty_printf("\b\b\b \n" );
+ else if( fd_passwd ) {
+ pw = m_alloc_secure( strlen(fd_passwd)+1 );
+ strcpy( pw, fd_passwd );
}
else if( opt.batch )
log_fatal("Can't query password in batchmode\n");
@@ -192,54 +199,69 @@ passphrase_to_dek( u32 *keyid, int cipher_algo, STRING2KEY *s2k, int mode )
/****************
* Hash a passphrase using the supplied s2k. If create is true, create
- * a new salt or whatelse must be filled into the s2k for a new key.
+ * a new salt or what else must be filled into the s2k for a new key.
* always needs: dek->algo, s2k->mode, s2k->hash_algo.
*/
static void
hash_passphrase( DEK *dek, char *pw, STRING2KEY *s2k, int create )
{
MD_HANDLE md;
+ int pass, i;
+ int used = 0;
+ int pwlen = strlen(pw);
assert( s2k->hash_algo );
- dek->keylen = 0;
+ dek->keylen = cipher_get_keylen( dek->algo ) / 8;
+ if( !(dek->keylen > 0 && dek->keylen <= DIM(dek->key)) )
+ BUG();
+
md = md_open( s2k->hash_algo, 1);
- if( s2k->mode == 1 || s2k->mode == 3 ) {
- ulong count = 0;
- int len = strlen(pw);
- int len2 = len + 8;
+ for(pass=0; used < dek->keylen ; pass++ ) {
+ if( pass ) {
+ md_reset(md);
+ for(i=0; i < pass; i++ ) /* preset the hash context */
+ md_putc(md, 0 );
+ }
- if( create )
- randomize_buffer(s2k->salt, 8, 1);
+ if( s2k->mode == 1 || s2k->mode == 3 ) {
+ int len2 = pwlen + 8;
+ ulong count = len2;
- if( s2k->mode == 3 ) {
- count = (16ul + (s2k->count & 15)) << ((s2k->count >> 4) + 6);
- log_debug("s2k iteration count=%lu\n", count );
- }
- for(;;) {
- md_write( md, s2k->salt, 8 );
- md_write( md, pw, len );
- if( count <= len2 )
- break;
- count -= len2;
- }
- if( count ) {
- if( count < 8 ) {
- md_write( md, s2k->salt, count );
+ if( create && !pass ) {
+ randomize_buffer(s2k->salt, 8, 1);
+ if( s2k->mode == 3 )
+ s2k->count = 96; /* = 56536 */
}
+
+ if( s2k->mode == 3 ) {
+ count = (16ul + (s2k->count & 15)) << ((s2k->count >> 4) + 6);
+ if( count < len2 )
+ count = len2;
+ }
+ /* a little bit complicated because we need a ulong for count */
+ while( count > len2 ) { /* maybe iterated+salted */
+ md_write( md, s2k->salt, 8 );
+ md_write( md, pw, pwlen );
+ count -= len2;
+ }
+ if( count < 8 )
+ md_write( md, s2k->salt, count );
else {
md_write( md, s2k->salt, 8 );
count -= 8;
- assert( count <= len );
+ assert( count >= 0 );
md_write( md, pw, count );
}
}
+ else
+ md_write( md, pw, pwlen );
+ md_final( md );
+ i = md_digest_length( s2k->hash_algo );
+ if( i > dek->keylen - used )
+ i = dek->keylen - used;
+ memcpy( dek->key+used, md_read(md, s2k->hash_algo), i );
+ used += i;
}
- else
- md_write( md, pw, strlen(pw) );
- md_final( md );
- dek->keylen = cipher_get_keylen( dek->algo ) / 8;
- assert(dek->keylen > 0 && dek->keylen <= DIM(dek->key) );
- memcpy( dek->key, md_read(md,0), dek->keylen );
md_close(md);
}
diff --git a/g10/pkclist.c b/g10/pkclist.c
index 4f52eebb7..272a861b7 100644
--- a/g10/pkclist.c
+++ b/g10/pkclist.c
@@ -182,7 +182,8 @@ do_we_trust( PKT_public_key *pk, int trustlevel )
int rc;
if( (trustlevel & TRUST_FLAG_REVOKED) ) {
- log_info("key has been revoked!\n");
+ log_info("%08lX: key has been revoked!\n",
+ (ulong)keyid_from_pk( pk, NULL) );
if( opt.batch )
return 0;
@@ -209,12 +210,13 @@ do_we_trust( PKT_public_key *pk, int trustlevel )
return do_we_trust( pk, trustlevel );
case TRUST_EXPIRED:
- log_info("key has expired\n");
+ log_info("%08lX: key has expired\n", (ulong)keyid_from_pk( pk, NULL) );
return 0; /* no */
case TRUST_UNDEFINED:
if( opt.batch || opt.answer_no )
- log_info("no info to calculate a trust probability\n");
+ log_info("%08lX: no info to calculate a trust probability\n",
+ (ulong)keyid_from_pk( pk, NULL) );
else {
rc = add_ownertrust( pk );
if( !rc ) {
@@ -229,12 +231,14 @@ do_we_trust( PKT_public_key *pk, int trustlevel )
return 0;
case TRUST_NEVER:
- log_info("We do NOT trust this key\n");
+ log_info("%08lX: We do NOT trust this key\n",
+ (ulong)keyid_from_pk( pk, NULL) );
return 0; /* no */
case TRUST_MARGINAL:
- log_info("I'm not sure whether this key really belongs to the owner\n"
- "but I proceed anyway\n");
+ log_info("%08lX: I'm not sure whether this key really belongs to the owner\n"
+ "but I proceed anyway\n",
+ (ulong)keyid_from_pk( pk, NULL) );
return 1; /* yes */
case TRUST_FULLY:
diff --git a/g10/seckey-cert.c b/g10/seckey-cert.c
index 9253b8ce1..d43f8619d 100644
--- a/g10/seckey-cert.c
+++ b/g10/seckey-cert.c
@@ -168,7 +168,7 @@ check_secret_key( PKT_secret_key *sk, int n )
if( i )
log_error(_("Invalid passphrase; please try again ...\n"));
rc = do_check( sk );
- if( get_passphrase_fd() != -1 )
+ if( have_static_passphrase() )
break;
}
diff --git a/g10/sig-check.c b/g10/sig-check.c
index 1dda44529..5e6873f9d 100644
--- a/g10/sig-check.c
+++ b/g10/sig-check.c
@@ -152,8 +152,8 @@ do_check( PKT_public_key *pk, PKT_signature *sig, MD_HANDLE digest )
u32 cur_time;
if( pk->version == 4 && pk->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E ) {
- log_info("this is a PGP generated "
- "ElGamal key which is NOT secure for signatures!\n");
+ log_info(_("this is a PGP generated "
+ "ElGamal key which is NOT secure for signatures!\n"));
return G10ERR_PUBKEY_ALGO;
}
diff --git a/g10/status.c b/g10/status.c
index 7cb2f5c5d..97b4fba97 100644
--- a/g10/status.c
+++ b/g10/status.c
@@ -31,6 +31,9 @@
#ifdef HAVE_SYS_SHM_H
#include <sys/shm.h>
#endif
+ #if defined(HAVE_MLOCK)
+ #include <sys/mman.h>
+ #endif
#endif
#include "util.h"
#include "status.h"
@@ -142,11 +145,21 @@ init_shm_coprocessing ( ulong requested_shm_size, int lock_mem )
log_info("mapped %uk shared memory at %p, id=%d\n",
(unsigned)shm_size/1024, shm_area, shm_id );
if( lock_mem ) {
+ #ifdef IPC_HAVE_SHM_LOCK
if ( shmctl (shm_id, SHM_LOCK, 0) )
- log_info("Locking shared memory %d failed: %s\n",
+ log_info("locking shared memory %d failed: %s\n",
shm_id, strerror(errno));
else
shm_is_locked = 1;
+ #elif defined(HAVE_MLOCK) && !defined(HAVE_BROKEN_MLOCK)
+ if ( mlock (shm_area, shm_size) )
+ log_info("locking shared memory %d failed: %s\n",
+ shm_id, strerror(errno));
+ else
+ shm_is_locked = 1;
+ #else
+ log_info("Locking shared memory %d failed: No way to do it\n", shm_id );
+ #endif
}
@@ -225,7 +238,7 @@ do_shm_get( const char *keyword, int hidden, int bool )
static void
display_help( const char *keyword )
{
- char *p;
+ const char *p;
int hint = 0;
tty_kill_prompt();
diff --git a/g10/trustdb.c b/g10/trustdb.c
index bce0df0c9..b36c176ae 100644
--- a/g10/trustdb.c
+++ b/g10/trustdb.c
@@ -105,7 +105,7 @@ static TRUST_SEG_LIST last_trust_web_tslist;
#define HEXTOBIN(a) ( (a) >= '0' && (a) <= '9' ? ((a)-'0') : \
(a) >= 'A' && (a) <= 'F' ? ((a)-'A'+10) : ((a)-'a'+10))
-
+
/**********************************************
************* list helpers *******************
**********************************************/
@@ -239,6 +239,8 @@ keyid_from_lid( ulong lid, u32 *keyid )
return 0;
}
+
+
/****************
* Walk through the signatures of a public key.
* The caller must provide a context structure, with all fields set
@@ -333,7 +335,7 @@ walk_sigrecs( SIGREC_CONTEXT *c, int create )
-
+
/***********************************************
************* Trust stuff ******************
***********************************************/
@@ -357,6 +359,10 @@ verify_own_keys()
if( DBG_TRUST )
log_debug("key %08lX: checking secret key\n", (ulong)keyid[1] );
+ if( is_secret_key_protected( sk ) < 1 )
+ log_info("note: secret key %08lX is NOT protected.\n",
+ (ulong)keyid[1] );
+
/* see whether we can access the public key of this secret key */
memset( pk, 0, sizeof *pk );
rc = get_pubkey( pk, keyid );
@@ -1204,7 +1210,7 @@ do_check( TRUSTREC *dr, unsigned *trustlevel )
return 0;
}
-
+
/***********************************************
**************** API ************************
***********************************************/
@@ -1564,6 +1570,8 @@ check_trustdb( const char *username )
}
}
+
+
/****************
* Get the trustlevel for this PK.
* Note: This does not ask any questions
@@ -1612,11 +1620,11 @@ check_trust( PKT_public_key *pk, unsigned *r_trustlevel )
rc = insert_trust_record( pk );
if( rc ) {
log_error(_("key %08lX: insert trust record failed: %s\n"),
- keyid[1], g10_errstr(rc));
+ (ulong)keyid[1], g10_errstr(rc));
goto leave;
}
log_info(_("key %08lX.%lu: inserted into trustdb\n"),
- keyid[1], pk->local_id );
+ (ulong)keyid[1], pk->local_id );
/* and re-read the dir record */
if( tdbio_read_record( pk->local_id, &rec, RECTYPE_DIR ) ) {
log_error("check_trust: reread dir record failed\n");
@@ -1628,14 +1636,14 @@ check_trust( PKT_public_key *pk, unsigned *r_trustlevel )
if( pk->timestamp > cur_time ) {
log_info(_("key %08lX.%lu: created in future "
"(time warp or clock problem)\n"),
- keyid[1], pk->local_id );
+ (ulong)keyid[1], pk->local_id );
return G10ERR_TIME_CONFLICT;
}
if( pk->valid_days && add_days_to_timestamp(pk->timestamp,
pk->valid_days) < cur_time ) {
log_info(_("key %08lX.%lu: expired at %s\n"),
- keyid[1], pk->local_id,
+ (ulong)keyid[1], pk->local_id,
asctimestamp( add_days_to_timestamp(pk->timestamp,
pk->valid_days)));
trustlevel = TRUST_EXPIRED;
@@ -1644,7 +1652,7 @@ check_trust( PKT_public_key *pk, unsigned *r_trustlevel )
rc = do_check( &rec, &trustlevel );
if( rc ) {
log_error(_("key %08lX.%lu: trust check failed: %s\n"),
- keyid[1], pk->local_id, g10_errstr(rc));
+ (ulong)keyid[1], pk->local_id, g10_errstr(rc));
return rc;
}
}